3 final class DifferentialRevisionRequestReviewTransaction
4 extends DifferentialRevisionActionTransaction
{
6 const TRANSACTIONTYPE
= 'differential.revision.request';
7 const ACTIONKEY
= 'request-review';
9 const SOURCE_HARBORMASTER
= 'harbormaster';
10 const SOURCE_AUTHOR
= 'author';
11 const SOURCE_VIEWER
= 'viewer';
13 protected function getRevisionActionLabel(
14 DifferentialRevision
$revision,
15 PhabricatorUser
$viewer) {
17 // See PHI1810. Allow non-authors to "Request Review" on draft revisions
18 // to promote them out of the draft state. This smoothes over the workflow
19 // where an author asks for review of an urgent change but has not used
20 // "Request Review" to skip builds.
22 if ($revision->isDraft()) {
23 if (!$this->isViewerRevisionAuthor($revision, $viewer)) {
24 return pht('Begin Review Now');
28 return pht('Request Review');
31 protected function getRevisionActionDescription(
32 DifferentialRevision
$revision,
33 PhabricatorUser
$viewer) {
34 if ($revision->isDraft()) {
35 if (!$this->isViewerRevisionAuthor($revision, $viewer)) {
37 'This revision will be moved out of the draft state so you can '.
38 'review it immediately.');
41 'This revision will be submitted to reviewers for feedback.');
44 return pht('This revision will be returned to reviewers for feedback.');
48 protected function getRevisionActionMetadata(
49 DifferentialRevision
$revision,
50 PhabricatorUser
$viewer) {
53 if ($revision->isDraft()) {
54 $action_source = $this->getActorSourceType(
57 $map['promotion.source'] = $action_source;
63 protected function getRevisionActionSubmitButtonText(
64 DifferentialRevision
$revision,
65 PhabricatorUser
$viewer) {
67 // See PHI975. When the action stack will promote the revision out of
68 // draft, change the button text from "Submit Quietly".
69 if ($revision->isDraft()) {
70 return pht('Publish Revision');
77 public function getColor() {
81 protected function getRevisionActionOrder() {
85 public function getActionName() {
86 return pht('Requested Review');
89 public function generateOldValue($object) {
90 return $object->isNeedsReview();
93 public function applyInternalEffects($object, $value) {
94 $status_review = DifferentialRevisionStatus
::NEEDS_REVIEW
;
96 ->setModernRevisionStatus($status_review)
97 ->setShouldBroadcast(true);
100 protected function validateAction($object, PhabricatorUser
$viewer) {
101 if ($object->isNeedsReview()) {
104 'You can not request review of this revision because this '.
105 'revision is already under review and the action would have '.
109 if ($object->isClosed()) {
112 'You can not request review of this revision because it has '.
113 'already been closed. You can only request review of open '.
117 $this->getActorSourceType($object, $viewer);
120 public function getTitle() {
121 $source = $this->getDraftPromotionSource();
124 case self
::SOURCE_HARBORMASTER
:
125 case self
::SOURCE_VIEWER
:
126 case self
::SOURCE_AUTHOR
:
128 '%s published this revision for review.',
129 $this->renderAuthor());
132 '%s requested review of this revision.',
133 $this->renderAuthor());
137 public function getTitleForFeed() {
138 $source = $this->getDraftPromotionSource();
141 case self
::SOURCE_HARBORMASTER
:
142 case self
::SOURCE_VIEWER
:
143 case self
::SOURCE_AUTHOR
:
145 '%s published %s for review.',
146 $this->renderAuthor(),
147 $this->renderObject());
150 '%s requested review of %s.',
151 $this->renderAuthor(),
152 $this->renderObject());
156 public function getTransactionTypeForConduit($xaction) {
157 return 'request-review';
160 public function getFieldValuesForConduit($object, $data) {
164 private function getDraftPromotionSource() {
165 return $this->getMetadataValue('promotion.source');
168 private function getActorSourceType(
169 DifferentialRevision
$revision,
170 PhabricatorUser
$viewer) {
172 $is_harbormaster = $viewer->isOmnipotent();
173 $is_author = $this->isViewerRevisionAuthor($revision, $viewer);
174 $is_draft = $revision->isDraft();
176 if ($is_harbormaster) {
177 // When revisions automatically promote out of "Draft" after builds
178 // finish, the viewer may be acting as the Harbormaster application.
179 $source = self
::SOURCE_HARBORMASTER
;
180 } else if ($is_author) {
181 $source = self
::SOURCE_AUTHOR
;
182 } else if ($is_draft) {
183 // Non-authors are allowed to "Request Review" on draft revisions, to
184 // force them into review immediately.
185 $source = self
::SOURCE_VIEWER
;
189 'You can not request review of this revision because you are not '.
190 'the author of the revision and it is not currently a draft.'));