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 @@ -1723,6 +1723,7 @@ 'PhabricatorMarkupPreviewController' => 'infrastructure/markup/PhabricatorMarkupPreviewController.php', 'PhabricatorMemeRemarkupRule' => 'applications/macro/markup/PhabricatorMemeRemarkupRule.php', 'PhabricatorMentionRemarkupRule' => 'applications/people/markup/PhabricatorMentionRemarkupRule.php', + 'PhabricatorMentionableInterface' => 'applications/transactions/interface/PhabricatorMentionableInterface.php', 'PhabricatorMercurialGraphStream' => 'applications/repository/daemon/PhabricatorMercurialGraphStream.php', 'PhabricatorMetaMTAActor' => 'applications/metamta/query/PhabricatorMetaMTAActor.php', 'PhabricatorMetaMTAActorQuery' => 'applications/metamta/query/PhabricatorMetaMTAActorQuery.php', @@ -1808,6 +1809,8 @@ 'PhabricatorObjectListQueryTestCase' => 'applications/phid/query/__tests__/PhabricatorObjectListQueryTestCase.php', 'PhabricatorObjectMailReceiver' => 'applications/metamta/receiver/PhabricatorObjectMailReceiver.php', 'PhabricatorObjectMailReceiverTestCase' => 'applications/metamta/receiver/__tests__/PhabricatorObjectMailReceiverTestCase.php', + 'PhabricatorObjectMentionedByObject' => 'applications/transactions/edges/PhabricatorObjectMentionedByObject.php', + 'PhabricatorObjectMentionsObject' => 'applications/transactions/edges/PhabricatorObjectMentionsObject.php', 'PhabricatorObjectQuery' => 'applications/phid/query/PhabricatorObjectQuery.php', 'PhabricatorObjectRemarkupRule' => 'infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php', 'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php', @@ -3084,6 +3087,7 @@ 'PhabricatorSubscribableInterface', 'PhabricatorCustomFieldInterface', 'PhabricatorApplicationTransactionInterface', + 'PhabricatorMentionableInterface', 'PhabricatorDestructibleInterface', 'PhabricatorProjectInterface', ), @@ -3698,6 +3702,7 @@ 'PhabricatorPolicyInterface', 'PhabricatorTokenReceiverInterface', 'PhabricatorFlaggableInterface', + 'PhabricatorMentionableInterface', 'PhrequentTrackableInterface', 'PhabricatorCustomFieldInterface', 'PhabricatorDestructibleInterface', @@ -4658,6 +4663,8 @@ 'PhabricatorObjectListQueryTestCase' => 'PhabricatorTestCase', 'PhabricatorObjectMailReceiver' => 'PhabricatorMailReceiver', 'PhabricatorObjectMailReceiverTestCase' => 'PhabricatorTestCase', + 'PhabricatorObjectMentionedByObject' => 'PhabricatorEdgeType', + 'PhabricatorObjectMentionsObject' => 'PhabricatorEdgeType', 'PhabricatorObjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery', @@ -4693,6 +4700,7 @@ 'PhabricatorSubscribableInterface', 'PhabricatorTokenReceiverInterface', 'PhabricatorFlaggableInterface', + 'PhabricatorMentionableInterface', 'PhabricatorPolicyInterface', 'PhabricatorProjectInterface', ), @@ -4908,6 +4916,7 @@ 'PhabricatorFlaggableInterface', 'PhabricatorTokenReceiverInterface', 'PhabricatorSubscribableInterface', + 'PhabricatorMentionableInterface', 'HarbormasterBuildableInterface', 'PhabricatorCustomFieldInterface', 'PhabricatorApplicationTransactionInterface', diff --git a/src/applications/differential/editor/DifferentialTransactionEditor.php b/src/applications/differential/editor/DifferentialTransactionEditor.php --- a/src/applications/differential/editor/DifferentialTransactionEditor.php +++ b/src/applications/differential/editor/DifferentialTransactionEditor.php @@ -1271,8 +1271,10 @@ ->execute(); if ($tasks) { + $phid_map = mpull($tasks, 'getPHID', 'getPHID'); $edge_related = DifferentialRevisionHasTaskEdgeType::EDGECONST; - $edges[$edge_related] = mpull($tasks, 'getPHID', 'getPHID'); + $edges[$edge_related] = $phid_map; + $this->setUnmentionablePHIDMap($phid_map); } } diff --git a/src/applications/differential/storage/DifferentialRevision.php b/src/applications/differential/storage/DifferentialRevision.php --- a/src/applications/differential/storage/DifferentialRevision.php +++ b/src/applications/differential/storage/DifferentialRevision.php @@ -10,6 +10,7 @@ PhabricatorSubscribableInterface, PhabricatorCustomFieldInterface, PhabricatorApplicationTransactionInterface, + PhabricatorMentionableInterface, PhabricatorDestructibleInterface, PhabricatorProjectInterface { diff --git a/src/applications/maniphest/storage/ManiphestTask.php b/src/applications/maniphest/storage/ManiphestTask.php --- a/src/applications/maniphest/storage/ManiphestTask.php +++ b/src/applications/maniphest/storage/ManiphestTask.php @@ -6,6 +6,7 @@ PhabricatorPolicyInterface, PhabricatorTokenReceiverInterface, PhabricatorFlaggableInterface, + PhabricatorMentionableInterface, PhrequentTrackableInterface, PhabricatorCustomFieldInterface, PhabricatorDestructibleInterface, diff --git a/src/applications/paste/storage/PhabricatorPaste.php b/src/applications/paste/storage/PhabricatorPaste.php --- a/src/applications/paste/storage/PhabricatorPaste.php +++ b/src/applications/paste/storage/PhabricatorPaste.php @@ -5,6 +5,7 @@ PhabricatorSubscribableInterface, PhabricatorTokenReceiverInterface, PhabricatorFlaggableInterface, + PhabricatorMentionableInterface, PhabricatorPolicyInterface, PhabricatorProjectInterface { diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommit.php b/src/applications/repository/storage/PhabricatorRepositoryCommit.php --- a/src/applications/repository/storage/PhabricatorRepositoryCommit.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommit.php @@ -7,6 +7,7 @@ PhabricatorFlaggableInterface, PhabricatorTokenReceiverInterface, PhabricatorSubscribableInterface, + PhabricatorMentionableInterface, HarbormasterBuildableInterface, PhabricatorCustomFieldInterface, PhabricatorApplicationTransactionInterface { diff --git a/src/applications/transactions/edges/PhabricatorObjectMentionedByObject.php b/src/applications/transactions/edges/PhabricatorObjectMentionedByObject.php new file mode 100644 --- /dev/null +++ b/src/applications/transactions/edges/PhabricatorObjectMentionedByObject.php @@ -0,0 +1,26 @@ +disableEmail; } + public function setUnmentionablePHIDMap($map) { + $this->unmentionablePHIDMap = $map; + return $this; + } + + public function getUnmentionablePHIDMap() { + return $this->unmentionablePHIDMap; + } + public function getTransactionTypes() { $types = array(); @@ -1013,7 +1023,7 @@ } } - private function buildMentionTransaction( + private function buildSubscribeTransaction( PhabricatorLiskDAO $object, array $xactions, array $blocks) { @@ -1119,12 +1129,12 @@ $blocks[$key] = $this->getRemarkupBlocksFromTransaction($xaction); } - $mention_xaction = $this->buildMentionTransaction( + $subscribe_xaction = $this->buildSubscribeTransaction( $object, $xactions, $blocks); - if ($mention_xaction) { - $xactions[] = $mention_xaction; + if ($subscribe_xaction) { + $xactions[] = $subscribe_xaction; } // TODO: For now, this is just a placeholder. @@ -1156,17 +1166,22 @@ $blocks, $engine); - if ($object instanceof PhabricatorProjectInterface) { - $phids = array(); - foreach ($blocks as $key => $xaction_blocks) { - foreach ($xaction_blocks as $block) { - $engine->markupText($block); - $phids += $engine->getTextMetadata( - PhabricatorObjectRemarkupRule::KEY_MENTIONED_OBJECTS, - array()); - } + $mentioned_phids = array(); + foreach ($blocks as $key => $xaction_blocks) { + foreach ($xaction_blocks as $block) { + $engine->markupText($block); + $mentioned_phids += $engine->getTextMetadata( + PhabricatorObjectRemarkupRule::KEY_MENTIONED_OBJECTS, + array()); } + } + + if (!$mentioned_phids) { + return $block_xactions; + } + if ($object instanceof PhabricatorProjectInterface) { + $phids = $mentioned_phids; $project_type = PhabricatorProjectProjectPHIDType::TYPECONST; foreach ($phids as $key => $phid) { if (phid_get_type($phid) != $project_type) { @@ -1184,6 +1199,29 @@ } } + $objects = id(new PhabricatorObjectQuery()) + ->setViewer($this->getActor()) + ->withPHIDs($mentioned_phids) + ->execute(); + + $mentionable_phids = array(); + foreach ($objects as $object) { + if ($object instanceof PhabricatorMentionableInterface) { + if (idx($this->getUnmentionablePHIDMap(), $object->getPHID())) { + continue; + } + $mentionable_phids[$object->getPHID()] = $object->getPHID(); + } + } + if ($mentionable_phids) { + $edge_type = PhabricatorObjectMentionsObject::EDGECONST; + $block_xactions[] = newv(get_class(head($xactions)), array()) + ->setIgnoreOnNoEffect(true) + ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) + ->setMetadataValue('edge:type', $edge_type) + ->setNewValue(array('+' => $mentionable_phids)); + } + return $block_xactions; } diff --git a/src/applications/transactions/interface/PhabricatorMentionableInterface.php b/src/applications/transactions/interface/PhabricatorMentionableInterface.php new file mode 100644 --- /dev/null +++ b/src/applications/transactions/interface/PhabricatorMentionableInterface.php @@ -0,0 +1,12 @@ +shouldHideInApplicationTransactions($this); } + case PhabricatorTransactions::TYPE_EDGE: + $edge_type = $this->getMetadataValue('edge:type'); + switch ($edge_type) { + case PhabricatorObjectMentionsObject::EDGECONST: + return true; + break; + case PhabricatorObjectMentionedByObject::EDGECONST: + return false; + break; + default: + break; + } + break; } return false; @@ -456,6 +469,17 @@ return false; } return true; + case PhabricatorTransactions::TYPE_EDGE: + $edge_type = $this->getMetadataValue('edge:type'); + switch ($edge_type) { + case PhabricatorObjectMentionsObject::EDGECONST: + case PhabricatorObjectMentionedByObject::EDGECONST: + return true; + break; + default: + break; + } + break; } return $this->shouldHide(); @@ -475,6 +499,17 @@ return false; } return true; + case PhabricatorTransactions::TYPE_EDGE: + $edge_type = $this->getMetadataValue('edge:type'); + switch ($edge_type) { + case PhabricatorObjectMentionsObject::EDGECONST: + case PhabricatorObjectMentionedByObject::EDGECONST: + return true; + break; + default: + break; + } + break; } return $this->shouldHide();