From 2ceffadee78aeccd1faf89ee2d9cbebf88412ced Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 5 Mar 2014 12:07:13 -0800 Subject: [PATCH] Support Herald rules for new Differential edits Summary: Ref T2222. Ref T4484. See D8404 for discussion. When a revision is updated with the new Editor, apply Herald rules. Additionally, apply them in a modern way which generates transactions. Test Plan: {F122299} Reviewers: btrahan Reviewed By: btrahan CC: aran, chad Maniphest Tasks: T2222, T4484 Differential Revision: https://secure.phabricator.com/D8405 --- .../editor/DifferentialTransactionEditor.php | 137 ++++++++++++++++++ .../HeraldDifferentialRevisionAdapter.php | 4 + ...habricatorApplicationTransactionEditor.php | 15 ++ 3 files changed, 156 insertions(+) diff --git a/src/applications/differential/editor/DifferentialTransactionEditor.php b/src/applications/differential/editor/DifferentialTransactionEditor.php index c8ab780348..a57b9a4e84 100644 --- a/src/applications/differential/editor/DifferentialTransactionEditor.php +++ b/src/applications/differential/editor/DifferentialTransactionEditor.php @@ -3,6 +3,8 @@ final class DifferentialTransactionEditor extends PhabricatorApplicationTransactionEditor { + private $heraldEmailPHIDs; + public function getTransactionTypes() { $types = parent::getTransactionTypes(); @@ -851,6 +853,18 @@ final class DifferentialTransactionEditor return $phids; } + protected function getMailCC(PhabricatorLiskDAO $object) { + $phids = parent::getMailCC($object); + + if ($this->heraldEmailPHIDs) { + foreach ($this->heraldEmailPHIDs as $phid) { + $phids[] = $phid; + } + } + + return $phids; + } + protected function getMailSubjectPrefix() { return PhabricatorEnv::getEnvConfig('metamta.differential.subject-prefix'); } @@ -1072,5 +1086,128 @@ final class DifferentialTransactionEditor ->executeOne(); } +/* -( Herald Integration )------------------------------------------------- */ + + protected function shouldApplyHeraldRules( + PhabricatorLiskDAO $object, + array $xactions) { + + if ($this->getIsNewObject()) { + return true; + } + + foreach ($xactions as $xaction) { + switch ($xaction->getTransactionType()) { + case DifferentialTransaction::TYPE_UPDATE: + return true; + } + } + + return parent::shouldApplyHeraldRules($object, $xactions); + } + + protected function buildHeraldAdapter( + PhabricatorLiskDAO $object, + array $xactions) { + + $unsubscribed_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( + $object->getPHID(), + PhabricatorEdgeConfig::TYPE_OBJECT_HAS_UNSUBSCRIBER); + + $subscribed_phids = PhabricatorSubscribersQuery::loadSubscribersForPHID( + $object->getPHID()); + + $revision = id(new DifferentialRevisionQuery()) + ->setViewer($this->getActor()) + ->withPHIDs(array($object->getPHID())) + ->needActiveDiffs(true) + ->needReviewerStatus(true) + ->executeOne(); + if (!$revision) { + throw new Exception( + pht( + 'Failed to load revision for Herald adapter construction!')); + } + + $adapter = HeraldDifferentialRevisionAdapter::newLegacyAdapter( + $object, + $object->getActiveDiff()); + + $reviewers = $revision->getReviewerStatus(); + $reviewer_phids = mpull($reviewers, 'getReviewerPHID'); + + $adapter->setExplicitCCs($subscribed_phids); + $adapter->setExplicitReviewers($reviewer_phids); + $adapter->setForbiddenCCs($unsubscribed_phids); + + $adapter->setIsNewObject($this->getIsNewObject()); + + return $adapter; + } + + protected function didApplyHeraldRules( + PhabricatorLiskDAO $object, + HeraldAdapter $adapter, + HeraldTranscript $transcript) { + + $xactions = array(); + + // Build a transaction to adjust CCs. + $ccs = array( + '+' => array_keys($adapter->getCCsAddedByHerald()), + '-' => array_keys($adapter->getCCsRemovedByHerald()), + ); + $value = array(); + foreach ($ccs as $type => $phids) { + foreach ($phids as $phid) { + $value[$type][$phid] = $phid; + } + } + + if ($value) { + $xactions[] = id(new DifferentialTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS) + ->setNewValue($value); + } + + // Build a transaction to adjust reviewers. + $reviewers = array( + DifferentialReviewerStatus::STATUS_ADDED => + array_keys($adapter->getReviewersAddedByHerald()), + DifferentialReviewerStatus::STATUS_BLOCKING => + array_keys($adapter->getBlockingReviewersAddedByHerald()), + ); + + $value = array(); + foreach ($reviewers as $status => $phids) { + foreach ($phids as $phid) { + $value['+'][$phid] = array( + 'data' => array( + 'status' => $status, + ), + ); + } + } + + if ($value) { + $edge_reviewer = PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER; + + $xactions[] = id(new DifferentialTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) + ->setMetadataValue('edge:type', $edge_reviewer) + ->setNewValue($value); + } + + // Save extra email PHIDs for later. + $this->heraldEmailPHIDs = $adapter->getEmailPHIDsAddedByHerald(); + + // Apply build plans. + HarbormasterBuildable::applyBuildPlans( + $adapter->getDiff(), + $adapter->getPHID(), + $adapter->getBuildPlans()); + + return $xactions; + } } diff --git a/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php b/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php index f0994f87a6..38d354e9db 100644 --- a/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php +++ b/src/applications/herald/adapter/HeraldDifferentialRevisionAdapter.php @@ -28,6 +28,10 @@ final class HeraldDifferentialRevisionAdapter extends HeraldAdapter { return $this->revision; } + public function getDiff() { + return $this->diff; + } + public function getAdapterContentType() { return 'differential'; } diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php index 12da96f964..b154930a3b 100644 --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -1634,6 +1634,21 @@ abstract class PhabricatorApplicationTransactionEditor ->setIsBulk(true) ->setBody($body->render()); + $herald_xscript = $this->getHeraldTranscript(); + if ($herald_xscript) { + $herald_header = $herald_xscript->getXHeraldRulesHeader(); + $herald_header = HeraldTranscript::saveXHeraldRulesHeader( + $object->getPHID(), + $herald_header); + } else { + $herald_header = HeraldTranscript::loadXHeraldRulesHeader( + $object->getPHID()); + } + + if ($herald_header) { + $template->addHeader('X-Herald-Rules', $herald_header); + } + if ($this->getParentMessageID()) { $template->setParentMessageID($this->getParentMessageID()); }