Remove product literal strings in "pht()", part 6
[phabricator.git] / src / applications / differential / query / DifferentialRevisionSearchEngine.php
blob1ec5265630d929a799b6f2ccf16fe17d61940eb8
1 <?php
3 final class DifferentialRevisionSearchEngine
4 extends PhabricatorApplicationSearchEngine {
6 public function getResultTypeDescription() {
7 return pht('Differential Revisions');
10 public function getApplicationClassName() {
11 return 'PhabricatorDifferentialApplication';
14 protected function newResultBuckets() {
15 return DifferentialRevisionResultBucket::getAllResultBuckets();
18 public function newQuery() {
19 return id(new DifferentialRevisionQuery())
20 ->needFlags(true)
21 ->needDrafts(true)
22 ->needReviewers(true);
25 protected function buildQueryFromParameters(array $map) {
26 $query = $this->newQuery();
28 if ($map['responsiblePHIDs']) {
29 $query->withResponsibleUsers($map['responsiblePHIDs']);
32 if ($map['authorPHIDs']) {
33 $query->withAuthors($map['authorPHIDs']);
36 if ($map['reviewerPHIDs']) {
37 $query->withReviewers($map['reviewerPHIDs']);
40 if ($map['repositoryPHIDs']) {
41 $query->withRepositoryPHIDs($map['repositoryPHIDs']);
44 if ($map['statuses']) {
45 $query->withStatuses($map['statuses']);
48 if ($map['createdStart'] || $map['createdEnd']) {
49 $query->withCreatedEpochBetween(
50 $map['createdStart'],
51 $map['createdEnd']);
54 if ($map['modifiedStart'] || $map['modifiedEnd']) {
55 $query->withUpdatedEpochBetween(
56 $map['modifiedStart'],
57 $map['modifiedEnd']);
60 if ($map['affectedPaths']) {
61 $query->withPaths($map['affectedPaths']);
64 return $query;
67 protected function buildCustomSearchFields() {
68 return array(
69 id(new PhabricatorSearchDatasourceField())
70 ->setLabel(pht('Responsible Users'))
71 ->setKey('responsiblePHIDs')
72 ->setAliases(array('responsiblePHID', 'responsibles', 'responsible'))
73 ->setDatasource(new DifferentialResponsibleDatasource())
74 ->setDescription(
75 pht('Find revisions that a given user is responsible for.')),
76 id(new PhabricatorUsersSearchField())
77 ->setLabel(pht('Authors'))
78 ->setKey('authorPHIDs')
79 ->setAliases(array('author', 'authors', 'authorPHID'))
80 ->setDescription(
81 pht('Find revisions with specific authors.')),
82 id(new PhabricatorSearchDatasourceField())
83 ->setLabel(pht('Reviewers'))
84 ->setKey('reviewerPHIDs')
85 ->setAliases(array('reviewer', 'reviewers', 'reviewerPHID'))
86 ->setDatasource(new DifferentialReviewerFunctionDatasource())
87 ->setDescription(
88 pht('Find revisions with specific reviewers.')),
89 id(new PhabricatorSearchDatasourceField())
90 ->setLabel(pht('Repositories'))
91 ->setKey('repositoryPHIDs')
92 ->setAliases(array('repository', 'repositories', 'repositoryPHID'))
93 ->setDatasource(new DiffusionRepositoryFunctionDatasource())
94 ->setDescription(
95 pht('Find revisions from specific repositories.')),
96 id(new PhabricatorSearchDatasourceField())
97 ->setLabel(pht('Statuses'))
98 ->setKey('statuses')
99 ->setAliases(array('status'))
100 ->setDatasource(new DifferentialRevisionStatusFunctionDatasource())
101 ->setDescription(
102 pht('Find revisions with particular statuses.')),
103 id(new PhabricatorSearchDateField())
104 ->setLabel(pht('Created After'))
105 ->setKey('createdStart')
106 ->setDescription(
107 pht('Find revisions created at or after a particular time.')),
108 id(new PhabricatorSearchDateField())
109 ->setLabel(pht('Created Before'))
110 ->setKey('createdEnd')
111 ->setDescription(
112 pht('Find revisions created at or before a particular time.')),
113 id(new PhabricatorSearchDateField())
114 ->setLabel(pht('Modified After'))
115 ->setKey('modifiedStart')
116 ->setIsHidden(true)
117 ->setDescription(
118 pht('Find revisions modified at or after a particular time.')),
119 id(new PhabricatorSearchDateField())
120 ->setLabel(pht('Modified Before'))
121 ->setKey('modifiedEnd')
122 ->setIsHidden(true)
123 ->setDescription(
124 pht('Find revisions modified at or before a particular time.')),
125 id(new PhabricatorSearchStringListField())
126 ->setKey('affectedPaths')
127 ->setLabel(pht('Affected Paths'))
128 ->setDescription(
129 pht('Search for revisions affecting particular paths.'))
130 ->setIsHidden(true),
134 protected function getURI($path) {
135 return '/differential/'.$path;
138 protected function getBuiltinQueryNames() {
139 $names = array();
141 if ($this->requireViewer()->isLoggedIn()) {
142 $names['active'] = pht('Active Revisions');
143 $names['authored'] = pht('Authored');
146 $names['all'] = pht('All Revisions');
148 return $names;
151 public function buildSavedQueryFromBuiltin($query_key) {
152 $query = $this->newSavedQuery();
153 $query->setQueryKey($query_key);
155 $viewer = $this->requireViewer();
157 switch ($query_key) {
158 case 'active':
159 $bucket_key = DifferentialRevisionRequiredActionResultBucket::BUCKETKEY;
161 return $query
162 ->setParameter('responsiblePHIDs', array($viewer->getPHID()))
163 ->setParameter('statuses', array('open()'))
164 ->setParameter('bucket', $bucket_key);
165 case 'authored':
166 return $query
167 ->setParameter('authorPHIDs', array($viewer->getPHID()));
168 case 'all':
169 return $query;
172 return parent::buildSavedQueryFromBuiltin($query_key);
175 private function getStatusOptions() {
176 return array(
177 DifferentialLegacyQuery::STATUS_ANY => pht('All'),
178 DifferentialLegacyQuery::STATUS_OPEN => pht('Open'),
179 DifferentialLegacyQuery::STATUS_ACCEPTED => pht('Accepted'),
180 DifferentialLegacyQuery::STATUS_NEEDS_REVIEW => pht('Needs Review'),
181 DifferentialLegacyQuery::STATUS_NEEDS_REVISION => pht('Needs Revision'),
182 DifferentialLegacyQuery::STATUS_CLOSED => pht('Closed'),
183 DifferentialLegacyQuery::STATUS_ABANDONED => pht('Abandoned'),
187 protected function renderResultList(
188 array $revisions,
189 PhabricatorSavedQuery $query,
190 array $handles) {
191 assert_instances_of($revisions, 'DifferentialRevision');
193 $viewer = $this->requireViewer();
194 $template = id(new DifferentialRevisionListView())
195 ->setViewer($viewer)
196 ->setNoBox($this->isPanelContext());
198 $bucket = $this->getResultBucket($query);
200 $unlanded = $this->loadUnlandedDependencies($revisions);
202 $views = array();
203 if ($bucket) {
204 $bucket->setViewer($viewer);
206 try {
207 $groups = $bucket->newResultGroups($query, $revisions);
209 foreach ($groups as $group) {
210 // Don't show groups in Dashboard Panels
211 if ($group->getObjects() || !$this->isPanelContext()) {
212 $views[] = id(clone $template)
213 ->setHeader($group->getName())
214 ->setNoDataString($group->getNoDataString())
215 ->setRevisions($group->getObjects());
218 } catch (Exception $ex) {
219 $this->addError($ex->getMessage());
221 } else {
222 $views[] = id(clone $template)
223 ->setRevisions($revisions);
226 if (!$views) {
227 $views[] = id(new DifferentialRevisionListView())
228 ->setViewer($viewer)
229 ->setNoDataString(pht('No revisions found.'));
232 foreach ($views as $view) {
233 $view->setUnlandedDependencies($unlanded);
236 if (count($views) == 1) {
237 // Reduce this to a PHUIObjectItemListView so we can get the free
238 // support from ApplicationSearch.
239 $list = head($views)->render();
240 } else {
241 $list = $views;
244 $result = new PhabricatorApplicationSearchResultView();
245 $result->setContent($list);
247 return $result;
250 protected function getNewUserBody() {
251 $create_button = id(new PHUIButtonView())
252 ->setTag('a')
253 ->setText(pht('Create a Diff'))
254 ->setHref('/differential/diff/create/')
255 ->setColor(PHUIButtonView::GREEN);
257 $icon = $this->getApplication()->getIcon();
258 $app_name = $this->getApplication()->getName();
259 $view = id(new PHUIBigInfoView())
260 ->setIcon($icon)
261 ->setTitle(pht('Welcome to %s', $app_name))
262 ->setDescription(
263 pht('Pre-commit code review. Revisions that are waiting on your input '.
264 'will appear here.'))
265 ->addAction($create_button);
267 return $view;
270 private function loadUnlandedDependencies(array $revisions) {
271 $phids = array();
272 foreach ($revisions as $revision) {
273 if (!$revision->isAccepted()) {
274 continue;
277 $phids[] = $revision->getPHID();
280 if (!$phids) {
281 return array();
284 $query = id(new PhabricatorEdgeQuery())
285 ->withSourcePHIDs($phids)
286 ->withEdgeTypes(
287 array(
288 DifferentialRevisionDependsOnRevisionEdgeType::EDGECONST,
291 $query->execute();
293 $revision_phids = $query->getDestinationPHIDs();
294 if (!$revision_phids) {
295 return array();
298 $viewer = $this->requireViewer();
300 $blocking_revisions = id(new DifferentialRevisionQuery())
301 ->setViewer($viewer)
302 ->withPHIDs($revision_phids)
303 ->withIsOpen(true)
304 ->execute();
305 $blocking_revisions = mpull($blocking_revisions, null, 'getPHID');
307 $result = array();
308 foreach ($revisions as $revision) {
309 $revision_phid = $revision->getPHID();
310 $blocking_phids = $query->getDestinationPHIDs(array($revision_phid));
311 $blocking = array_select_keys($blocking_revisions, $blocking_phids);
312 if ($blocking) {
313 $result[$revision_phid] = $blocking;
317 return $result;
320 protected function newExportFields() {
321 $fields = array(
322 id(new PhabricatorStringExportField())
323 ->setKey('monogram')
324 ->setLabel(pht('Monogram')),
325 id(new PhabricatorPHIDExportField())
326 ->setKey('authorPHID')
327 ->setLabel(pht('Author PHID')),
328 id(new PhabricatorStringExportField())
329 ->setKey('author')
330 ->setLabel(pht('Author')),
331 id(new PhabricatorStringExportField())
332 ->setKey('status')
333 ->setLabel(pht('Status')),
334 id(new PhabricatorStringExportField())
335 ->setKey('statusName')
336 ->setLabel(pht('Status Name')),
337 id(new PhabricatorURIExportField())
338 ->setKey('uri')
339 ->setLabel(pht('URI')),
340 id(new PhabricatorStringExportField())
341 ->setKey('title')
342 ->setLabel(pht('Title')),
343 id(new PhabricatorStringExportField())
344 ->setKey('summary')
345 ->setLabel(pht('Summary')),
346 id(new PhabricatorStringExportField())
347 ->setKey('testPlan')
348 ->setLabel(pht('Test Plan')),
351 return $fields;
354 protected function newExportData(array $revisions) {
355 $viewer = $this->requireViewer();
357 $phids = array();
358 foreach ($revisions as $revision) {
359 $phids[] = $revision->getAuthorPHID();
361 $handles = $viewer->loadHandles($phids);
363 $export = array();
364 foreach ($revisions as $revision) {
366 $author_phid = $revision->getAuthorPHID();
367 if ($author_phid) {
368 $author_name = $handles[$author_phid]->getName();
369 } else {
370 $author_name = null;
373 $status = $revision->getStatusObject();
374 $status_name = $status->getDisplayName();
375 $status_value = $status->getKey();
377 $export[] = array(
378 'monogram' => $revision->getMonogram(),
379 'authorPHID' => $author_phid,
380 'author' => $author_name,
381 'status' => $status_value,
382 'statusName' => $status_name,
383 'uri' => PhabricatorEnv::getProductionURI($revision->getURI()),
384 'title' => (string)$revision->getTitle(),
385 'summary' => (string)$revision->getSummary(),
386 'testPlan' => (string)$revision->getTestPlan(),
390 return $export;