Generate file attachment transactions for explicit Remarkup attachments on common...
[phabricator.git] / src / applications / differential / xaction / DifferentialRevisionVoidTransaction.php
blob331c637aad1ab1196ca69672d169b6a7087174c8
1 <?php
3 /**
4 * This is an internal transaction type used to void reviews.
6 * For example, "Request Review" voids any open accepts, so they no longer
7 * act as current accepts.
8 */
9 final class DifferentialRevisionVoidTransaction
10 extends DifferentialRevisionTransactionType {
12 const TRANSACTIONTYPE = 'differential.revision.void';
14 public function generateOldValue($object) {
15 return false;
18 public function generateNewValue($object, $value) {
19 $reviewers = id(new DifferentialReviewer())->loadAllWhere(
20 'revisionPHID = %s
21 AND voidedPHID IS NULL
22 AND reviewerStatus IN (%Ls)',
23 $object->getPHID(),
24 $value);
26 $must_downgrade = $this->getMetadataValue('void.force', array());
27 $must_downgrade = array_fuse($must_downgrade);
29 $default = PhabricatorEnv::getEnvConfig('differential.sticky-accept');
30 foreach ($reviewers as $key => $reviewer) {
31 $status = $reviewer->getReviewerStatus();
33 // If this void is forced, always downgrade. For example, this happens
34 // when an author chooses "Request Review": existing reviews are always
35 // voided, even if they're sticky.
36 if (isset($must_downgrade[$status])) {
37 continue;
40 // Otherwise, if this is a sticky accept, don't void it. Accepts may be
41 // explicitly sticky or unsticky, or they'll use the default value if
42 // no value is specified.
43 $is_sticky = $reviewer->getOption('sticky');
44 $is_sticky = coalesce($is_sticky, $default);
46 if ($status === DifferentialReviewerStatus::STATUS_ACCEPTED) {
47 if ($is_sticky) {
48 unset($reviewers[$key]);
49 continue;
55 return mpull($reviewers, 'getReviewerPHID');
58 public function getTransactionHasEffect($object, $old, $new) {
59 return (bool)$new;
62 public function applyExternalEffects($object, $value) {
63 $table = new DifferentialReviewer();
64 $table_name = $table->getTableName();
65 $conn = $table->establishConnection('w');
67 queryfx(
68 $conn,
69 'UPDATE %T SET voidedPHID = %s
70 WHERE revisionPHID = %s
71 AND voidedPHID IS NULL
72 AND reviewerPHID IN (%Ls)',
73 $table_name,
74 $this->getActingAsPHID(),
75 $object->getPHID(),
76 $value);
79 public function shouldHide() {
80 // This is an internal transaction, so don't show it in feeds or
81 // transaction logs.
82 return true;
85 private function getVoidableStatuses() {
86 return array(
87 DifferentialReviewerStatus::STATUS_ACCEPTED,
88 DifferentialReviewerStatus::STATUS_REJECTED,