Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F780985
DifferentialExtensionsRevisionSearchEngine.php (v2)
No One
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Authored By
epriestley
Sep 5 2015, 12:51 AM
2015-09-05 00:51:52 (UTC+0)
Size
13 KB
Referenced Files
None
Subscribers
None
DifferentialExtensionsRevisionSearchEngine.php (v2)
View Options
<?php
final class DifferentialExtensionsRevisionSearchEngine
extends PhabricatorApplicationSearchEngine {
public function getResultTypeDescription() {
return pht('Differential Revisions');
}
public function getApplicationClassName() {
return 'DifferentialExtensionsApplication';
}
public function getPageSize(PhabricatorSavedQuery $saved) {
if ($saved->getParameter('blockingPHIDs')) {
return 0xFFFF;
}
if ($saved->getQueryKey() == 'active') {
return 0xFFFF;
}
return parent::getPageSize($saved);
}
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
$saved->setParameter(
'responsiblePHIDs',
$this->readUsersFromRequest($request, 'responsibles'));
$saved->setParameter(
'authorPHIDs',
$this->readUsersFromRequest($request, 'authors'));
$saved->setParameter(
'reviewerPHIDs',
$this->readUsersFromRequest(
$request,
'reviewers',
array(
PhabricatorProjectProjectPHIDType::TYPECONST,
)));
$saved->setParameter(
'subscriberPHIDs',
$this->readSubscribersFromRequest($request, 'subscribers'));
$saved->setParameter(
'repositoryPHIDs',
$request->getArr('repositories'));
$saved->setParameter(
'projects',
$this->readProjectsFromRequest($request, 'projects'));
$saved->setParameter(
'draft',
$request->getBool('draft'));
$saved->setParameter(
'order',
$request->getStr('order'));
$saved->setParameter(
'status',
$request->getStr('status'));
$saved->setParameter(
'blockingPHIDs',
$this->readUsersFromRequest(
$request,
'blockers',
array(
PhabricatorProjectProjectPHIDType::TYPECONST,
)));
$saved->setParameter(
'onlyAcceptedByNonBlocker',
$request->getBool('onlyAcceptedByNonBlocker'));
return $saved;
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new DifferentialRevisionQuery())
->needFlags(true)
->needDrafts(true)
->needReviewerStatus(true)
->needRelationships(true);
$user_datasource = id(new PhabricatorPeopleUserFunctionDatasource())
->setViewer($this->requireViewer());
$responsible_phids = $saved->getParameter('responsiblePHIDs', array());
$responsible_phids = $user_datasource->evaluateTokens($responsible_phids);
if ($responsible_phids) {
$query->withResponsibleUsers($responsible_phids);
}
$this->setQueryProjects($query, $saved);
$author_phids = $saved->getParameter('authorPHIDs', array());
$author_phids = $user_datasource->evaluateTokens($author_phids);
if ($author_phids) {
$query->withAuthors($author_phids);
}
$blocker_phids = $saved->getParameter('blockingPHIDs', array());
$reviewer_phids = $saved->getParameter('reviewerPHIDs', array());
$reviewer_phids = array_merge($reviewer_phids, $blocker_phids);
if ($reviewer_phids) {
$query->withReviewers($reviewer_phids);
}
$sub_datasource = id(new PhabricatorMetaMTAMailableFunctionDatasource())
->setViewer($this->requireViewer());
$subscriber_phids = $saved->getParameter('subscriberPHIDs', array());
$subscriber_phids = $sub_datasource->evaluateTokens($subscriber_phids);
if ($subscriber_phids) {
$query->withCCs($subscriber_phids);
}
$repository_phids = $saved->getParameter('repositoryPHIDs', array());
if ($repository_phids) {
$query->withRepositoryPHIDs($repository_phids);
}
$draft = $saved->getParameter('draft', false);
if ($draft && $this->requireViewer()->isLoggedIn()) {
$query->withDraftRepliesByAuthors(
array($this->requireViewer()->getPHID()));
}
$status = $saved->getParameter('status');
if (idx($this->getStatusOptions(), $status)) {
$query->withStatus($status);
}
$order = $saved->getParameter('order');
if (idx($this->getOrderOptions(), $order)) {
$query->setOrder($order);
} else {
$query->setOrder(DifferentialRevisionQuery::ORDER_CREATED);
}
return $query;
}
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved) {
$responsible_phids = $saved->getParameter('responsiblePHIDs', array());
$author_phids = $saved->getParameter('authorPHIDs', array());
$reviewer_phids = $saved->getParameter('reviewerPHIDs', array());
$blocking_phids = $saved->getParameter('blockingPHIDs', array());
$subscriber_phids = $saved->getParameter('subscriberPHIDs', array());
$repository_phids = $saved->getParameter('repositoryPHIDs', array());
$only_draft = $saved->getParameter('draft', false);
$projects = $saved->getParameter('projects', array());
$only_accepted = $saved->getParameter('onlyAcceptedByNonBlocker');
$form
->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Responsible Users'))
->setName('responsibles')
->setDatasource(new PhabricatorPeopleUserFunctionDatasource())
->setValue($responsible_phids))
->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Authors'))
->setName('authors')
->setDatasource(new PhabricatorPeopleUserFunctionDatasource())
->setValue($author_phids))
->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Reviewers'))
->setName('reviewers')
->setDatasource(new PhabricatorProjectOrUserDatasource())
->setValue($reviewer_phids))
->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Exact Blocking or Rejected Reviewers'))
->setName('blockers')
->setDatasource(new PhabricatorProjectOrUserDatasource())
->setValue($blocking_phids))
->appendControl(
id(new AphrontFormCheckboxControl())
->addCheckbox(
'onlyAcceptedByNonBlocker',
1,
pht(
'Only show revisions which have been accepted by at least one '.
'user who is not listed in "Exact Blocking or Rejected '.
'Reviewers", and is also not a member of any projects listed '.
'in that field.'),
$only_accepted))
->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Subscribers'))
->setName('subscribers')
->setDatasource(new PhabricatorMetaMTAMailableFunctionDatasource())
->setValue($subscriber_phids))
->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Repositories'))
->setName('repositories')
->setDatasource(new DiffusionRepositoryDatasource())
->setValue($repository_phids))
->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Projects'))
->setName('projects')
->setDatasource(new PhabricatorProjectLogicalDatasource())
->setValue($projects))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Status'))
->setName('status')
->setOptions($this->getStatusOptions())
->setValue($saved->getParameter('status')));
if ($this->requireViewer()->isLoggedIn()) {
$form
->appendChild(
id(new AphrontFormCheckboxControl())
->addCheckbox(
'draft',
1,
pht('Show only revisions with a draft comment.'),
$only_draft));
}
$form
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Order'))
->setName('order')
->setOptions($this->getOrderOptions())
->setValue($saved->getParameter('order')));
}
protected function getURI($path) {
return '/differential-extensions/'.$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':
return $query
->setParameter('responsiblePHIDs', array($viewer->getPHID()))
->setParameter('status', DifferentialRevisionQuery::STATUS_OPEN);
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'),
);
}
private function getOrderOptions() {
return array(
DifferentialRevisionQuery::ORDER_CREATED => pht('Created'),
DifferentialRevisionQuery::ORDER_MODIFIED => pht('Updated'),
);
}
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());
$blocking_phids = $query->getParameter('blockingPHIDs', array());
$blocking_phids = array_fuse($blocking_phids);
$accept_status = array(
DifferentialReviewerStatus::STATUS_ACCEPTED,
DifferentialReviewerStatus::STATUS_ACCEPTED_OLDER,
);
$accept_status = array_fuse($accept_status);
$blocking_status = array(
DifferentialReviewerStatus::STATUS_BLOCKING,
DifferentialReviewerStatus::STATUS_REJECTED,
DifferentialReviewerStatus::STATUS_REJECTED_OLDER,
);
$blocking_status = array_fuse($blocking_status);
$must_accept = $query->getParameter('onlyAcceptedByNonBlocker');
if ($blocking_phids) {
if ($must_accept) {
$ignore_accept = array_fuse($blocking_phids);
$projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withPHIDs($blocking_phids)
->needMembers(true)
->execute();
if ($projects) {
foreach ($projects as $project) {
$ignore_accept += array_fuse($project->getMemberPHIDs());
}
}
}
}
foreach ($revisions as $key => $revision) {
$reviewers = $revision->getReviewerStatus();
$has_blocking = false;
$has_accept = false;
foreach ($reviewers as $reviewer) {
$reviewer_status = $reviewer->getStatus();
$reviewer_phid = $reviewer->getReviewerPHID();
if ($must_accept) {
if (isset($accept_status[$reviewer_status])) {
if (empty($ignore_accept[$reviewer_phid])) {
$has_accept = true;
}
}
}
if ($blocking_phids) {
if (isset($blocking_status[$reviewer_status])) {
if (isset($blocking_phids[$reviewer_phid])) {
$has_blocking = true;
}
}
}
}
$keep = true;
if ($must_accept && !$has_accept) {
$keep = false;
}
if ($blocking_phids && !$has_blocking) {
$keep = false;
}
if (!$keep) {
unset($revisions[$key]);
}
}
$views = array();
if ($query->getQueryKey() == 'active') {
$split = DifferentialRevisionQuery::splitResponsible(
$revisions,
$query->getParameter('responsiblePHIDs'));
list($blocking, $active, $waiting) = $split;
$views[] = id(clone $template)
->setHeader(pht('Blocking Others'))
->setNoDataString(
pht('No revisions are blocked on your action.'))
->setHighlightAge(true)
->setRevisions($blocking)
->setHandles(array());
$views[] = id(clone $template)
->setHeader(pht('Action Required'))
->setNoDataString(
pht('No revisions require your action.'))
->setHighlightAge(true)
->setRevisions($active)
->setHandles(array());
$views[] = id(clone $template)
->setHeader(pht('Waiting on Others'))
->setNoDataString(
pht('You have no revisions waiting on others.'))
->setRevisions($waiting)
->setHandles(array());
} 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);
}
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;
}
}
File Metadata
Details
Attached
Mime Type
text/plain; charset=utf-8
Storage Engine
amazon-s3
Storage Format
Raw Data
Storage Handle
phabricator/64/mb/4leptmoikwkjv7gr
Default Alt Text
DifferentialExtensionsRevisionSearchEngine.php (v2) (13 KB)
Attached To
Mode
P1851 DifferentialExtensionsRevisionSearchEngine.php (v2)
Attached
Detach File
Event Timeline
Log In to Comment