Fix handling of notifications with project members

Summary: Fixes T7377. We don't expand projects into members when sending notifications right now. Instead, expand them.

Test Plan:
  - Added a project as a reviewer to a revision, made a comment, saw project members receive a read notification + email (with appropriate preferences).
  - There's meaningful test coverage on the core mail stuff.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7377

Differential Revision: https://secure.phabricator.com/D12142
This commit is contained in:
epriestley 2015-03-24 12:47:38 -07:00
parent 0efae2858e
commit 86404a1a18
4 changed files with 42 additions and 42 deletions

View file

@ -192,6 +192,8 @@ final class PhabricatorFeedStoryPublisher {
* @return list<phid> List of actual subscribers. * @return list<phid> List of actual subscribers.
*/ */
private function filterSubscribedPHIDs(array $phids) { private function filterSubscribedPHIDs(array $phids) {
$phids = $this->expandRecipients($phids);
$tags = $this->getMailTags(); $tags = $this->getMailTags();
if ($tags) { if ($tags) {
$all_prefs = id(new PhabricatorUserPreferences())->loadAllWhere( $all_prefs = id(new PhabricatorUserPreferences())->loadAllWhere(
@ -234,6 +236,13 @@ final class PhabricatorFeedStoryPublisher {
return array_values(array_unique($keep)); return array_values(array_unique($keep));
} }
private function expandRecipients(array $phids) {
return id(new PhabricatorMetaMTAMemberQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs($phids)
->executeExpansion();
}
/** /**
* We generate a unique chronological key for each story type because we want * We generate a unique chronological key for each story type because we want
* to be able to page through the stream with a cursor (i.e., select stories * to be able to page through the stream with a cursor (i.e., select stories

View file

@ -59,6 +59,11 @@ final class PhabricatorMetaMTAMemberQuery extends PhabricatorQuery {
} }
break; break;
default: default:
// For other types, just map the PHID to itself without modification.
// This allows callers to do less work.
foreach ($phids as $phid) {
$results[$phid] = array($phid);
}
break; break;
} }
} }
@ -66,4 +71,13 @@ final class PhabricatorMetaMTAMemberQuery extends PhabricatorQuery {
return $results; return $results;
} }
/**
* Execute the query, merging results into a single list of unique member
* PHIDs.
*/
public function executeExpansion() {
return array_unique(array_mergev($this->execute()));
}
} }

View file

@ -360,21 +360,10 @@ abstract class PhabricatorMailReplyHandler {
} }
$phids = mpull($handles, 'getPHID'); $phids = mpull($handles, 'getPHID');
$map = id(new PhabricatorMetaMTAMemberQuery()) $results = id(new PhabricatorMetaMTAMemberQuery())
->setViewer(PhabricatorUser::getOmnipotentUser()) ->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs($phids) ->withPHIDs($phids)
->execute(); ->executeExpansion();
$results = array();
foreach ($phids as $phid) {
if (isset($map[$phid])) {
foreach ($map[$phid] as $expanded_phid) {
$results[$expanded_phid] = $expanded_phid;
}
} else {
$results[$phid] = $phid;
}
}
return id(new PhabricatorHandleQuery()) return id(new PhabricatorHandleQuery())
->setViewer(PhabricatorUser::getOmnipotentUser()) ->setViewer(PhabricatorUser::getOmnipotentUser())

View file

@ -773,40 +773,30 @@ final class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
* Get all of the recipients for this mail, after preference filters are * Get all of the recipients for this mail, after preference filters are
* applied. This list has all objects to whom delivery will be attempted. * applied. This list has all objects to whom delivery will be attempted.
* *
* Note that this expands recipients into their members, because delivery
* is never directly attempted to aggregate actors like projects.
*
* @return list<phid> A list of all recipients to whom delivery will be * @return list<phid> A list of all recipients to whom delivery will be
* attempted. * attempted.
* @task recipients * @task recipients
*/ */
public function buildRecipientList() { public function buildRecipientList() {
$actors = $this->loadActors( $actors = $this->loadAllActors();
array_merge(
$this->getToPHIDs(),
$this->getCcPHIDs()));
$actors = $this->filterDeliverableActors($actors); $actors = $this->filterDeliverableActors($actors);
return mpull($actors, 'getPHID'); return mpull($actors, 'getPHID');
} }
public function loadAllActors() { public function loadAllActors() {
$actor_phids = array_merge( $actor_phids = $this->getAllActorPHIDs();
array($this->getParam('from')),
$this->getToPHIDs(),
$this->getCcPHIDs());
$this->loadRecipientExpansions($actor_phids);
$actor_phids = $this->expandRecipients($actor_phids); $actor_phids = $this->expandRecipients($actor_phids);
return $this->loadActors($actor_phids); return $this->loadActors($actor_phids);
} }
private function loadRecipientExpansions(array $phids) { private function getAllActorPHIDs() {
$expansions = id(new PhabricatorMetaMTAMemberQuery()) return array_merge(
->setViewer(PhabricatorUser::getOmnipotentUser()) array($this->getParam('from')),
->withPHIDs($phids) $this->getToPHIDs(),
->execute(); $this->getCcPHIDs());
$this->recipientExpansionMap = $expansions;
return $this;
} }
/** /**
@ -821,19 +811,17 @@ final class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
*/ */
private function expandRecipients(array $phids) { private function expandRecipients(array $phids) {
if ($this->recipientExpansionMap === null) { if ($this->recipientExpansionMap === null) {
throw new Exception( $all_phids = $this->getAllActorPHIDs();
pht( $this->recipientExpansionMap = id(new PhabricatorMetaMTAMemberQuery())
'Call loadRecipientExpansions() before expandRecipients()!')); ->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs($all_phids)
->execute();
} }
$results = array(); $results = array();
foreach ($phids as $phid) { foreach ($phids as $phid) {
if (!isset($this->recipientExpansionMap[$phid])) { foreach ($this->recipientExpansionMap[$phid] as $recipient_phid) {
$results[$phid] = $phid; $results[$recipient_phid] = $recipient_phid;
} else {
foreach ($this->recipientExpansionMap[$phid] as $recipient_phid) {
$results[$recipient_phid] = $recipient_phid;
}
} }
} }