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

Transactions - add infrastructure for "mentions"

Summary: Fixes T4036. Now if you say something on diff X like "This reminds me of Tx and Dy and commitHashFoo and Px." each of those objects gets a little visible transaction that the mention occurred. No feed, email, or notifications.

Test Plan: made a comment like above and verified transactions. also submitted a diff that "Fixes Tx" and Tx did not get the transaction as expected.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: joshuaspence, epriestley, Korvin

Maniphest Tasks: T4036

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

+155 -14
+9
src/__phutil_library_map__.php
··· 1723 1723 'PhabricatorMarkupPreviewController' => 'infrastructure/markup/PhabricatorMarkupPreviewController.php', 1724 1724 'PhabricatorMemeRemarkupRule' => 'applications/macro/markup/PhabricatorMemeRemarkupRule.php', 1725 1725 'PhabricatorMentionRemarkupRule' => 'applications/people/markup/PhabricatorMentionRemarkupRule.php', 1726 + 'PhabricatorMentionableInterface' => 'applications/transactions/interface/PhabricatorMentionableInterface.php', 1726 1727 'PhabricatorMercurialGraphStream' => 'applications/repository/daemon/PhabricatorMercurialGraphStream.php', 1727 1728 'PhabricatorMetaMTAActor' => 'applications/metamta/query/PhabricatorMetaMTAActor.php', 1728 1729 'PhabricatorMetaMTAActorQuery' => 'applications/metamta/query/PhabricatorMetaMTAActorQuery.php', ··· 1808 1809 'PhabricatorObjectListQueryTestCase' => 'applications/phid/query/__tests__/PhabricatorObjectListQueryTestCase.php', 1809 1810 'PhabricatorObjectMailReceiver' => 'applications/metamta/receiver/PhabricatorObjectMailReceiver.php', 1810 1811 'PhabricatorObjectMailReceiverTestCase' => 'applications/metamta/receiver/__tests__/PhabricatorObjectMailReceiverTestCase.php', 1812 + 'PhabricatorObjectMentionedByObject' => 'applications/transactions/edges/PhabricatorObjectMentionedByObject.php', 1813 + 'PhabricatorObjectMentionsObject' => 'applications/transactions/edges/PhabricatorObjectMentionsObject.php', 1811 1814 'PhabricatorObjectQuery' => 'applications/phid/query/PhabricatorObjectQuery.php', 1812 1815 'PhabricatorObjectRemarkupRule' => 'infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php', 1813 1816 'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php', ··· 3084 3087 'PhabricatorSubscribableInterface', 3085 3088 'PhabricatorCustomFieldInterface', 3086 3089 'PhabricatorApplicationTransactionInterface', 3090 + 'PhabricatorMentionableInterface', 3087 3091 'PhabricatorDestructibleInterface', 3088 3092 'PhabricatorProjectInterface', 3089 3093 ), ··· 3698 3702 'PhabricatorPolicyInterface', 3699 3703 'PhabricatorTokenReceiverInterface', 3700 3704 'PhabricatorFlaggableInterface', 3705 + 'PhabricatorMentionableInterface', 3701 3706 'PhrequentTrackableInterface', 3702 3707 'PhabricatorCustomFieldInterface', 3703 3708 'PhabricatorDestructibleInterface', ··· 4658 4663 'PhabricatorObjectListQueryTestCase' => 'PhabricatorTestCase', 4659 4664 'PhabricatorObjectMailReceiver' => 'PhabricatorMailReceiver', 4660 4665 'PhabricatorObjectMailReceiverTestCase' => 'PhabricatorTestCase', 4666 + 'PhabricatorObjectMentionedByObject' => 'PhabricatorEdgeType', 4667 + 'PhabricatorObjectMentionsObject' => 'PhabricatorEdgeType', 4661 4668 'PhabricatorObjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4662 4669 'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule', 4663 4670 'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery', ··· 4693 4700 'PhabricatorSubscribableInterface', 4694 4701 'PhabricatorTokenReceiverInterface', 4695 4702 'PhabricatorFlaggableInterface', 4703 + 'PhabricatorMentionableInterface', 4696 4704 'PhabricatorPolicyInterface', 4697 4705 'PhabricatorProjectInterface', 4698 4706 ), ··· 4908 4916 'PhabricatorFlaggableInterface', 4909 4917 'PhabricatorTokenReceiverInterface', 4910 4918 'PhabricatorSubscribableInterface', 4919 + 'PhabricatorMentionableInterface', 4911 4920 'HarbormasterBuildableInterface', 4912 4921 'PhabricatorCustomFieldInterface', 4913 4922 'PhabricatorApplicationTransactionInterface',
+3 -1
src/applications/differential/editor/DifferentialTransactionEditor.php
··· 1270 1270 ->execute(); 1271 1271 1272 1272 if ($tasks) { 1273 + $phid_map = mpull($tasks, 'getPHID', 'getPHID'); 1273 1274 $edge_related = DifferentialRevisionHasTaskEdgeType::EDGECONST; 1274 - $edges[$edge_related] = mpull($tasks, 'getPHID', 'getPHID'); 1275 + $edges[$edge_related] = $phid_map; 1276 + $this->setUnmentionablePHIDMap($phid_map); 1275 1277 } 1276 1278 } 1277 1279
+1
src/applications/differential/storage/DifferentialRevision.php
··· 10 10 PhabricatorSubscribableInterface, 11 11 PhabricatorCustomFieldInterface, 12 12 PhabricatorApplicationTransactionInterface, 13 + PhabricatorMentionableInterface, 13 14 PhabricatorDestructibleInterface, 14 15 PhabricatorProjectInterface { 15 16
+1
src/applications/maniphest/storage/ManiphestTask.php
··· 6 6 PhabricatorPolicyInterface, 7 7 PhabricatorTokenReceiverInterface, 8 8 PhabricatorFlaggableInterface, 9 + PhabricatorMentionableInterface, 9 10 PhrequentTrackableInterface, 10 11 PhabricatorCustomFieldInterface, 11 12 PhabricatorDestructibleInterface,
+1
src/applications/paste/storage/PhabricatorPaste.php
··· 5 5 PhabricatorSubscribableInterface, 6 6 PhabricatorTokenReceiverInterface, 7 7 PhabricatorFlaggableInterface, 8 + PhabricatorMentionableInterface, 8 9 PhabricatorPolicyInterface, 9 10 PhabricatorProjectInterface { 10 11
+1
src/applications/repository/storage/PhabricatorRepositoryCommit.php
··· 7 7 PhabricatorFlaggableInterface, 8 8 PhabricatorTokenReceiverInterface, 9 9 PhabricatorSubscribableInterface, 10 + PhabricatorMentionableInterface, 10 11 HarbormasterBuildableInterface, 11 12 PhabricatorCustomFieldInterface, 12 13 PhabricatorApplicationTransactionInterface {
+26
src/applications/transactions/edges/PhabricatorObjectMentionedByObject.php
··· 1 + <?php 2 + 3 + final class PhabricatorObjectMentionedByObject extends PhabricatorEdgeType { 4 + 5 + const EDGECONST = 51; 6 + 7 + public function getInverseEdgeConstant() { 8 + return PhabricatorObjectMentionsObject::EDGECONST; 9 + } 10 + 11 + public function shouldWriteInverseTransactions() { 12 + return true; 13 + } 14 + 15 + public function getTransactionAddString( 16 + $actor, 17 + $add_count, 18 + $add_edges) { 19 + 20 + return pht( 21 + '%s mentioned this in %s.', 22 + $actor, 23 + $add_edges); 24 + } 25 + 26 + }
+15
src/applications/transactions/edges/PhabricatorObjectMentionsObject.php
··· 1 + <?php 2 + 3 + final class PhabricatorObjectMentionsObject extends PhabricatorEdgeType { 4 + 5 + const EDGECONST = 52; 6 + 7 + public function getInverseEdgeConstant() { 8 + return PhabricatorObjectMentionedByObject::EDGECONST; 9 + } 10 + 11 + public function shouldWriteInverseTransactions() { 12 + return true; 13 + } 14 + 15 + }
+51 -13
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 21 21 private $heraldAdapter; 22 22 private $heraldTranscript; 23 23 private $subscribers; 24 + private $unmentionablePHIDMap = array(); 24 25 25 26 private $isPreview; 26 27 private $isHeraldEditor; ··· 173 174 174 175 public function getDisableEmail() { 175 176 return $this->disableEmail; 177 + } 178 + 179 + public function setUnmentionablePHIDMap(array $map) { 180 + $this->unmentionablePHIDMap = $map; 181 + return $this; 182 + } 183 + 184 + public function getUnmentionablePHIDMap() { 185 + return $this->unmentionablePHIDMap; 176 186 } 177 187 178 188 public function getTransactionTypes() { ··· 1013 1023 } 1014 1024 } 1015 1025 1016 - private function buildMentionTransaction( 1026 + private function buildSubscribeTransaction( 1017 1027 PhabricatorLiskDAO $object, 1018 1028 array $xactions, 1019 1029 array $blocks) { ··· 1119 1129 $blocks[$key] = $this->getRemarkupBlocksFromTransaction($xaction); 1120 1130 } 1121 1131 1122 - $mention_xaction = $this->buildMentionTransaction( 1132 + $subscribe_xaction = $this->buildSubscribeTransaction( 1123 1133 $object, 1124 1134 $xactions, 1125 1135 $blocks); 1126 - if ($mention_xaction) { 1127 - $xactions[] = $mention_xaction; 1136 + if ($subscribe_xaction) { 1137 + $xactions[] = $subscribe_xaction; 1128 1138 } 1129 1139 1130 1140 // TODO: For now, this is just a placeholder. ··· 1156 1166 $blocks, 1157 1167 $engine); 1158 1168 1159 - if ($object instanceof PhabricatorProjectInterface) { 1160 - $phids = array(); 1161 - foreach ($blocks as $key => $xaction_blocks) { 1162 - foreach ($xaction_blocks as $block) { 1163 - $engine->markupText($block); 1164 - $phids += $engine->getTextMetadata( 1165 - PhabricatorObjectRemarkupRule::KEY_MENTIONED_OBJECTS, 1166 - array()); 1167 - } 1169 + $mentioned_phids = array(); 1170 + foreach ($blocks as $key => $xaction_blocks) { 1171 + foreach ($xaction_blocks as $block) { 1172 + $engine->markupText($block); 1173 + $mentioned_phids += $engine->getTextMetadata( 1174 + PhabricatorObjectRemarkupRule::KEY_MENTIONED_OBJECTS, 1175 + array()); 1168 1176 } 1177 + } 1169 1178 1179 + if (!$mentioned_phids) { 1180 + return $block_xactions; 1181 + } 1182 + 1183 + if ($object instanceof PhabricatorProjectInterface) { 1184 + $phids = $mentioned_phids; 1170 1185 $project_type = PhabricatorProjectProjectPHIDType::TYPECONST; 1171 1186 foreach ($phids as $key => $phid) { 1172 1187 if (phid_get_type($phid) != $project_type) { ··· 1182 1197 ->setMetadataValue('edge:type', $edge_type) 1183 1198 ->setNewValue(array('+' => $phids)); 1184 1199 } 1200 + } 1201 + 1202 + $objects = id(new PhabricatorObjectQuery()) 1203 + ->setViewer($this->getActor()) 1204 + ->withPHIDs($mentioned_phids) 1205 + ->execute(); 1206 + 1207 + $mentionable_phids = array(); 1208 + foreach ($objects as $object) { 1209 + if ($object instanceof PhabricatorMentionableInterface) { 1210 + if (idx($this->getUnmentionablePHIDMap(), $object->getPHID())) { 1211 + continue; 1212 + } 1213 + $mentionable_phids[$object->getPHID()] = $object->getPHID(); 1214 + } 1215 + } 1216 + if ($mentionable_phids) { 1217 + $edge_type = PhabricatorObjectMentionsObject::EDGECONST; 1218 + $block_xactions[] = newv(get_class(head($xactions)), array()) 1219 + ->setIgnoreOnNoEffect(true) 1220 + ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) 1221 + ->setMetadataValue('edge:type', $edge_type) 1222 + ->setNewValue(array('+' => $mentionable_phids)); 1185 1223 } 1186 1224 1187 1225 return $block_xactions;
+12
src/applications/transactions/interface/PhabricatorMentionableInterface.php
··· 1 + <?php 2 + 3 + /** 4 + * Allow infrastructure to automagically create "mentioned" transactions 5 + * - actually TYPE_EDGE transactions that add "mentioned" edges - to the 6 + * implementing object. 7 + */ 8 + interface PhabricatorMentionableInterface { 9 + 10 + public function getPHID(); 11 + 12 + }
+35
src/applications/transactions/storage/PhabricatorApplicationTransaction.php
··· 438 438 if ($field) { 439 439 return $field->shouldHideInApplicationTransactions($this); 440 440 } 441 + case PhabricatorTransactions::TYPE_EDGE: 442 + $edge_type = $this->getMetadataValue('edge:type'); 443 + switch ($edge_type) { 444 + case PhabricatorObjectMentionsObject::EDGECONST: 445 + return true; 446 + break; 447 + case PhabricatorObjectMentionedByObject::EDGECONST: 448 + return false; 449 + break; 450 + default: 451 + break; 452 + } 453 + break; 441 454 } 442 455 443 456 return false; ··· 456 469 return false; 457 470 } 458 471 return true; 472 + case PhabricatorTransactions::TYPE_EDGE: 473 + $edge_type = $this->getMetadataValue('edge:type'); 474 + switch ($edge_type) { 475 + case PhabricatorObjectMentionsObject::EDGECONST: 476 + case PhabricatorObjectMentionedByObject::EDGECONST: 477 + return true; 478 + break; 479 + default: 480 + break; 481 + } 482 + break; 459 483 } 460 484 461 485 return $this->shouldHide(); ··· 475 499 return false; 476 500 } 477 501 return true; 502 + case PhabricatorTransactions::TYPE_EDGE: 503 + $edge_type = $this->getMetadataValue('edge:type'); 504 + switch ($edge_type) { 505 + case PhabricatorObjectMentionsObject::EDGECONST: 506 + case PhabricatorObjectMentionedByObject::EDGECONST: 507 + return true; 508 + break; 509 + default: 510 + break; 511 + } 512 + break; 478 513 } 479 514 480 515 return $this->shouldHide();