diff --git a/src/applications/feed/PhabricatorFeedStoryPublisher.php b/src/applications/feed/PhabricatorFeedStoryPublisher.php index 8d018c61b3..47dde8c98a 100644 --- a/src/applications/feed/PhabricatorFeedStoryPublisher.php +++ b/src/applications/feed/PhabricatorFeedStoryPublisher.php @@ -12,6 +12,7 @@ final class PhabricatorFeedStoryPublisher extends Phobject { private $mailRecipientPHIDs = array(); private $notifyAuthor; private $mailTags = array(); + private $unexpandablePHIDs = array(); public function setMailTags(array $mail_tags) { $this->mailTags = $mail_tags; @@ -46,6 +47,15 @@ final class PhabricatorFeedStoryPublisher extends Phobject { return $this; } + public function setUnexpandablePHIDs(array $unexpandable_phids) { + $this->unexpandablePHIDs = $unexpandable_phids; + return $this; + } + + public function getUnexpandablePHIDs() { + return $this->unexpandablePHIDs; + } + public function setStoryType($story_type) { $this->storyType = $story_type; return $this; @@ -254,10 +264,36 @@ final class PhabricatorFeedStoryPublisher extends Phobject { } private function expandRecipients(array $phids) { - return id(new PhabricatorMetaMTAMemberQuery()) + $expanded_phids = id(new PhabricatorMetaMTAMemberQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) ->withPHIDs($phids) ->executeExpansion(); + + // Filter out unexpandable PHIDs from the results. The typical case for + // this is that resigned reviewers should not be notified just because + // they are a member of some project or package reviewer. + + $original_map = array_fuse($phids); + $unexpandable_map = array_fuse($this->unexpandablePHIDs); + + foreach ($expanded_phids as $key => $phid) { + // We can keep this expanded PHID if it was present originally. + if (isset($original_map[$phid])) { + continue; + } + + // We can also keep it if it isn't marked as unexpandable. + if (!isset($unexpandable_map[$phid])) { + continue; + } + + // If it's unexpandable and we produced it by expanding recipients, + // throw it away. + unset($expanded_phids[$key]); + } + $expanded_phids = array_values($expanded_phids); + + return $expanded_phids; } /** diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php index 26be0f87af..8184eafb50 100644 --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -3199,6 +3199,11 @@ abstract class PhabricatorApplicationTransactionEditor $story_type = $this->getFeedStoryType(); $story_data = $this->getFeedStoryData($object, $xactions); + $unexpandable_phids = $this->mailUnexpandablePHIDs; + if (!is_array($unexpandable_phids)) { + $unexpandable_phids = array(); + } + id(new PhabricatorFeedStoryPublisher()) ->setStoryType($story_type) ->setStoryData($story_data) @@ -3207,6 +3212,7 @@ abstract class PhabricatorApplicationTransactionEditor ->setRelatedPHIDs($related_phids) ->setPrimaryObjectPHID($object->getPHID()) ->setSubscribedPHIDs($subscribed_phids) + ->setUnexpandablePHIDs($unexpandable_phids) ->setMailRecipientPHIDs($mailed_phids) ->setMailTags($this->getMailTags($object, $xactions)) ->publish();