2014-02-12 23:05:40 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class DifferentialTransactionView
|
|
|
|
extends PhabricatorApplicationTransactionView {
|
|
|
|
|
|
|
|
private $changesets;
|
2014-02-14 01:03:23 +01:00
|
|
|
private $revision;
|
|
|
|
private $rightDiff;
|
|
|
|
private $leftDiff;
|
|
|
|
|
|
|
|
public function setLeftDiff(DifferentialDiff $left_diff) {
|
|
|
|
$this->leftDiff = $left_diff;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getLeftDiff() {
|
|
|
|
return $this->leftDiff;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setRightDiff(DifferentialDiff $right_diff) {
|
|
|
|
$this->rightDiff = $right_diff;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRightDiff() {
|
|
|
|
return $this->rightDiff;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setRevision(DifferentialRevision $revision) {
|
|
|
|
$this->revision = $revision;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRevision() {
|
|
|
|
return $this->revision;
|
|
|
|
}
|
2014-02-12 23:05:40 +01:00
|
|
|
|
|
|
|
public function setChangesets(array $changesets) {
|
|
|
|
assert_instances_of($changesets, 'DifferentialChangeset');
|
|
|
|
$this->changesets = $changesets;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getChangesets() {
|
|
|
|
return $this->changesets;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: There's a whole lot of code duplication between this and
|
|
|
|
// PholioTransactionView to handle inlines. Merge this into the core? Some of
|
|
|
|
// it can probably be shared, while other parts are trickier.
|
|
|
|
|
|
|
|
protected function shouldGroupTransactions(
|
|
|
|
PhabricatorApplicationTransaction $u,
|
|
|
|
PhabricatorApplicationTransaction $v) {
|
|
|
|
|
|
|
|
if ($u->getAuthorPHID() != $v->getAuthorPHID()) {
|
|
|
|
// Don't group transactions by different authors.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (($v->getDateCreated() - $u->getDateCreated()) > 60) {
|
|
|
|
// Don't group if transactions that happened more than 60s apart.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ($u->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
case DifferentialTransaction::TYPE_INLINE:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ($v->getTransactionType()) {
|
|
|
|
case DifferentialTransaction::TYPE_INLINE:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::shouldGroupTransactions($u, $v);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function renderTransactionContent(
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
|
|
|
|
|
|
|
$out = array();
|
|
|
|
|
|
|
|
$type_inline = DifferentialTransaction::TYPE_INLINE;
|
|
|
|
|
|
|
|
$group = $xaction->getTransactionGroup();
|
|
|
|
if ($xaction->getTransactionType() == $type_inline) {
|
|
|
|
array_unshift($group, $xaction);
|
|
|
|
} else {
|
|
|
|
$out[] = parent::renderTransactionContent($xaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$group) {
|
|
|
|
return $out;
|
|
|
|
}
|
|
|
|
|
|
|
|
$inlines = array();
|
|
|
|
foreach ($group as $xaction) {
|
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case DifferentialTransaction::TYPE_INLINE:
|
|
|
|
$inlines[] = $xaction;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new Exception("Unknown grouped transaction type!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($inlines) {
|
|
|
|
$inline_view = new PhabricatorInlineSummaryView();
|
|
|
|
|
|
|
|
$changesets = $this->getChangesets();
|
|
|
|
$changesets = mpull($changesets, null, 'getID');
|
|
|
|
|
|
|
|
// Group the changesets by file and reorder them by display order.
|
|
|
|
$inline_groups = array();
|
|
|
|
foreach ($inlines as $inline) {
|
|
|
|
$inline_groups[$inline->getComment()->getChangesetID()][] = $inline;
|
|
|
|
}
|
|
|
|
|
|
|
|
$changsets = msort($changesets, 'getFilename');
|
|
|
|
$inline_groups = array_select_keys(
|
|
|
|
$inline_groups,
|
|
|
|
array_keys($changesets));
|
|
|
|
|
|
|
|
foreach ($inline_groups as $changeset_id => $group) {
|
2014-02-14 00:06:38 +01:00
|
|
|
// Sort the group of inlines by line number.
|
|
|
|
$by_line = array();
|
|
|
|
foreach ($group as $inline) {
|
|
|
|
$by_line[] = array(
|
2014-02-14 01:03:23 +01:00
|
|
|
'line' => ((int)$inline->getComment()->getLineNumber() << 16) +
|
|
|
|
((int)$inline->getComment()->getLineLength()),
|
2014-02-14 00:06:38 +01:00
|
|
|
'inline' => $inline,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
$by_line = isort($by_line, 'line');
|
|
|
|
$group = ipull($by_line, 'inline');
|
2014-02-12 23:05:40 +01:00
|
|
|
|
|
|
|
$changeset = $changesets[$changeset_id];
|
|
|
|
$items = array();
|
|
|
|
foreach ($group as $inline) {
|
|
|
|
$comment = $inline->getComment();
|
|
|
|
$item = array(
|
|
|
|
'id' => $comment->getID(),
|
|
|
|
'line' => $comment->getLineNumber(),
|
|
|
|
'length' => $comment->getLineLength(),
|
|
|
|
'content' => parent::renderTransactionContent($inline),
|
|
|
|
);
|
|
|
|
|
2014-02-14 01:03:23 +01:00
|
|
|
$changeset_diff_id = $changeset->getDiffID();
|
|
|
|
if ($comment->getIsNewFile()) {
|
|
|
|
$visible_diff_id = $this->getRightDiff()->getID();
|
|
|
|
} else {
|
|
|
|
$visible_diff_id = $this->getLeftDiff()->getID();
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: We still get one edge case wrong here, when we have a
|
|
|
|
// versus diff and the file didn't exist in the old version. The
|
|
|
|
// comment is visible because we show the left side of the target
|
|
|
|
// diff when there's no corresponding file in the versus diff, but
|
|
|
|
// we incorrectly link it off-page.
|
|
|
|
|
|
|
|
$is_visible = ($changeset_diff_id == $visible_diff_id);
|
|
|
|
if (!$is_visible) {
|
|
|
|
$item['where'] = pht('(On Diff #%d)', $changeset_diff_id);
|
|
|
|
|
|
|
|
$revision_id = $this->getRevision()->getID();
|
|
|
|
$comment_id = $comment->getID();
|
|
|
|
|
|
|
|
$item['href'] =
|
|
|
|
"/D".$revision_id.
|
|
|
|
"?id=".$changeset_diff_id.
|
|
|
|
"#inline-".$comment_id;
|
|
|
|
}
|
2014-02-12 23:05:40 +01:00
|
|
|
|
|
|
|
$items[] = $item;
|
|
|
|
}
|
|
|
|
$inline_view->addCommentGroup(
|
|
|
|
$changeset->getFilename(),
|
|
|
|
$items);
|
|
|
|
}
|
|
|
|
|
|
|
|
$out[] = $inline_view;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $out;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|