@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Modularize "Send an Email" Herald actions

Summary: Ref T8726. No surprises.

Test Plan:
Created rules using both action variants, applied upgrade, saw rules still work correctly.

{F658842}

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: joshuaspence, epriestley

Maniphest Tasks: T8726

Differential Revision: https://secure.phabricator.com/D13701

+183 -91
+13
resources/sql/autopatches/20150724.herald.2.sql
··· 1 + UPDATE {$NAMESPACE}_herald.herald_actionrecord a 2 + JOIN {$NAMESPACE}_herald.herald_rule r 3 + ON a.ruleID = r.id 4 + SET a.action = 'email.other' 5 + WHERE r.ruleType != 'personal' 6 + AND a.action = 'email'; 7 + 8 + UPDATE {$NAMESPACE}_herald.herald_actionrecord a 9 + JOIN {$NAMESPACE}_herald.herald_rule r 10 + ON a.ruleID = r.id 11 + SET a.action = 'email.self' 12 + WHERE r.ruleType = 'personal' 13 + AND a.action = 'email';
+6
src/__phutil_library_map__.php
··· 2274 2274 'PhabricatorMetaMTADAO' => 'applications/metamta/storage/PhabricatorMetaMTADAO.php', 2275 2275 'PhabricatorMetaMTAEmailBodyParser' => 'applications/metamta/parser/PhabricatorMetaMTAEmailBodyParser.php', 2276 2276 'PhabricatorMetaMTAEmailBodyParserTestCase' => 'applications/metamta/parser/__tests__/PhabricatorMetaMTAEmailBodyParserTestCase.php', 2277 + 'PhabricatorMetaMTAEmailHeraldAction' => 'applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php', 2278 + 'PhabricatorMetaMTAEmailOthersHeraldAction' => 'applications/metamta/herald/PhabricatorMetaMTAEmailOthersHeraldAction.php', 2279 + 'PhabricatorMetaMTAEmailSelfHeraldAction' => 'applications/metamta/herald/PhabricatorMetaMTAEmailSelfHeraldAction.php', 2277 2280 'PhabricatorMetaMTAErrorMailAction' => 'applications/metamta/action/PhabricatorMetaMTAErrorMailAction.php', 2278 2281 'PhabricatorMetaMTAMail' => 'applications/metamta/storage/PhabricatorMetaMTAMail.php', 2279 2282 'PhabricatorMetaMTAMailBody' => 'applications/metamta/view/PhabricatorMetaMTAMailBody.php', ··· 6170 6173 'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO', 6171 6174 'PhabricatorMetaMTAEmailBodyParser' => 'Phobject', 6172 6175 'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase', 6176 + 'PhabricatorMetaMTAEmailHeraldAction' => 'HeraldAction', 6177 + 'PhabricatorMetaMTAEmailOthersHeraldAction' => 'PhabricatorMetaMTAEmailHeraldAction', 6178 + 'PhabricatorMetaMTAEmailSelfHeraldAction' => 'PhabricatorMetaMTAEmailHeraldAction', 6173 6179 'PhabricatorMetaMTAErrorMailAction' => 'PhabricatorSystemAction', 6174 6180 'PhabricatorMetaMTAMail' => array( 6175 6181 'PhabricatorMetaMTADAO',
-2
src/applications/differential/herald/HeraldDifferentialRevisionAdapter.php
··· 162 162 case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: 163 163 return array_merge( 164 164 array( 165 - self::ACTION_EMAIL, 166 165 self::ACTION_ADD_REVIEWERS, 167 166 self::ACTION_ADD_BLOCKING_REVIEWERS, 168 167 self::ACTION_APPLY_BUILD_PLANS, ··· 172 171 case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 173 172 return array_merge( 174 173 array( 175 - self::ACTION_EMAIL, 176 174 self::ACTION_ADD_REVIEWERS, 177 175 self::ACTION_ADD_BLOCKING_REVIEWERS, 178 176 ),
-2
src/applications/diffusion/herald/HeraldCommitAdapter.php
··· 89 89 case HeraldRuleTypeConfig::RULE_TYPE_OBJECT: 90 90 return array_merge( 91 91 array( 92 - self::ACTION_EMAIL, 93 92 self::ACTION_AUDIT, 94 93 self::ACTION_APPLY_BUILD_PLANS, 95 94 ), ··· 97 96 case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 98 97 return array_merge( 99 98 array( 100 - self::ACTION_EMAIL, 101 99 self::ACTION_AUDIT, 102 100 ), 103 101 parent::getActions($rule_type));
-2
src/applications/diffusion/herald/HeraldPreCommitAdapter.php
··· 80 80 return array_merge( 81 81 array( 82 82 self::ACTION_BLOCK, 83 - self::ACTION_EMAIL, 84 83 ), 85 84 parent::getActions($rule_type)); 86 85 case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 87 86 return array_merge( 88 87 array( 89 - self::ACTION_EMAIL, 90 88 ), 91 89 parent::getActions($rule_type)); 92 90 }
+8 -33
src/applications/herald/adapter/HeraldAdapter.php
··· 26 26 const CONDITION_IS_TRUE = 'true'; 27 27 const CONDITION_IS_FALSE = 'false'; 28 28 29 - const ACTION_EMAIL = 'email'; 30 29 const ACTION_AUDIT = 'audit'; 31 30 const ACTION_ASSIGN_TASK = 'assigntask'; 32 31 const ACTION_ADD_PROJECTS = 'addprojects'; ··· 54 53 55 54 public function getForcedEmailPHIDs() { 56 55 return array_values($this->forcedEmailPHIDs); 56 + } 57 + 58 + public function addEmailPHID($phid, $force) { 59 + $this->emailPHIDs[$phid] = $phid; 60 + if ($force) { 61 + $this->forcedEmailPHIDs[$phid] = $phid; 62 + } 63 + return $this; 57 64 } 58 65 59 66 public function getCustomActions() { ··· 721 728 case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: 722 729 case HeraldRuleTypeConfig::RULE_TYPE_OBJECT: 723 730 $standard = array( 724 - self::ACTION_EMAIL => pht('Send an email to'), 725 731 self::ACTION_AUDIT => pht('Trigger an Audit by'), 726 732 self::ACTION_ASSIGN_TASK => pht('Assign task to'), 727 733 self::ACTION_ADD_PROJECTS => pht('Add projects'), ··· 735 741 break; 736 742 case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 737 743 $standard = array( 738 - self::ACTION_EMAIL => pht('Send me an email'), 739 744 self::ACTION_AUDIT => pht('Trigger an Audit by me'), 740 745 self::ACTION_ASSIGN_TASK => pht('Assign task to me'), 741 746 self::ACTION_ADD_REVIEWERS => pht('Add me as a reviewer'), ··· 779 784 $rule_type = $rule->getRuleType(); 780 785 if ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL) { 781 786 switch ($action->getAction()) { 782 - case self::ACTION_EMAIL: 783 787 case self::ACTION_AUDIT: 784 788 case self::ACTION_ASSIGN_TASK: 785 789 case self::ACTION_ADD_REVIEWERS: ··· 820 824 821 825 if ($is_personal) { 822 826 switch ($action) { 823 - case self::ACTION_EMAIL: 824 827 case self::ACTION_AUDIT: 825 828 case self::ACTION_ASSIGN_TASK: 826 829 case self::ACTION_ADD_REVIEWERS: ··· 833 836 } 834 837 } else { 835 838 switch ($action) { 836 - case self::ACTION_EMAIL: 837 - return $this->buildTokenizerFieldValue( 838 - new PhabricatorMetaMTAMailableDatasource()); 839 839 case self::ACTION_ADD_PROJECTS: 840 840 case self::ACTION_REMOVE_PROJECTS: 841 841 return $this->buildTokenizerFieldValue( ··· 1204 1204 case self::ACTION_ADD_PROJECTS: 1205 1205 case self::ACTION_REMOVE_PROJECTS: 1206 1206 return $this->applyProjectsEffect($effect); 1207 - case self::ACTION_EMAIL: 1208 - return $this->applyEmailEffect($effect); 1209 1207 default: 1210 1208 break; 1211 1209 } ··· 1251 1249 $effect, 1252 1250 true, 1253 1251 pht('Added projects.')); 1254 - } 1255 - 1256 - 1257 - /** 1258 - * @task apply 1259 - */ 1260 - private function applyEmailEffect(HeraldEffect $effect) { 1261 - foreach ($effect->getTarget() as $phid) { 1262 - $this->emailPHIDs[$phid] = $phid; 1263 - 1264 - // If this is a personal rule, we'll force delivery of a real email. This 1265 - // effect is stronger than notification preferences, so you get an actual 1266 - // email even if your preferences are set to "Notify" or "Ignore". 1267 - $rule = $effect->getRule(); 1268 - if ($rule->isPersonalRule()) { 1269 - $this->forcedEmailPHIDs[$phid] = $phid; 1270 - } 1271 - } 1272 - 1273 - return new HeraldApplyTranscript( 1274 - $effect, 1275 - true, 1276 - pht('Added mailable to mail targets.')); 1277 1252 } 1278 1253 1279 1254 public function loadEdgePHIDs($type) {
-2
src/applications/maniphest/herald/HeraldManiphestTaskAdapter.php
··· 72 72 case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: 73 73 return array_merge( 74 74 array( 75 - self::ACTION_EMAIL, 76 75 self::ACTION_ASSIGN_TASK, 77 76 ), 78 77 parent::getActions($rule_type)); 79 78 case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 80 79 return array_merge( 81 80 array( 82 - self::ACTION_EMAIL, 83 81 self::ACTION_ASSIGN_TASK, 84 82 ), 85 83 parent::getActions($rule_type));
+69
src/applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorMetaMTAEmailHeraldAction 4 + extends HeraldAction { 5 + 6 + const DO_SEND = 'do.send'; 7 + const DO_FORCE = 'do.force'; 8 + 9 + public function supportsObject($object) { 10 + // NOTE: This implementation lacks generality, but there's no great way to 11 + // figure out if something generates email right now. 12 + 13 + if ($object instanceof DifferentialDiff) { 14 + return false; 15 + } 16 + 17 + return true; 18 + } 19 + 20 + public function getActionGroupKey() { 21 + return HeraldNotifyActionGroup::ACTIONGROUPKEY; 22 + } 23 + 24 + protected function applyEmail(array $phids, $force) { 25 + $adapter = $this->getAdapter(); 26 + 27 + foreach ($phids as $phid) { 28 + $adapter->addEmailPHID($phid, $force); 29 + } 30 + 31 + if ($force) { 32 + $this->logEffect(self::DO_FORCE, $phids); 33 + } else { 34 + $this->logEffect(self::DO_SEND, $phids); 35 + } 36 + } 37 + 38 + protected function getActionEffectMap() { 39 + return array( 40 + self::DO_SEND => array( 41 + 'icon' => 'fa-envelope', 42 + 'color' => 'green', 43 + 'name' => pht('Sent Mail'), 44 + ), 45 + self::DO_FORCE => array( 46 + 'icon' => 'fa-envelope', 47 + 'color' => 'blue', 48 + 'name' => pht('Forced Mail'), 49 + ), 50 + ); 51 + } 52 + 53 + public function renderActionEffectDescription($type, $data) { 54 + switch ($type) { 55 + case self::DO_SEND: 56 + return pht( 57 + 'Queued email to be delivered to %s target(s): %s.', 58 + new PhutilNumber(count($data)), 59 + $this->renderHandleList($data)); 60 + case self::DO_FORCE: 61 + return pht( 62 + 'Queued email to be delivered to %s target(s), ignoring their '. 63 + 'notification preferences: %s.', 64 + new PhutilNumber(count($data)), 65 + $this->renderHandleList($data)); 66 + } 67 + } 68 + 69 + }
+32
src/applications/metamta/herald/PhabricatorMetaMTAEmailOthersHeraldAction.php
··· 1 + <?php 2 + 3 + final class PhabricatorMetaMTAEmailOthersHeraldAction 4 + extends PhabricatorMetaMTAEmailHeraldAction { 5 + 6 + const ACTIONCONST = 'email.other'; 7 + 8 + public function getHeraldActionName() { 9 + return pht('Send an email to'); 10 + } 11 + 12 + public function supportsRuleType($rule_type) { 13 + return ($rule_type != HeraldRuleTypeConfig::RULE_TYPE_PERSONAL); 14 + } 15 + 16 + public function applyEffect($object, HeraldEffect $effect) { 17 + return $this->applyEmail($effect->getTarget(), $force = false); 18 + } 19 + 20 + public function getHeraldActionStandardType() { 21 + return self::STANDARD_PHID_LIST; 22 + } 23 + 24 + protected function getDatasource() { 25 + return new PhabricatorMetaMTAMailableDatasource(); 26 + } 27 + 28 + public function renderActionDescription($value) { 29 + return pht('Send an email to: %s.', $this->renderHandleList($value)); 30 + } 31 + 32 + }
+34
src/applications/metamta/herald/PhabricatorMetaMTAEmailSelfHeraldAction.php
··· 1 + <?php 2 + 3 + final class PhabricatorMetaMTAEmailSelfHeraldAction 4 + extends PhabricatorMetaMTAEmailHeraldAction { 5 + 6 + const ACTIONCONST = 'email.self'; 7 + 8 + public function getHeraldActionName() { 9 + return pht('Send me an email'); 10 + } 11 + 12 + public function supportsRuleType($rule_type) { 13 + return ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL); 14 + } 15 + 16 + public function applyEffect($object, HeraldEffect $effect) { 17 + $phid = $effect->getRule()->getAuthorPHID(); 18 + 19 + // For personal rules, we'll force delivery of a real email. This effect 20 + // is stronger than notification preferences, so you get an actual email 21 + // even if your preferences are set to "Notify" or "Ignore". 22 + 23 + return $this->applyEmail(array($phid), $force = true); 24 + } 25 + 26 + public function getHeraldActionStandardType() { 27 + return self::STANDARD_NONE; 28 + } 29 + 30 + public function renderActionDescription($value) { 31 + return pht('Send an email to rule author.'); 32 + } 33 + 34 + }
-18
src/applications/phriction/herald/PhrictionDocumentHeraldAdapter.php
··· 48 48 } 49 49 } 50 50 51 - public function getActions($rule_type) { 52 - switch ($rule_type) { 53 - case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: 54 - return array_merge( 55 - array( 56 - self::ACTION_EMAIL, 57 - ), 58 - parent::getActions($rule_type)); 59 - case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 60 - return array_merge( 61 - array( 62 - self::ACTION_EMAIL, 63 - ), 64 - parent::getActions($rule_type)); 65 - } 66 - } 67 - 68 - 69 51 public function getHeraldName() { 70 52 return pht('Wiki Document %d', $this->getDocument()->getID()); 71 53 }
-8
src/applications/subscriptions/herald/PhabricatorSubscriptionsAddSelfHeraldAction.php
··· 9 9 return pht('Add me as a subscriber'); 10 10 } 11 11 12 - public function getActionGroupKey() { 13 - return HeraldSupportActionGroup::ACTIONGROUPKEY; 14 - } 15 - 16 - public function supportsObject($object) { 17 - return ($object instanceof PhabricatorSubscribableInterface); 18 - } 19 - 20 12 public function supportsRuleType($rule_type) { 21 13 return ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL); 22 14 }
-8
src/applications/subscriptions/herald/PhabricatorSubscriptionsAddSubscribersHeraldAction.php
··· 9 9 return pht('Add subscribers'); 10 10 } 11 11 12 - public function getActionGroupKey() { 13 - return HeraldSupportActionGroup::ACTIONGROUPKEY; 14 - } 15 - 16 - public function supportsObject($object) { 17 - return ($object instanceof PhabricatorSubscribableInterface); 18 - } 19 - 20 12 public function supportsRuleType($rule_type) { 21 13 return ($rule_type != HeraldRuleTypeConfig::RULE_TYPE_PERSONAL); 22 14 }
+8
src/applications/subscriptions/herald/PhabricatorSubscriptionsHeraldAction.php
··· 12 12 const DO_SUBSCRIBED = 'do.subscribed'; 13 13 const DO_UNSUBSCRIBED = 'do.unsubscribed'; 14 14 15 + public function getActionGroupKey() { 16 + return HeraldSupportActionGroup::ACTIONGROUPKEY; 17 + } 18 + 19 + public function supportsObject($object) { 20 + return ($object instanceof PhabricatorSubscribableInterface); 21 + } 22 + 15 23 protected function applySubscribe(array $phids, $is_add) { 16 24 $adapter = $this->getAdapter(); 17 25
-8
src/applications/subscriptions/herald/PhabricatorSubscriptionsRemoveSelfHeraldAction.php
··· 9 9 return pht('Remove me as a subscriber'); 10 10 } 11 11 12 - public function getActionGroupKey() { 13 - return HeraldSupportActionGroup::ACTIONGROUPKEY; 14 - } 15 - 16 - public function supportsObject($object) { 17 - return ($object instanceof PhabricatorSubscribableInterface); 18 - } 19 - 20 12 public function supportsRuleType($rule_type) { 21 13 return ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL); 22 14 }
-8
src/applications/subscriptions/herald/PhabricatorSubscriptionsRemoveSubscribersHeraldAction.php
··· 9 9 return pht('Remove subscribers'); 10 10 } 11 11 12 - public function getActionGroupKey() { 13 - return HeraldSupportActionGroup::ACTIONGROUPKEY; 14 - } 15 - 16 - public function supportsObject($object) { 17 - return ($object instanceof PhabricatorSubscribableInterface); 18 - } 19 - 20 12 public function supportsRuleType($rule_type) { 21 13 return ($rule_type != HeraldRuleTypeConfig::RULE_TYPE_PERSONAL); 22 14 }
+13
src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
··· 1290 1290 'Removed subscribers: %2$s.', 1291 1291 ), 1292 1292 1293 + 'Queued email to be delivered to %s target(s): %s.' => array( 1294 + 'Queued email to be delivered to target: %2$s.', 1295 + 'Queued email to be delivered to targets: %2$s.', 1296 + ), 1297 + 1298 + 'Queued email to be delivered to %s target(s), ignoring their '. 1299 + 'notification preferences: %s.' => array( 1300 + 'Queued email to be delivered to target, ignoring notification '. 1301 + 'preferences: %2$s.', 1302 + 'Queued email to be delivered to targets, ignoring notification '. 1303 + 'preferences: %2$s.', 1304 + ), 1305 + 1293 1306 ); 1294 1307 } 1295 1308