@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.

Herald - add support for application emails.

Summary:
Fixes T5039. The trick / possibly lame part here is we only match 1 application email and its undefined which one. e.g. if a user emails us at address x, y, and z only one of those will pick up the mail. Ergo, don't let users define non-sensical herald conditions like "matches all". Also document what I think was non-intuitive about the code with an inline comment; we have to return an array with just a phid from an object and out of context it feels very "what the...???"

Note this needs to be deployed to other applications still, but I think its okay to close T5039 aggressively here since its done from a user story perspective.

Test Plan: set up a herald rule to flag tasks created as blue via app email x. sent an email to x via `bin/mail receive-test` and verified the task had the blue flag

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T5039

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

+72 -13
+11 -11
resources/celerity/map.php
··· 378 378 'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => 'e5822781', 379 379 'rsrc/js/application/files/behavior-icon-composer.js' => '8ef9ab58', 380 380 'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888', 381 - 'rsrc/js/application/herald/HeraldRuleEditor.js' => '335fd41f', 381 + 'rsrc/js/application/herald/HeraldRuleEditor.js' => '6e2de6f2', 382 382 'rsrc/js/application/herald/PathTypeahead.js' => 'f7fc67ec', 383 383 'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3', 384 384 'rsrc/js/application/maniphest/behavior-batch-editor.js' => 'f24f3253', ··· 530 530 'global-drag-and-drop-css' => '697324ad', 531 531 'harbormaster-css' => '49d64eb4', 532 532 'herald-css' => '826075fa', 533 - 'herald-rule-editor' => '335fd41f', 533 + 'herald-rule-editor' => '6e2de6f2', 534 534 'herald-test-css' => '778b008e', 535 535 'homepage-panel-css' => 'e34bf140', 536 536 'inline-comment-summary-css' => '8cfd34e8', ··· 1028 1028 'javelin-behavior-device', 1029 1029 'phabricator-title', 1030 1030 ), 1031 - '335fd41f' => array( 1032 - 'multirow-row-manager', 1033 - 'javelin-install', 1034 - 'javelin-util', 1035 - 'javelin-dom', 1036 - 'javelin-stratcom', 1037 - 'javelin-json', 1038 - 'phabricator-prefab', 1039 - ), 1040 1031 '3ab51e2c' => array( 1041 1032 'javelin-behavior', 1042 1033 'javelin-behavior-device', ··· 1291 1282 'javelin-dom', 1292 1283 'javelin-typeahead', 1293 1284 'javelin-uri', 1285 + ), 1286 + '6e2de6f2' => array( 1287 + 'multirow-row-manager', 1288 + 'javelin-install', 1289 + 'javelin-util', 1290 + 'javelin-dom', 1291 + 'javelin-stratcom', 1292 + 'javelin-json', 1293 + 'phabricator-prefab', 1294 1294 ), 1295 1295 '6e8cefa4' => array( 1296 1296 'javelin-install',
+33 -2
src/applications/herald/adapter/HeraldAdapter.php
··· 39 39 const FIELD_AUTHOR_RAW = 'author-raw'; 40 40 const FIELD_COMMITTER_RAW = 'committer-raw'; 41 41 const FIELD_IS_NEW_OBJECT = 'new-object'; 42 + const FIELD_APPLICATION_EMAIL = 'applicaton-email'; 42 43 const FIELD_TASK_PRIORITY = 'taskpriority'; 43 44 const FIELD_TASK_STATUS = 'taskstatus'; 44 45 const FIELD_ARCANIST_PROJECT = 'arcanist-project'; ··· 98 99 const VALUE_BUILD_PLAN = 'buildplan'; 99 100 const VALUE_TASK_PRIORITY = 'taskpriority'; 100 101 const VALUE_TASK_STATUS = 'taskstatus'; 101 - const VALUE_ARCANIST_PROJECT = 'arcanistprojects'; 102 - const VALUE_LEGAL_DOCUMENTS = 'legaldocuments'; 102 + const VALUE_ARCANIST_PROJECT = 'arcanistprojects'; 103 + const VALUE_LEGAL_DOCUMENTS = 'legaldocuments'; 104 + const VALUE_APPLICATION_EMAIL = 'applicationemail'; 103 105 104 106 private $contentSource; 105 107 private $isNewObject; 108 + private $applicationEmail; 106 109 private $customFields = false; 107 110 private $customActions = null; 108 111 private $queuedTransactions = array(); ··· 154 157 public function setIsNewObject($new) { 155 158 $this->isNewObject = (bool) $new; 156 159 return $this; 160 + } 161 + 162 + public function setApplicationEmail( 163 + PhabricatorMetaMTAApplicationEmail $email) { 164 + $this->applicationEmail = $email; 165 + return $this; 166 + } 167 + 168 + public function getApplicationEmail() { 169 + return $this->applicationEmail; 157 170 } 158 171 159 172 abstract public function getPHID(); ··· 169 182 return true; 170 183 case self::FIELD_IS_NEW_OBJECT: 171 184 return $this->getIsNewObject(); 185 + case self::FIELD_APPLICATION_EMAIL: 186 + $value = array(); 187 + // while there is only one match by implementation, we do set 188 + // comparisons on phids, so return an array with just the phid 189 + if ($this->getApplicationEmail()) { 190 + $value[] = $this->getApplicationEmail()->getPHID(); 191 + } 192 + return $value; 172 193 default: 173 194 if ($this->isHeraldCustomKey($field_name)) { 174 195 return $this->getCustomFieldValue($field_name); ··· 312 333 self::FIELD_AUTHOR_RAW => pht('Raw author name'), 313 334 self::FIELD_COMMITTER_RAW => pht('Raw committer name'), 314 335 self::FIELD_IS_NEW_OBJECT => pht('Is newly created?'), 336 + self::FIELD_APPLICATION_EMAIL => pht('Receiving email address'), 315 337 self::FIELD_TASK_PRIORITY => pht('Task priority'), 316 338 self::FIELD_TASK_STATUS => pht('Task status'), 317 339 self::FIELD_ARCANIST_PROJECT => pht('Arcanist Project'), ··· 396 418 case self::FIELD_REPOSITORY_PROJECTS: 397 419 return array( 398 420 self::CONDITION_INCLUDE_ALL, 421 + self::CONDITION_INCLUDE_ANY, 422 + self::CONDITION_INCLUDE_NONE, 423 + self::CONDITION_EXISTS, 424 + self::CONDITION_NOT_EXISTS, 425 + ); 426 + case self::FIELD_APPLICATION_EMAIL: 427 + return array( 399 428 self::CONDITION_INCLUDE_ANY, 400 429 self::CONDITION_INCLUDE_NONE, 401 430 self::CONDITION_EXISTS, ··· 874 903 return self::VALUE_PROJECT; 875 904 case self::FIELD_REVIEWERS: 876 905 return self::VALUE_USER_OR_PROJECT; 906 + case self::FIELD_APPLICATION_EMAIL: 907 + return self::VALUE_APPLICATION_EMAIL; 877 908 default: 878 909 return self::VALUE_USER; 879 910 }
+1
src/applications/herald/adapter/HeraldManiphestTaskAdapter.php
··· 91 91 self::FIELD_TASK_PRIORITY, 92 92 self::FIELD_TASK_STATUS, 93 93 self::FIELD_IS_NEW_OBJECT, 94 + self::FIELD_APPLICATION_EMAIL, 94 95 ), 95 96 parent::getFields()); 96 97 }
+1
src/applications/herald/controller/HeraldRuleController.php
··· 602 602 'user' => new PhabricatorPeopleDatasource(), 603 603 'email' => new PhabricatorMetaMTAMailableDatasource(), 604 604 'userorproject' => new PhabricatorProjectOrUserDatasource(), 605 + 'applicationemail' => new PhabricatorMetaMTAApplicationEmailDatasource(), 605 606 ); 606 607 607 608 foreach ($sources as $key => $source) {
+1
src/applications/maniphest/mail/ManiphestCreateMailReceiver.php
··· 41 41 $handler->setActor($sender); 42 42 $handler->setExcludeMailRecipientPHIDs( 43 43 $mail->loadExcludeMailRecipientPHIDs()); 44 + $handler->setApplicationEmail($this->getApplicationEmail()); 44 45 $handler->processEmail($mail); 45 46 46 47 $mail->setRelatedPHID($task->getPHID());
+1
src/applications/maniphest/mail/ManiphestReplyHandler.php
··· 171 171 ->setContinueOnNoEffect(true) 172 172 ->setContinueOnMissingFields(true) 173 173 ->setContentSource($content_source) 174 + ->setApplicationEmail($this->getApplicationEmail()) 174 175 ->applyTransactions($task, $xactions); 175 176 176 177 $event = new PhabricatorEvent(
+11
src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php
··· 3 3 abstract class PhabricatorMailReplyHandler { 4 4 5 5 private $mailReceiver; 6 + private $applicationEmail; 6 7 private $actor; 7 8 private $excludePHIDs = array(); 8 9 ··· 14 15 15 16 final public function getMailReceiver() { 16 17 return $this->mailReceiver; 18 + } 19 + 20 + public function setApplicationEmail( 21 + PhabricatorMetaMTAApplicationEmail $email) { 22 + $this->applicationEmail = $email; 23 + return $this; 24 + } 25 + 26 + public function getApplicationEmail() { 27 + return $this->applicationEmail; 17 28 } 18 29 19 30 final public function setActor(PhabricatorUser $actor) {
+12
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 22 22 private $heraldTranscript; 23 23 private $subscribers; 24 24 private $unmentionablePHIDMap = array(); 25 + private $applicationEmail; 25 26 26 27 private $isPreview; 27 28 private $isHeraldEditor; ··· 183 184 184 185 public function getUnmentionablePHIDMap() { 185 186 return $this->unmentionablePHIDMap; 187 + } 188 + 189 + public function setApplicationEmail( 190 + PhabricatorMetaMTAApplicationEmail $email) { 191 + $this->applicationEmail = $email; 192 + return $this; 193 + } 194 + 195 + public function getApplicationEmail() { 196 + return $this->applicationEmail; 186 197 } 187 198 188 199 public function getTransactionTypes() { ··· 2427 2438 $adapter = $this->buildHeraldAdapter($object, $xactions); 2428 2439 $adapter->setContentSource($this->getContentSource()); 2429 2440 $adapter->setIsNewObject($this->getIsNewObject()); 2441 + $adapter->setApplicationEmail($this->getApplicationEmail()); 2430 2442 $xscript = HeraldEngine::loadAndApplyRules($adapter); 2431 2443 2432 2444 $this->setHeraldAdapter($adapter);
+1
webroot/rsrc/js/application/herald/HeraldRuleEditor.js
··· 222 222 case 'taskstatus': 223 223 case 'arcanistprojects': 224 224 case 'legaldocuments': 225 + case 'applicationemail': 225 226 var tokenizer = this._newTokenizer(type); 226 227 input = tokenizer[0]; 227 228 get_fn = tokenizer[1];