@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 DifferentialTransactionComment
4 extends PhabricatorApplicationTransactionComment
5 implements
6 PhabricatorInlineCommentInterface {
7
8 protected $revisionPHID;
9 protected $changesetID;
10 protected $isNewFile = 0;
11 protected $lineNumber = 0;
12 protected $lineLength = 0;
13 protected $fixedState;
14 protected $hasReplies = 0;
15 protected $replyToCommentPHID;
16 protected $attributes = array();
17
18 private $replyToComment = self::ATTACHABLE;
19 private $isHidden = self::ATTACHABLE;
20 private $changeset = self::ATTACHABLE;
21 private $inlineContext = self::ATTACHABLE;
22
23 public function getApplicationTransactionObject() {
24 return new DifferentialTransaction();
25 }
26
27 public function attachReplyToComment(
28 ?DifferentialTransactionComment $comment = null) {
29 $this->replyToComment = $comment;
30 return $this;
31 }
32
33 public function getReplyToComment() {
34 return $this->assertAttached($this->replyToComment);
35 }
36
37 protected function getConfiguration() {
38 $config = parent::getConfiguration();
39
40 $config[self::CONFIG_COLUMN_SCHEMA] = array(
41 'revisionPHID' => 'phid?',
42 'changesetID' => 'id?',
43 'isNewFile' => 'bool',
44 'lineNumber' => 'uint32',
45 'lineLength' => 'uint32',
46 'fixedState' => 'text12?',
47 'hasReplies' => 'bool',
48 'replyToCommentPHID' => 'phid?',
49 ) + $config[self::CONFIG_COLUMN_SCHEMA];
50
51 $config[self::CONFIG_KEY_SCHEMA] = array(
52 'key_draft' => array(
53 'columns' => array('authorPHID', 'transactionPHID'),
54 ),
55 'key_changeset' => array(
56 'columns' => array('changesetID'),
57 ),
58 'key_revision' => array(
59 'columns' => array('revisionPHID'),
60 ),
61 ) + $config[self::CONFIG_KEY_SCHEMA];
62
63 $config[self::CONFIG_SERIALIZATION] = array(
64 'attributes' => self::SERIALIZATION_JSON,
65 ) + idx($config, self::CONFIG_SERIALIZATION, array());
66
67 return $config;
68 }
69
70 public function shouldUseMarkupCache($field) {
71 // Only cache submitted comments.
72 return ($this->getTransactionPHID() != null);
73 }
74
75 /**
76 * @param array<DifferentialTransaction> $inlines
77 * @param array<DifferentialChangeset> $changesets
78 */
79 public static function sortAndGroupInlines(
80 array $inlines,
81 array $changesets) {
82 assert_instances_of($inlines, DifferentialTransaction::class);
83 assert_instances_of($changesets, DifferentialChangeset::class);
84
85 $changesets = mpull($changesets, null, 'getID');
86 $changesets = msort($changesets, 'getFilename');
87
88 // Group the changesets by file and reorder them by display order.
89 $inline_groups = array();
90 foreach ($inlines as $inline) {
91 $changeset_id = $inline->getComment()->getChangesetID();
92 $inline_groups[$changeset_id][] = $inline;
93 }
94 $inline_groups = array_select_keys($inline_groups, array_keys($changesets));
95
96 foreach ($inline_groups as $changeset_id => $group) {
97 // Sort the group of inlines by line number.
98 $items = array();
99 foreach ($group as $inline) {
100 $comment = $inline->getComment();
101 $num = $comment->getLineNumber();
102 $len = $comment->getLineLength();
103 $id = $comment->getID();
104
105 $items[] = array(
106 'inline' => $inline,
107 'sort' => sprintf('~%010d%010d%010d', $num, $len, $id),
108 );
109 }
110
111 $items = isort($items, 'sort');
112 $items = ipull($items, 'inline');
113 $inline_groups[$changeset_id] = $items;
114 }
115
116 return $inline_groups;
117 }
118
119 public function getIsHidden() {
120 return $this->assertAttached($this->isHidden);
121 }
122
123 public function attachIsHidden($hidden) {
124 $this->isHidden = $hidden;
125 return $this;
126 }
127
128 public function getAttribute($key, $default = null) {
129 return idx($this->attributes, $key, $default);
130 }
131
132 public function setAttribute($key, $value) {
133 $this->attributes[$key] = $value;
134 return $this;
135 }
136
137 public function newInlineCommentObject() {
138 return DifferentialInlineComment::newFromModernComment($this);
139 }
140
141 public function getInlineContext() {
142 return $this->assertAttached($this->inlineContext);
143 }
144
145 public function attachInlineContext(
146 ?PhabricatorInlineCommentContext $context = null) {
147 $this->inlineContext = $context;
148 return $this;
149 }
150
151
152 public function isEmptyComment() {
153 if (!parent::isEmptyComment()) {
154 return false;
155 }
156
157 return $this->newInlineCommentObject()
158 ->getContentState()
159 ->isEmptyContentState();
160 }
161
162
163}