diff --git a/src/applications/differential/editor/comment/DifferentialCommentEditor.php b/src/applications/differential/editor/comment/DifferentialCommentEditor.php index d2690e019f..be49a064a0 100644 --- a/src/applications/differential/editor/comment/DifferentialCommentEditor.php +++ b/src/applications/differential/editor/comment/DifferentialCommentEditor.php @@ -273,7 +273,7 @@ class DifferentialCommentEditor { $current_ccs = $revision->getCCPHIDs(); if ($current_ccs) { - $current_ccs = array_combine($current_ccs, $current_ccs); + $current_ccs = array_fill_keys($current_ccs, true); foreach ($added_ccs as $k => $cc) { if (isset($current_ccs[$cc])) { unset($added_ccs[$k]); @@ -307,9 +307,6 @@ class DifferentialCommentEditor { $this->actorPHID); } - // Reload relationships to pick up any reviewer/CC changes. - $revision->loadRelationships(); - $inline_comments = array(); if ($this->attachInlineComments) { $inline_comments = id(new DifferentialInlineComment())->loadAllWhere( @@ -341,6 +338,43 @@ class DifferentialCommentEditor { } } + // Find any "@mentions" in the comment blocks. + $content_blocks = array($comment->getContent()); + foreach ($inline_comments as $inline) { + $content_blocks[] = $inline->getContent(); + } + $mention_ccs = DifferentialMarkupEngineFactory::extractPHIDsFromMentions( + $content_blocks); + if ($mention_ccs) { + $current_ccs = $revision->getCCPHIDs(); + if ($current_ccs) { + $current_ccs = array_fill_keys($current_ccs, true); + foreach ($mention_ccs as $key => $mention_cc) { + if (isset($current_ccs[$mention_cc])) { + unset($mention_ccs); + } + } + } + if ($mention_ccs) { + $metadata = $comment->getMetadata(); + $metacc = idx( + $metadata, + DifferentialComment::METADATA_ADDED_CCS, + array()); + foreach ($mention_ccs as $cc_phid) { + DifferentialRevisionEditor::addCC( + $revision, + $cc_phid, + $this->actorPHID); + $metacc[] = $cc_phid; + } + $metadata[DifferentialComment::METADATA_ADDED_CCS] = $metacc; + + $comment->setMetadata($metadata); + $comment->save(); + } + } + $phids = array($this->actorPHID); $handles = id(new PhabricatorObjectHandleData($phids)) ->loadHandles(); diff --git a/src/applications/differential/editor/comment/__init__.php b/src/applications/differential/editor/comment/__init__.php index a11be0084c..74deebcb49 100644 --- a/src/applications/differential/editor/comment/__init__.php +++ b/src/applications/differential/editor/comment/__init__.php @@ -10,6 +10,7 @@ phutil_require_module('phabricator', 'applications/differential/constants/action phutil_require_module('phabricator', 'applications/differential/constants/revisionstatus'); phutil_require_module('phabricator', 'applications/differential/editor/revision'); phutil_require_module('phabricator', 'applications/differential/mail/comment'); +phutil_require_module('phabricator', 'applications/differential/parser/markup'); phutil_require_module('phabricator', 'applications/differential/storage/changeset'); phutil_require_module('phabricator', 'applications/differential/storage/comment'); phutil_require_module('phabricator', 'applications/differential/storage/inlinecomment'); diff --git a/src/applications/differential/editor/revision/DifferentialRevisionEditor.php b/src/applications/differential/editor/revision/DifferentialRevisionEditor.php index 01ff614cc4..9b9e5b554c 100644 --- a/src/applications/differential/editor/revision/DifferentialRevisionEditor.php +++ b/src/applications/differential/editor/revision/DifferentialRevisionEditor.php @@ -600,6 +600,8 @@ class DifferentialRevisionEditor { implode(', ', $sql)); } $conn_w->saveTransaction(); + + $revision->loadRelationships(); } diff --git a/src/applications/differential/parser/markup/DifferentialMarkupEngineFactory.php b/src/applications/differential/parser/markup/DifferentialMarkupEngineFactory.php index 959c18fbb8..7116f6050d 100644 --- a/src/applications/differential/parser/markup/DifferentialMarkupEngineFactory.php +++ b/src/applications/differential/parser/markup/DifferentialMarkupEngineFactory.php @@ -18,6 +18,23 @@ class DifferentialMarkupEngineFactory { + public static function extractPHIDsFromMentions(array $content_blocks) { + $mentions = array(); + + $factory = new DifferentialMarkupEngineFactory(); + $engine = $factory->newDifferentialCommentMarkupEngine(); + + foreach ($content_blocks as $content_block) { + $engine->markupText($content_block); + $phids = $engine->getTextMetadata( + 'phabricator.mentioned-user-phids', + array()); + $mentions += $phids; + } + + return $mentions; + } + public function newDifferentialCommentMarkupEngine() { $engine = new PhutilRemarkupEngine(); diff --git a/src/infrastructure/markup/remarkup/markuprule/mention/PhabricatorRemarkupRuleMention.php b/src/infrastructure/markup/remarkup/markuprule/mention/PhabricatorRemarkupRuleMention.php index 0849570767..ccacba0f82 100644 --- a/src/infrastructure/markup/remarkup/markuprule/mention/PhabricatorRemarkupRuleMention.php +++ b/src/infrastructure/markup/remarkup/markuprule/mention/PhabricatorRemarkupRuleMention.php @@ -48,10 +48,17 @@ class PhabricatorRemarkupRuleMention $user_table->getTableName(), $usernames); + $engine = $this->getEngine(); + $metadata_key = 'phabricator.mentioned-user-phids'; + $mentioned = $engine->getTextMetadata($metadata_key, array()); + foreach ($real_user_names as $row) { $this->actualUsers[strtolower($row['username'])] = $row; + $mentioned[$row['phid']] = $row['phid']; } + $engine->setTextMetadata($metadata_key, $mentioned); + return preg_replace_callback( $regexp, array($this, 'markupMention'),