2014-02-03 21:51:08 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class PhabricatorSearchApplicationSearchEngine
|
|
|
|
extends PhabricatorApplicationSearchEngine {
|
|
|
|
|
|
|
|
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
|
|
|
$saved = new PhabricatorSavedQuery();
|
|
|
|
|
2014-02-03 21:52:47 +01:00
|
|
|
$saved->setParameter('query', $request->getStr('query'));
|
|
|
|
$saved->setParameter(
|
|
|
|
'statuses',
|
|
|
|
$this->readListFromRequest($request, 'statuses'));
|
|
|
|
$saved->setParameter(
|
|
|
|
'types',
|
|
|
|
$this->readListFromRequest($request, 'types'));
|
|
|
|
|
|
|
|
$saved->setParameter(
|
|
|
|
'authorPHIDs',
|
|
|
|
$this->readUsersFromRequest($request, 'authorPHIDs'));
|
|
|
|
|
|
|
|
$saved->setParameter(
|
|
|
|
'ownerPHIDs',
|
|
|
|
$this->readUsersFromRequest($request, 'ownerPHIDs'));
|
|
|
|
|
|
|
|
$saved->setParameter(
|
|
|
|
'withUnowned',
|
|
|
|
$this->readBoolFromRequest($request, 'withUnowned'));
|
|
|
|
|
|
|
|
$saved->setParameter(
|
|
|
|
'subscriberPHIDs',
|
|
|
|
$this->readPHIDsFromRequest($request, 'subscriberPHIDs'));
|
|
|
|
|
|
|
|
$saved->setParameter(
|
|
|
|
'projectPHIDs',
|
|
|
|
$this->readPHIDsFromRequest($request, 'projectPHIDs'));
|
|
|
|
|
2014-02-03 21:51:08 +01:00
|
|
|
return $saved;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
2014-02-03 21:52:47 +01:00
|
|
|
$query = id(new PhabricatorSearchDocumentQuery())
|
|
|
|
->withSavedQuery($saved);
|
2014-02-03 21:51:08 +01:00
|
|
|
return $query;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function buildSearchForm(
|
|
|
|
AphrontFormView $form,
|
2014-02-03 21:52:47 +01:00
|
|
|
PhabricatorSavedQuery $saved) {
|
|
|
|
|
|
|
|
$options = array();
|
|
|
|
$author_value = null;
|
|
|
|
$owner_value = null;
|
|
|
|
$subscribers_value = null;
|
|
|
|
$project_value = null;
|
|
|
|
|
|
|
|
$author_phids = $saved->getParameter('authorPHIDs', array());
|
|
|
|
$owner_phids = $saved->getParameter('ownerPHIDs', array());
|
|
|
|
$subscriber_phids = $saved->getParameter('subscriberPHIDs', array());
|
|
|
|
$project_phids = $saved->getParameter('projectPHIDs', array());
|
|
|
|
|
|
|
|
$all_phids = array_merge(
|
|
|
|
$author_phids,
|
|
|
|
$owner_phids,
|
|
|
|
$subscriber_phids,
|
|
|
|
$project_phids);
|
|
|
|
|
|
|
|
$all_handles = id(new PhabricatorHandleQuery())
|
|
|
|
->setViewer($this->requireViewer())
|
|
|
|
->withPHIDs($all_phids)
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
$author_handles = array_select_keys($all_handles, $author_phids);
|
|
|
|
$owner_handles = array_select_keys($all_handles, $owner_phids);
|
|
|
|
$subscriber_handles = array_select_keys($all_handles, $subscriber_phids);
|
|
|
|
$project_handles = array_select_keys($all_handles, $project_phids);
|
|
|
|
|
|
|
|
$with_unowned = $saved->getParameter('withUnowned', array());
|
|
|
|
|
|
|
|
$status_values = $saved->getParameter('statuses', array());
|
|
|
|
$status_values = array_fuse($status_values);
|
|
|
|
|
|
|
|
$statuses = array(
|
|
|
|
PhabricatorSearchRelationship::RELATIONSHIP_OPEN => pht('Open'),
|
|
|
|
PhabricatorSearchRelationship::RELATIONSHIP_CLOSED => pht('Closed'),
|
|
|
|
);
|
|
|
|
$status_control = id(new AphrontFormCheckboxControl())
|
|
|
|
->setLabel(pht('Document Status'));
|
|
|
|
foreach ($statuses as $status => $name) {
|
|
|
|
$status_control->addCheckbox(
|
|
|
|
'statuses[]',
|
|
|
|
$status,
|
|
|
|
$name,
|
|
|
|
isset($status_values[$status]));
|
|
|
|
}
|
|
|
|
|
|
|
|
$type_values = $saved->getParameter('types', array());
|
|
|
|
$type_values = array_fuse($type_values);
|
|
|
|
|
Don't show document types in search for uninstalled applications
Summary:
Fixes T4917. Currently, if a user doesn't have access to, e.g., Phriction, they still get a checkbox in the search results to search for Wiki Documents. Those results will be filtered anyway, so this is confusing at best.
Instead, bind PHID types to applications. This is a relatively tailored fix; some areas for potential future work:
- Go through every PHID type and bind them all to applications. Vaguely nice to have, but doesn't get us anything for now.
- If no searchable application is installed, we don't show you an error state. This isn't currently possible ("People" is always installed) but in the interest of generality we could throw an exception or something at least.
- The elasticserach thing could probably constrain types to visible types, but we don't have a viewer there easily right now.
Test Plan: Uninstalled Phriction, saw the checkbox vanish.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T4917
Differential Revision: https://secure.phabricator.com/D8904
2014-04-30 00:01:50 +02:00
|
|
|
$types = self::getIndexableDocumentTypes($this->requireViewer());
|
2014-02-03 21:52:47 +01:00
|
|
|
|
|
|
|
$types_control = id(new AphrontFormCheckboxControl())
|
|
|
|
->setLabel(pht('Document Types'));
|
|
|
|
foreach ($types as $type => $name) {
|
|
|
|
$types_control->addCheckbox(
|
|
|
|
'types[]',
|
|
|
|
$type,
|
|
|
|
$name,
|
|
|
|
isset($type_values[$type]));
|
|
|
|
}
|
|
|
|
|
|
|
|
$form
|
|
|
|
->appendChild(
|
|
|
|
phutil_tag(
|
|
|
|
'input',
|
|
|
|
array(
|
|
|
|
'type' => 'hidden',
|
|
|
|
'name' => 'jump',
|
|
|
|
'value' => 'no',
|
|
|
|
)))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTextControl())
|
|
|
|
->setLabel('Query')
|
|
|
|
->setName('query')
|
|
|
|
->setValue($saved->getParameter('query')))
|
|
|
|
->appendChild($status_control)
|
|
|
|
->appendChild($types_control)
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTokenizerControl())
|
|
|
|
->setName('authorPHIDs')
|
|
|
|
->setLabel('Authors')
|
|
|
|
->setDatasource('/typeahead/common/users/')
|
|
|
|
->setValue($author_handles))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTokenizerControl())
|
|
|
|
->setName('ownerPHIDs')
|
|
|
|
->setLabel('Owners')
|
|
|
|
->setDatasource('/typeahead/common/searchowner/')
|
|
|
|
->setValue($owner_handles))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormCheckboxControl())
|
|
|
|
->addCheckbox(
|
|
|
|
'withUnowned',
|
|
|
|
1,
|
|
|
|
pht('Show only unowned documents.'),
|
|
|
|
$with_unowned))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTokenizerControl())
|
|
|
|
->setName('subscriberPHIDs')
|
|
|
|
->setLabel('Subscribers')
|
|
|
|
->setDatasource('/typeahead/common/users/')
|
|
|
|
->setValue($subscriber_handles))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTokenizerControl())
|
|
|
|
->setName('projectPHIDs')
|
|
|
|
->setLabel('In Any Project')
|
|
|
|
->setDatasource('/typeahead/common/projects/')
|
|
|
|
->setValue($project_handles));
|
2014-02-03 21:51:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function getURI($path) {
|
|
|
|
return '/search/'.$path;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getBuiltinQueryNames() {
|
|
|
|
$names = array(
|
|
|
|
'all' => pht('All Documents'),
|
2014-02-03 21:52:47 +01:00
|
|
|
'open' => pht('Open Documents'),
|
|
|
|
'open-tasks' => pht('Open Tasks'),
|
2014-02-03 21:51:08 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
return $names;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function buildSavedQueryFromBuiltin($query_key) {
|
|
|
|
|
|
|
|
$query = $this->newSavedQuery();
|
|
|
|
$query->setQueryKey($query_key);
|
|
|
|
|
|
|
|
switch ($query_key) {
|
|
|
|
case 'all':
|
|
|
|
return $query;
|
2014-02-03 21:52:47 +01:00
|
|
|
case 'open':
|
|
|
|
return $query->setParameter('statuses', array('open'));
|
|
|
|
case 'open-tasks':
|
|
|
|
return $query
|
|
|
|
->setParameter('statuses', array('open'))
|
|
|
|
->setParameter('types', array(ManiphestPHIDTypeTask::TYPECONST));
|
2014-02-03 21:51:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
|
|
|
}
|
|
|
|
|
Don't show document types in search for uninstalled applications
Summary:
Fixes T4917. Currently, if a user doesn't have access to, e.g., Phriction, they still get a checkbox in the search results to search for Wiki Documents. Those results will be filtered anyway, so this is confusing at best.
Instead, bind PHID types to applications. This is a relatively tailored fix; some areas for potential future work:
- Go through every PHID type and bind them all to applications. Vaguely nice to have, but doesn't get us anything for now.
- If no searchable application is installed, we don't show you an error state. This isn't currently possible ("People" is always installed) but in the interest of generality we could throw an exception or something at least.
- The elasticserach thing could probably constrain types to visible types, but we don't have a viewer there easily right now.
Test Plan: Uninstalled Phriction, saw the checkbox vanish.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T4917
Differential Revision: https://secure.phabricator.com/D8904
2014-04-30 00:01:50 +02:00
|
|
|
public static function getIndexableDocumentTypes(
|
|
|
|
PhabricatorUser $viewer = null) {
|
|
|
|
|
2014-02-03 21:52:47 +01:00
|
|
|
// TODO: This is inelegant and not very efficient, but gets us reasonable
|
|
|
|
// results. It would be nice to do this more elegantly.
|
|
|
|
|
|
|
|
$indexers = id(new PhutilSymbolLoader())
|
|
|
|
->setAncestorClass('PhabricatorSearchDocumentIndexer')
|
|
|
|
->loadObjects();
|
|
|
|
|
Don't show document types in search for uninstalled applications
Summary:
Fixes T4917. Currently, if a user doesn't have access to, e.g., Phriction, they still get a checkbox in the search results to search for Wiki Documents. Those results will be filtered anyway, so this is confusing at best.
Instead, bind PHID types to applications. This is a relatively tailored fix; some areas for potential future work:
- Go through every PHID type and bind them all to applications. Vaguely nice to have, but doesn't get us anything for now.
- If no searchable application is installed, we don't show you an error state. This isn't currently possible ("People" is always installed) but in the interest of generality we could throw an exception or something at least.
- The elasticserach thing could probably constrain types to visible types, but we don't have a viewer there easily right now.
Test Plan: Uninstalled Phriction, saw the checkbox vanish.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T4917
Differential Revision: https://secure.phabricator.com/D8904
2014-04-30 00:01:50 +02:00
|
|
|
if ($viewer) {
|
|
|
|
$types = PhabricatorPHIDType::getAllInstalledTypes($viewer);
|
|
|
|
} else {
|
|
|
|
$types = PhabricatorPHIDType::getAllTypes();
|
|
|
|
}
|
2014-02-03 21:52:47 +01:00
|
|
|
|
|
|
|
$results = array();
|
|
|
|
foreach ($types as $type) {
|
|
|
|
$typeconst = $type->getTypeConstant();
|
|
|
|
foreach ($indexers as $indexer) {
|
|
|
|
$fake_phid = 'PHID-'.$typeconst.'-fake';
|
|
|
|
if ($indexer->shouldIndexDocumentByPHID($fake_phid)) {
|
|
|
|
$results[$typeconst] = $type->getTypeName();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
asort($results);
|
|
|
|
|
2014-04-24 17:11:13 +02:00
|
|
|
// Put tasks first, see T4606.
|
|
|
|
$results = array_select_keys(
|
|
|
|
$results,
|
|
|
|
array(
|
|
|
|
ManiphestPHIDTypeTask::TYPECONST,
|
|
|
|
)) + $results;
|
|
|
|
|
2014-02-03 21:52:47 +01:00
|
|
|
return $results;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-02-03 21:51:08 +01:00
|
|
|
}
|