2011-10-02 20:42:41 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Render a table of Differential revisions.
|
|
|
|
*/
|
|
|
|
final class DifferentialRevisionListView extends AphrontView {
|
|
|
|
|
|
|
|
private $revisions;
|
2012-08-17 21:46:26 +02:00
|
|
|
private $flags = array();
|
2012-08-17 08:35:50 +02:00
|
|
|
private $drafts = array();
|
2011-10-02 20:42:41 +02:00
|
|
|
private $handles;
|
2012-02-20 14:38:21 +01:00
|
|
|
private $fields;
|
2012-08-20 23:05:46 +02:00
|
|
|
private $highlightAge;
|
2012-02-20 14:38:21 +01:00
|
|
|
|
|
|
|
public function setFields(array $fields) {
|
2012-04-04 22:13:08 +02:00
|
|
|
assert_instances_of($fields, 'DifferentialFieldSpecification');
|
2012-02-20 14:38:21 +01:00
|
|
|
$this->fields = $fields;
|
|
|
|
return $this;
|
|
|
|
}
|
2011-10-02 20:42:41 +02:00
|
|
|
|
|
|
|
public function setRevisions(array $revisions) {
|
2012-04-04 22:13:08 +02:00
|
|
|
assert_instances_of($revisions, 'DifferentialRevision');
|
2011-10-02 20:42:41 +02:00
|
|
|
$this->revisions = $revisions;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2012-08-20 23:05:46 +02:00
|
|
|
public function setHighlightAge($bool) {
|
|
|
|
$this->highlightAge = $bool;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2011-10-02 20:42:41 +02:00
|
|
|
public function getRequiredHandlePHIDs() {
|
|
|
|
$phids = array();
|
2012-02-20 14:38:21 +01:00
|
|
|
foreach ($this->fields as $field) {
|
|
|
|
foreach ($this->revisions as $revision) {
|
|
|
|
$phids[] = $field->getRequiredHandlePHIDsForRevisionList($revision);
|
2011-10-02 20:42:41 +02:00
|
|
|
}
|
|
|
|
}
|
2012-02-20 14:38:21 +01:00
|
|
|
return array_mergev($phids);
|
2011-10-02 20:42:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function setHandles(array $handles) {
|
2012-04-04 22:13:08 +02:00
|
|
|
assert_instances_of($handles, 'PhabricatorObjectHandle');
|
2011-10-02 20:42:41 +02:00
|
|
|
$this->handles = $handles;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2012-08-17 21:46:26 +02:00
|
|
|
public function loadAssets() {
|
|
|
|
$user = $this->user;
|
|
|
|
if (!$user) {
|
|
|
|
throw new Exception("Call setUser() before loadAssets()!");
|
|
|
|
}
|
|
|
|
if ($this->revisions === null) {
|
|
|
|
throw new Exception("Call setRevisions() before loadAssets()!");
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->flags = id(new PhabricatorFlagQuery())
|
|
|
|
->withOwnerPHIDs(array($user->getPHID()))
|
|
|
|
->withObjectPHIDs(mpull($this->revisions, 'getPHID'))
|
|
|
|
->execute();
|
|
|
|
|
2012-08-17 08:35:50 +02:00
|
|
|
$this->drafts = id(new DifferentialRevisionQuery())
|
|
|
|
->withIDs(mpull($this->revisions, 'getID'))
|
|
|
|
->withDraftRepliesByAuthors(array($user->getPHID()))
|
|
|
|
->execute();
|
|
|
|
|
2012-08-17 21:46:26 +02:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2011-10-02 20:42:41 +02:00
|
|
|
public function render() {
|
|
|
|
|
|
|
|
$user = $this->user;
|
|
|
|
if (!$user) {
|
|
|
|
throw new Exception("Call setUser() before render()!");
|
|
|
|
}
|
|
|
|
|
2012-08-21 23:20:21 +02:00
|
|
|
$fresh = null;
|
|
|
|
$stale = null;
|
|
|
|
|
2012-08-20 23:05:46 +02:00
|
|
|
if ($this->highlightAge) {
|
2012-08-21 23:20:21 +02:00
|
|
|
$fresh = PhabricatorEnv::getEnvConfig('differential.days-fresh');
|
|
|
|
if ($fresh) {
|
|
|
|
$fresh = PhabricatorCalendarHoliday::getNthBusinessDay(
|
|
|
|
time(),
|
|
|
|
-$fresh);
|
|
|
|
}
|
|
|
|
|
|
|
|
$stale = PhabricatorEnv::getEnvConfig('differential.days-stale');
|
|
|
|
if ($stale) {
|
|
|
|
$stale = PhabricatorCalendarHoliday::getNthBusinessDay(
|
|
|
|
time(),
|
|
|
|
-$stale);
|
|
|
|
}
|
2012-08-20 23:05:46 +02:00
|
|
|
}
|
|
|
|
|
2012-08-08 03:37:49 +02:00
|
|
|
Javelin::initBehavior('phabricator-tooltips', array());
|
|
|
|
require_celerity_resource('aphront-tooltip-css');
|
|
|
|
|
2012-08-17 21:46:26 +02:00
|
|
|
$flagged = mpull($this->flags, null, 'getObjectPHID');
|
2012-08-01 23:33:30 +02:00
|
|
|
|
2012-02-20 14:38:21 +01:00
|
|
|
foreach ($this->fields as $field) {
|
|
|
|
$field->setUser($this->user);
|
|
|
|
$field->setHandles($this->handles);
|
|
|
|
}
|
|
|
|
|
2012-08-20 23:05:46 +02:00
|
|
|
$cell_classes = array();
|
2011-10-02 20:42:41 +02:00
|
|
|
$rows = array();
|
|
|
|
foreach ($this->revisions as $revision) {
|
2012-08-01 23:33:30 +02:00
|
|
|
$phid = $revision->getPHID();
|
|
|
|
$flag = '';
|
|
|
|
if (isset($flagged[$phid])) {
|
|
|
|
$class = PhabricatorFlagColor::getCSSClass($flagged[$phid]->getColor());
|
|
|
|
$note = $flagged[$phid]->getNote();
|
2013-01-25 21:57:17 +01:00
|
|
|
$flag = javelin_tag(
|
2012-08-01 23:33:30 +02:00
|
|
|
'div',
|
2012-08-08 03:37:49 +02:00
|
|
|
$note ? array(
|
|
|
|
'class' => 'phabricator-flag-icon '.$class,
|
|
|
|
'sigil' => 'has-tooltip',
|
|
|
|
'meta' => array(
|
|
|
|
'tip' => $note,
|
|
|
|
'align' => 'N',
|
|
|
|
'size' => 240,
|
|
|
|
),
|
|
|
|
) : array(
|
2012-08-01 23:33:30 +02:00
|
|
|
'class' => 'phabricator-flag-icon '.$class,
|
|
|
|
),
|
|
|
|
'');
|
2012-08-17 08:35:50 +02:00
|
|
|
|
|
|
|
} else if (array_key_exists($revision->getID(), $this->drafts)) {
|
|
|
|
$src = '/rsrc/image/icon/fatcow/page_white_edit.png';
|
2013-02-13 23:50:15 +01:00
|
|
|
$flag = hsprintf(
|
|
|
|
'<a href="%s">%s</a>',
|
|
|
|
'/D'.$revision->getID().'#comment-preview',
|
|
|
|
phutil_tag(
|
|
|
|
'img',
|
|
|
|
array(
|
|
|
|
'src' => celerity_get_resource_uri($src),
|
|
|
|
'width' => 16,
|
|
|
|
'height' => 16,
|
|
|
|
'alt' => 'Draft',
|
|
|
|
'title' => pht('Draft Comment'),
|
|
|
|
)));
|
2012-08-01 23:33:30 +02:00
|
|
|
}
|
2012-08-17 08:35:50 +02:00
|
|
|
|
2012-08-01 23:33:30 +02:00
|
|
|
$row = array($flag);
|
2012-08-20 23:05:46 +02:00
|
|
|
|
|
|
|
$modified = $revision->getDateModified();
|
|
|
|
|
2012-02-20 14:38:21 +01:00
|
|
|
foreach ($this->fields as $field) {
|
2012-08-21 23:20:21 +02:00
|
|
|
if (($fresh || $stale) &&
|
2012-08-20 23:05:46 +02:00
|
|
|
$field instanceof DifferentialDateModifiedFieldSpecification) {
|
2012-08-21 23:20:21 +02:00
|
|
|
if ($stale && $modified < $stale) {
|
2012-08-20 23:05:46 +02:00
|
|
|
$class = 'revision-age-old';
|
2012-08-21 23:20:21 +02:00
|
|
|
} else if ($fresh && $modified < $fresh) {
|
2012-08-20 23:05:46 +02:00
|
|
|
$class = 'revision-age-stale';
|
|
|
|
} else {
|
|
|
|
$class = 'revision-age-fresh';
|
|
|
|
}
|
|
|
|
$cell_classes[count($rows)][count($row)] = $class;
|
|
|
|
}
|
|
|
|
|
2012-02-20 14:38:21 +01:00
|
|
|
$row[] = $field->renderValueForRevisionList($revision);
|
2011-10-02 20:42:41 +02:00
|
|
|
}
|
2012-08-20 23:05:46 +02:00
|
|
|
|
2012-02-20 14:38:21 +01:00
|
|
|
$rows[] = $row;
|
|
|
|
}
|
2011-10-02 20:42:41 +02:00
|
|
|
|
2012-08-01 23:33:30 +02:00
|
|
|
$headers = array('');
|
|
|
|
$classes = array('');
|
2012-02-20 14:38:21 +01:00
|
|
|
foreach ($this->fields as $field) {
|
|
|
|
$headers[] = $field->renderHeaderForRevisionList();
|
|
|
|
$classes[] = $field->getColumnClassForRevisionList();
|
2011-10-02 20:42:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$table = new AphrontTableView($rows);
|
2012-02-20 14:38:21 +01:00
|
|
|
$table->setHeaders($headers);
|
|
|
|
$table->setColumnClasses($classes);
|
2012-08-20 23:05:46 +02:00
|
|
|
$table->setCellClasses($cell_classes);
|
2011-10-02 20:42:41 +02:00
|
|
|
|
2013-01-24 22:18:44 +01:00
|
|
|
$table->setNoDataString(pht('No revisions found.'));
|
2011-10-02 20:42:41 +02:00
|
|
|
|
2012-08-20 23:05:46 +02:00
|
|
|
require_celerity_resource('differential-revision-history-css');
|
|
|
|
|
2011-10-02 20:42:41 +02:00
|
|
|
return $table->render();
|
|
|
|
}
|
|
|
|
|
2012-02-20 14:38:21 +01:00
|
|
|
public static function getDefaultFields() {
|
|
|
|
$selector = DifferentialFieldSelector::newSelector();
|
|
|
|
$fields = $selector->getFieldSpecifications();
|
|
|
|
foreach ($fields as $key => $field) {
|
|
|
|
if (!$field->shouldAppearOnRevisionList()) {
|
|
|
|
unset($fields[$key]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$fields) {
|
|
|
|
throw new Exception(
|
|
|
|
"Phabricator configuration has no fields that appear on the list ".
|
|
|
|
"interface!");
|
|
|
|
}
|
|
|
|
|
|
|
|
return $selector->sortFieldsForRevisionList($fields);
|
|
|
|
}
|
|
|
|
|
2011-10-02 20:42:41 +02:00
|
|
|
}
|