Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/differential/controller/DifferentialCommentSaveControllerPro.php b/src/applications/differential/controller/DifferentialCommentSaveControllerPro.php
index 8128372187..be450c98db 100644
--- a/src/applications/differential/controller/DifferentialCommentSaveControllerPro.php
+++ b/src/applications/differential/controller/DifferentialCommentSaveControllerPro.php
@@ -1,178 +1,181 @@
<?php
final class DifferentialCommentSaveControllerPro
extends DifferentialController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
if (!$request->isFormPost()) {
return new Aphront400Response();
}
$revision = id(new DifferentialRevisionQuery())
->setViewer($viewer)
->withIDs(array($this->id))
->needReviewerStatus(true)
->executeOne();
if (!$revision) {
return new Aphront404Response();
}
$type_action = DifferentialTransaction::TYPE_ACTION;
$type_subscribers = PhabricatorTransactions::TYPE_SUBSCRIBERS;
$type_edge = PhabricatorTransactions::TYPE_EDGE;
$type_comment = PhabricatorTransactions::TYPE_COMMENT;
$type_inline = DifferentialTransaction::TYPE_INLINE;
$edge_reviewer = PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER;
$xactions = array();
$action = $request->getStr('action');
switch ($action) {
case DifferentialAction::ACTION_COMMENT:
case DifferentialAction::ACTION_ADDREVIEWERS:
case DifferentialAction::ACTION_ADDCCS:
// These transaction types have no direct effect, they just
// accompany other transaction types which can have an effect.
break;
default:
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_action)
->setNewValue($request->getStr('action'));
break;
}
$ccs = $request->getArr('ccs');
if ($ccs) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_subscribers)
->setNewValue(array('+' => $ccs));
}
$current_reviewers = mpull(
$revision->getReviewerStatus(),
null,
'getReviewerPHID');
$reviewer_edges = array();
$add_reviewers = $request->getArr('reviewers');
foreach ($add_reviewers as $reviewer_phid) {
if (isset($current_reviewers[$reviewer_phid])) {
continue;
}
$reviewer = new DifferentialReviewer(
$reviewer_phid,
array(
'status' => DifferentialReviewerStatus::STATUS_ADDED,
));
$reviewer_edges[$reviewer_phid] = array(
'data' => $reviewer->getEdgeData(),
);
}
if ($add_reviewers) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_edge)
->setMetadataValue('edge:type', $edge_reviewer)
->setNewValue(array('+' => $reviewer_edges));
}
$inline_phids = $this->loadUnsubmittedInlinePHIDs($revision);
if ($inline_phids) {
$inlines = id(new PhabricatorApplicationTransactionCommentQuery())
->setTemplate(new DifferentialTransactionComment())
->setViewer($viewer)
->withPHIDs($inline_phids)
->execute();
} else {
$inlines = null;
}
foreach ($inlines as $inline) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_inline)
->attachComment($inline);
}
// NOTE: If there are no other transactions, add an empty comment
// transaction so that we'll raise a more user-friendly error message,
// to the effect of "you can not post an empty comment".
$no_xactions = !$xactions;
$comment = $request->getStr('comment');
if (strlen($comment) || $no_xactions) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType($type_comment)
->attachComment(
id(new DifferentialTransactionComment())
->setRevisionPHID($revision->getPHID())
->setContent($comment));
}
$editor = id(new DifferentialTransactionEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect($request->isContinueRequest());
$revision_uri = '/D'.$revision->getID();
try {
$editor->applyTransactions($revision, $xactions);
} catch (PhabricatorApplicationTransactionNoEffectException $ex) {
return id(new PhabricatorApplicationTransactionNoEffectResponse())
->setCancelURI($revision_uri)
->setException($ex);
+ } catch (PhabricatorApplicationTransactionValidationException $ex) {
+ // TODO: Provide a nice Response for rendering these in a clean way.
+ throw $ex;
}
$user = $request->getUser();
$draft = id(new PhabricatorDraft())->loadOneWhere(
'authorPHID = %s AND draftKey = %s',
$user->getPHID(),
'differential-comment-'.$revision->getID());
if ($draft) {
$draft->delete();
}
DifferentialDraft::deleteAllDrafts($user->getPHID(), $revision->getPHID());
return id(new AphrontRedirectResponse())
->setURI('/D'.$revision->getID());
}
private function loadUnsubmittedInlinePHIDs(DifferentialRevision $revision) {
$viewer = $this->getRequest()->getUser();
// TODO: This probably needs to move somewhere more central as we move
// away from DifferentialInlineCommentQuery, but
// PhabricatorApplicationTransactionCommentQuery is currently `final` and
// I'm not yet decided on how to approach that. For now, just get the PHIDs
// and then execute a PHID-based query through the standard stack.
$table = new DifferentialTransactionComment();
$conn_r = $table->establishConnection('r');
$phids = queryfx_all(
$conn_r,
'SELECT phid FROM %T
WHERE revisionPHID = %s
AND authorPHID = %s
AND transactionPHID IS NULL',
$table->getTableName(),
$revision->getPHID(),
$viewer->getPHID());
return ipull($phids, 'phid');
}
}
diff --git a/src/applications/differential/editor/DifferentialTransactionEditor.php b/src/applications/differential/editor/DifferentialTransactionEditor.php
index ca7c55bde6..5257141e93 100644
--- a/src/applications/differential/editor/DifferentialTransactionEditor.php
+++ b/src/applications/differential/editor/DifferentialTransactionEditor.php
@@ -1,224 +1,450 @@
<?php
final class DifferentialTransactionEditor
extends PhabricatorApplicationTransactionEditor {
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
$types[] = DifferentialTransaction::TYPE_ACTION;
$types[] = DifferentialTransaction::TYPE_INLINE;
/*
$types[] = DifferentialTransaction::TYPE_UPDATE;
*/
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorTransactions::TYPE_VIEW_POLICY:
return $object->getViewPolicy();
case PhabricatorTransactions::TYPE_EDIT_POLICY:
return $object->getEditPolicy();
case DifferentialTransaction::TYPE_ACTION:
return null;
case DifferentialTransaction::TYPE_INLINE:
return null;
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
case DifferentialTransaction::TYPE_ACTION:
return $xaction->getNewValue();
case DifferentialTransaction::TYPE_INLINE:
return null;
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function transactionHasEffect(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case DifferentialTransaction::TYPE_INLINE:
return $xaction->hasComment();
+ case DifferentialTransaction::TYPE_ACTION:
+ $status_closed = ArcanistDifferentialRevisionStatus::CLOSED;
+ $status_abandoned = ArcanistDifferentialRevisionStatus::ABANDONED;
+ $status_review = ArcanistDifferentialRevisionStatus::NEEDS_REVIEW;
+ $status_revision = ArcanistDifferentialRevisionStatus::NEEDS_REVISION;
+
+ switch ($xaction->getNewValue()) {
+ case DifferentialAction::ACTION_CLOSE:
+ return ($object->getStatus() != $status_closed);
+ case DifferentialAction::ACTION_ABANDON:
+ return ($object->getStatus() != $status_abandoned);
+ case DifferentialAction::ACTION_RECLAIM:
+ return ($object->getStatus() == $status_abandoned);
+ case DifferentialAction::ACTION_REOPEN:
+ return ($object->getStatus() == $status_closed);
+ case DifferentialAction::ACTION_RETHINK:
+ return ($object->getStatus() != $status_revision);
+ case DifferentialAction::ACTION_REQUEST:
+ return ($object->getStatus() != $status_review);
+ }
}
return parent::transactionHasEffect($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorTransactions::TYPE_VIEW_POLICY:
$object->setViewPolicy($xaction->getNewValue());
return;
case PhabricatorTransactions::TYPE_EDIT_POLICY:
$object->setEditPolicy($xaction->getNewValue());
return;
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
case PhabricatorTransactions::TYPE_COMMENT:
case DifferentialTransaction::TYPE_INLINE:
return;
case PhabricatorTransactions::TYPE_EDGE:
// TODO: When removing reviewers, we may be able to move the revision
// to "Accepted".
return;
case DifferentialTransaction::TYPE_ACTION:
- // TODO: For now, we're just shipping these through without acting
- // on them.
+ $status_review = ArcanistDifferentialRevisionStatus::NEEDS_REVIEW;
+ $status_revision = ArcanistDifferentialRevisionStatus::NEEDS_REVISION;
+
+ switch ($xaction->getNewValue()) {
+ case DifferentialAction::ACTION_ABANDON:
+ $object->setStatus(ArcanistDifferentialRevisionStatus::ABANDONED);
+ break;
+ case DifferentialAction::ACTION_RETHINK:
+ $object->setStatus($status_revision);
+ break;
+ case DifferentialAction::ACTION_RECLAIM:
+ $object->setStatus($status_review);
+ // TODO: Update review status?
+ break;
+ case DifferentialAction::ACTION_REOPEN:
+ $object->setStatus($status_review);
+ // TODO: Update review status?
+ break;
+ case DifferentialAction::ACTION_REQUEST:
+ $object->setStatus($status_review);
+ // TODO: Update review status?
+ break;
+ case DifferentialAction::ACTION_CLOSE:
+ if (!$object->getDateCommitted()) {
+ // TODO: Can we remove this? It is probably no longer used by
+ // anything anymore. See also T4434.
+ $object->setDateCommitted(time());
+ }
+ $object->setStatus(ArcanistDifferentialRevisionStatus::CLOSED);
+ break;
+ default:
+ // TODO: For now, we're just shipping the rest of these through
+ // without acting on them.
+ break;
+ }
return null;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
return;
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
case PhabricatorTransactions::TYPE_EDGE:
case PhabricatorTransactions::TYPE_COMMENT:
case DifferentialTransaction::TYPE_ACTION:
case DifferentialTransaction::TYPE_INLINE:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
- switch ($type) {
+ foreach ($xactions as $xaction) {
+ switch ($type) {
+ case DifferentialTransaction::TYPE_ACTION:
+ $error = $this->validateDifferentialAction(
+ $object,
+ $type,
+ $xaction,
+ $xaction->getNewValue());
+ if ($error) {
+ $errors[] = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Invalid'),
+ $error,
+ $xaction);
+ }
+ break;
+ }
}
return $errors;
}
+ private function validateDifferentialAction(
+ DifferentialRevision $revision,
+ $type,
+ DifferentialTransaction $xaction,
+ $action) {
+
+ $author_phid = $revision->getAuthorPHID();
+ $actor_phid = $this->getActor()->getPHID();
+ $actor_is_author = ($author_phid == $actor_phid);
+
+ $config_close_key = 'differential.always-allow-close';
+ $always_allow_close = PhabricatorEnv::getEnvConfig($config_close_key);
+
+ $config_reopen_key = 'differential.allow-reopen';
+ $allow_reopen = PhabricatorEnv::getEnvConfig($config_reopen_key);
+
+ $revision_status = $revision->getStatus();
+
+ $status_accepted = ArcanistDifferentialRevisionStatus::ACCEPTED;
+ $status_abandoned = ArcanistDifferentialRevisionStatus::ABANDONED;
+ $status_closed = ArcanistDifferentialRevisionStatus::CLOSED;
+
+ switch ($action) {
+ case DifferentialAction::ACTION_ABANDON:
+ if (!$actor_is_author) {
+ return pht(
+ "You can not abandon this revision because you do not own it. ".
+ "You can only abandon revisions you own.");
+ }
+
+ if ($revision_status == $status_closed) {
+ return pht(
+ "You can not abandon this revision because it has already been ".
+ "closed.");
+ }
+
+ // NOTE: Abandons of already-abandoned revisions are treated as no-op
+ // instead of invalid. Other abandons are OK.
+
+ break;
+
+ case DifferentialAction::ACTION_RECLAIM:
+ if (!$actor_is_author) {
+ return pht(
+ "You can not reclaim this revision because you do not own ".
+ "it. You can only reclaim revisions you own.");
+ }
+
+ if ($revision_status == $status_closed) {
+ return pht(
+ "You can not reclaim this revision because it has already been ".
+ "closed.");
+ }
+
+ // NOTE: Reclaims of other non-abandoned revisions are treated as no-op
+ // instead of invalid.
+
+ break;
+
+ case DifferentialAction::ACTION_REOPEN:
+ if (!$allow_reopen) {
+ return pht(
+ 'The reopen action is not enabled on this Phabricator install. '.
+ 'Adjust your configuration to enable it.');
+ }
+
+ // NOTE: If the revision is not closed, this is caught as a no-op
+ // instead of an invalid transaction.
+
+ break;
+
+ case DifferentialAction::ACTION_RETHINK:
+ if (!$actor_is_author) {
+ return pht(
+ "You can not plan changes to this revision because you do not ".
+ "own it. To plan chagnes to a revision, you must be its owner.");
+ }
+
+ switch ($revision_status) {
+ case ArcanistDifferentialRevisionStatus::ACCEPTED:
+ case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
+ case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
+ // These are OK.
+ break;
+ case ArcanistDifferentialRevisionStatus::ABANDONED:
+ return pht(
+ "You can not plan changes to this revision because it has ".
+ "been abandoned.");
+ case ArcanistDifferentialRevisionStatus::CLOSED:
+ return pht(
+ "You can not plan changes to this revision because it has ".
+ "already been closed.");
+ default:
+ throw new Exception(
+ pht(
+ 'Encountered unexpected revision status ("%s") when '.
+ 'validating "%s" action.',
+ $revision_status,
+ $action));
+ }
+ break;
+
+ case DifferentialAction::ACTION_REQUEST:
+ if (!$actor_is_author) {
+ return pht(
+ "You can not request review of this revision because you do ".
+ "not own it. To request review of a revision, you must be its ".
+ "owner.");
+ }
+
+ switch ($revision_status) {
+ case ArcanistDifferentialRevisionStatus::ACCEPTED:
+ case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
+ // These are OK.
+ break;
+ case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
+ // This will be caught as "no effect" later on.
+ break;
+ case ArcanistDifferentialRevisionStatus::ABANDONED:
+ return pht(
+ "You can not request review of this revision because it has ".
+ "been abandoned. Instead, reclaim it.");
+ case ArcanistDifferentialRevisionStatus::CLOSED:
+ return pht(
+ "You can not request review of this revision because it has ".
+ "already been closed.");
+ default:
+ throw new Exception(
+ pht(
+ 'Encountered unexpected revision status ("%s") when '.
+ 'validating "%s" action.',
+ $revision_status,
+ $action));
+ }
+ break;
+
+ case DifferentialAction::ACTION_CLOSE:
+
+ // TODO: Permit the daemons to take this action in all cases.
+
+ if (!$actor_is_author && !$always_allow_close) {
+ return pht(
+ "You can not close this revision because you do not own it. To ".
+ "close a revision, you must be its owner.");
+ }
+
+ if ($revision_status != $status_accepted) {
+ return pht(
+ "You can not close this revision because it has not been ".
+ "accepted. You can only close accepted revisions.");
+ }
+ break;
+ }
+
+ return null;
+ }
+
protected function sortTransactions(array $xactions) {
$head = array();
$tail = array();
// Move bare comments to the end, so the actions precede them.
foreach ($xactions as $xaction) {
$type = $xaction->getTransactionType();
if ($type == DifferentialTransaction::TYPE_INLINE) {
$tail[] = $xaction;
} else {
$head[] = $xaction;
}
}
return array_values(array_merge($head, $tail));
}
protected function requireCapabilities(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
}
return parent::requireCapabilities($object, $xaction);
}
protected function shouldSendMail(
PhabricatorLiskDAO $object,
array $xactions) {
return true;
}
protected function getMailTo(PhabricatorLiskDAO $object) {
$phids = array();
$phids[] = $object->getAuthorPHID();
foreach ($object->getReviewerStatus() as $reviewer) {
$phids[] = $reviewer->getReviewerPHID();
}
return $phids;
}
protected function getMailSubjectPrefix() {
return PhabricatorEnv::getEnvConfig('metamta.differential.subject-prefix');
}
protected function buildReplyHandler(PhabricatorLiskDAO $object) {
return id(new DifferentialReplyHandler())
->setMailReceiver($object);
}
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
$id = $object->getID();
$title = $object->getTitle();
$original_title = $object->getOriginalTitle();
$subject = "D{$id}: {$title}";
$thread_topic = "D{$id}: {$original_title}";
return id(new PhabricatorMetaMTAMail())
->setSubject($subject)
->addHeader('Thread-Topic', $thread_topic);
}
protected function buildMailBody(
PhabricatorLiskDAO $object,
array $xactions) {
$body = parent::buildMailBody($object, $xactions);
$body->addTextSection(
pht('REVISION DETAIL'),
PhabricatorEnv::getProductionURI('/D'.$object->getID()));
return $body;
}
protected function supportsSearch() {
return true;
}
protected function extractFilePHIDsFromCustomTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
}
return parent::extractFilePHIDsFromCustomTransaction($object, $xaction);
}
}
diff --git a/src/applications/differential/storage/DifferentialTransaction.php b/src/applications/differential/storage/DifferentialTransaction.php
index e3b251eb5d..56a02c6f47 100644
--- a/src/applications/differential/storage/DifferentialTransaction.php
+++ b/src/applications/differential/storage/DifferentialTransaction.php
@@ -1,132 +1,153 @@
<?php
final class DifferentialTransaction extends PhabricatorApplicationTransaction {
const TYPE_INLINE = 'differential:inline';
const TYPE_UPDATE = 'differential:update';
const TYPE_ACTION = 'differential:action';
public function getApplicationName() {
return 'differential';
}
public function getApplicationTransactionType() {
return DifferentialPHIDTypeRevision::TYPECONST;
}
public function getApplicationTransactionCommentObject() {
return new DifferentialTransactionComment();
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$author_handle = $this->renderHandleLink($author_phid);
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_INLINE:
return pht(
'%s added inline comments.',
$author_handle);
case self::TYPE_UPDATE:
if ($new) {
// TODO: Migrate to PHIDs and use handles here?
// TODO: Link this?
return pht(
'%s updated this revision to Diff #%d.',
$author_handle,
$new);
} else {
return pht(
'%s updated this revision.',
$author_handle);
}
case self::TYPE_ACTION:
return DifferentialAction::getBasicStoryText($new, $author_handle);
}
return parent::getTitle();
}
public function getIcon() {
switch ($this->getTransactionType()) {
case self::TYPE_INLINE:
return 'comment';
case self::TYPE_UPDATE:
return 'refresh';
case self::TYPE_ACTION:
switch ($this->getNewValue()) {
case DifferentialAction::ACTION_CLOSE:
return 'ok';
case DifferentialAction::ACTION_ACCEPT:
return 'enable';
case DifferentialAction::ACTION_REJECT:
case DifferentialAction::ACTION_ABANDON:
return 'delete';
case DifferentialAction::ACTION_RETHINK:
return 'disable';
case DifferentialAction::ACTION_REQUEST:
return 'refresh';
case DifferentialAction::ACTION_RECLAIM:
case DifferentialAction::ACTION_REOPEN:
return 'new';
case DifferentialAction::ACTION_RESIGN:
return 'undo';
case DifferentialAction::ACTION_CLAIM:
return 'user';
}
}
return parent::getIcon();
}
public function getColor() {
switch ($this->getTransactionType()) {
case self::TYPE_UPDATE:
return PhabricatorTransactions::COLOR_SKY;
case self::TYPE_ACTION:
switch ($this->getNewValue()) {
case DifferentialAction::ACTION_CLOSE:
return PhabricatorTransactions::COLOR_BLUE;
case DifferentialAction::ACTION_ACCEPT:
return PhabricatorTransactions::COLOR_GREEN;
case DifferentialAction::ACTION_REJECT:
return PhabricatorTransactions::COLOR_RED;
case DifferentialAction::ACTION_ABANDON:
return PhabricatorTransactions::COLOR_BLACK;
case DifferentialAction::ACTION_RETHINK:
return PhabricatorTransactions::COLOR_RED;
case DifferentialAction::ACTION_REQUEST:
return PhabricatorTransactions::COLOR_SKY;
case DifferentialAction::ACTION_RECLAIM:
return PhabricatorTransactions::COLOR_SKY;
case DifferentialAction::ACTION_REOPEN:
return PhabricatorTransactions::COLOR_SKY;
case DifferentialAction::ACTION_RESIGN:
return PhabricatorTransactions::COLOR_ORANGE;
case DifferentialAction::ACTION_CLAIM:
return PhabricatorTransactions::COLOR_YELLOW;
}
}
return parent::getColor();
}
public function getNoEffectDescription() {
switch ($this->getTransactionType()) {
case PhabricatorTransactions::TYPE_EDGE:
switch ($this->getMetadataValue('edge:type')) {
case PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER:
return pht(
'Those reviewers are already reviewing this revision.');
}
+ break;
+ case DifferentialTransaction::TYPE_ACTION:
+ switch ($this->getNewValue()) {
+ case DifferentialAction::ACTION_CLOSE:
+ return pht('This revision is already closed.');
+ case DifferentialAction::ACTION_ABANDON:
+ return pht('This revision has already been abandoned.');
+ case DifferentialAction::ACTION_RECLAIM:
+ return pht(
+ 'You can not reclaim this revision because his revision is '.
+ 'not abandoned.');
+ case DifferentialAction::ACTION_REOPEN:
+ return pht(
+ 'You can not reopen this revision because this revision is '.
+ 'not closed.');
+ case DifferentialAction::ACTION_RETHINK:
+ return pht('This revision already requires changes.');
+ case DifferentialAction::ACTION_REQUEST:
+ return pht('Review is already requested for this revision.');
+ }
+ break;
}
return parent::getNoEffectDescription();
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jul 28, 10:48 PM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
187601
Default Alt Text
(27 KB)

Event Timeline