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

Convert Audit comment rendering to standard infrastructure

Summary: Ref T4896. Depends on D10055. This uses core rendering stuff for audit comments, and fixes all the wonkiness with inlines so we can actually land the migration.

Test Plan: Viewed, previewed and edited various types of comments in Diffusion.

Reviewers: chad, btrahan, joshuaspence

Reviewed By: joshuaspence

Subscribers: epriestley

Maniphest Tasks: T4896

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

+336 -442
+1 -4
resources/celerity/map.php
··· 12 12 'darkconsole.pkg.js' => 'df001cab', 13 13 'differential.pkg.css' => '4a93db37', 14 14 'differential.pkg.js' => '7528cfc9', 15 - 'diffusion.pkg.css' => '471bc9eb', 15 + 'diffusion.pkg.css' => '591664fa', 16 16 'diffusion.pkg.js' => 'bfc0737b', 17 17 'maniphest.pkg.css' => 'f5d89daf', 18 18 'maniphest.pkg.js' => 'df4aa49f', ··· 62 62 'rsrc/css/application/differential/revision-history.css' => '0e8eb855', 63 63 'rsrc/css/application/differential/revision-list.css' => 'f3c47d33', 64 64 'rsrc/css/application/differential/table-of-contents.css' => '6bf8e1d2', 65 - 'rsrc/css/application/diffusion/commit-view.css' => '92d1e8f9', 66 65 'rsrc/css/application/diffusion/diffusion-icons.css' => '9c5828da', 67 66 'rsrc/css/application/diffusion/diffusion-source.css' => '66fdf661', 68 67 'rsrc/css/application/feed/feed.css' => '4e544db4', ··· 534 533 'differential-revision-history-css' => '0e8eb855', 535 534 'differential-revision-list-css' => 'f3c47d33', 536 535 'differential-table-of-contents-css' => '6bf8e1d2', 537 - 'diffusion-commit-view-css' => '92d1e8f9', 538 536 'diffusion-icons-css' => '9c5828da', 539 537 'diffusion-source-css' => '66fdf661', 540 538 'diviner-shared-css' => '38813222', ··· 2137 2135 'javelin-behavior-aphront-more', 2138 2136 ), 2139 2137 'diffusion.pkg.css' => array( 2140 - 'diffusion-commit-view-css', 2141 2138 'diffusion-icons-css', 2142 2139 ), 2143 2140 'diffusion.pkg.js' => array(
-1
resources/celerity/packages.php
··· 164 164 'javelin-behavior-aphront-more', 165 165 ), 166 166 'diffusion.pkg.css' => array( 167 - 'diffusion-commit-view-css', 168 167 'diffusion-icons-css', 169 168 ), 170 169 'diffusion.pkg.js' => array(
+2 -4
src/__phutil_library_map__.php
··· 364 364 'DiffusionBrowseSearchController' => 'applications/diffusion/controller/DiffusionBrowseSearchController.php', 365 365 'DiffusionBrowseTableView' => 'applications/diffusion/view/DiffusionBrowseTableView.php', 366 366 'DiffusionChangeController' => 'applications/diffusion/controller/DiffusionChangeController.php', 367 - 'DiffusionCommentListView' => 'applications/diffusion/view/DiffusionCommentListView.php', 368 - 'DiffusionCommentView' => 'applications/diffusion/view/DiffusionCommentView.php', 369 367 'DiffusionCommitBranchesController' => 'applications/diffusion/controller/DiffusionCommitBranchesController.php', 370 368 'DiffusionCommitChangeTableView' => 'applications/diffusion/view/DiffusionCommitChangeTableView.php', 371 369 'DiffusionCommitController' => 'applications/diffusion/controller/DiffusionCommitController.php', ··· 1153 1151 'PhabricatorAuditTransaction' => 'applications/audit/storage/PhabricatorAuditTransaction.php', 1154 1152 'PhabricatorAuditTransactionComment' => 'applications/audit/storage/PhabricatorAuditTransactionComment.php', 1155 1153 'PhabricatorAuditTransactionQuery' => 'applications/audit/query/PhabricatorAuditTransactionQuery.php', 1154 + 'PhabricatorAuditTransactionView' => 'applications/audit/view/PhabricatorAuditTransactionView.php', 1156 1155 'PhabricatorAuthAccountView' => 'applications/auth/view/PhabricatorAuthAccountView.php', 1157 1156 'PhabricatorAuthApplication' => 'applications/auth/application/PhabricatorAuthApplication.php', 1158 1157 'PhabricatorAuthAuthFactorPHIDType' => 'applications/auth/phid/PhabricatorAuthAuthFactorPHIDType.php', ··· 3099 3098 'DiffusionBrowseSearchController' => 'DiffusionBrowseController', 3100 3099 'DiffusionBrowseTableView' => 'DiffusionView', 3101 3100 'DiffusionChangeController' => 'DiffusionController', 3102 - 'DiffusionCommentListView' => 'AphrontView', 3103 - 'DiffusionCommentView' => 'AphrontView', 3104 3101 'DiffusionCommitBranchesController' => 'DiffusionController', 3105 3102 'DiffusionCommitChangeTableView' => 'DiffusionView', 3106 3103 'DiffusionCommitController' => 'DiffusionController', ··· 3944 3941 'PhabricatorAuditTransaction' => 'PhabricatorApplicationTransaction', 3945 3942 'PhabricatorAuditTransactionComment' => 'PhabricatorApplicationTransactionComment', 3946 3943 'PhabricatorAuditTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 3944 + 'PhabricatorAuditTransactionView' => 'PhabricatorApplicationTransactionView', 3947 3945 'PhabricatorAuthAccountView' => 'AphrontView', 3948 3946 'PhabricatorAuthApplication' => 'PhabricatorApplication', 3949 3947 'PhabricatorAuthAuthFactorPHIDType' => 'PhabricatorPHIDType',
+32 -49
src/applications/audit/controller/PhabricatorAuditPreviewController.php
··· 18 18 return new Aphront404Response(); 19 19 } 20 20 21 - $action = $request->getStr('action'); 21 + $xactions = array(); 22 22 23 - $phids = array( 24 - $user->getPHID(), 25 - $commit->getPHID(), 26 - ); 27 - 28 - $comments = array(); 29 - 23 + $action = $request->getStr('action'); 30 24 if ($action != PhabricatorAuditActionConstants::COMMENT) { 31 - $action_comment = id(new PhabricatorAuditComment()) 32 - ->setActorPHID($user->getPHID()) 33 - ->setTargetPHID($commit->getPHID()) 34 - ->setAction($action); 25 + $action_xaction = id(new PhabricatorAuditTransaction()) 26 + ->setAuthorPHID($user->getPHID()) 27 + ->setObjectPHID($commit->getPHID()) 28 + ->setTransactionType(PhabricatorAuditActionConstants::ACTION) 29 + ->setNewValue($action); 35 30 36 31 $auditors = $request->getStrList('auditors'); 37 32 if ($action == PhabricatorAuditActionConstants::ADD_AUDITORS && 38 33 $auditors) { 39 - 40 - $action_comment->setMetadata(array( 41 - PhabricatorAuditComment::METADATA_ADDED_AUDITORS => $auditors)); 42 - $phids = array_merge($phids, $auditors); 34 + $action_xaction->setTransactionType($action); 35 + $action_xaction->setNewValue(array_fuse($auditors)); 43 36 } 44 37 45 38 $ccs = $request->getStrList('ccs'); 46 39 if ($action == PhabricatorAuditActionConstants::ADD_CCS && $ccs) { 47 - $action_comment->setMetadata(array( 48 - PhabricatorAuditComment::METADATA_ADDED_CCS => $ccs)); 49 - $phids = array_merge($phids, $ccs); 40 + $action_xaction->setTransactionType($action); 41 + $action_xaction->setNewValue(array_fuse($ccs)); 50 42 } 51 43 52 - $comments[] = $action_comment; 44 + $xactions[] = $action_xaction; 53 45 } 54 46 55 47 $content = $request->getStr('content'); 56 48 if (strlen($content)) { 57 - $comments[] = id(new PhabricatorAuditComment()) 58 - ->setActorPHID($user->getPHID()) 59 - ->setTargetPHID($commit->getPHID()) 60 - ->setAction(PhabricatorAuditActionConstants::COMMENT) 61 - ->setContent($content); 49 + $xactions[] = id(new PhabricatorAuditTransaction()) 50 + ->setAuthorPHID($user->getPHID()) 51 + ->setObjectPHID($commit->getPHID()) 52 + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) 53 + ->attachComment( 54 + id(new PhabricatorAuditTransactionComment()) 55 + ->setContent($content)); 62 56 } 63 57 64 - $engine = new PhabricatorMarkupEngine(); 65 - $engine->setViewer($user); 66 - foreach ($comments as $comment) { 67 - $engine->addObject( 68 - $comment, 69 - PhabricatorAuditComment::MARKUP_FIELD_BODY); 70 - } 71 - $engine->process(); 72 - 73 - $views = array(); 74 - foreach ($comments as $comment) { 75 - $view = id(new DiffusionCommentView()) 76 - ->setMarkupEngine($engine) 77 - ->setUser($user) 78 - ->setComment($comment) 79 - ->setIsPreview(true); 80 - 81 - $phids = array_merge($phids, $view->getRequiredHandlePHIDs()); 82 - $views[] = $view; 58 + $phids = array(); 59 + foreach ($xactions as $xaction) { 60 + $phids[] = $xaction->getRequiredHandlePHIDs(); 83 61 } 84 - 62 + $phids = array_mergev($phids); 85 63 $handles = $this->loadViewerHandles($phids); 86 - 87 - foreach ($views as $view) { 88 - $view->setHandles($handles); 64 + foreach ($xactions as $xaction) { 65 + $xaction->setHandles($handles); 89 66 } 90 67 68 + $view = id(new PhabricatorAuditTransactionView()) 69 + ->setIsPreview(true) 70 + ->setUser($user) 71 + ->setObjectPHID($commit->getPHID()) 72 + ->setTransactions($xactions); 73 + 91 74 id(new PhabricatorDraft()) 92 75 ->setAuthorPHID($user->getPHID()) 93 76 ->setDraftKey('diffusion-audit-'.$this->id) 94 77 ->setDraft($content) 95 78 ->replaceOrDelete(); 96 79 97 - return id(new AphrontAjaxResponse())->setContent(hsprintf('%s', $views)); 80 + return id(new AphrontAjaxResponse())->setContent(hsprintf('%s', $view)); 98 81 } 99 82 100 83 }
+140
src/applications/audit/storage/PhabricatorAuditTransaction.php
··· 15 15 return new PhabricatorAuditTransactionComment(); 16 16 } 17 17 18 + public function getRequiredHandlePHIDs() { 19 + $phids = parent::getRequiredHandlePHIDs(); 20 + 21 + $type = $this->getTransactionType(); 22 + 23 + switch ($type) { 24 + case PhabricatorAuditActionConstants::ADD_CCS: 25 + case PhabricatorAuditActionConstants::ADD_AUDITORS: 26 + $old = $this->getOldValue(); 27 + $new = $this->getNewValue(); 28 + 29 + if (!is_array($old)) { 30 + $old = array(); 31 + } 32 + if (!is_array($new)) { 33 + $new = array(); 34 + } 35 + 36 + foreach (array_keys($old + $new) as $phid) { 37 + $phids[] = $phid; 38 + } 39 + break; 40 + } 41 + 42 + return $phids; 43 + } 44 + 45 + public function getColor() { 46 + 47 + $type = $this->getTransactionType(); 48 + 49 + switch ($type) { 50 + case PhabricatorAuditActionConstants::ACTION: 51 + switch ($this->getNewValue()) { 52 + case PhabricatorAuditActionConstants::CONCERN: 53 + return 'red'; 54 + case PhabricatorAuditActionConstants::ACCEPT: 55 + return 'green'; 56 + } 57 + } 58 + 59 + return parent::getColor(); 60 + } 61 + 62 + public function getTitle() { 63 + $old = $this->getOldValue(); 64 + $new = $this->getNewValue(); 65 + 66 + $author_handle = $this->getHandle($this->getAuthorPHID())->renderLink(); 67 + 68 + $type = $this->getTransactionType(); 69 + 70 + switch ($type) { 71 + case PhabricatorAuditActionConstants::ADD_CCS: 72 + case PhabricatorAuditActionConstants::ADD_AUDITORS: 73 + if (!is_array($old)) { 74 + $old = array(); 75 + } 76 + if (!is_array($new)) { 77 + $new = array(); 78 + } 79 + $add = array_keys(array_diff_key($new, $old)); 80 + $rem = array_keys(array_diff_key($old, $new)); 81 + break; 82 + } 83 + 84 + switch ($type) { 85 + case PhabricatorAuditActionConstants::INLINE: 86 + break; 87 + case PhabricatorAuditActionConstants::ADD_CCS: 88 + if ($add && $rem) { 89 + return pht( 90 + '%s edited subscribers; added: %s, removed: %s.', 91 + $author_handle, 92 + $this->renderHandleList($add), 93 + $this->renderHandleList($rem)); 94 + } else if ($add) { 95 + return pht( 96 + '%s added subscribers: %s.', 97 + $author_handle, 98 + $this->renderHandleList($add)); 99 + } else if ($rem) { 100 + return pht( 101 + '%s removed subscribers: %s.', 102 + $author_handle, 103 + $this->renderHandleList($rem)); 104 + } else { 105 + return pht( 106 + '%s added subscribers...', 107 + $author_handle); 108 + } 109 + 110 + case PhabricatorAuditActionConstants::ADD_AUDITORS: 111 + if ($add && $rem) { 112 + return pht( 113 + '%s edited auditors; added: %s, removed: %s.', 114 + $author_handle, 115 + $this->renderHandleList($add), 116 + $this->renderHandleList($rem)); 117 + } else if ($add) { 118 + return pht( 119 + '%s added auditors: %s.', 120 + $author_handle, 121 + $this->renderHandleList($add)); 122 + } else if ($rem) { 123 + return pht( 124 + '%s removed auditors: %s.', 125 + $author_handle, 126 + $this->renderHandleList($rem)); 127 + } else { 128 + return pht( 129 + '%s added auditors...', 130 + $author_handle); 131 + } 132 + 133 + case PhabricatorAuditActionConstants::ACTION: 134 + switch ($new) { 135 + case PhabricatorAuditActionConstants::ACCEPT: 136 + return pht( 137 + '%s accepted this commit.', 138 + $author_handle); 139 + case PhabricatorAuditActionConstants::CONCERN: 140 + return pht( 141 + '%s raised a concern with this commit.', 142 + $author_handle); 143 + case PhabricatorAuditActionConstants::RESIGN: 144 + return pht( 145 + '%s resigned from this audit.', 146 + $author_handle); 147 + case PhabricatorAuditActionConstants::CLOSE: 148 + return pht( 149 + '%s closed this audit.', 150 + $author_handle); 151 + } 152 + 153 + } 154 + 155 + return parent::getTitle(); 156 + } 157 + 18 158 }
+124
src/applications/audit/view/PhabricatorAuditTransactionView.php
··· 1 + <?php 2 + 3 + final class PhabricatorAuditTransactionView 4 + extends PhabricatorApplicationTransactionView { 5 + 6 + private $pathMap; 7 + 8 + public function setPathMap(array $path_map) { 9 + $this->pathMap = $path_map; 10 + return $this; 11 + } 12 + 13 + public function getPathMap() { 14 + return $this->pathMap; 15 + } 16 + 17 + // TODO: This shares a lot of code with Differential and Pholio and should 18 + // probably be merged up. 19 + 20 + protected function shouldGroupTransactions( 21 + PhabricatorApplicationTransaction $u, 22 + PhabricatorApplicationTransaction $v) { 23 + 24 + if ($u->getAuthorPHID() != $v->getAuthorPHID()) { 25 + // Don't group transactions by different authors. 26 + return false; 27 + } 28 + 29 + if (($v->getDateCreated() - $u->getDateCreated()) > 60) { 30 + // Don't group if transactions that happened more than 60s apart. 31 + return false; 32 + } 33 + 34 + switch ($u->getTransactionType()) { 35 + case PhabricatorTransactions::TYPE_COMMENT: 36 + case PhabricatorAuditActionConstants::INLINE: 37 + break; 38 + default: 39 + return false; 40 + } 41 + 42 + switch ($v->getTransactionType()) { 43 + case PhabricatorAuditActionConstants::INLINE: 44 + return true; 45 + } 46 + 47 + return parent::shouldGroupTransactions($u, $v); 48 + } 49 + 50 + protected function renderTransactionContent( 51 + PhabricatorApplicationTransaction $xaction) { 52 + 53 + $out = array(); 54 + 55 + $type_inline = PhabricatorAuditActionConstants::INLINE; 56 + 57 + $group = $xaction->getTransactionGroup(); 58 + if ($xaction->getTransactionType() == $type_inline) { 59 + array_unshift($group, $xaction); 60 + } else { 61 + $out[] = parent::renderTransactionContent($xaction); 62 + } 63 + 64 + if (!$group) { 65 + return $out; 66 + } 67 + 68 + $inlines = array(); 69 + foreach ($group as $xaction) { 70 + switch ($xaction->getTransactionType()) { 71 + case PhabricatorAuditActionConstants::INLINE: 72 + $inlines[] = $xaction; 73 + break; 74 + default: 75 + throw new Exception('Unknown grouped transaction type!'); 76 + } 77 + } 78 + 79 + if ($inlines) { 80 + 81 + // TODO: This should do something similar to sortAndGroupInlines() to get 82 + // a stable ordering. 83 + 84 + $inlines_by_path = array(); 85 + foreach ($inlines as $key => $inline) { 86 + $comment = $inline->getComment(); 87 + if (!$comment) { 88 + // TODO: Migrate these away? They probably do not exist on normal 89 + // non-development installs. 90 + unset($inlines[$key]); 91 + continue; 92 + } 93 + $path_id = $comment->getPathID(); 94 + $inlines_by_path[$path_id][] = $inline; 95 + } 96 + 97 + $inline_view = new PhabricatorInlineSummaryView(); 98 + foreach ($inlines_by_path as $path_id => $group) { 99 + $path = idx($this->pathMap, $path_id); 100 + if ($path === null) { 101 + continue; 102 + } 103 + 104 + $items = array(); 105 + foreach ($group as $inline) { 106 + $comment = $inline->getComment(); 107 + $item = array( 108 + 'id' => $comment->getID(), 109 + 'line' => $comment->getLineNumber(), 110 + 'length' => $comment->getLineLength(), 111 + 'content' => parent::renderTransactionContent($inline), 112 + ); 113 + $items[] = $item; 114 + } 115 + $inline_view->addCommentGroup($path, $items); 116 + } 117 + 118 + $out[] = $inline_view; 119 + } 120 + 121 + return $out; 122 + } 123 + 124 + }
+20 -38
src/applications/diffusion/controller/DiffusionCommitController.php
··· 100 100 $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine(); 101 101 $engine->setConfig('viewer', $user); 102 102 103 - require_celerity_resource('diffusion-commit-view-css'); 104 103 require_celerity_resource('phabricator-remarkup-css'); 105 104 106 105 $parents = $this->callConduitWithDiffusionRequest( ··· 642 641 } 643 642 644 643 private function buildComments(PhabricatorRepositoryCommit $commit) { 645 - $user = $this->getRequest()->getUser(); 646 - $comments = PhabricatorAuditComment::loadComments( 647 - $user, 648 - $commit->getPHID()); 644 + $viewer = $this->getRequest()->getUser(); 649 645 650 - $inlines = PhabricatorAuditInlineComment::loadPublishedComments( 651 - $user, 652 - $commit->getPHID()); 646 + $xactions = id(new PhabricatorAuditTransactionQuery()) 647 + ->setViewer($viewer) 648 + ->withObjectPHIDs(array($commit->getPHID())) 649 + ->needComments(true) 650 + ->execute(); 653 651 654 - $path_ids = mpull($inlines, 'getPathID'); 652 + $path_ids = array(); 653 + foreach ($xactions as $xaction) { 654 + if ($xaction->hasComment()) { 655 + $path_id = $xaction->getComment()->getPathID(); 656 + if ($path_id) { 657 + $path_ids[] = $path_id; 658 + } 659 + } 660 + } 655 661 656 662 $path_map = array(); 657 663 if ($path_ids) { ··· 661 667 $path_map = ipull($path_map, 'path', 'id'); 662 668 } 663 669 664 - $engine = new PhabricatorMarkupEngine(); 665 - $engine->setViewer($user); 666 - 667 - foreach ($comments as $comment) { 668 - $engine->addObject( 669 - $comment, 670 - PhabricatorAuditComment::MARKUP_FIELD_BODY); 671 - } 672 - 673 - foreach ($inlines as $inline) { 674 - $engine->addObject( 675 - $inline, 676 - PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY); 677 - } 678 - 679 - $engine->process(); 680 - 681 - $view = new DiffusionCommentListView(); 682 - $view->setMarkupEngine($engine); 683 - $view->setUser($user); 684 - $view->setComments($comments); 685 - $view->setInlineComments($inlines); 686 - $view->setPathMap($path_map); 687 - 688 - $phids = $view->getRequiredHandlePHIDs(); 689 - $handles = $this->loadViewerHandles($phids); 690 - $view->setHandles($handles); 691 - 692 - return $view; 670 + return id(new PhabricatorAuditTransactionView()) 671 + ->setUser($viewer) 672 + ->setObjectPHID($commit->getPHID()) 673 + ->setPathMap($path_map) 674 + ->setTransactions($xactions); 693 675 } 694 676 695 677 private function renderAddCommentPanel(
-96
src/applications/diffusion/view/DiffusionCommentListView.php
··· 1 - <?php 2 - 3 - final class DiffusionCommentListView extends AphrontView { 4 - 5 - private $comments; 6 - private $inlineComments = array(); 7 - private $pathMap = array(); 8 - private $handles = array(); 9 - private $markupEngine; 10 - 11 - public function setComments(array $comments) { 12 - assert_instances_of($comments, 'PhabricatorAuditComment'); 13 - $this->comments = $comments; 14 - return $this; 15 - } 16 - 17 - public function setInlineComments(array $inline_comments) { 18 - assert_instances_of($inline_comments, 'PhabricatorInlineCommentInterface'); 19 - $this->inlineComments = $inline_comments; 20 - return $this; 21 - } 22 - 23 - public function setPathMap(array $path_map) { 24 - $this->pathMap = $path_map; 25 - return $this; 26 - } 27 - 28 - public function setMarkupEngine(PhabricatorMarkupEngine $markup_engine) { 29 - $this->markupEngine = $markup_engine; 30 - return $this; 31 - } 32 - 33 - public function getMarkupEngine() { 34 - return $this->markupEngine; 35 - } 36 - 37 - public function getRequiredHandlePHIDs() { 38 - $phids = array(); 39 - foreach ($this->comments as $comment) { 40 - $phids[$comment->getActorPHID()] = true; 41 - $metadata = $comment->getMetaData(); 42 - 43 - $ccs_key = PhabricatorAuditComment::METADATA_ADDED_CCS; 44 - $added_ccs = idx($metadata, $ccs_key, array()); 45 - foreach ($added_ccs as $cc) { 46 - $phids[$cc] = true; 47 - } 48 - $auditors_key = PhabricatorAuditComment::METADATA_ADDED_AUDITORS; 49 - $added_auditors = idx($metadata, $auditors_key, array()); 50 - foreach ($added_auditors as $auditor) { 51 - $phids[$auditor] = true; 52 - } 53 - } 54 - foreach ($this->inlineComments as $comment) { 55 - $phids[$comment->getAuthorPHID()] = true; 56 - } 57 - return array_keys($phids); 58 - } 59 - 60 - public function setHandles(array $handles) { 61 - assert_instances_of($handles, 'PhabricatorObjectHandle'); 62 - $this->handles = $handles; 63 - return $this; 64 - } 65 - 66 - public function render() { 67 - 68 - $inline_comments = mgroup($this->inlineComments, 'getTransactionPHID'); 69 - 70 - $num = 1; 71 - 72 - $comments = array(); 73 - foreach ($this->comments as $comment) { 74 - 75 - $inlines = idx($inline_comments, $comment->getPHID(), array()); 76 - 77 - $view = id(new DiffusionCommentView()) 78 - ->setMarkupEngine($this->getMarkupEngine()) 79 - ->setComment($comment) 80 - ->setInlineComments($inlines) 81 - ->setCommentNumber($num) 82 - ->setHandles($this->handles) 83 - ->setPathMap($this->pathMap) 84 - ->setUser($this->user); 85 - 86 - $comments[] = $view->render(); 87 - ++$num; 88 - } 89 - 90 - return phutil_tag( 91 - 'div', 92 - array('class' => 'diffusion-comment-list'), 93 - $comments); 94 - } 95 - 96 - }
-209
src/applications/diffusion/view/DiffusionCommentView.php
··· 1 - <?php 2 - 3 - final class DiffusionCommentView extends AphrontView { 4 - 5 - private $comment; 6 - private $commentNumber; 7 - private $handles; 8 - private $isPreview; 9 - private $pathMap; 10 - 11 - private $inlineComments; 12 - private $markupEngine; 13 - 14 - public function setComment(PhabricatorAuditComment $comment) { 15 - $this->comment = $comment; 16 - return $this; 17 - } 18 - 19 - public function setCommentNumber($comment_number) { 20 - $this->commentNumber = $comment_number; 21 - return $this; 22 - } 23 - 24 - public function setHandles(array $handles) { 25 - assert_instances_of($handles, 'PhabricatorObjectHandle'); 26 - $this->handles = $handles; 27 - return $this; 28 - } 29 - 30 - public function setIsPreview($is_preview) { 31 - $this->isPreview = $is_preview; 32 - return $this; 33 - } 34 - 35 - public function setInlineComments(array $inline_comments) { 36 - assert_instances_of($inline_comments, 'PhabricatorInlineCommentInterface'); 37 - $this->inlineComments = $inline_comments; 38 - return $this; 39 - } 40 - 41 - public function setPathMap(array $path_map) { 42 - $this->pathMap = $path_map; 43 - return $this; 44 - } 45 - 46 - public function setMarkupEngine(PhabricatorMarkupEngine $markup_engine) { 47 - $this->markupEngine = $markup_engine; 48 - return $this; 49 - } 50 - 51 - public function getMarkupEngine() { 52 - return $this->markupEngine; 53 - } 54 - 55 - public function getRequiredHandlePHIDs() { 56 - return array($this->comment->getActorPHID()); 57 - } 58 - 59 - private function getHandle($phid) { 60 - if (empty($this->handles[$phid])) { 61 - throw new Exception("Unloaded handle '{$phid}'!"); 62 - } 63 - return $this->handles[$phid]; 64 - } 65 - 66 - public function render() { 67 - $comment = $this->comment; 68 - $author = $this->getHandle($comment->getActorPHID()); 69 - $author_link = $author->renderLink(); 70 - 71 - $actions = $this->renderActions(); 72 - $content = $this->renderContent(); 73 - $classes = $this->renderClasses(); 74 - 75 - $xaction_view = id(new PhabricatorTransactionView()) 76 - ->setUser($this->user) 77 - ->setImageURI($author->getImageURI()) 78 - ->setActions($actions) 79 - ->appendChild($content); 80 - 81 - if ($this->isPreview) { 82 - $xaction_view->setIsPreview(true); 83 - } else { 84 - $xaction_view 85 - ->setAnchor('comment-'.$this->commentNumber, '#'.$this->commentNumber) 86 - ->setEpoch($comment->getDateCreated()); 87 - } 88 - 89 - foreach ($classes as $class) { 90 - $xaction_view->addClass($class); 91 - } 92 - 93 - return $xaction_view->render(); 94 - } 95 - 96 - private function renderActions() { 97 - $comment = $this->comment; 98 - $author = $this->getHandle($comment->getActorPHID()); 99 - $author_link = $author->renderLink(); 100 - 101 - $action = $comment->getAction(); 102 - $verb = PhabricatorAuditActionConstants::getActionPastTenseVerb($action); 103 - 104 - $metadata = $comment->getMetadata(); 105 - $added_auditors = idx( 106 - $metadata, 107 - PhabricatorAuditComment::METADATA_ADDED_AUDITORS, 108 - array()); 109 - $added_ccs = idx( 110 - $metadata, 111 - PhabricatorAuditComment::METADATA_ADDED_CCS, 112 - array()); 113 - 114 - $actions = array(); 115 - if ($action == PhabricatorAuditActionConstants::ADD_CCS) { 116 - $rendered_ccs = $this->renderHandleList($added_ccs); 117 - $actions[] = pht('%s added CCs: %s.', $author_link, $rendered_ccs); 118 - } else if ($action == PhabricatorAuditActionConstants::ADD_AUDITORS) { 119 - $rendered_auditors = $this->renderHandleList($added_auditors); 120 - $actions[] = pht( 121 - '%s added auditors: %s.', 122 - $author_link, 123 - $rendered_auditors); 124 - } else { 125 - $actions[] = hsprintf('%s %s this commit.', $author_link, $verb); 126 - } 127 - 128 - foreach ($actions as $key => $action) { 129 - $actions[$key] = phutil_tag('div', array(), $action); 130 - } 131 - 132 - return $actions; 133 - } 134 - 135 - private function renderContent() { 136 - $comment = $this->comment; 137 - $engine = $this->getMarkupEngine(); 138 - 139 - if (!strlen($comment->getContent()) && empty($this->inlineComments)) { 140 - return null; 141 - } else { 142 - return phutil_tag_div('phabricator-remarkup', array( 143 - $engine->getOutput( 144 - $comment, 145 - PhabricatorAuditComment::MARKUP_FIELD_BODY), 146 - $this->renderInlines(), 147 - )); 148 - } 149 - } 150 - 151 - private function renderInlines() { 152 - if (!$this->inlineComments) { 153 - return null; 154 - } 155 - 156 - $engine = $this->getMarkupEngine(); 157 - 158 - $inlines_by_path = mgroup($this->inlineComments, 'getPathID'); 159 - 160 - $view = new PhabricatorInlineSummaryView(); 161 - foreach ($inlines_by_path as $path_id => $inlines) { 162 - $path = idx($this->pathMap, $path_id); 163 - if ($path === null) { 164 - continue; 165 - } 166 - 167 - $items = array(); 168 - foreach ($inlines as $inline) { 169 - $items[] = array( 170 - 'id' => $inline->getID(), 171 - 'line' => $inline->getLineNumber(), 172 - 'length' => $inline->getLineLength(), 173 - 'content' => $engine->getOutput( 174 - $inline, 175 - PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY), 176 - ); 177 - } 178 - 179 - $view->addCommentGroup($path, $items); 180 - } 181 - 182 - return $view; 183 - } 184 - 185 - private function renderHandleList(array $phids) { 186 - $result = array(); 187 - foreach ($phids as $phid) { 188 - $result[] = $this->handles[$phid]->renderLink(); 189 - } 190 - return phutil_implode_html(', ', $result); 191 - } 192 - 193 - private function renderClasses() { 194 - $comment = $this->comment; 195 - 196 - $classes = array(); 197 - switch ($comment->getAction()) { 198 - case PhabricatorAuditActionConstants::ACCEPT: 199 - $classes[] = 'audit-accept'; 200 - break; 201 - case PhabricatorAuditActionConstants::CONCERN: 202 - $classes[] = 'audit-concern'; 203 - break; 204 - } 205 - 206 - return $classes; 207 - } 208 - 209 - }
+3 -2
src/applications/transactions/storage/PhabricatorApplicationTransaction.php
··· 264 264 if (empty($this->handles[$phid])) { 265 265 throw new Exception( 266 266 pht( 267 - 'Transaction ("%s") requires a handle ("%s") that it did not '. 268 - 'load.', 267 + 'Transaction ("%s", of type "%s") requires a handle ("%s") that it '. 268 + 'did not load.', 269 269 $this->getPHID(), 270 + $this->getTransactionType(), 270 271 $phid)); 271 272 } 272 273 return $this->handles[$phid];
+1 -11
src/applications/transactions/view/PhabricatorApplicationTransactionView.php
··· 159 159 } 160 160 161 161 if ($this->getShowEditActions()) { 162 - $list_id = celerity_generate_unique_node_id(); 163 - 164 - $view->setID($list_id); 165 - 166 - Javelin::initBehavior( 167 - 'phabricator-transaction-list', 168 - array( 169 - 'listID' => $list_id, 170 - 'objectPHID' => $this->getObjectPHID(), 171 - 'nextAnchor' => $this->anchorOffset + count($events), 172 - )); 162 + Javelin::initBehavior('phabricator-transaction-list'); 173 163 } 174 164 175 165 return $view->render();
+13 -13
src/view/phui/PHUITimelineEventView.php
··· 495 495 $xaction_phid = $this->getTransactionPHID(); 496 496 497 497 $items = array(); 498 - if ($this->getQuoteTargetID()) { 498 + 499 + if ($this->getIsEditable()) { 500 + $items[] = id(new PhabricatorActionView()) 501 + ->setIcon('fa-pencil') 502 + ->setHref('/transactions/edit/'.$xaction_phid.'/') 503 + ->setName(pht('Edit Comment')) 504 + ->addSigil('transaction-edit') 505 + ->setMetadata( 506 + array( 507 + 'anchor' => $anchor, 508 + )); 509 + } 499 510 511 + if ($this->getQuoteTargetID()) { 500 512 $ref = null; 501 513 if ($this->getQuoteRef()) { 502 514 $ref = $this->getQuoteRef(); 503 515 if ($anchor) { 504 516 $ref = $ref.'#'.$anchor; 505 517 } 506 - } 507 - 508 - if ($this->getIsEditable()) { 509 - $items[] = id(new PhabricatorActionView()) 510 - ->setIcon('fa-pencil') 511 - ->setHref('/transactions/edit/'.$xaction_phid.'/') 512 - ->setName(pht('Edit Comment')) 513 - ->addSigil('transaction-edit') 514 - ->setMetadata( 515 - array( 516 - 'anchor' => $anchor, 517 - )); 518 518 } 519 519 520 520 $items[] = id(new PhabricatorActionView())
-15
webroot/rsrc/css/application/diffusion/commit-view.css
··· 1 - /** 2 - * @provides diffusion-commit-view-css 3 - */ 4 - 5 - .diffusion-comment-list { 6 - margin: 2em; 7 - } 8 - 9 - .phabricator-transaction-view .audit-accept { 10 - border-color: #009933; 11 - } 12 - 13 - .phabricator-transaction-view .audit-concern { 14 - border-color: #aa0000; 15 - }