Page MenuHomePhabricator

D13897.diff
No OneTemporary

D13897.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2247,6 +2247,9 @@
'PhabricatorMacroTransactionComment' => 'applications/macro/storage/PhabricatorMacroTransactionComment.php',
'PhabricatorMacroTransactionQuery' => 'applications/macro/query/PhabricatorMacroTransactionQuery.php',
'PhabricatorMacroViewController' => 'applications/macro/controller/PhabricatorMacroViewController.php',
+ 'PhabricatorMailEmailHeraldField' => 'applications/metamta/herald/PhabricatorMailEmailHeraldField.php',
+ 'PhabricatorMailEmailHeraldFieldGroup' => 'applications/metamta/herald/PhabricatorMailEmailHeraldFieldGroup.php',
+ 'PhabricatorMailEmailSubjectHeraldField' => 'applications/metamta/herald/PhabricatorMailEmailSubjectHeraldField.php',
'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationAdapter.php',
'PhabricatorMailImplementationAmazonSESAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationAmazonSESAdapter.php',
'PhabricatorMailImplementationMailgunAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationMailgunAdapter.php',
@@ -2263,10 +2266,15 @@
'PhabricatorMailManagementShowOutboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php',
'PhabricatorMailManagementVolumeWorkflow' => 'applications/metamta/management/PhabricatorMailManagementVolumeWorkflow.php',
'PhabricatorMailManagementWorkflow' => 'applications/metamta/management/PhabricatorMailManagementWorkflow.php',
+ 'PhabricatorMailOutboundMailHeraldAdapter' => 'applications/metamta/herald/PhabricatorMailOutboundMailHeraldAdapter.php',
+ 'PhabricatorMailOutboundRoutingHeraldAction' => 'applications/metamta/herald/PhabricatorMailOutboundRoutingHeraldAction.php',
+ 'PhabricatorMailOutboundRoutingSelfEmailHeraldAction' => 'applications/metamta/herald/PhabricatorMailOutboundRoutingSelfEmailHeraldAction.php',
+ 'PhabricatorMailOutboundRoutingSelfNotificationHeraldAction' => 'applications/metamta/herald/PhabricatorMailOutboundRoutingSelfNotificationHeraldAction.php',
'PhabricatorMailOutboundStatus' => 'applications/metamta/constants/PhabricatorMailOutboundStatus.php',
'PhabricatorMailReceiver' => 'applications/metamta/receiver/PhabricatorMailReceiver.php',
'PhabricatorMailReceiverTestCase' => 'applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php',
'PhabricatorMailReplyHandler' => 'applications/metamta/replyhandler/PhabricatorMailReplyHandler.php',
+ 'PhabricatorMailRoutingRule' => 'applications/metamta/constants/PhabricatorMailRoutingRule.php',
'PhabricatorMailSetupCheck' => 'applications/config/check/PhabricatorMailSetupCheck.php',
'PhabricatorMailTarget' => 'applications/metamta/replyhandler/PhabricatorMailTarget.php',
'PhabricatorMailgunConfigOptions' => 'applications/config/option/PhabricatorMailgunConfigOptions.php',
@@ -6178,6 +6186,9 @@
'PhabricatorMacroTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhabricatorMacroTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorMacroViewController' => 'PhabricatorMacroController',
+ 'PhabricatorMailEmailHeraldField' => 'HeraldField',
+ 'PhabricatorMailEmailHeraldFieldGroup' => 'HeraldFieldGroup',
+ 'PhabricatorMailEmailSubjectHeraldField' => 'PhabricatorMailEmailHeraldField',
'PhabricatorMailImplementationAdapter' => 'Phobject',
'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter',
'PhabricatorMailImplementationMailgunAdapter' => 'PhabricatorMailImplementationAdapter',
@@ -6194,10 +6205,15 @@
'PhabricatorMailManagementShowOutboundWorkflow' => 'PhabricatorMailManagementWorkflow',
'PhabricatorMailManagementVolumeWorkflow' => 'PhabricatorMailManagementWorkflow',
'PhabricatorMailManagementWorkflow' => 'PhabricatorManagementWorkflow',
+ 'PhabricatorMailOutboundMailHeraldAdapter' => 'HeraldAdapter',
+ 'PhabricatorMailOutboundRoutingHeraldAction' => 'HeraldAction',
+ 'PhabricatorMailOutboundRoutingSelfEmailHeraldAction' => 'PhabricatorMailOutboundRoutingHeraldAction',
+ 'PhabricatorMailOutboundRoutingSelfNotificationHeraldAction' => 'PhabricatorMailOutboundRoutingHeraldAction',
'PhabricatorMailOutboundStatus' => 'Phobject',
'PhabricatorMailReceiver' => 'Phobject',
'PhabricatorMailReceiverTestCase' => 'PhabricatorTestCase',
'PhabricatorMailReplyHandler' => 'Phobject',
+ 'PhabricatorMailRoutingRule' => 'Phobject',
'PhabricatorMailSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorMailTarget' => 'Phobject',
'PhabricatorMailgunConfigOptions' => 'PhabricatorApplicationConfigOptions',
diff --git a/src/applications/herald/controller/HeraldTestConsoleController.php b/src/applications/herald/controller/HeraldTestConsoleController.php
--- a/src/applications/herald/controller/HeraldTestConsoleController.php
+++ b/src/applications/herald/controller/HeraldTestConsoleController.php
@@ -48,6 +48,9 @@
} else if ($object instanceof PonderQuestion) {
$adapter = id(new HeraldPonderQuestionAdapter())
->setQuestion($object);
+ } else if ($object instanceof PhabricatorMetaMTAMail) {
+ $adapter = id(new PhabricatorMailOutboundMailHeraldAdapter())
+ ->setObject($object);
} else {
throw new Exception(pht('Can not build adapter for object!'));
}
diff --git a/src/applications/herald/controller/HeraldTranscriptController.php b/src/applications/herald/controller/HeraldTranscriptController.php
--- a/src/applications/herald/controller/HeraldTranscriptController.php
+++ b/src/applications/herald/controller/HeraldTranscriptController.php
@@ -356,7 +356,17 @@
// Handle older transcripts which used a static string to record
// action results.
- if (!is_array($log)) {
+
+ if ($xscript->getDryRun()) {
+ $action_list->addItem(
+ id(new PHUIStatusItemView())
+ ->setIcon('fa-ban', 'grey')
+ ->setTarget(pht('Dry Run'))
+ ->setNote(
+ pht(
+ 'This was a dry run, so no actions were taken.')));
+ continue;
+ } else if (!is_array($log)) {
$action_list->addItem(
id(new PHUIStatusItemView())
->setIcon('fa-clock-o', 'grey')
diff --git a/src/applications/metamta/constants/PhabricatorMailRoutingRule.php b/src/applications/metamta/constants/PhabricatorMailRoutingRule.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/constants/PhabricatorMailRoutingRule.php
@@ -0,0 +1,51 @@
+<?php
+
+final class PhabricatorMailRoutingRule extends Phobject {
+
+ const ROUTE_AS_NOTIFICATION = 'route.notification';
+ const ROUTE_AS_MAIL = 'route.mail';
+
+ public static function isStrongerThan($rule_u, $rule_v) {
+ $strength_u = self::getRuleStrength($rule_u);
+ $strength_v = self::getRuleStrength($rule_v);
+
+ return ($strength_u > $strength_v);
+ }
+
+ public static function getRuleStrength($const) {
+ $strength = array(
+ self::ROUTE_AS_NOTIFICATION => 1,
+ self::ROUTE_AS_MAIL => 2,
+ );
+
+ return idx($strength, $const, 0);
+ }
+
+ public static function getRuleName($const) {
+ $names = array(
+ self::ROUTE_AS_NOTIFICATION => pht('Route as Notification'),
+ self::ROUTE_AS_MAIL => pht('Route as Mail'),
+ );
+
+ return idx($names, $const, $const);
+ }
+
+ public static function getRuleIcon($const) {
+ $icons = array(
+ self::ROUTE_AS_NOTIFICATION => 'fa-bell',
+ self::ROUTE_AS_MAIL => 'fa-envelope',
+ );
+
+ return idx($icons, $const, 'fa-question-circle');
+ }
+
+ public static function getRuleColor($const) {
+ $colors = array(
+ self::ROUTE_AS_NOTIFICATION => 'grey',
+ self::ROUTE_AS_MAIL => 'grey',
+ );
+
+ return idx($colors, $const, 'yellow');
+ }
+
+}
diff --git a/src/applications/metamta/controller/PhabricatorMetaMTAMailViewController.php b/src/applications/metamta/controller/PhabricatorMetaMTAMailViewController.php
--- a/src/applications/metamta/controller/PhabricatorMetaMTAMailViewController.php
+++ b/src/applications/metamta/controller/PhabricatorMetaMTAMailViewController.php
@@ -86,6 +86,10 @@
pht('Cc'),
$cc_list);
+ $properties->addProperty(
+ pht('Sent'),
+ phabricator_datetime($mail->getDateCreated(), $viewer));
+
$properties->addSectionHeader(
pht('Message'),
PHUIPropertyListView::ICON_SUMMARY);
@@ -144,23 +148,16 @@
$actors = $mail->getDeliveredActors();
$reasons = null;
if (!$actors) {
- // TODO: We can get rid of this special-cased message after these changes
- // have been live for a while, but provide a more tailored message for
- // now so things are a little less confusing for users.
- if ($mail->getStatus() == PhabricatorMetaMTAMail::STATUS_SENT) {
- $delivery = phutil_tag(
- 'em',
- array(),
- pht(
- 'This is an older message that predates recording delivery '.
- 'information, so none is available.'));
- } else {
- $delivery = phutil_tag(
- 'em',
- array(),
+ if ($mail->getStatus() == PhabricatorMailOutboundStatus::STATUS_QUEUE) {
+ $delivery = $this->renderEmptyMessage(
pht(
'This message has not been delivered yet, so delivery information '.
'is not available.'));
+ } else {
+ $delivery = $this->renderEmptyMessage(
+ pht(
+ 'This is an older message that predates recording delivery '.
+ 'information, so none is available.'));
}
} else {
$actor = idx($actors, $viewer->getPHID());
@@ -214,6 +211,127 @@
$properties->addProperty(pht('Delivery'), $delivery);
if ($reasons) {
$properties->addProperty(pht('Reasons'), $reasons);
+ $properties->addProperty(
+ null,
+ $this->renderEmptyMessage(
+ pht(
+ 'Delivery reasons are listed from weakest to strongest.')));
+ }
+
+ $properties->addSectionHeader(pht('Routing Rules'));
+
+ $map = $mail->getDeliveredRoutingMap();
+ $routing_detail = null;
+ if ($map === null) {
+ if ($mail->getStatus() == PhabricatorMailOutboundStatus::STATUS_QUEUE) {
+ $routing_result = $this->renderEmptyMessage(
+ pht(
+ 'This message has not been sent yet, so routing rules have '.
+ 'not been computed.'));
+ } else {
+ $routing_result = $this->renderEmptyMessage(
+ pht(
+ 'This is an older message which predates routing rules.'));
+ }
+ } else {
+ $rule = idx($map, $viewer->getPHID());
+ if ($rule === null) {
+ $rule = idx($map, 'default');
+ }
+
+ if ($rule === null) {
+ $routing_result = $this->renderEmptyMessage(
+ pht(
+ 'No routing rules applied when delivering this message to you.'));
+ } else {
+ $rule_const = $rule['rule'];
+ $reason_phid = $rule['reason'];
+ switch ($rule_const) {
+ case PhabricatorMailRoutingRule::ROUTE_AS_NOTIFICATION:
+ $routing_result = pht(
+ 'This message was routed as a notification because it '.
+ 'matched %s.',
+ $viewer->renderHandle($reason_phid)->render());
+ break;
+ case PhabricatorMailRoutingRule::ROUTE_AS_MAIL:
+ $routing_result = pht(
+ 'This message was routed as an email because it matched %s.',
+ $viewer->renderHandle($reason_phid)->render());
+ break;
+ default:
+ $routing_result = pht('Unknown routing rule "%s".', $rule_const);
+ break;
+ }
+ }
+
+ $routing_rules = $mail->getDeliveredRoutingRules();
+ if ($routing_rules) {
+ $rules = array();
+ foreach ($routing_rules as $rule) {
+ $phids = idx($rule, 'phids');
+ if ($phids === null) {
+ $rules[] = $rule;
+ } else if (in_array($viewer->getPHID(), $phids)) {
+ $rules[] = $rule;
+ }
+ }
+
+ // Reorder rules by strength.
+ foreach ($rules as $key => $rule) {
+ $const = $rule['routingRule'];
+ $phids = $rule['phids'];
+
+ if ($phids === null) {
+ $type = 'A';
+ } else {
+ $type = 'B';
+ }
+
+ $rules[$key]['strength'] = sprintf(
+ '~%s%08d',
+ $type,
+ PhabricatorMailRoutingRule::getRuleStrength($const));
+ }
+ $rules = isort($rules, 'strength');
+
+ $routing_detail = id(new PHUIStatusListView());
+ foreach ($rules as $rule) {
+ $const = $rule['routingRule'];
+ $phids = $rule['phids'];
+
+ $name = PhabricatorMailRoutingRule::getRuleName($const);
+
+ $icon = PhabricatorMailRoutingRule::getRuleIcon($const);
+ $color = PhabricatorMailRoutingRule::getRuleColor($const);
+
+ if ($phids === null) {
+ $kind = pht('Global');
+ } else {
+ $kind = pht('Personal');
+ }
+
+ $target = array($kind, ': ', $name);
+ $target = phutil_tag('strong', array(), $target);
+
+ $item = id(new PHUIStatusItemView())
+ ->setTarget($target)
+ ->setNote($viewer->renderHandle($rule['reasonPHID']))
+ ->setIcon($icon, $color);
+
+ $routing_detail->addItem($item);
+ }
+ }
+ }
+
+ $properties->addProperty(pht('Effective Rule'), $routing_result);
+
+ if ($routing_detail !== null) {
+ $properties->addProperty(pht('All Matching Rules'), $routing_detail);
+ $properties->addProperty(
+ null,
+ $this->renderEmptyMessage(
+ pht(
+ 'Matching rules are listed from weakest to strongest.')));
}
return $properties;
@@ -252,4 +370,8 @@
return $properties;
}
+ private function renderEmptyMessage($message) {
+ return phutil_tag('em', array(), $message);
+ }
+
}
diff --git a/src/applications/metamta/herald/PhabricatorMailEmailHeraldField.php b/src/applications/metamta/herald/PhabricatorMailEmailHeraldField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/herald/PhabricatorMailEmailHeraldField.php
@@ -0,0 +1,14 @@
+<?php
+
+abstract class PhabricatorMailEmailHeraldField
+ extends HeraldField {
+
+ public function supportsObject($object) {
+ return ($object instanceof PhabricatorMetaMTAMail);
+ }
+
+ public function getFieldGroupKey() {
+ return PhabricatorMailEmailHeraldFieldGroup::FIELDGROUPKEY;
+ }
+
+}
diff --git a/src/applications/metamta/herald/PhabricatorMailEmailHeraldFieldGroup.php b/src/applications/metamta/herald/PhabricatorMailEmailHeraldFieldGroup.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/herald/PhabricatorMailEmailHeraldFieldGroup.php
@@ -0,0 +1,15 @@
+<?php
+
+final class PhabricatorMailEmailHeraldFieldGroup extends HeraldFieldGroup {
+
+ const FIELDGROUPKEY = 'mail.message';
+
+ public function getGroupLabel() {
+ return pht('Message Fields');
+ }
+
+ protected function getGroupOrder() {
+ return 1000;
+ }
+
+}
diff --git a/src/applications/metamta/herald/PhabricatorMailEmailSubjectHeraldField.php b/src/applications/metamta/herald/PhabricatorMailEmailSubjectHeraldField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/herald/PhabricatorMailEmailSubjectHeraldField.php
@@ -0,0 +1,20 @@
+<?php
+
+final class PhabricatorMailEmailSubjectHeraldField
+ extends PhabricatorMailEmailHeraldField {
+
+ const FIELDCONST = 'mail.message.subject';
+
+ public function getHeraldFieldName() {
+ return pht('Subject');
+ }
+
+ public function getHeraldFieldValue($object) {
+ return $object->getSubject();
+ }
+
+ protected function getHeraldFieldStandardType() {
+ return self::STANDARD_TEXT;
+ }
+
+}
diff --git a/src/applications/metamta/herald/PhabricatorMailOutboundMailHeraldAdapter.php b/src/applications/metamta/herald/PhabricatorMailOutboundMailHeraldAdapter.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/herald/PhabricatorMailOutboundMailHeraldAdapter.php
@@ -0,0 +1,62 @@
+<?php
+
+final class PhabricatorMailOutboundMailHeraldAdapter
+ extends HeraldAdapter {
+
+ private $mail;
+
+ public function getAdapterApplicationClass() {
+ return 'PhabricatorMetaMTAApplication';
+ }
+
+ public function getAdapterContentDescription() {
+ return pht('Route outbound email.');
+ }
+
+ protected function initializeNewAdapter() {
+ $this->mail = $this->newObject();
+ }
+
+ protected function newObject() {
+ return new PhabricatorMetaMTAMail();
+ }
+
+ public function getObject() {
+ return $this->mail;
+ }
+
+ public function setObject(PhabricatorMetaMTAMail $mail) {
+ $this->mail = $mail;
+ return $this;
+ }
+
+ public function getAdapterContentName() {
+ return pht('Outbound Mail');
+ }
+
+ public function isSingleEventAdapter() {
+ return true;
+ }
+
+ public function getRepetitionOptions() {
+ return array(
+ HeraldRepetitionPolicyConfig::FIRST,
+ );
+ }
+
+ public function supportsRuleType($rule_type) {
+ switch ($rule_type) {
+ case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL:
+ case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL:
+ return true;
+ case HeraldRuleTypeConfig::RULE_TYPE_OBJECT:
+ default:
+ return false;
+ }
+ }
+
+ public function getHeraldName() {
+ return pht('Mail %d', $this->getObject()->getID());
+ }
+
+}
diff --git a/src/applications/metamta/herald/PhabricatorMailOutboundRoutingHeraldAction.php b/src/applications/metamta/herald/PhabricatorMailOutboundRoutingHeraldAction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/herald/PhabricatorMailOutboundRoutingHeraldAction.php
@@ -0,0 +1,46 @@
+<?php
+
+abstract class PhabricatorMailOutboundRoutingHeraldAction
+ extends HeraldAction {
+
+ const DO_ROUTE = 'do.route';
+
+ public function supportsObject($object) {
+ return ($object instanceof PhabricatorMetaMTAMail);
+ }
+
+ public function getActionGroupKey() {
+ return HeraldApplicationActionGroup::ACTIONGROUPKEY;
+ }
+
+ protected function applyRouting(HeraldRule $rule, $route, $phids) {
+ $adapter = $this->getAdapter();
+ $mail = $adapter->getObject();
+ $mail->addRoutingRule($route, $phids, $rule->getPHID());
+
+ $this->logEffect(
+ self::DO_ROUTE,
+ array(
+ 'route' => $route,
+ 'phids' => $phids,
+ ));
+ }
+
+ protected function getActionEffectMap() {
+ return array(
+ self::DO_ROUTE => array(
+ 'icon' => 'fa-arrow-right',
+ 'color' => 'green',
+ 'name' => pht('Routed Message'),
+ ),
+ );
+ }
+
+ protected function renderActionEffectDescription($type, $data) {
+ switch ($type) {
+ case self::DO_ROUTE:
+ return pht('Routed mail.');
+ }
+ }
+
+}
diff --git a/src/applications/metamta/herald/PhabricatorMailOutboundRoutingSelfEmailHeraldAction.php b/src/applications/metamta/herald/PhabricatorMailOutboundRoutingSelfEmailHeraldAction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/herald/PhabricatorMailOutboundRoutingSelfEmailHeraldAction.php
@@ -0,0 +1,34 @@
+<?php
+
+final class PhabricatorMailOutboundRoutingSelfEmailHeraldAction
+ extends PhabricatorMailOutboundRoutingHeraldAction {
+
+ const ACTIONCONST = 'routing.self.email';
+
+ public function getHeraldActionName() {
+ return pht('Deliver as email');
+ }
+
+ public function supportsRuleType($rule_type) {
+ return ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL);
+ }
+
+ public function applyEffect($object, HeraldEffect $effect) {
+ $rule = $effect->getRule();
+ $author_phid = $rule->getAuthorPHID();
+
+ $this->applyRouting(
+ $rule,
+ PhabricatorMailRoutingRule::ROUTE_AS_MAIL,
+ array($author_phid));
+ }
+
+ public function getHeraldActionStandardType() {
+ return self::STANDARD_NONE;
+ }
+
+ public function renderActionDescription($value) {
+ return pht('Deliver as email.');
+ }
+
+}
diff --git a/src/applications/metamta/herald/PhabricatorMailOutboundRoutingSelfNotificationHeraldAction.php b/src/applications/metamta/herald/PhabricatorMailOutboundRoutingSelfNotificationHeraldAction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/herald/PhabricatorMailOutboundRoutingSelfNotificationHeraldAction.php
@@ -0,0 +1,34 @@
+<?php
+
+final class PhabricatorMailOutboundRoutingSelfNotificationHeraldAction
+ extends PhabricatorMailOutboundRoutingHeraldAction {
+
+ const ACTIONCONST = 'routing.self.notification';
+
+ public function getHeraldActionName() {
+ return pht('Deliver as notification');
+ }
+
+ public function supportsRuleType($rule_type) {
+ return ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL);
+ }
+
+ public function applyEffect($object, HeraldEffect $effect) {
+ $rule = $effect->getRule();
+ $author_phid = $rule->getAuthorPHID();
+
+ $this->applyRouting(
+ $rule,
+ PhabricatorMailRoutingRule::ROUTE_AS_NOTIFICATION,
+ array($author_phid));
+ }
+
+ public function getHeraldActionStandardType() {
+ return self::STANDARD_NONE;
+ }
+
+ public function renderActionDescription($value) {
+ return pht('Deliver as notification.');
+ }
+
+}
diff --git a/src/applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php b/src/applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php
--- a/src/applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php
+++ b/src/applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php
@@ -14,6 +14,10 @@
return false;
}
+ if ($object instanceof PhabricatorMetaMTAMail) {
+ return false;
+ }
+
return true;
}
diff --git a/src/applications/metamta/phid/PhabricatorMetaMTAMailPHIDType.php b/src/applications/metamta/phid/PhabricatorMetaMTAMailPHIDType.php
--- a/src/applications/metamta/phid/PhabricatorMetaMTAMailPHIDType.php
+++ b/src/applications/metamta/phid/PhabricatorMetaMTAMailPHIDType.php
@@ -37,7 +37,7 @@
$handle
->setName($name)
- ->setFullName($name);
+ ->setURI('/mail/detail/'.$id.'/');
}
}
}
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
@@ -18,6 +18,8 @@
const REASON_BOT = 'bot';
const REASON_FORCE = 'force';
const REASON_FORCE_HERALD = 'force-herald';
+ const REASON_ROUTE_AS_NOTIFICATION = 'route-as-notification';
+ const REASON_ROUTE_AS_MAIL = 'route-as-mail';
private $phid;
private $emailAddress;
@@ -77,6 +79,7 @@
case self::REASON_NONE:
case self::REASON_FORCE:
case self::REASON_FORCE_HERALD:
+ case self::REASON_ROUTE_AS_MAIL:
return true;
default:
// All other reasons cause the message to not be delivered.
@@ -99,6 +102,8 @@
self::REASON_UNLOADABLE => pht('Bad Recipient'),
self::REASON_FORCE => pht('Forced Mail'),
self::REASON_FORCE_HERALD => pht('Forced by Herald'),
+ self::REASON_ROUTE_AS_NOTIFICATION => pht('Route as Notification'),
+ self::REASON_ROUTE_AS_MAIL => pht('Route as Mail'),
);
return idx($names, $reason, pht('Unknown ("%s")', $reason));
@@ -147,6 +152,12 @@
self::REASON_FORCE_HERALD => pht(
'This recipient was added by a "Send me an Email" rule in Herald, '.
'which overrides some delivery settings.'),
+ self::REASON_ROUTE_AS_NOTIFICATION => pht(
+ 'This message was downgraded to a notification by outbound mail '.
+ 'rules in Herald.'),
+ self::REASON_ROUTE_AS_MAIL => pht(
+ 'This message was upgraded to email by outbound mail rules '.
+ 'in Herald.'),
);
return idx($descriptions, $reason, pht('Unknown Reason ("%s")', $reason));
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
@@ -16,6 +16,7 @@
protected $relatedPHID;
private $recipientExpansionMap;
+ private $routingMap;
public function __construct() {
@@ -656,6 +657,9 @@
}
$this->setParam('actors.sent', $actor_list);
+ $this->setParam('routing.sent', $this->getParam('routing'));
+ $this->setParam('routingmap.sent', $this->getRoutingRuleMap());
+
if (!$add_to && !$add_cc) {
$this->setStatus(PhabricatorMailOutboundStatus::STATUS_VOID);
$this->setMessage(
@@ -963,9 +967,25 @@
}
}
+ foreach ($deliverable as $phid) {
+ switch ($this->getRoutingRule($phid)) {
+ case PhabricatorMailRoutingRule::ROUTE_AS_NOTIFICATION:
+ $actors[$phid]->setUndeliverable(
+ PhabricatorMetaMTAActor::REASON_ROUTE_AS_NOTIFICATION);
+ break;
+ case PhabricatorMailRoutingRule::ROUTE_AS_MAIL:
+ $actors[$phid]->setDeliverable(
+ PhabricatorMetaMTAActor::REASON_ROUTE_AS_MAIL);
+ break;
+ default:
+ // No change.
+ break;
+ }
+ }
+
// If recipients were initially deliverable and were added by "Send me an
// email" Herald rules, annotate them as such and make them deliverable
- // again, overriding any changes made by the "self mail" and "mail tags"
+ // again, overriding any changes made by the "self mail" and "mail tags"
// settings.
$force_recipients = $this->getForceHeraldMailRecipientPHIDs();
$force_recipients = array_fuse($force_recipients);
@@ -1065,6 +1085,82 @@
return $this->getParam('actors.sent');
}
+ public function getDeliveredRoutingRules() {
+ return $this->getParam('routing.sent');
+ }
+
+ public function getDeliveredRoutingMap() {
+ return $this->getParam('routingmap.sent');
+ }
+
+
+/* -( Routing )------------------------------------------------------------ */
+
+
+ public function addRoutingRule($routing_rule, $phids, $reason_phid) {
+ $routing = $this->getParam('routing', array());
+ $routing[] = array(
+ 'routingRule' => $routing_rule,
+ 'phids' => $phids,
+ 'reasonPHID' => $reason_phid,
+ );
+ $this->setParam('routing', $routing);
+
+ // Throw the routing map away so we rebuild it.
+ $this->routingMap = null;
+
+ return $this;
+ }
+
+ private function getRoutingRule($phid) {
+ $map = $this->getRoutingRuleMap();
+
+ $info = idx($map, $phid, idx($map, 'default'));
+ if ($info) {
+ return idx($info, 'rule');
+ }
+
+ return null;
+ }
+
+ private function getRoutingRuleMap() {
+ if ($this->routingMap === null) {
+ $map = array();
+
+ $routing = $this->getParam('routing', array());
+ foreach ($routing as $route) {
+ $phids = $route['phids'];
+ if ($phids === null) {
+ $phids = array('default');
+ }
+
+ foreach ($phids as $phid) {
+ $new_rule = $route['routingRule'];
+
+ $current_rule = idx($map, $phid);
+ if ($current_rule === null) {
+ $is_stronger = true;
+ } else {
+ $is_stronger = PhabricatorMailRoutingRule::isStrongerThan(
+ $new_rule,
+ $current_rule);
+ }
+
+ if ($is_stronger) {
+ $map[$phid] = array(
+ 'rule' => $new_rule,
+ 'reason' => $route['reasonPHID'],
+ );
+ }
+ }
+ }
+
+ $this->routingMap = $map;
+ }
+
+ return $this->routingMap;
+ }
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
--- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -1055,6 +1055,7 @@
}
if ($this->shouldPublishFeedStory($object, $xactions)) {
+
$mailed = array();
foreach ($messages as $mail) {
foreach ($mail->buildRecipientList() as $phid) {
@@ -2299,6 +2300,8 @@
}
}
+ $this->runHeraldMailRules($messages);
+
return $messages;
}
@@ -3140,4 +3143,16 @@
);
}
+ private function runHeraldMailRules(array $messages) {
+ foreach ($messages as $message) {
+ $engine = new HeraldEngine();
+ $adapter = id(new PhabricatorMailOutboundMailHeraldAdapter())
+ ->setObject($message);
+
+ $rules = $engine->loadRulesForAdapter($adapter);
+ $effects = $engine->applyRules($rules, $adapter);
+ $engine->applyEffects($effects, $adapter, $rules);
+ }
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
May 16 2024, 2:16 AM (4 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6290617
Default Alt Text
D13897.diff (28 KB)

Event Timeline