@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 a standalone view for browsing changesets of very large revisions

Summary: Ref T13110. Installs have various reasons for sending unreviewable changes (changes where the text of the change will never be reviewed by a human) through Differential anyway. Prepare for accommodating this more gracefully by building a standalone changeset list page which paginates the changesets.

Test Plan: Clicked the new "Changeset List" button on a revision, was taken to a separate page.

Maniphest Tasks: T13110

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

+216 -21
+4
src/__phutil_library_map__.php
··· 389 389 'DifferentialChangesetDetailView' => 'applications/differential/view/DifferentialChangesetDetailView.php', 390 390 'DifferentialChangesetFileTreeSideNavBuilder' => 'applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php', 391 391 'DifferentialChangesetHTMLRenderer' => 'applications/differential/render/DifferentialChangesetHTMLRenderer.php', 392 + 'DifferentialChangesetListController' => 'applications/differential/controller/DifferentialChangesetListController.php', 392 393 'DifferentialChangesetListView' => 'applications/differential/view/DifferentialChangesetListView.php', 393 394 'DifferentialChangesetOneUpMailRenderer' => 'applications/differential/render/DifferentialChangesetOneUpMailRenderer.php', 394 395 'DifferentialChangesetOneUpRenderer' => 'applications/differential/render/DifferentialChangesetOneUpRenderer.php', ··· 397 398 'DifferentialChangesetParserTestCase' => 'applications/differential/parser/__tests__/DifferentialChangesetParserTestCase.php', 398 399 'DifferentialChangesetQuery' => 'applications/differential/query/DifferentialChangesetQuery.php', 399 400 'DifferentialChangesetRenderer' => 'applications/differential/render/DifferentialChangesetRenderer.php', 401 + 'DifferentialChangesetSearchEngine' => 'applications/differential/query/DifferentialChangesetSearchEngine.php', 400 402 'DifferentialChangesetTestRenderer' => 'applications/differential/render/DifferentialChangesetTestRenderer.php', 401 403 'DifferentialChangesetTwoUpRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpRenderer.php', 402 404 'DifferentialChangesetTwoUpTestRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpTestRenderer.php', ··· 5605 5607 'DifferentialChangesetDetailView' => 'AphrontView', 5606 5608 'DifferentialChangesetFileTreeSideNavBuilder' => 'Phobject', 5607 5609 'DifferentialChangesetHTMLRenderer' => 'DifferentialChangesetRenderer', 5610 + 'DifferentialChangesetListController' => 'DifferentialController', 5608 5611 'DifferentialChangesetListView' => 'AphrontView', 5609 5612 'DifferentialChangesetOneUpMailRenderer' => 'DifferentialChangesetRenderer', 5610 5613 'DifferentialChangesetOneUpRenderer' => 'DifferentialChangesetHTMLRenderer', ··· 5613 5616 'DifferentialChangesetParserTestCase' => 'PhabricatorTestCase', 5614 5617 'DifferentialChangesetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 5615 5618 'DifferentialChangesetRenderer' => 'Phobject', 5619 + 'DifferentialChangesetSearchEngine' => 'PhabricatorApplicationSearchEngine', 5616 5620 'DifferentialChangesetTestRenderer' => 'DifferentialChangesetRenderer', 5617 5621 'DifferentialChangesetTwoUpRenderer' => 'DifferentialChangesetHTMLRenderer', 5618 5622 'DifferentialChangesetTwoUpTestRenderer' => 'DifferentialChangesetTestRenderer',
+7 -1
src/applications/differential/application/PhabricatorDifferentialApplication.php
··· 52 52 '(?:query/(?P<queryKey>[^/]+)/)?' 53 53 => 'DifferentialRevisionListController', 54 54 'diff/' => array( 55 - '(?P<id>[1-9]\d*)/' => 'DifferentialDiffViewController', 55 + '(?P<id>[1-9]\d*)/' => array( 56 + '' => 'DifferentialDiffViewController', 57 + 'changesets/' => array( 58 + $this->getQueryRoutePattern() 59 + => 'DifferentialChangesetListController', 60 + ), 61 + ), 56 62 'create/' => 'DifferentialDiffCreateController', 57 63 ), 58 64 'changeset/' => 'DifferentialChangesetViewController',
+51
src/applications/differential/controller/DifferentialChangesetListController.php
··· 1 + <?php 2 + 3 + final class DifferentialChangesetListController 4 + extends DifferentialController { 5 + 6 + private $diff; 7 + 8 + public function shouldAllowPublic() { 9 + return true; 10 + } 11 + 12 + public function handleRequest(AphrontRequest $request) { 13 + $viewer = $this->getViewer(); 14 + 15 + $diff = id(new DifferentialDiffQuery()) 16 + ->setViewer($viewer) 17 + ->withIDs(array($request->getURIData('id'))) 18 + ->executeOne(); 19 + if (!$diff) { 20 + return new Aphront404Response(); 21 + } 22 + $this->diff = $diff; 23 + 24 + return id(new DifferentialChangesetSearchEngine()) 25 + ->setController($this) 26 + ->setDiff($diff) 27 + ->buildResponse(); 28 + } 29 + 30 + protected function buildApplicationCrumbs() { 31 + $crumbs = parent::buildApplicationCrumbs(); 32 + 33 + $diff = $this->diff; 34 + if ($diff) { 35 + $revision = $diff->getRevision(); 36 + if ($revision) { 37 + $crumbs->addTextCrumb( 38 + $revision->getMonogram(), 39 + $revision->getURI()); 40 + } 41 + 42 + $crumbs->addTextCrumb( 43 + pht('Diff %d', $diff->getID()), 44 + $diff->getURI()); 45 + } 46 + 47 + return $crumbs; 48 + } 49 + 50 + 51 + }
+11 -1
src/applications/differential/controller/DifferentialRevisionViewController.php
··· 399 399 ->appendChild($other_view)); 400 400 } 401 401 402 + $view_button = id(new PHUIButtonView()) 403 + ->setTag('a') 404 + ->setText(pht('Changeset List')) 405 + ->setHref('/differential/diff/'.$target->getID().'/changesets/') 406 + ->setIcon('fa-align-left'); 407 + 408 + $tab_header = id(new PHUIHeaderView()) 409 + ->setHeader(pht('Revision Contents')) 410 + ->addActionLink($view_button); 411 + 402 412 $tab_view = id(new PHUIObjectBoxView()) 403 - ->setHeaderText(pht('Revision Contents')) 413 + ->setHeader($tab_header) 404 414 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 405 415 ->addTabGroup($tab_group); 406 416
+10 -19
src/applications/differential/query/DifferentialChangesetQuery.php
··· 41 41 } 42 42 } 43 43 44 + public function newResultObject() { 45 + return new DifferentialChangeset(); 46 + } 47 + 44 48 protected function loadPage() { 45 - $table = new DifferentialChangeset(); 46 - $conn_r = $table->establishConnection('r'); 47 - 48 - $data = queryfx_all( 49 - $conn_r, 50 - 'SELECT * FROM %T %Q %Q %Q', 51 - $table->getTableName(), 52 - $this->buildWhereClause($conn_r), 53 - $this->buildOrderClause($conn_r), 54 - $this->buildLimitClause($conn_r)); 55 - 56 - return $table->loadAllFromArray($data); 49 + return $this->loadStandardPage($this->newResultObject()); 57 50 } 58 51 59 52 protected function willFilterPage(array $changesets) { ··· 124 117 return $changesets; 125 118 } 126 119 127 - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { 128 - $where = array(); 120 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 121 + $where = parent::buildWhereClauseParts($conn); 129 122 130 123 if ($this->diffs !== null) { 131 124 $where[] = qsprintf( 132 - $conn_r, 125 + $conn, 133 126 'diffID IN (%Ld)', 134 127 mpull($this->diffs, 'getID')); 135 128 } 136 129 137 130 if ($this->ids !== null) { 138 131 $where[] = qsprintf( 139 - $conn_r, 132 + $conn, 140 133 'id IN (%Ld)', 141 134 $this->ids); 142 135 } 143 136 144 - $where[] = $this->buildPagingClause($conn_r); 145 - 146 - return $this->formatWhereClause($where); 137 + return $where; 147 138 } 148 139 149 140 public function getQueryApplicationClass() {
+133
src/applications/differential/query/DifferentialChangesetSearchEngine.php
··· 1 + <?php 2 + 3 + final class DifferentialChangesetSearchEngine 4 + extends PhabricatorApplicationSearchEngine { 5 + 6 + private $diff; 7 + 8 + public function setDiff(DifferentialDiff $diff) { 9 + $this->diff = $diff; 10 + return $this; 11 + } 12 + 13 + public function getDiff() { 14 + return $this->diff; 15 + } 16 + 17 + public function getResultTypeDescription() { 18 + return pht('Differential Changesets'); 19 + } 20 + 21 + public function getApplicationClassName() { 22 + return 'PhabricatorDifferentialApplication'; 23 + } 24 + 25 + public function newQuery() { 26 + $query = id(new DifferentialChangesetQuery()); 27 + 28 + if ($this->diff) { 29 + $query->withDiffs(array($this->diff)); 30 + } 31 + 32 + return $query; 33 + } 34 + 35 + protected function buildQueryFromParameters(array $map) { 36 + $query = $this->newQuery(); 37 + return $query; 38 + } 39 + 40 + protected function buildCustomSearchFields() { 41 + return array(); 42 + } 43 + 44 + protected function getURI($path) { 45 + $diff = $this->getDiff(); 46 + if ($diff) { 47 + return '/differential/diff/'.$diff->getID().'/changesets/'.$path; 48 + } 49 + 50 + throw new PhutilMethodNotImplementedException(); 51 + } 52 + 53 + protected function getBuiltinQueryNames() { 54 + $names = array(); 55 + $names['all'] = pht('All Changesets'); 56 + return $names; 57 + } 58 + 59 + public function buildSavedQueryFromBuiltin($query_key) { 60 + $query = $this->newSavedQuery(); 61 + $query->setQueryKey($query_key); 62 + 63 + $viewer = $this->requireViewer(); 64 + 65 + switch ($query_key) { 66 + case 'all': 67 + return $query->setParameter('order', 'oldest'); 68 + } 69 + 70 + return parent::buildSavedQueryFromBuiltin($query_key); 71 + } 72 + 73 + protected function renderResultList( 74 + array $changesets, 75 + PhabricatorSavedQuery $query, 76 + array $handles) { 77 + 78 + assert_instances_of($changesets, 'DifferentialChangeset'); 79 + $viewer = $this->requireViewer(); 80 + 81 + $rows = array(); 82 + foreach ($changesets as $changeset) { 83 + $link = phutil_tag( 84 + 'a', 85 + array( 86 + 'href' => '/differential/changeset/?ref='.$changeset->getID(), 87 + ), 88 + $changeset->getDisplayFilename()); 89 + 90 + $type = $changeset->getChangeType(); 91 + 92 + $title = DifferentialChangeType::getFullNameForChangeType($type); 93 + 94 + $add_lines = $changeset->getAddLines(); 95 + if (!$add_lines) { 96 + $add_lines = null; 97 + } else { 98 + $add_lines = '+'.$add_lines; 99 + } 100 + 101 + $rem_lines = $changeset->getDelLines(); 102 + if (!$rem_lines) { 103 + $rem_lines = null; 104 + } else { 105 + $rem_lines = '-'.$rem_lines; 106 + } 107 + 108 + $rows[] = array( 109 + $changeset->newFileTreeIcon(), 110 + $title, 111 + $link, 112 + ); 113 + } 114 + 115 + $table = id(new AphrontTableView($rows)) 116 + ->setHeaders( 117 + array( 118 + null, 119 + pht('Change'), 120 + pht('Path'), 121 + )) 122 + ->setColumnClasses( 123 + array( 124 + null, 125 + null, 126 + 'pri wide', 127 + )); 128 + 129 + return id(new PhabricatorApplicationSearchResultView()) 130 + ->setTable($table); 131 + } 132 + 133 + }