mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-05 11:28:25 +01:00
d179d0150c
Summary: Ref T10967. There have been two different ways to load reviewers for a while: `needReviewerStatus()` and `needRelationships()`. The `needRelationships()` stuff was a false start along time ago that didn't really go anywhere. I believe the idea was that we might want to load several different types of edges (subscribers, reviewers, etc) on lots of different types of objects. However, all that stuff pretty much ended up modularizing so that main `Query` classes did not need to know about it, so `needRelationships()` never got generalized or went anywhere. A handful of things still use it, but get rid of them: they should either `needReviewerStatus()` to get reviewer info, or the ~3 callsites that care about subscribers can just load them directly. Test Plan: - Grepped for removed methods (`needRelationships()`, `getReviewers()`, `getCCPHIDs()`, etc). - Browsed Diffusion, Differential. - Called `differential.query`. It's possible I missed some stuff, but it should mostly show up as super obvious fatals ("call needReviewerStatus() before getReviewerStatus()!"). Reviewers: chad Reviewed By: chad Maniphest Tasks: T10967 Differential Revision: https://secure.phabricator.com/D17518
280 lines
8.1 KiB
PHP
280 lines
8.1 KiB
PHP
<?php
|
|
|
|
final class DifferentialRevisionSearchEngine
|
|
extends PhabricatorApplicationSearchEngine {
|
|
|
|
public function getResultTypeDescription() {
|
|
return pht('Differential Revisions');
|
|
}
|
|
|
|
public function getApplicationClassName() {
|
|
return 'PhabricatorDifferentialApplication';
|
|
}
|
|
|
|
protected function newResultBuckets() {
|
|
return DifferentialRevisionResultBucket::getAllResultBuckets();
|
|
}
|
|
|
|
public function newQuery() {
|
|
return id(new DifferentialRevisionQuery())
|
|
->needFlags(true)
|
|
->needDrafts(true)
|
|
->needReviewerStatus(true);
|
|
}
|
|
|
|
protected function buildQueryFromParameters(array $map) {
|
|
$query = $this->newQuery();
|
|
|
|
if ($map['responsiblePHIDs']) {
|
|
$query->withResponsibleUsers($map['responsiblePHIDs']);
|
|
}
|
|
|
|
if ($map['authorPHIDs']) {
|
|
$query->withAuthors($map['authorPHIDs']);
|
|
}
|
|
|
|
if ($map['reviewerPHIDs']) {
|
|
$query->withReviewers($map['reviewerPHIDs']);
|
|
}
|
|
|
|
if ($map['repositoryPHIDs']) {
|
|
$query->withRepositoryPHIDs($map['repositoryPHIDs']);
|
|
}
|
|
|
|
if ($map['status']) {
|
|
$query->withStatus($map['status']);
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
protected function buildCustomSearchFields() {
|
|
return array(
|
|
id(new PhabricatorSearchDatasourceField())
|
|
->setLabel(pht('Responsible Users'))
|
|
->setKey('responsiblePHIDs')
|
|
->setAliases(array('responsiblePHID', 'responsibles', 'responsible'))
|
|
->setDatasource(new DifferentialResponsibleDatasource())
|
|
->setDescription(
|
|
pht('Find revisions that a given user is responsible for.')),
|
|
id(new PhabricatorUsersSearchField())
|
|
->setLabel(pht('Authors'))
|
|
->setKey('authorPHIDs')
|
|
->setAliases(array('author', 'authors', 'authorPHID'))
|
|
->setDescription(
|
|
pht('Find revisions with specific authors.')),
|
|
id(new PhabricatorSearchDatasourceField())
|
|
->setLabel(pht('Reviewers'))
|
|
->setKey('reviewerPHIDs')
|
|
->setAliases(array('reviewer', 'reviewers', 'reviewerPHID'))
|
|
->setDatasource(new DiffusionAuditorFunctionDatasource())
|
|
->setDescription(
|
|
pht('Find revisions with specific reviewers.')),
|
|
id(new PhabricatorSearchDatasourceField())
|
|
->setLabel(pht('Repositories'))
|
|
->setKey('repositoryPHIDs')
|
|
->setAliases(array('repository', 'repositories', 'repositoryPHID'))
|
|
->setDatasource(new DiffusionRepositoryFunctionDatasource())
|
|
->setDescription(
|
|
pht('Find revisions from specific repositories.')),
|
|
id(new PhabricatorSearchSelectField())
|
|
->setLabel(pht('Status'))
|
|
->setKey('status')
|
|
->setOptions($this->getStatusOptions())
|
|
->setDescription(
|
|
pht('Find revisions with particular statuses.')),
|
|
);
|
|
}
|
|
|
|
protected function getURI($path) {
|
|
return '/differential/'.$path;
|
|
}
|
|
|
|
protected function getBuiltinQueryNames() {
|
|
$names = array();
|
|
|
|
if ($this->requireViewer()->isLoggedIn()) {
|
|
$names['active'] = pht('Active Revisions');
|
|
$names['authored'] = pht('Authored');
|
|
}
|
|
|
|
$names['all'] = pht('All Revisions');
|
|
|
|
return $names;
|
|
}
|
|
|
|
public function buildSavedQueryFromBuiltin($query_key) {
|
|
$query = $this->newSavedQuery();
|
|
$query->setQueryKey($query_key);
|
|
|
|
$viewer = $this->requireViewer();
|
|
|
|
switch ($query_key) {
|
|
case 'active':
|
|
$bucket_key = DifferentialRevisionRequiredActionResultBucket::BUCKETKEY;
|
|
|
|
return $query
|
|
->setParameter('responsiblePHIDs', array($viewer->getPHID()))
|
|
->setParameter('status', DifferentialRevisionQuery::STATUS_OPEN)
|
|
->setParameter('bucket', $bucket_key);
|
|
case 'authored':
|
|
return $query
|
|
->setParameter('authorPHIDs', array($viewer->getPHID()));
|
|
case 'all':
|
|
return $query;
|
|
}
|
|
|
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
|
}
|
|
|
|
private function getStatusOptions() {
|
|
return array(
|
|
DifferentialRevisionQuery::STATUS_ANY => pht('All'),
|
|
DifferentialRevisionQuery::STATUS_OPEN => pht('Open'),
|
|
DifferentialRevisionQuery::STATUS_ACCEPTED => pht('Accepted'),
|
|
DifferentialRevisionQuery::STATUS_NEEDS_REVIEW => pht('Needs Review'),
|
|
DifferentialRevisionQuery::STATUS_NEEDS_REVISION => pht('Needs Revision'),
|
|
DifferentialRevisionQuery::STATUS_CLOSED => pht('Closed'),
|
|
DifferentialRevisionQuery::STATUS_ABANDONED => pht('Abandoned'),
|
|
);
|
|
}
|
|
|
|
protected function renderResultList(
|
|
array $revisions,
|
|
PhabricatorSavedQuery $query,
|
|
array $handles) {
|
|
assert_instances_of($revisions, 'DifferentialRevision');
|
|
|
|
$viewer = $this->requireViewer();
|
|
$template = id(new DifferentialRevisionListView())
|
|
->setUser($viewer)
|
|
->setNoBox($this->isPanelContext());
|
|
|
|
$bucket = $this->getResultBucket($query);
|
|
|
|
$unlanded = $this->loadUnlandedDependencies($revisions);
|
|
|
|
$views = array();
|
|
if ($bucket) {
|
|
$bucket->setViewer($viewer);
|
|
|
|
try {
|
|
$groups = $bucket->newResultGroups($query, $revisions);
|
|
|
|
foreach ($groups as $group) {
|
|
$views[] = id(clone $template)
|
|
->setHeader($group->getName())
|
|
->setNoDataString($group->getNoDataString())
|
|
->setRevisions($group->getObjects());
|
|
}
|
|
} catch (Exception $ex) {
|
|
$this->addError($ex->getMessage());
|
|
}
|
|
} else {
|
|
$views[] = id(clone $template)
|
|
->setRevisions($revisions)
|
|
->setHandles(array());
|
|
}
|
|
|
|
$phids = array_mergev(mpull($views, 'getRequiredHandlePHIDs'));
|
|
if ($phids) {
|
|
$handles = id(new PhabricatorHandleQuery())
|
|
->setViewer($viewer)
|
|
->withPHIDs($phids)
|
|
->execute();
|
|
} else {
|
|
$handles = array();
|
|
}
|
|
|
|
foreach ($views as $view) {
|
|
$view->setHandles($handles);
|
|
$view->setUnlandedDependencies($unlanded);
|
|
}
|
|
|
|
if (count($views) == 1) {
|
|
// Reduce this to a PHUIObjectItemListView so we can get the free
|
|
// support from ApplicationSearch.
|
|
$list = head($views)->render();
|
|
} else {
|
|
$list = $views;
|
|
}
|
|
|
|
$result = new PhabricatorApplicationSearchResultView();
|
|
$result->setContent($list);
|
|
|
|
return $result;
|
|
}
|
|
|
|
protected function getNewUserBody() {
|
|
$create_button = id(new PHUIButtonView())
|
|
->setTag('a')
|
|
->setText(pht('Create a Diff'))
|
|
->setHref('/differential/diff/create/')
|
|
->setColor(PHUIButtonView::GREEN);
|
|
|
|
$icon = $this->getApplication()->getIcon();
|
|
$app_name = $this->getApplication()->getName();
|
|
$view = id(new PHUIBigInfoView())
|
|
->setIcon($icon)
|
|
->setTitle(pht('Welcome to %s', $app_name))
|
|
->setDescription(
|
|
pht('Pre-commit code review. Revisions that are waiting on your input '.
|
|
'will appear here.'))
|
|
->addAction($create_button);
|
|
|
|
return $view;
|
|
}
|
|
|
|
private function loadUnlandedDependencies(array $revisions) {
|
|
$status_accepted = ArcanistDifferentialRevisionStatus::ACCEPTED;
|
|
|
|
$phids = array();
|
|
foreach ($revisions as $revision) {
|
|
if ($revision->getStatus() != $status_accepted) {
|
|
continue;
|
|
}
|
|
|
|
$phids[] = $revision->getPHID();
|
|
}
|
|
|
|
if (!$phids) {
|
|
return array();
|
|
}
|
|
|
|
$query = id(new PhabricatorEdgeQuery())
|
|
->withSourcePHIDs($phids)
|
|
->withEdgeTypes(
|
|
array(
|
|
DifferentialRevisionDependsOnRevisionEdgeType::EDGECONST,
|
|
));
|
|
|
|
$query->execute();
|
|
|
|
$revision_phids = $query->getDestinationPHIDs();
|
|
if (!$revision_phids) {
|
|
return array();
|
|
}
|
|
|
|
$viewer = $this->requireViewer();
|
|
|
|
$blocking_revisions = id(new DifferentialRevisionQuery())
|
|
->setViewer($viewer)
|
|
->withPHIDs($revision_phids)
|
|
->withStatus(DifferentialRevisionQuery::STATUS_OPEN)
|
|
->execute();
|
|
$blocking_revisions = mpull($blocking_revisions, null, 'getPHID');
|
|
|
|
$result = array();
|
|
foreach ($revisions as $revision) {
|
|
$revision_phid = $revision->getPHID();
|
|
$blocking_phids = $query->getDestinationPHIDs(array($revision_phid));
|
|
$blocking = array_select_keys($blocking_revisions, $blocking_phids);
|
|
if ($blocking) {
|
|
$result[$revision_phid] = $blocking;
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
}
|