@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 PhabricatorCommitSearchEngine
4 extends PhabricatorApplicationSearchEngine {
5
6 public function getResultTypeDescription() {
7 return pht('Diffusion Commits');
8 }
9
10 public function getApplicationClassName() {
11 return PhabricatorDiffusionApplication::class;
12 }
13
14 public function newQuery() {
15 return id(new DiffusionCommitQuery())
16 ->needAuditRequests(true)
17 ->needCommitData(true)
18 ->needIdentities(true)
19 ->needDrafts(true);
20 }
21
22 protected function newResultBuckets() {
23 return DiffusionCommitResultBucket::getAllResultBuckets();
24 }
25
26 protected function buildQueryFromParameters(array $map) {
27 $query = $this->newQuery();
28
29 if ($map['responsiblePHIDs']) {
30 $query->withResponsiblePHIDs($map['responsiblePHIDs']);
31 }
32
33 if ($map['auditorPHIDs']) {
34 $query->withAuditorPHIDs($map['auditorPHIDs']);
35 }
36
37 if ($map['authorPHIDs']) {
38 $query->withAuthorPHIDs($map['authorPHIDs']);
39 }
40
41 if ($map['statuses']) {
42 $query->withStatuses($map['statuses']);
43 }
44
45 if ($map['repositoryPHIDs']) {
46 $query->withRepositoryPHIDs($map['repositoryPHIDs']);
47 }
48
49 if ($map['packagePHIDs']) {
50 $query->withPackagePHIDs($map['packagePHIDs']);
51 }
52
53 if ($map['unreachable'] !== null) {
54 $query->withUnreachable($map['unreachable']);
55 }
56
57 if ($map['permanent'] !== null) {
58 $query->withPermanent($map['permanent']);
59 }
60
61 if ($map['ancestorsOf']) {
62 $query->withAncestorsOf($map['ancestorsOf']);
63 }
64
65 if ($map['identifiers']) {
66 $query->withIdentifiers($map['identifiers']);
67 }
68
69 return $query;
70 }
71
72 protected function buildCustomSearchFields() {
73 $show_audit_fields = (id(new PhabricatorAuditApplication())->isInstalled());
74 $show_packages = PhabricatorApplication::isClassInstalled(
75 PhabricatorPackagesApplication::class);
76 return array(
77 id(new PhabricatorSearchDatasourceField())
78 ->setLabel(pht('Responsible Users'))
79 ->setKey('responsiblePHIDs')
80 ->setConduitKey('responsible')
81 ->setAliases(array('responsible', 'responsibles', 'responsiblePHID'))
82 ->setDatasource(new DifferentialResponsibleDatasource())
83 ->setDescription(
84 pht(
85 'Find commits where given users, projects, or packages are '.
86 'responsible for the next steps in the audit workflow.')),
87 id(new PhabricatorUsersSearchField())
88 ->setLabel(pht('Authors'))
89 ->setKey('authorPHIDs')
90 ->setConduitKey('authors')
91 ->setAliases(array('author', 'authors', 'authorPHID'))
92 ->setDescription(pht('Find commits authored by particular users.')),
93 id(new PhabricatorSearchDatasourceField())
94 ->setLabel(pht('Auditors'))
95 ->setKey('auditorPHIDs')
96 ->setConduitKey('auditors')
97 ->setAliases(array('auditor', 'auditors', 'auditorPHID'))
98 ->setDatasource(new DiffusionAuditorFunctionDatasource())
99 ->setIsHidden(!$show_audit_fields)
100 ->setDescription(
101 pht(
102 'Find commits where given users, projects, or packages are '.
103 'auditors.')),
104 id(new PhabricatorSearchCheckboxesField())
105 ->setLabel(pht('Audit Status'))
106 ->setKey('statuses')
107 ->setAliases(array('status'))
108 ->setOptions(DiffusionCommitAuditStatus::newOptions())
109 ->setDeprecatedOptions(
110 DiffusionCommitAuditStatus::newDeprecatedOptions())
111 ->setIsHidden(!$show_audit_fields)
112 ->setDescription(pht('Find commits with given audit statuses.')),
113 id(new PhabricatorSearchDatasourceField())
114 ->setLabel(pht('Repositories'))
115 ->setKey('repositoryPHIDs')
116 ->setConduitKey('repositories')
117 ->setAliases(array('repository', 'repositories', 'repositoryPHID'))
118 ->setDatasource(new DiffusionRepositoryFunctionDatasource())
119 ->setDescription(pht('Find commits in particular repositories.')),
120 id(new PhabricatorSearchDatasourceField())
121 ->setLabel(pht('Packages'))
122 ->setKey('packagePHIDs')
123 ->setConduitKey('packages')
124 ->setAliases(array('package', 'packages', 'packagePHID'))
125 ->setDatasource(new PhabricatorOwnersPackageDatasource())
126 ->setIsHidden(!$show_packages)
127 ->setDescription(
128 pht('Find commits which affect given packages.')),
129 id(new PhabricatorSearchThreeStateField())
130 ->setLabel(pht('Unreachable'))
131 ->setKey('unreachable')
132 ->setOptions(
133 pht('(Show All)'),
134 pht('Show Only Unreachable Commits'),
135 pht('Hide Unreachable Commits'))
136 ->setDescription(
137 pht(
138 'Find or exclude unreachable commits which are not ancestors of '.
139 'any branch, tag, or ref.')),
140 id(new PhabricatorSearchThreeStateField())
141 ->setLabel(pht('Permanent'))
142 ->setKey('permanent')
143 ->setOptions(
144 pht('(Show All)'),
145 pht('Show Only Permanent Commits'),
146 pht('Hide Permanent Commits'))
147 ->setDescription(
148 pht(
149 'Find or exclude permanent commits which are ancestors of '.
150 'any permanent branch, tag, or ref.')),
151 id(new PhabricatorSearchStringListField())
152 ->setLabel(pht('Ancestors Of'))
153 ->setKey('ancestorsOf')
154 ->setDescription(
155 pht(
156 'Find commits which are ancestors of a particular ref, '.
157 'like "master".')),
158 id(new PhabricatorSearchStringListField())
159 ->setLabel(pht('Identifiers'))
160 ->setKey('identifiers')
161 ->setDescription(
162 pht(
163 'Find commits with particular identifiers (usually, hashes). '.
164 'Supports full or partial identifiers (like "abcd12340987..." or '.
165 '"abcd1234") and qualified or unqualified identifiers (like '.
166 '"rXabcd1234" or "abcd1234").')),
167 );
168 }
169
170 protected function getURI($path) {
171 return '/diffusion/commit/'.$path;
172 }
173
174 protected function getBuiltinQueryNames() {
175 $names = array();
176
177 if ($this->requireViewer()->isLoggedIn()) {
178 if (id(new PhabricatorAuditApplication())->isInstalled()) {
179 $names['active'] = pht('Active Audits');
180 }
181 $names['authored'] = pht('Authored');
182 if (id(new PhabricatorAuditApplication())->isInstalled()) {
183 $names['audited'] = pht('Audited');
184 }
185 }
186
187 $names['all'] = pht('All Commits');
188
189 return $names;
190 }
191
192 public function buildSavedQueryFromBuiltin($query_key) {
193 $query = $this->newSavedQuery();
194 $query->setQueryKey($query_key);
195 $viewer = $this->requireViewer();
196
197 $viewer_phid = $viewer->getPHID();
198 switch ($query_key) {
199 case 'all':
200 return $query;
201 case 'active':
202 $bucket_key = DiffusionCommitRequiredActionResultBucket::BUCKETKEY;
203
204 $open = DiffusionCommitAuditStatus::getOpenStatusConstants();
205
206 $query
207 ->setParameter('responsiblePHIDs', array($viewer_phid))
208 ->setParameter('statuses', $open)
209 ->setParameter('bucket', $bucket_key)
210 ->setParameter('unreachable', false);
211 return $query;
212 case 'authored':
213 $query
214 ->setParameter('authorPHIDs', array($viewer_phid));
215 return $query;
216 case 'audited':
217 $query
218 ->setParameter('auditorPHIDs', array($viewer_phid));
219 return $query;
220 }
221
222 return parent::buildSavedQueryFromBuiltin($query_key);
223 }
224
225 /**
226 * @param array<PhabricatorRepositoryCommit> $commits
227 * @param PhabricatorSavedQuery $query
228 * @param array<PhabricatorObjectHandle> $handles
229 */
230 protected function renderResultList(
231 array $commits,
232 PhabricatorSavedQuery $query,
233 array $handles) {
234 assert_instances_of($commits, PhabricatorRepositoryCommit::class);
235 $viewer = $this->requireViewer();
236
237 $bucket = $this->getResultBucket($query);
238
239 // hide "Auditors" on /diffusion/commit/query/all/ if Audit not enabled
240 $show_auditors = id(new PhabricatorAuditApplication())->isInstalled();
241 $template = id(new DiffusionCommitGraphView())
242 ->setViewer($viewer)
243 ->setShowAuditors($show_auditors);
244
245 $views = array();
246 if ($bucket) {
247 $bucket->setViewer($viewer);
248
249 try {
250 $groups = $bucket->newResultGroups($query, $commits);
251
252 foreach ($groups as $group) {
253 // Don't show groups in Dashboard Panels
254 if ($group->getObjects() || !$this->isPanelContext()) {
255 $item_list = id(clone $template)
256 ->setCommits($group->getObjects())
257 ->newObjectItemListView();
258
259 $views[] = $item_list
260 ->setHeader($group->getName())
261 ->setNoDataString($group->getNoDataString());
262 }
263 }
264 } catch (Exception $ex) {
265 $this->addError($ex->getMessage());
266 }
267 }
268
269 if (!$views) {
270 $item_list = id(clone $template)
271 ->setCommits($commits)
272 ->newObjectItemListView();
273
274 $views[] = $item_list
275 ->setNoDataString(pht('No commits found.'));
276 }
277
278 return id(new PhabricatorApplicationSearchResultView())
279 ->setContent($views);
280 }
281
282 /**
283 * @return PHUIBigInfoView
284 */
285 protected function getNewUserBody() {
286 if (id(new PhabricatorAuditApplication())->isInstalled()) {
287 $view = id(new PHUIBigInfoView())
288 ->setIcon('fa-check-circle-o')
289 ->setTitle(pht('Welcome to Audit'))
290 ->setDescription(
291 pht('Post-commit code review and auditing. Audits you are assigned '.
292 'to will appear here.'));
293 } else {
294 $view = id(new PHUIBigInfoView())
295 ->setIcon('fa-code')
296 ->setTitle(pht('Welcome to Diffusion'))
297 ->setDescription(
298 pht('Your authored repository commits will appear here.'));
299 }
300 return $view;
301 }
302
303}