diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index 9a74a00540..ad56b66abc 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -221,6 +221,7 @@ phutil_register_library_map(array(
'DifferentialRevisionIDFieldSpecification' => 'applications/differential/field/specification/revisionid',
'DifferentialRevisionListController' => 'applications/differential/controller/revisionlist',
'DifferentialRevisionListData' => 'applications/differential/data/revisionlist',
+ 'DifferentialRevisionListView' => 'applications/differential/view/revisionlist',
'DifferentialRevisionStatus' => 'applications/differential/constants/revisionstatus',
'DifferentialRevisionStatusFieldSpecification' => 'applications/differential/field/specification/revisionstatus',
'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/revisionupdatehistory',
@@ -914,6 +915,7 @@ phutil_register_library_map(array(
'DifferentialRevisionEditController' => 'DifferentialController',
'DifferentialRevisionIDFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialRevisionListController' => 'DifferentialController',
+ 'DifferentialRevisionListView' => 'AphrontView',
'DifferentialRevisionStatusFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
'DifferentialRevisionViewController' => 'DifferentialController',
diff --git a/src/applications/differential/controller/revisionlist/DifferentialRevisionListController.php b/src/applications/differential/controller/revisionlist/DifferentialRevisionListController.php
index 177a7e0c4f..87d169ee83 100644
--- a/src/applications/differential/controller/revisionlist/DifferentialRevisionListController.php
+++ b/src/applications/differential/controller/revisionlist/DifferentialRevisionListController.php
@@ -172,38 +172,42 @@ class DifferentialRevisionListController extends DifferentialController {
$queries[$key]['revisions'] = $revisions;
}
- $rev = new DifferentialRevision();
if ($rev_ids) {
- $rev_ids = array_keys($rev_ids);
- $reviewers = queryfx_all(
+ $rev = new DifferentialRevision();
+ $relationships = queryfx_all(
$rev->establishConnection('r'),
- 'SELECT revisionID, objectPHID FROM %T revision JOIN %T relationship
- ON revision.id = relationship.revisionID
- WHERE revision.id IN (%Ld)
- AND relationship.relation = %s
- ORDER BY sequence',
- $rev->getTableName(),
+ 'SELECT * FROM %T WHERE revisionID IN (%Ld) ORDER BY sequence',
DifferentialRevision::RELATIONSHIP_TABLE,
- $rev_ids,
- DifferentialRevision::RELATION_REVIEWER);
-
- $reviewer_map = array();
- foreach ($reviewers as $reviewer) {
- $reviewer_map[$reviewer['revisionID']][] = $reviewer['objectPHID'];
- }
- foreach ($reviewer_map as $revision_id => $reviewer_ids) {
- $phids[reset($reviewer_ids)] = true;
- }
+ array_keys($rev_ids));
+ $relationships = igroup($relationships, 'revisionID');
} else {
- $reviewer_map = array();
+ $relationships = array();
}
- if ($phids) {
- $phids = array_keys($phids);
- $handles = id(new PhabricatorObjectHandleData($phids))
- ->loadHandles();
- } else {
- $handles = array();
+ foreach ($queries as $query) {
+ foreach ($query['revisions'] as $revision) {
+ $revision->attachRelationships(
+ idx(
+ $relationships,
+ $revision->getID(),
+ array()));
+ }
+ }
+
+ $phids = array();
+ foreach ($queries as $key => $query) {
+ $view = id(new DifferentialRevisionListView())
+ ->setRevisions($query['revisions'])
+ ->setUser($user)
+ ->setNoDataString(idx($query, 'nodata'));
+ $phids[] = $view->getRequiredHandlePHIDs();
+ $queries[$key]['view'] = $view;
+ }
+ $phids = array_mergev($phids);
+ $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
+
+ foreach ($queries as $query) {
+ $query['view']->setHandles($handles);
}
if (empty($filters[$this->filter]['nofilter'])) {
@@ -226,13 +230,13 @@ class DifferentialRevisionListController extends DifferentialController {
}
foreach ($queries as $query) {
- $table = $this->renderRevisionTable(
- $query['revisions'],
- $query['header'],
- idx($query, 'nodata'),
- $handles,
- $reviewer_map);
- $side_nav->appendChild($table);
+ $table = $query['view']->render();
+
+ $panel = new AphrontPanelView();
+ $panel->setHeader($query['header']);
+ $panel->appendChild($table);
+
+ $side_nav->appendChild($panel);
}
return $this->buildStandardPageResponse(
@@ -243,81 +247,4 @@ class DifferentialRevisionListController extends DifferentialController {
));
}
- private function renderRevisionTable(
- array $revisions,
- $header,
- $nodata,
- array $handles,
- array $reviewer_map) {
-
- $rows = array();
- foreach ($revisions as $revision) {
- $status = DifferentialRevisionStatus::getNameForRevisionStatus(
- $revision->getStatus());
-
- $reviewers = idx($reviewer_map, $revision->getID(), array());
- if ($reviewers) {
- $first = reset($reviewers);
- if (count($reviewers) > 1) {
- $suffix = ' (+'.(count($reviewers) - 1).')';
- } else {
- $suffix = null;
- }
- $reviewers = $handles[$first]->renderLink().$suffix;
- } else {
- $reviewers = 'None';
- }
-
- $rows[] = array(
- 'D'.$revision->getID(),
- ''.phutil_render_tag(
- 'a',
- array(
- 'href' => '/D'.$revision->getID(),
- ),
- phutil_escape_html($revision->getTitle())).'',
- phutil_escape_html($status),
- number_format($revision->getLineCount()),
- $handles[$revision->getAuthorPHID()]->renderLink(),
- $reviewers,
- phabricator_format_timestamp($revision->getDateModified()),
- phabricator_format_timestamp($revision->getDateCreated()),
- );
- }
-
- $table = new AphrontTableView($rows);
- $table->setHeaders(
- array(
- 'ID',
- 'Revision',
- 'Status',
- 'Lines',
- 'Author',
- 'Reviewers',
- 'Updated',
- 'Created',
- ));
- $table->setColumnClasses(
- array(
- null,
- 'wide',
- null,
- null,
- null,
- null,
- null,
- null,
- ));
- if ($nodata !== null) {
- $table->setNoDataString($nodata);
- }
-
-
- $panel = new AphrontPanelView();
- $panel->setHeader($header);
- $panel->appendChild($table);
-
- return $panel;
- }
-
}
diff --git a/src/applications/differential/controller/revisionlist/__init__.php b/src/applications/differential/controller/revisionlist/__init__.php
index 72cf17b88d..9a6525b135 100644
--- a/src/applications/differential/controller/revisionlist/__init__.php
+++ b/src/applications/differential/controller/revisionlist/__init__.php
@@ -7,19 +7,17 @@
phutil_require_module('phabricator', 'aphront/response/redirect');
-phutil_require_module('phabricator', 'applications/differential/constants/revisionstatus');
phutil_require_module('phabricator', 'applications/differential/controller/base');
phutil_require_module('phabricator', 'applications/differential/data/revisionlist');
phutil_require_module('phabricator', 'applications/differential/storage/revision');
+phutil_require_module('phabricator', 'applications/differential/view/revisionlist');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'storage/queryfx');
-phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/tokenizer');
phutil_require_module('phabricator', 'view/layout/listfilter');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phabricator', 'view/layout/sidenav');
-phutil_require_module('phabricator', 'view/utils');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
diff --git a/src/applications/differential/storage/revision/DifferentialRevision.php b/src/applications/differential/storage/revision/DifferentialRevision.php
index 2e055ef361..79cfce3479 100644
--- a/src/applications/differential/storage/revision/DifferentialRevision.php
+++ b/src/applications/differential/storage/revision/DifferentialRevision.php
@@ -134,8 +134,11 @@ class DifferentialRevision extends DifferentialDAO {
self::RELATIONSHIP_TABLE,
$this->getID());
- $this->relationships = igroup($data, 'relation');
+ return $this->attachRelationships($data);
+ }
+ public function attachRelationships(array $relationships) {
+ $this->relationships = igroup($relationships, 'relation');
return $this;
}
diff --git a/src/applications/differential/view/revisionlist/DifferentialRevisionListView.php b/src/applications/differential/view/revisionlist/DifferentialRevisionListView.php
new file mode 100644
index 0000000000..83fb49a9ac
--- /dev/null
+++ b/src/applications/differential/view/revisionlist/DifferentialRevisionListView.php
@@ -0,0 +1,136 @@
+revisions = $revisions;
+ return $this;
+ }
+
+ public function getRequiredHandlePHIDs() {
+ $phids = array();
+ foreach ($this->revisions as $revision) {
+ $phids[] = $revision->getAuthorPHID();
+ $reviewers = $revision->getReviewers();
+ if ($reviewers) {
+ $phids[] = head($reviewers);
+ }
+ }
+ return $phids;
+ }
+
+ public function setHandles(array $handles) {
+ $this->handles = $handles;
+ return $this;
+ }
+
+ public function setUser(PhabricatorUser $user) {
+ $this->user = $user;
+ return $this;
+ }
+
+ public function setNoDataString($no_data_string) {
+ $this->noDataString = $no_data_string;
+ return $this;
+ }
+
+ public function render() {
+
+ $user = $this->user;
+ if (!$user) {
+ throw new Exception("Call setUser() before render()!");
+ }
+
+ $rows = array();
+ foreach ($this->revisions as $revision) {
+ $status = $revision->getStatus();
+ $status = DifferentialRevisionStatus::getNameForRevisionStatus($status);
+
+ $reviewer_phids = $revision->getReviewers();
+ if ($reviewer_phids) {
+ $first = reset($reviewer_phids);
+ if (count($reviewer_phids) > 1) {
+ $suffix = ' (+'.(count($reviewer_phids) - 1).')';
+ } else {
+ $suffix = null;
+ }
+ $reviewers = $this->handles[$first]->renderLink().$suffix;
+ } else {
+ $reviewers = 'None';
+ }
+
+ $link = phutil_render_tag(
+ 'a',
+ array(
+ 'href' => '/D'.$revision->getID(),
+ ),
+ phutil_escape_html($revision->getTitle()));
+
+ $rows[] = array(
+ 'D'.$revision->getID(),
+ $link,
+ phutil_escape_html($status),
+ number_format($revision->getLineCount()),
+ $this->handles[$revision->getAuthorPHID()]->renderLink(),
+ $reviewers,
+ phabricator_datetime($revision->getDateModified(), $user),
+ phabricator_date($revision->getDateCreated(), $user),
+ );
+ }
+
+ $table = new AphrontTableView($rows);
+ $table->setHeaders(
+ array(
+ 'ID',
+ 'Revision',
+ 'Status',
+ 'Lines',
+ 'Author',
+ 'Reviewers',
+ 'Updated',
+ 'Created',
+ ));
+ $table->setColumnClasses(
+ array(
+ null,
+ 'wide pri',
+ null,
+ 'n',
+ null,
+ null,
+ 'right',
+ 'right',
+ ));
+
+ if ($this->noDataString) {
+ $table->setNoDataString($this->noDataString);
+ }
+
+ return $table->render();
+ }
+
+}
diff --git a/src/applications/differential/view/revisionlist/__init__.php b/src/applications/differential/view/revisionlist/__init__.php
new file mode 100644
index 0000000000..8c33583de6
--- /dev/null
+++ b/src/applications/differential/view/revisionlist/__init__.php
@@ -0,0 +1,18 @@
+