@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<?php
2
3final class DifferentialTransactionView
4 extends PhabricatorApplicationTransactionView {
5
6 private $changesets = array();
7 private $revision;
8 private $rightDiff;
9 private $leftDiff;
10
11 public function setLeftDiff(DifferentialDiff $left_diff) {
12 $this->leftDiff = $left_diff;
13 return $this;
14 }
15
16 public function getLeftDiff() {
17 return $this->leftDiff;
18 }
19
20 public function setRightDiff(DifferentialDiff $right_diff) {
21 $this->rightDiff = $right_diff;
22 return $this;
23 }
24
25 public function getRightDiff() {
26 return $this->rightDiff;
27 }
28
29 public function setRevision(DifferentialRevision $revision) {
30 $this->revision = $revision;
31 return $this;
32 }
33
34 public function getRevision() {
35 return $this->revision;
36 }
37
38 /**
39 * @param array<DifferentialChangeset> $changesets
40 */
41 public function setChangesets(array $changesets) {
42 assert_instances_of($changesets, DifferentialChangeset::class);
43 $this->changesets = $changesets;
44 return $this;
45 }
46
47 public function getChangesets() {
48 return $this->changesets;
49 }
50
51 // TODO: There's a whole lot of code duplication between this and
52 // PholioTransactionView to handle inlines. Merge this into the core? Some of
53 // it can probably be shared, while other parts are trickier.
54
55 protected function shouldGroupTransactions(
56 PhabricatorApplicationTransaction $u,
57 PhabricatorApplicationTransaction $v) {
58
59 if ($u->getAuthorPHID() != $v->getAuthorPHID()) {
60 // Don't group transactions by different authors.
61 return false;
62 }
63
64 if (($v->getDateCreated() - $u->getDateCreated()) > 60) {
65 // Don't group if transactions that happened more than 60s apart.
66 return false;
67 }
68
69 switch ($u->getTransactionType()) {
70 case PhabricatorTransactions::TYPE_COMMENT:
71 case DifferentialTransaction::TYPE_INLINE:
72 break;
73 default:
74 return false;
75 }
76
77 switch ($v->getTransactionType()) {
78 case DifferentialTransaction::TYPE_INLINE:
79 return true;
80 }
81
82 return parent::shouldGroupTransactions($u, $v);
83 }
84
85 protected function renderTransactionContent(
86 PhabricatorApplicationTransaction $xaction) {
87
88 $out = array();
89
90 $type_inline = DifferentialTransaction::TYPE_INLINE;
91
92 $group = $xaction->getTransactionGroup();
93 if ($xaction->getTransactionType() == $type_inline) {
94 array_unshift($group, $xaction);
95 } else {
96 $out[] = parent::renderTransactionContent($xaction);
97 }
98
99 // If we're rendering a preview, we show the inline comments in a separate
100 // section underneath the main transaction preview, so we skip rendering
101 // them in the preview body.
102 if ($this->getIsPreview()) {
103 return $out;
104 }
105
106 if (!$group) {
107 return $out;
108 }
109
110 $inlines = array();
111 foreach ($group as $xaction) {
112 switch ($xaction->getTransactionType()) {
113 case DifferentialTransaction::TYPE_INLINE:
114 $inlines[] = $xaction;
115 break;
116 default:
117 throw new Exception(pht('Unknown grouped transaction type!'));
118 }
119 }
120
121 if ($inlines) {
122 $inline_view = new PhabricatorInlineSummaryView();
123
124 $changesets = $this->getChangesets();
125
126 $inline_groups = DifferentialTransactionComment::sortAndGroupInlines(
127 $inlines,
128 $changesets);
129 foreach ($inline_groups as $changeset_id => $group) {
130 $changeset = $changesets[$changeset_id];
131 $items = array();
132 foreach ($group as $inline) {
133 $comment = $inline->getComment();
134 $item = array(
135 'id' => $comment->getID(),
136 'line' => $comment->getLineNumber(),
137 'length' => $comment->getLineLength(),
138 'content' => parent::renderTransactionContent($inline),
139 );
140
141 $changeset_diff_id = $changeset->getDiffID();
142 if ($comment->getIsNewFile()) {
143 $visible_diff_id = $this->getRightDiff()->getID();
144 } else {
145 $visible_diff_id = $this->getLeftDiff()->getID();
146 }
147
148 // TODO: We still get one edge case wrong here, when we have a
149 // versus diff and the file didn't exist in the old version. The
150 // comment is visible because we show the left side of the target
151 // diff when there's no corresponding file in the versus diff, but
152 // we incorrectly link it off-page.
153
154 $is_visible = ($changeset_diff_id == $visible_diff_id);
155 if (!$is_visible) {
156 $revision_id = $this->getRevision()->getID();
157 $comment_id = $comment->getID();
158 $item['href'] =
159 '/D'.$revision_id.
160 '?id='.$changeset_diff_id.
161 '#inline-'.$comment_id;
162 $item['where'] = pht('(On Diff #%d)', $changeset_diff_id);
163 }
164
165 $items[] = $item;
166 }
167 $inline_view->addCommentGroup(
168 $changeset->getFilename(),
169 $items);
170 }
171
172 $out[] = $inline_view;
173 }
174
175 return $out;
176 }
177
178}