diff --git a/src/applications/differential/editor/DifferentialRevisionEditEngine.php b/src/applications/differential/editor/DifferentialRevisionEditEngine.php --- a/src/applications/differential/editor/DifferentialRevisionEditEngine.php +++ b/src/applications/differential/editor/DifferentialRevisionEditEngine.php @@ -229,6 +229,8 @@ ->setValue(array()); $actions = DifferentialRevisionActionTransaction::loadAllActions(); + $actions = msortv($actions, 'getRevisionActionOrderVector'); + foreach ($actions as $key => $action) { $fields[] = $action->newEditField($object, $viewer); } diff --git a/src/applications/differential/storage/DifferentialRevision.php b/src/applications/differential/storage/DifferentialRevision.php --- a/src/applications/differential/storage/DifferentialRevision.php +++ b/src/applications/differential/storage/DifferentialRevision.php @@ -447,6 +447,11 @@ return ($this->getStatus() == $status_abandoned); } + public function isAccepted() { + $status_accepted = ArcanistDifferentialRevisionStatus::ACCEPTED; + return ($this->getStatus() == $status_accepted); + } + public function getStatusIcon() { $map = array( ArcanistDifferentialRevisionStatus::NEEDS_REVIEW diff --git a/src/applications/differential/xaction/DifferentialRevisionAbandonTransaction.php b/src/applications/differential/xaction/DifferentialRevisionAbandonTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionAbandonTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionAbandonTransaction.php @@ -22,6 +22,10 @@ return 'indigo'; } + protected function getRevisionActionOrder() { + return 500; + } + public function generateOldValue($object) { return $object->isAbandoned(); } diff --git a/src/applications/differential/xaction/DifferentialRevisionAcceptTransaction.php b/src/applications/differential/xaction/DifferentialRevisionAcceptTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionAcceptTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionAcceptTransaction.php @@ -22,6 +22,10 @@ return 'green'; } + protected function getRevisionActionOrder() { + return 500; + } + public function generateOldValue($object) { $actor = $this->getActor(); return $this->isViewerAcceptingReviewer($object, $actor); diff --git a/src/applications/differential/xaction/DifferentialRevisionActionTransaction.php b/src/applications/differential/xaction/DifferentialRevisionActionTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionActionTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionActionTransaction.php @@ -19,6 +19,15 @@ abstract protected function validateAction($object, PhabricatorUser $viewer); abstract protected function getRevisionActionLabel(); + protected function getRevisionActionOrder() { + return 1000; + } + + public function getRevisionActionOrderVector() { + return id(new PhutilSortVector()) + ->addInt($this->getRevisionActionOrder()); + } + protected function getRevisionActionGroupKey() { return DifferentialRevisionEditEngine::ACTIONGROUP_REVISION; } diff --git a/src/applications/differential/xaction/DifferentialRevisionCloseTransaction.php b/src/applications/differential/xaction/DifferentialRevisionCloseTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionCloseTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionCloseTransaction.php @@ -22,6 +22,10 @@ return 'indigo'; } + protected function getRevisionActionOrder() { + return 300; + } + public function generateOldValue($object) { return $object->isClosed(); } @@ -49,6 +53,13 @@ 'closed. Only open revisions can be closed.')); } + if (!$object->isAccepted()) { + throw new Exception( + pht( + 'You can not close this revision because it has not been accepted. '. + 'Revisions must be accepted before they can be closed.')); + } + $config_key = 'differential.always-allow-close'; if (!PhabricatorEnv::getEnvConfig($config_key)) { if (!$this->isViewerRevisionAuthor($object, $viewer)) { diff --git a/src/applications/differential/xaction/DifferentialRevisionCommandeerTransaction.php b/src/applications/differential/xaction/DifferentialRevisionCommandeerTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionCommandeerTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionCommandeerTransaction.php @@ -22,6 +22,10 @@ return 'sky'; } + protected function getRevisionActionOrder() { + return 700; + } + public function generateOldValue($object) { return $object->getAuthorPHID(); } diff --git a/src/applications/differential/xaction/DifferentialRevisionPlanChangesTransaction.php b/src/applications/differential/xaction/DifferentialRevisionPlanChangesTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionPlanChangesTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionPlanChangesTransaction.php @@ -23,6 +23,10 @@ return 'red'; } + protected function getRevisionActionOrder() { + return 200; + } + public function generateOldValue($object) { $status_planned = ArcanistDifferentialRevisionStatus::CHANGES_PLANNED; return ($object->getStatus() == $status_planned); diff --git a/src/applications/differential/xaction/DifferentialRevisionReclaimTransaction.php b/src/applications/differential/xaction/DifferentialRevisionReclaimTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionReclaimTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionReclaimTransaction.php @@ -22,6 +22,10 @@ return 'sky'; } + protected function getRevisionActionOrder() { + return 600; + } + public function generateOldValue($object) { return !$object->isAbandoned(); } diff --git a/src/applications/differential/xaction/DifferentialRevisionRejectTransaction.php b/src/applications/differential/xaction/DifferentialRevisionRejectTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionRejectTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionRejectTransaction.php @@ -22,6 +22,10 @@ return 'red'; } + protected function getRevisionActionOrder() { + return 600; + } + public function generateOldValue($object) { $actor = $this->getActor(); return $this->isViewerRejectingReviewer($object, $actor); diff --git a/src/applications/differential/xaction/DifferentialRevisionReopenTransaction.php b/src/applications/differential/xaction/DifferentialRevisionReopenTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionReopenTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionReopenTransaction.php @@ -22,6 +22,10 @@ return 'sky'; } + protected function getRevisionActionOrder() { + return 400; + } + public function generateOldValue($object) { return !$object->isClosed(); } diff --git a/src/applications/differential/xaction/DifferentialRevisionRequestReviewTransaction.php b/src/applications/differential/xaction/DifferentialRevisionRequestReviewTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionRequestReviewTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionRequestReviewTransaction.php @@ -18,6 +18,10 @@ return 'sky'; } + protected function getRevisionActionOrder() { + return 200; + } + public function generateOldValue($object) { $status_review = ArcanistDifferentialRevisionStatus::NEEDS_REVIEW; return ($object->getStatus() == $status_review); diff --git a/src/applications/differential/xaction/DifferentialRevisionResignTransaction.php b/src/applications/differential/xaction/DifferentialRevisionResignTransaction.php --- a/src/applications/differential/xaction/DifferentialRevisionResignTransaction.php +++ b/src/applications/differential/xaction/DifferentialRevisionResignTransaction.php @@ -22,6 +22,10 @@ return 'orange'; } + protected function getRevisionActionOrder() { + return 700; + } + public function generateOldValue($object) { $actor = $this->getActor(); return !$this->isViewerAnyReviewer($object, $actor);