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

Add Differential and Herald mail stamps and some refinements

Summary:
Ref T13053. Adds revision stamps (status, reviewers, etc). Adds Herald rule stamps, like the existing X-Herald-Rules header.

Removes the "self" stamps, since you can just write a rule against `whatever(@epriestley)` equivalently. If there's routing logic around this, it can live in the routing layer. This avoids tons of self-actor, self-mention, self-reviewer, self-blocking-reviewer, self-resigned-reviewer, etc., stamps.

Use `natcasesort()` instead of `sort()` so that numeric values (like monograms) sort `9, 80, 700` instead of `700, 80, 9`.

Remove the commas from rendering since they don't really add anything.

Test Plan: Edited tasks and revisions, looked at mail stamps, saw stamps that looked pretty reasonable (with no more self stuff, no more commas, sorting numbers, and Herald stamps).

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13053

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

+131 -57
+2 -2
src/__phutil_library_map__.php
··· 487 487 'DifferentialLintField' => 'applications/differential/customfield/DifferentialLintField.php', 488 488 'DifferentialLintStatus' => 'applications/differential/constants/DifferentialLintStatus.php', 489 489 'DifferentialLocalCommitsView' => 'applications/differential/view/DifferentialLocalCommitsView.php', 490 + 'DifferentialMailEngineExtension' => 'applications/differential/engineextension/DifferentialMailEngineExtension.php', 490 491 'DifferentialMailView' => 'applications/differential/mail/DifferentialMailView.php', 491 492 'DifferentialManiphestTasksField' => 'applications/differential/customfield/DifferentialManiphestTasksField.php', 492 493 'DifferentialModernHunk' => 'applications/differential/storage/DifferentialModernHunk.php', ··· 4402 4403 'PhabricatorVersionedDraft' => 'applications/draft/storage/PhabricatorVersionedDraft.php', 4403 4404 'PhabricatorVeryWowEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorVeryWowEnglishTranslation.php', 4404 4405 'PhabricatorViewerDatasource' => 'applications/people/typeahead/PhabricatorViewerDatasource.php', 4405 - 'PhabricatorViewerMailStamp' => 'applications/metamta/stamp/PhabricatorViewerMailStamp.php', 4406 4406 'PhabricatorWatcherHasObjectEdgeType' => 'applications/transactions/edges/PhabricatorWatcherHasObjectEdgeType.php', 4407 4407 'PhabricatorWebContentSource' => 'infrastructure/contentsource/PhabricatorWebContentSource.php', 4408 4408 'PhabricatorWebServerSetupCheck' => 'applications/config/check/PhabricatorWebServerSetupCheck.php', ··· 5612 5612 'DifferentialLintField' => 'DifferentialHarbormasterField', 5613 5613 'DifferentialLintStatus' => 'Phobject', 5614 5614 'DifferentialLocalCommitsView' => 'AphrontView', 5615 + 'DifferentialMailEngineExtension' => 'PhabricatorMailEngineExtension', 5615 5616 'DifferentialMailView' => 'Phobject', 5616 5617 'DifferentialManiphestTasksField' => 'DifferentialCoreCustomField', 5617 5618 'DifferentialModernHunk' => 'DifferentialHunk', ··· 10152 10153 'PhabricatorVersionedDraft' => 'PhabricatorDraftDAO', 10153 10154 'PhabricatorVeryWowEnglishTranslation' => 'PhutilTranslation', 10154 10155 'PhabricatorViewerDatasource' => 'PhabricatorTypeaheadDatasource', 10155 - 'PhabricatorViewerMailStamp' => 'PhabricatorMailStamp', 10156 10156 'PhabricatorWatcherHasObjectEdgeType' => 'PhabricatorEdgeType', 10157 10157 'PhabricatorWebContentSource' => 'PhabricatorContentSource', 10158 10158 'PhabricatorWebServerSetupCheck' => 'PhabricatorSetupCheck',
+80
src/applications/differential/engineextension/DifferentialMailEngineExtension.php
··· 1 + <?php 2 + 3 + final class DifferentialMailEngineExtension 4 + extends PhabricatorMailEngineExtension { 5 + 6 + const EXTENSIONKEY = 'differential'; 7 + 8 + public function supportsObject($object) { 9 + return ($object instanceof DifferentialRevision); 10 + } 11 + 12 + public function newMailStampTemplates($object) { 13 + return array( 14 + id(new PhabricatorPHIDMailStamp()) 15 + ->setKey('author') 16 + ->setLabel(pht('Author')), 17 + id(new PhabricatorPHIDMailStamp()) 18 + ->setKey('reviewer') 19 + ->setLabel(pht('Reviewer')), 20 + id(new PhabricatorPHIDMailStamp()) 21 + ->setKey('blocking-reviewer') 22 + ->setLabel(pht('Reviewer')), 23 + id(new PhabricatorPHIDMailStamp()) 24 + ->setKey('resigned-reviewer') 25 + ->setLabel(pht('Reviewer')), 26 + id(new PhabricatorPHIDMailStamp()) 27 + ->setKey('revision-repository') 28 + ->setLabel(pht('Revision Repository')), 29 + id(new PhabricatorPHIDMailStamp()) 30 + ->setKey('revision-status') 31 + ->setLabel(pht('Revision Status')), 32 + ); 33 + } 34 + 35 + public function newMailStamps($object, array $xactions) { 36 + $editor = $this->getEditor(); 37 + $viewer = $this->getViewer(); 38 + 39 + $revision = id(new DifferentialRevisionQuery()) 40 + ->setViewer($viewer) 41 + ->needReviewers(true) 42 + ->withPHIDs(array($object->getPHID())) 43 + ->executeOne(); 44 + 45 + $reviewers = array(); 46 + $blocking = array(); 47 + $resigned = array(); 48 + foreach ($revision->getReviewers() as $reviewer) { 49 + $reviewer_phid = $reviewer->getReviewerPHID(); 50 + 51 + if ($reviewer->isResigned()) { 52 + $resigned[] = $reviewer_phid; 53 + } else { 54 + $reviewers[] = $reviewer_phid; 55 + if ($reviewer->isBlocking()) { 56 + $reviewers[] = $blocking; 57 + } 58 + } 59 + } 60 + 61 + $this->getMailStamp('author') 62 + ->setValue($revision->getAuthorPHID()); 63 + 64 + $this->getMailStamp('reviewer') 65 + ->setValue($reviewers); 66 + 67 + $this->getMailStamp('blocking-reviewer') 68 + ->setValue($blocking); 69 + 70 + $this->getMailStamp('resigned-reviewer') 71 + ->setValue($resigned); 72 + 73 + $this->getMailStamp('revision-repository') 74 + ->setValue($revision->getRepositoryPHID()); 75 + 76 + $this->getMailStamp('revision-status') 77 + ->setValue($revision->getModernRevisionStatus()); 78 + } 79 + 80 + }
+5
src/applications/differential/storage/DifferentialReviewer.php
··· 69 69 return ($this->getReviewerStatus() == $status_resigned); 70 70 } 71 71 72 + public function isBlocking() { 73 + $status_blocking = DifferentialReviewerStatus::STATUS_BLOCKING; 74 + return ($this->getReviewerStatus() == $status_blocking); 75 + } 76 + 72 77 public function isRejected($diff_phid) { 73 78 $status_rejected = DifferentialReviewerStatus::STATUS_REJECTED; 74 79
+2 -2
src/applications/metamta/replyhandler/PhabricatorMailTarget.php
··· 70 70 $body .= "\n"; 71 71 $body .= pht('STAMPS'); 72 72 $body .= "\n"; 73 - $body .= implode(', ', $stamps); 73 + $body .= implode(' ', $stamps); 74 74 $body .= "\n"; 75 75 76 76 if ($has_html) { 77 77 $html = array(); 78 78 $html[] = phutil_tag('strong', array(), pht('STAMPS')); 79 79 $html[] = phutil_tag('br'); 80 - $html[] = phutil_implode_html(', ', $stamps); 80 + $html[] = phutil_implode_html(' ', $stamps); 81 81 $html[] = phutil_tag('br'); 82 82 $html = phutil_tag('div', array(), $html); 83 83 $html_body .= hsprintf('%s', $html);
+12 -2
src/applications/metamta/stamp/PhabricatorStringMailStamp.php
··· 6 6 const STAMPTYPE = 'string'; 7 7 8 8 public function renderStamps($value) { 9 - if (!strlen($value)) { 9 + if ($value === null || $value === '') { 10 10 return null; 11 11 } 12 12 13 - return $this->renderStamp($this->getKey(), $value); 13 + $value = (array)$value; 14 + if (!$value) { 15 + return null; 16 + } 17 + 18 + $results = array(); 19 + foreach ($value as $v) { 20 + $results[] = $this->renderStamp($this->getKey(), $v); 21 + } 22 + 23 + return $results; 14 24 } 15 25 16 26 }
-35
src/applications/metamta/stamp/PhabricatorViewerMailStamp.php
··· 1 - <?php 2 - 3 - final class PhabricatorViewerMailStamp 4 - extends PhabricatorMailStamp { 5 - 6 - const STAMPTYPE = 'viewer'; 7 - 8 - public function renderStamps($value) { 9 - // If we're sending one mail to everyone, we never include viewer-based 10 - // stamps since they'll only be accurate for one recipient. Recipients 11 - // can still use the corresponding stamps with their usernames or PHIDs. 12 - if (!PhabricatorMetaMTAMail::shouldMailEachRecipient()) { 13 - return null; 14 - } 15 - 16 - $viewer_phid = $this->getViewer()->getPHID(); 17 - if (!$viewer_phid) { 18 - return null; 19 - } 20 - 21 - if (!$value) { 22 - return null; 23 - } 24 - 25 - $value = (array)$value; 26 - $value = array_fuse($value); 27 - 28 - if (!isset($value[$viewer_phid])) { 29 - return null; 30 - } 31 - 32 - return $this->renderStamp($this->getKey()); 33 - } 34 - 35 - }
+5 -3
src/applications/repository/phid/PhabricatorRepositoryRepositoryPHIDType.php
··· 41 41 $name = $repository->getName(); 42 42 $uri = $repository->getURI(); 43 43 44 - $handle->setName($monogram); 45 - $handle->setFullName("{$monogram} {$name}"); 46 - $handle->setURI($uri); 44 + $handle 45 + ->setName($monogram) 46 + ->setFullName("{$monogram} {$name}") 47 + ->setURI($uri) 48 + ->setMailStampName($monogram); 47 49 } 48 50 } 49 51
+20 -1
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 205 205 return $this->mustEncrypt; 206 206 } 207 207 208 + public function getHeraldRuleMonograms() { 209 + // Convert the stored "<123>, <456>" string into a list: "H123", "H456". 210 + $list = $this->heraldHeader; 211 + $list = preg_split('/[, ]+/', $list); 212 + 213 + foreach ($list as $key => $item) { 214 + $item = trim($item, '<>'); 215 + 216 + if (!is_numeric($item)) { 217 + unset($list[$key]); 218 + continue; 219 + } 220 + 221 + $list[$key] = 'H'.$item; 222 + } 223 + 224 + return $list; 225 + } 226 + 208 227 public function setIsInverseEdgeEditor($is_inverse_edge_editor) { 209 228 $this->isInverseEdgeEditor = $is_inverse_edge_editor; 210 229 return $this; ··· 4109 4128 } 4110 4129 } 4111 4130 4112 - sort($results); 4131 + natcasesort($results); 4113 4132 4114 4133 return $results; 4115 4134 }
+5 -12
src/applications/transactions/engineextension/PhabricatorEditorMailEngineExtension.php
··· 36 36 ->setKey('mention') 37 37 ->setLabel(pht('Mentioned User')); 38 38 39 - $templates[] = id(new PhabricatorViewerMailStamp()) 40 - ->setKey('self-actor') 41 - ->setLabel(pht('You Acted')); 42 - 43 - $templates[] = id(new PhabricatorViewerMailStamp()) 44 - ->setKey('self-mention') 45 - ->setLabel(pht('You Were Mentioned')); 39 + $templates[] = id(new PhabricatorStringMailStamp()) 40 + ->setKey('herald') 41 + ->setLabel(pht('Herald Rule')); 46 42 47 43 return $templates; 48 44 } ··· 71 67 $this->getMailStamp('mention') 72 68 ->setValue($mentioned_phids); 73 69 74 - $this->getMailStamp('self-actor') 75 - ->setValue($editor->getActingAsPHID()); 76 - 77 - $this->getMailStamp('self-mention') 78 - ->setValue($mentioned_phids); 70 + $this->getMailStamp('herald') 71 + ->setValue($editor->getHeraldRuleMonograms()); 79 72 } 80 73 81 74 }