@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 PhabricatorFeedTransactionSearchEngine
4 extends PhabricatorApplicationSearchEngine {
5
6 public function getResultTypeDescription() {
7 return pht('Transactions');
8 }
9
10 public function getApplicationClassName() {
11 return PhabricatorFeedApplication::class;
12 }
13
14 public function newQuery() {
15 return new PhabricatorFeedTransactionQuery();
16 }
17
18 protected function buildCustomSearchFields() {
19 return array(
20 id(new PhabricatorUsersSearchField())
21 ->setLabel(pht('Authors'))
22 ->setKey('authorPHIDs')
23 ->setAliases(array('author', 'authors')),
24 id(new PhabricatorSearchStringListField())
25 ->setLabel(pht('Object PHIDs'))
26 ->setKey('objectPHIDs')
27 ->setAliases(array('objectPhid'))
28 ->setPlaceholder(pht('Comma separated list of PHIDs or object names.')),
29 id(new PhabricatorSearchDatasourceField())
30 ->setLabel(pht('Object Types'))
31 ->setKey('objectTypes')
32 ->setAliases(array('objectType'))
33 ->setDatasource(new PhabricatorTransactionsObjectTypeDatasource()),
34 id(new PhabricatorSearchDateField())
35 ->setLabel(pht('Created After'))
36 ->setKey('createdStart'),
37 id(new PhabricatorSearchDateField())
38 ->setLabel(pht('Created Before'))
39 ->setKey('createdEnd'),
40 );
41 }
42
43 protected function buildQueryFromParameters(array $map) {
44 $query = $this->newQuery();
45
46 if ($map['authorPHIDs']) {
47 $query->withAuthorPHIDs($map['authorPHIDs']);
48 }
49
50 if ($map['objectTypes']) {
51 $query->withObjectTypes($map['objectTypes']);
52 }
53
54 if ($map['objectPHIDs']) {
55 $query->withObjectPHIDs($map['objectPHIDs']);
56 }
57
58 $created_min = $map['createdStart'];
59 $created_max = $map['createdEnd'];
60
61 if ($created_min && $created_max) {
62 if ($created_min > $created_max) {
63 throw new PhabricatorSearchConstraintException(
64 pht(
65 'The specified "Created Before" date is earlier in time than the '.
66 'specified "Created After" date, so this query can never match '.
67 'any results.'));
68 }
69 }
70
71 if ($created_min || $created_max) {
72 $query->withDateCreatedBetween($created_min, $created_max);
73 }
74
75 return $query;
76 }
77
78 protected function getURI($path) {
79 return '/feed/transactions/'.$path;
80 }
81
82 protected function getBuiltinQueryNames() {
83 $names = array(
84 'all' => pht('All Transactions'),
85 );
86
87 return $names;
88 }
89
90 public function buildSavedQueryFromBuiltin($query_key) {
91 $query = $this->newSavedQuery()
92 ->setQueryKey($query_key);
93
94 switch ($query_key) {
95 case 'all':
96 return $query;
97 }
98
99 return parent::buildSavedQueryFromBuiltin($query_key);
100 }
101
102 /**
103 * @param array<PhabricatorApplicationTransaction> $xactions
104 * @param PhabricatorSavedQuery $query
105 * @param array<PhabricatorObjectHandle> $handles
106 */
107 protected function renderResultList(
108 array $xactions,
109 PhabricatorSavedQuery $query,
110 array $handles) {
111
112 assert_instances_of($xactions, PhabricatorApplicationTransaction::class);
113
114 $viewer = $this->requireViewer();
115
116 $handle_phids = array();
117 foreach ($xactions as $xaction) {
118 $author_phid = $xaction->getAuthorPHID();
119 if ($author_phid !== null) {
120 $handle_phids[] = $author_phid;
121 }
122 $object_phid = $xaction->getObjectPHID();
123 if ($object_phid !== null) {
124 $handle_phids[] = $object_phid;
125 }
126 }
127
128 $handles = $viewer->loadHandles($handle_phids);
129
130 $rows = array();
131 foreach ($xactions as $xaction) {
132 $author_phid = $xaction->getAuthorPHID();
133 $object_phid = $xaction->getObjectPHID();
134
135 try {
136 $title = $xaction->getTitle();
137 } catch (Throwable $ex) {
138 $title = null;
139 }
140
141 $rows[] = array(
142 $handles[$author_phid]->renderLink(),
143 $handles[$object_phid]->renderLink(),
144 AphrontTableView::renderSingleDisplayLine($title),
145 phabricator_datetime($xaction->getDateCreated(), $viewer),
146 );
147 }
148
149 $table = id(new AphrontTableView($rows))
150 ->setHeaders(
151 array(
152 pht('Author'),
153 pht('Object'),
154 pht('Transaction'),
155 pht('Date'),
156 ))
157 ->setColumnClasses(
158 array(
159 null,
160 null,
161 'wide',
162 'right',
163 ));
164
165 return id(new PhabricatorApplicationSearchResultView())
166 ->setTable($table);
167 }
168
169 protected function newExportFields() {
170 $fields = array(
171 id(new PhabricatorPHIDExportField())
172 ->setKey('authorPHID')
173 ->setLabel(pht('Author PHID')),
174 id(new PhabricatorStringExportField())
175 ->setKey('author')
176 ->setLabel(pht('Author')),
177 id(new PhabricatorStringExportField())
178 ->setKey('objectType')
179 ->setLabel(pht('Object Type')),
180 id(new PhabricatorPHIDExportField())
181 ->setKey('objectPHID')
182 ->setLabel(pht('Object PHID')),
183 id(new PhabricatorStringExportField())
184 ->setKey('objectName')
185 ->setLabel(pht('Object Name')),
186 id(new PhabricatorStringExportField())
187 ->setKey('description')
188 ->setLabel(pht('Description')),
189 );
190
191 return $fields;
192 }
193
194 protected function newExportData(array $xactions) {
195 $viewer = $this->requireViewer();
196
197 $phids = array();
198 foreach ($xactions as $xaction) {
199 $phids[] = $xaction->getAuthorPHID();
200 $phids[] = $xaction->getObjectPHID();
201 }
202 $handles = $viewer->loadHandles($phids);
203
204 $export = array();
205 foreach ($xactions as $xaction) {
206 $xaction_phid = $xaction->getPHID();
207
208 $author_phid = $xaction->getAuthorPHID();
209 if ($author_phid) {
210 $author_name = $handles[$author_phid]->getName();
211 } else {
212 $author_name = null;
213 }
214
215 $object_phid = $xaction->getObjectPHID();
216 if ($object_phid) {
217 $object_name = $handles[$object_phid]->getName();
218 } else {
219 $object_name = null;
220 }
221
222 $old_target = $xaction->getRenderingTarget();
223 try {
224 $description = $xaction
225 ->setRenderingTarget(PhabricatorApplicationTransaction::TARGET_TEXT)
226 ->getTitle();
227 } catch (Throwable $ex) {
228 $description = null;
229 }
230 $xaction->setRenderingTarget($old_target);
231
232 $export[] = array(
233 'authorPHID' => $author_phid,
234 'author' => $author_name,
235 'objectType' => phid_get_subtype($xaction_phid),
236 'objectPHID' => $object_phid,
237 'objectName' => $object_name,
238 'description' => $description,
239 );
240 }
241
242 return $export;
243 }
244
245}