diff --git a/src/applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php b/src/applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php --- a/src/applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php +++ b/src/applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php @@ -127,9 +127,10 @@ $info[] = ' '.coalesce($actor->getName(), $actor->getPHID()); } else { $info[] = '! '.coalesce($actor->getName(), $actor->getPHID()); - foreach ($actor->getUndeliverableReasons() as $reason) { - $info[] = ' - '.$reason; - } + } + foreach ($actor->getDeliverabilityReasons() as $reason) { + $desc = PhabricatorMetaMTAActor::getReasonDescription($reason); + $info[] = ' - '.$desc; } } diff --git a/src/applications/metamta/query/PhabricatorMetaMTAActor.php b/src/applications/metamta/query/PhabricatorMetaMTAActor.php --- a/src/applications/metamta/query/PhabricatorMetaMTAActor.php +++ b/src/applications/metamta/query/PhabricatorMetaMTAActor.php @@ -2,9 +2,25 @@ final class PhabricatorMetaMTAActor { + const STATUS_DELIVERABLE = 'deliverable'; + const STATUS_UNDELIVERABLE = 'undeliverable'; + + const REASON_UNLOADABLE = 'unloadable'; + const REASON_UNMAILABLE = 'unmailable'; + const REASON_NO_ADDRESS = 'noaddress'; + const REASON_DISABLED = 'disabled'; + const REASON_MAIL_DISABLED = 'maildisabled'; + const REASON_EXTERNAL_TYPE = 'exernaltype'; + const REASON_RESPONSE = 'response'; + const REASON_SELF = 'self'; + const REASON_MAILTAGS = 'mailtags'; + const REASON_BOT = 'bot'; + const REASON_FORCE = 'force'; + private $phid; private $emailAddress; private $name; + private $status = self::STATUS_DELIVERABLE; private $reasons = array(); public function setName($name) { @@ -36,15 +52,66 @@ public function setUndeliverable($reason) { $this->reasons[] = $reason; + $this->status = self::STATUS_UNDELIVERABLE; + return $this; + } + + public function setDeliverable($reason) { + $this->reasons[] = $reason; + $this->status = self::STATUS_DELIVERABLE; return $this; } public function isDeliverable() { - return empty($this->reasons); + return ($this->status === self::STATUS_DELIVERABLE); } - public function getUndeliverableReasons() { + public function getDeliverabilityReasons() { return $this->reasons; } + public static function getReasonDescription($reason) { + $descriptions = array( + self::REASON_DISABLED => pht( + 'This user is disabled; disabled users do not receive mail.'), + self::REASON_BOT => pht( + 'This user is a bot; bot accounts do not receive mail.'), + self::REASON_NO_ADDRESS => pht( + 'Unable to load an email address for this PHID.'), + self::REASON_EXTERNAL_TYPE => pht( + 'Only external accounts of type "email" are deliverable; this '. + 'account has a different type.'), + self::REASON_UNMAILABLE => pht( + 'This PHID type does not correspond to a mailable object.'), + self::REASON_RESPONSE => pht( + 'This message is a response to another email message, and this '. + 'recipient received the original email message, so we are not '. + 'sending them this substantially similar message (for example, '. + 'the sender used "Reply All" instead of "Reply" in response to '. + 'mail from Phabricator).'), + self::REASON_SELF => pht( + 'This recipient is the user whose actions caused delivery of '. + 'this message, but they have set preferences so they do not '. + 'receive mail about their own actions (Settings > Email '. + 'Preferences > Self Actions).'), + self::REASON_MAIL_DISABLED => pht( + 'This recipient has disabled all email notifications '. + '(Settings > Email Preferences > Email Notifications).'), + self::REASON_MAILTAGS => pht( + 'This mail has tags which control which users receive it, and '. + 'this recipient has not elected to receive mail with any of '. + 'the tags on this message (Settings > Email Preferences).'), + self::REASON_UNLOADABLE => pht( + 'Unable to load user record for this PHID.'), + self::REASON_FORCE => pht( + 'Delivery of this mail is forced and ignores deliver preferences. '. + 'Mail which uses forced delivery is usually related to account '. + 'management or authentication. For example, password reset email '. + 'ignores mail preferences.'), + ); + + return idx($descriptions, $reason, pht('Unknown Reason ("%s")', $reason)); + } + + } diff --git a/src/applications/metamta/query/PhabricatorMetaMTAActorQuery.php b/src/applications/metamta/query/PhabricatorMetaMTAActorQuery.php --- a/src/applications/metamta/query/PhabricatorMetaMTAActorQuery.php +++ b/src/applications/metamta/query/PhabricatorMetaMTAActorQuery.php @@ -70,17 +70,14 @@ $user = idx($users, $phid); if (!$user) { - $actor->setUndeliverable( - pht('Unable to load user record for this PHID.')); + $actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_UNLOADABLE); } else { $actor->setName($this->getUserName($user)); if ($user->getIsDisabled()) { - $actor->setUndeliverable( - pht('This user is disabled; disabled users do not receive mail.')); + $actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_DISABLED); } if ($user->getIsSystemAgent()) { - $actor->setUndeliverable( - pht('This user is a bot; bot accounts do not receive mail.')); + $actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_BOT); } // NOTE: We do send email to unapproved users, and to unverified users, @@ -91,8 +88,7 @@ $email = idx($emails, $phid); if (!$email) { - $actor->setUndeliverable( - pht('Unable to load email record for this PHID.')); + $actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_NO_ADDRESS); } else { $actor->setEmailAddress($email->getAddress()); } @@ -113,18 +109,14 @@ $xuser = idx($xusers, $phid); if (!$xuser) { - $actor->setUndeliverable( - pht('Unable to load external user record for this PHID.')); + $actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_UNLOADABLE); continue; } $actor->setName($xuser->getDisplayName()); if ($xuser->getAccountType() != 'email') { - $actor->setUndeliverable( - pht( - 'Only external accounts of type "email" are deliverable; this '. - 'account has a different type.')); + $actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_EXTERNAL_TYPE); continue; } @@ -146,9 +138,7 @@ $list = idx($lists, $phid); if (!$list) { - $actor->setUndeliverable( - pht( - 'Unable to load mailing list record for this PHID.')); + $actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_UNLOADABLE); continue; } @@ -160,7 +150,7 @@ private function loadUnknownActors(array $actors, array $phids) { foreach ($phids as $phid) { $actor = $actors[$phid]; - $actor->setUndeliverable(pht('This PHID type is not mailable.')); + $actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_UNMAILABLE); } } diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php --- a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php @@ -852,6 +852,9 @@ if ($this->getForceDelivery()) { // If we're forcing delivery, skip all the opt-out checks. + foreach ($actors as $actor) { + $actor->setDeliverable(PhabricatorMetaMTAActor::REASON_FORCE); + } return $actors; } @@ -861,13 +864,7 @@ if (!$actor) { continue; } - $actor->setUndeliverable( - pht( - 'This message is a response to another email message, and this '. - 'recipient received the original email message, so we are not '. - 'sending them this substantially similar message (for example, '. - 'the sender used "Reply All" instead of "Reply" in response to '. - 'mail from Phabricator).')); + $actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_RESPONSE); } // Exclude the actor if their preferences are set. @@ -885,12 +882,7 @@ ->loadPreferences() ->getPreference($pref_key); if ($exclude_self) { - $from_actor->setUndeliverable( - pht( - 'This recipient is the user whose actions caused delivery of '. - 'this message, but they have set preferences so they do not '. - 'receive mail about their own actions (Settings > Email '. - 'Preferences > Self Actions).')); + $from_actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_SELF); } } } @@ -907,9 +899,7 @@ false); if ($exclude) { $actors[$phid]->setUndeliverable( - pht( - 'This recipient has disabled all email notifications '. - '(Settings > Email Preferences > Email Notifications).')); + PhabricatorMetaMTAActor::REASON_MAIL_DISABLED); } } @@ -937,10 +927,7 @@ if (!$send) { $actors[$phid]->setUndeliverable( - pht( - 'This mail has tags which control which users receive it, and '. - 'this recipient has not elected to receive mail with any of '. - 'the tags on this message (Settings > Email Preferences).')); + PhabricatorMetaMTAActor::REASON_MAILTAGS); } } }