mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-27 01:02:42 +01:00
Use delegation to generalize application search controllers
Summary: Ref T2625. Lifts almost all of the search logic out of Paste controllers and into Search. This uses controller delegation for generalization. We use this in a few places, but don't use it very much yet. I think it's pretty reasonable as-is, but I might be able to make even more stuff free. There are some slightly rough edges around routes, still, but I want to hit Phame and Differential (which both have multiple application search engines) before trying to generalize that. Test Plan: Executed, browsed and managed Paste searches. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T2625 Differential Revision: https://secure.phabricator.com/D6073
This commit is contained in:
parent
cf5009d5fb
commit
5d94a8a338
10 changed files with 367 additions and 237 deletions
|
@ -743,7 +743,9 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationReleephConfigOptions' => 'applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php',
|
'PhabricatorApplicationReleephConfigOptions' => 'applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php',
|
||||||
'PhabricatorApplicationRepositories' => 'applications/repository/application/PhabricatorApplicationRepositories.php',
|
'PhabricatorApplicationRepositories' => 'applications/repository/application/PhabricatorApplicationRepositories.php',
|
||||||
'PhabricatorApplicationSearch' => 'applications/search/application/PhabricatorApplicationSearch.php',
|
'PhabricatorApplicationSearch' => 'applications/search/application/PhabricatorApplicationSearch.php',
|
||||||
|
'PhabricatorApplicationSearchController' => 'applications/search/controller/PhabricatorApplicationSearchController.php',
|
||||||
'PhabricatorApplicationSearchEngine' => 'applications/search/engine/PhabricatorApplicationSearchEngine.php',
|
'PhabricatorApplicationSearchEngine' => 'applications/search/engine/PhabricatorApplicationSearchEngine.php',
|
||||||
|
'PhabricatorApplicationSearchResultsControllerInterface' => 'applications/search/interface/PhabricatorApplicationSearchResultsControllerInterface.php',
|
||||||
'PhabricatorApplicationSettings' => 'applications/settings/application/PhabricatorApplicationSettings.php',
|
'PhabricatorApplicationSettings' => 'applications/settings/application/PhabricatorApplicationSettings.php',
|
||||||
'PhabricatorApplicationSlowvote' => 'applications/slowvote/application/PhabricatorApplicationSlowvote.php',
|
'PhabricatorApplicationSlowvote' => 'applications/slowvote/application/PhabricatorApplicationSlowvote.php',
|
||||||
'PhabricatorApplicationStatusView' => 'applications/meta/view/PhabricatorApplicationStatusView.php',
|
'PhabricatorApplicationStatusView' => 'applications/meta/view/PhabricatorApplicationStatusView.php',
|
||||||
|
@ -1235,7 +1237,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPasteDAO' => 'applications/paste/storage/PhabricatorPasteDAO.php',
|
'PhabricatorPasteDAO' => 'applications/paste/storage/PhabricatorPasteDAO.php',
|
||||||
'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php',
|
'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php',
|
||||||
'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php',
|
'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php',
|
||||||
'PhabricatorPasteQueriesController' => 'applications/paste/controller/PhabricatorPasteQueriesController.php',
|
|
||||||
'PhabricatorPasteQuery' => 'applications/paste/query/PhabricatorPasteQuery.php',
|
'PhabricatorPasteQuery' => 'applications/paste/query/PhabricatorPasteQuery.php',
|
||||||
'PhabricatorPasteRemarkupRule' => 'applications/paste/remarkup/PhabricatorPasteRemarkupRule.php',
|
'PhabricatorPasteRemarkupRule' => 'applications/paste/remarkup/PhabricatorPasteRemarkupRule.php',
|
||||||
'PhabricatorPasteSearchEngine' => 'applications/paste/query/PhabricatorPasteSearchEngine.php',
|
'PhabricatorPasteSearchEngine' => 'applications/paste/query/PhabricatorPasteSearchEngine.php',
|
||||||
|
@ -2530,6 +2531,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationReleephConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorApplicationReleephConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorApplicationRepositories' => 'PhabricatorApplication',
|
'PhabricatorApplicationRepositories' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationSearch' => 'PhabricatorApplication',
|
'PhabricatorApplicationSearch' => 'PhabricatorApplication',
|
||||||
|
'PhabricatorApplicationSearchController' => 'PhabricatorSearchBaseController',
|
||||||
'PhabricatorApplicationSettings' => 'PhabricatorApplication',
|
'PhabricatorApplicationSettings' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationSlowvote' => 'PhabricatorApplication',
|
'PhabricatorApplicationSlowvote' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationStatusView' => 'AphrontView',
|
'PhabricatorApplicationStatusView' => 'AphrontView',
|
||||||
|
@ -3016,8 +3018,11 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPasteController' => 'PhabricatorController',
|
'PhabricatorPasteController' => 'PhabricatorController',
|
||||||
'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorPasteEditController' => 'PhabricatorPasteController',
|
'PhabricatorPasteEditController' => 'PhabricatorPasteController',
|
||||||
'PhabricatorPasteListController' => 'PhabricatorPasteController',
|
'PhabricatorPasteListController' =>
|
||||||
'PhabricatorPasteQueriesController' => 'PhabricatorPasteController',
|
array(
|
||||||
|
0 => 'PhabricatorPasteController',
|
||||||
|
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
|
||||||
|
),
|
||||||
'PhabricatorPasteQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorPasteQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorPasteRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
'PhabricatorPasteRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
||||||
'PhabricatorPasteSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
'PhabricatorPasteSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
|
|
|
@ -7,6 +7,18 @@ abstract class AphrontController extends Phobject {
|
||||||
|
|
||||||
private $request;
|
private $request;
|
||||||
private $currentApplication;
|
private $currentApplication;
|
||||||
|
private $delegatingController;
|
||||||
|
|
||||||
|
|
||||||
|
public function setDelegatingController(
|
||||||
|
AphrontController $delegating_controller) {
|
||||||
|
$this->delegatingController = $delegating_controller;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDelegatingController() {
|
||||||
|
return $this->delegatingController;
|
||||||
|
}
|
||||||
|
|
||||||
public function willBeginExecution() {
|
public function willBeginExecution() {
|
||||||
return;
|
return;
|
||||||
|
@ -31,6 +43,13 @@ abstract class AphrontController extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function delegateToController(AphrontController $controller) {
|
final public function delegateToController(AphrontController $controller) {
|
||||||
|
$controller->setDelegatingController($this);
|
||||||
|
|
||||||
|
$application = $this->getCurrentApplication();
|
||||||
|
if ($application) {
|
||||||
|
$controller->setCurrentApplication($application);
|
||||||
|
}
|
||||||
|
|
||||||
return $controller->processRequest();
|
return $controller->processRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,9 @@ final class PhabricatorApplicationPaste extends PhabricatorApplication {
|
||||||
return array(
|
return array(
|
||||||
'/P(?P<id>[1-9]\d*)' => 'PhabricatorPasteViewController',
|
'/P(?P<id>[1-9]\d*)' => 'PhabricatorPasteViewController',
|
||||||
'/paste/' => array(
|
'/paste/' => array(
|
||||||
'' => 'PhabricatorPasteListController',
|
'(query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorPasteListController',
|
||||||
'create/' => 'PhabricatorPasteEditController',
|
'create/' => 'PhabricatorPasteEditController',
|
||||||
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteEditController',
|
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteEditController',
|
||||||
'filter/(?P<filter>\w+)/' => 'PhabricatorPasteListController',
|
|
||||||
'query/(?P<queryKey>[^/]+)/'=> 'PhabricatorPasteListController',
|
|
||||||
'savedqueries/' => 'PhabricatorPasteQueriesController',
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,27 +12,9 @@ abstract class PhabricatorPasteController extends PhabricatorController {
|
||||||
$nav->addFilter('create', pht('Create Paste'));
|
$nav->addFilter('create', pht('Create Paste'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$nav->addLabel(pht('Queries'));
|
id(new PhabricatorPasteSearchEngine())
|
||||||
|
|
||||||
$engine = id(new PhabricatorPasteSearchEngine())
|
|
||||||
->setViewer($user);
|
|
||||||
|
|
||||||
$named_queries = id(new PhabricatorNamedQueryQuery())
|
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withUserPHIDs(array($user->getPHID()))
|
->addNavigationItems($nav);
|
||||||
->withEngineClassNames(array(get_class($engine)))
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$named_queries = $named_queries + $engine->getBuiltinQueries($user);
|
|
||||||
|
|
||||||
foreach ($named_queries as $query) {
|
|
||||||
$nav->addFilter('query/'.$query->getQueryKey(), $query->getQueryName());
|
|
||||||
}
|
|
||||||
|
|
||||||
$nav->addFilter('savedqueries', pht('Edit Queries...'));
|
|
||||||
|
|
||||||
$nav->addLabel(pht('Search'));
|
|
||||||
$nav->addFilter('query/advanced', pht('Advanced Search'));
|
|
||||||
|
|
||||||
$nav->selectFilter(null);
|
$nav->selectFilter(null);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class PhabricatorPasteListController extends PhabricatorPasteController {
|
final class PhabricatorPasteListController extends PhabricatorPasteController
|
||||||
|
implements PhabricatorApplicationSearchResultsControllerInterface {
|
||||||
|
|
||||||
private $queryKey;
|
private $queryKey;
|
||||||
|
|
||||||
|
@ -14,128 +15,15 @@ final class PhabricatorPasteListController extends PhabricatorPasteController {
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$user = $request->getUser();
|
$controller = id(new PhabricatorApplicationSearchController($request))
|
||||||
|
->setQueryKey($this->queryKey)
|
||||||
|
->setSearchEngine(new PhabricatorPasteSearchEngine())
|
||||||
|
->setNavigation($this->buildSideNavView());
|
||||||
|
|
||||||
$engine = id(new PhabricatorPasteSearchEngine())
|
return $this->delegateToController($controller);
|
||||||
->setViewer($user);
|
|
||||||
|
|
||||||
if ($request->isFormPost()) {
|
|
||||||
return id(new AphrontRedirectResponse())->setURI(
|
|
||||||
$engine->getQueryResultsPageURI(
|
|
||||||
$engine->buildSavedQueryFromRequest($request)->getQueryKey()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$nav = $this->buildSideNavView();
|
public function renderResultsList(array $pastes) {
|
||||||
|
|
||||||
$named_query = null;
|
|
||||||
$run_query = true;
|
|
||||||
$query_key = $this->queryKey;
|
|
||||||
if ($this->queryKey == 'advanced') {
|
|
||||||
$run_query = false;
|
|
||||||
$query_key = $request->getStr('query');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($engine->isBuiltinQuery($query_key)) {
|
|
||||||
$saved_query = $engine->buildSavedQueryFromBuiltin($query_key);
|
|
||||||
$named_query = $engine->getBuiltinQuery($query_key);
|
|
||||||
} else if ($query_key) {
|
|
||||||
$saved_query = id(new PhabricatorSavedQueryQuery())
|
|
||||||
->setViewer($user)
|
|
||||||
->withQueryKeys(array($query_key))
|
|
||||||
->executeOne();
|
|
||||||
|
|
||||||
if (!$saved_query) {
|
|
||||||
return new Aphront404Response();
|
|
||||||
}
|
|
||||||
|
|
||||||
$named_query = id(new PhabricatorNamedQueryQuery())
|
|
||||||
->setViewer($user)
|
|
||||||
->withQueryKeys(array($saved_query->getQueryKey()))
|
|
||||||
->withEngineClassNames(array(get_class($engine)))
|
|
||||||
->withUserPHIDs(array($user->getPHID()))
|
|
||||||
->executeOne();
|
|
||||||
} else {
|
|
||||||
$saved_query = $engine->buildSavedQueryFromRequest($request);
|
|
||||||
}
|
|
||||||
|
|
||||||
$filter = $nav->selectFilter(
|
|
||||||
'query/'.$saved_query->getQueryKey(),
|
|
||||||
'query/advanced');
|
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
|
||||||
->setNoShading(true)
|
|
||||||
->setUser($user);
|
|
||||||
|
|
||||||
$engine->buildSearchForm($form, $saved_query);
|
|
||||||
|
|
||||||
$submit = id(new AphrontFormSubmitControl())
|
|
||||||
->setValue(pht('Execute Query'));
|
|
||||||
|
|
||||||
if ($run_query && !$named_query) {
|
|
||||||
$submit->addCancelButton(
|
|
||||||
'/search/edit/'.$saved_query->getQueryKey().'/',
|
|
||||||
pht('Save Custom Query...'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$form->appendChild($submit);
|
|
||||||
$filter_view = id(new AphrontListFilterView())->appendChild($form);
|
|
||||||
|
|
||||||
if ($run_query && $named_query) {
|
|
||||||
if ($named_query->getIsBuiltin()) {
|
|
||||||
$description = pht(
|
|
||||||
'Showing results for query "%s".',
|
|
||||||
$named_query->getQueryName());
|
|
||||||
} else {
|
|
||||||
$description = pht(
|
|
||||||
'Showing results for saved query "%s".',
|
|
||||||
$named_query->getQueryName());
|
|
||||||
}
|
|
||||||
|
|
||||||
$filter_view->setCollapsed(
|
|
||||||
pht('Edit Query...'),
|
|
||||||
pht('Hide Query'),
|
|
||||||
$description,
|
|
||||||
$this->getApplicationURI('query/advanced/?query='.$query_key));
|
|
||||||
}
|
|
||||||
|
|
||||||
$nav->appendChild($filter_view);
|
|
||||||
|
|
||||||
if ($run_query) {
|
|
||||||
$query = id(new PhabricatorPasteSearchEngine())
|
|
||||||
->buildQueryFromSavedQuery($saved_query);
|
|
||||||
|
|
||||||
$pager = new AphrontCursorPagerView();
|
|
||||||
$pager->readFromRequest($request);
|
|
||||||
$pastes = $query->setViewer($request->getUser())
|
|
||||||
->needContent(true)
|
|
||||||
->executeWithCursorPager($pager);
|
|
||||||
|
|
||||||
$list = $this->buildPasteList($pastes);
|
|
||||||
$list->setPager($pager);
|
|
||||||
$list->setNoDataString(pht("No results found for this query."));
|
|
||||||
|
|
||||||
$nav->appendChild($list);
|
|
||||||
}
|
|
||||||
|
|
||||||
$crumbs = $this
|
|
||||||
->buildApplicationCrumbs($nav)
|
|
||||||
->addCrumb(
|
|
||||||
id(new PhabricatorCrumbView())
|
|
||||||
->setName(pht("Pastes"))
|
|
||||||
->setHref($this->getApplicationURI('filter/'.$filter.'/')));
|
|
||||||
|
|
||||||
$nav->setCrumbs($crumbs);
|
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
|
||||||
$nav,
|
|
||||||
array(
|
|
||||||
'title' => pht("Pastes"),
|
|
||||||
'device' => true,
|
|
||||||
'dust' => true,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildPasteList(array $pastes) {
|
|
||||||
assert_instances_of($pastes, 'PhabricatorPaste');
|
assert_instances_of($pastes, 'PhabricatorPaste');
|
||||||
|
|
||||||
$user = $this->getRequest()->getUser();
|
$user = $this->getRequest()->getUser();
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class PhabricatorPasteQueriesController
|
|
||||||
extends PhabricatorPasteController {
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
|
||||||
|
|
||||||
$engine = id(new PhabricatorPasteSearchEngine())
|
|
||||||
->setViewer($user);
|
|
||||||
|
|
||||||
$nav = $this->buildSideNavView();
|
|
||||||
$nav->selectFilter('savedqueries');
|
|
||||||
|
|
||||||
$named_queries = id(new PhabricatorNamedQueryQuery())
|
|
||||||
->setViewer($user)
|
|
||||||
->withUserPHIDs(array($user->getPHID()))
|
|
||||||
->withEngineClassNames(array(get_class($engine)))
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$named_queries += $engine->getBuiltinQueries();
|
|
||||||
|
|
||||||
$list = new PhabricatorObjectItemListView();
|
|
||||||
$list->setUser($user);
|
|
||||||
|
|
||||||
foreach ($named_queries as $named_query) {
|
|
||||||
$date_created = phabricator_datetime(
|
|
||||||
$named_query->getDateCreated(),
|
|
||||||
$user);
|
|
||||||
|
|
||||||
$item = id(new PhabricatorObjectItemView())
|
|
||||||
->setHeader($named_query->getQueryName())
|
|
||||||
->setHref($engine->getQueryResultsPageURI($named_query->getQueryKey()));
|
|
||||||
|
|
||||||
if ($named_query->getIsBuiltin()) {
|
|
||||||
$item->addIcon('lock-grey', pht('Builtin'));
|
|
||||||
$item->setBarColor('grey');
|
|
||||||
} else {
|
|
||||||
$item->addIcon('none', $date_created);
|
|
||||||
$item->addAction(
|
|
||||||
id(new PhabricatorMenuItemView())
|
|
||||||
->setIcon('delete')
|
|
||||||
->setHref('/search/delete/'.$named_query->getQueryKey().'/')
|
|
||||||
->setWorkflow(true));
|
|
||||||
$item->addAction(
|
|
||||||
id(new PhabricatorMenuItemView())
|
|
||||||
->setIcon('edit')
|
|
||||||
->setHref('/search/edit/'.$named_query->getQueryKey().'/'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$list->addItem($item);
|
|
||||||
}
|
|
||||||
|
|
||||||
$list->setNoDataString(pht("No results found for this query."));
|
|
||||||
|
|
||||||
$nav->appendChild(
|
|
||||||
array(
|
|
||||||
$list,
|
|
||||||
));
|
|
||||||
|
|
||||||
$crumbs = $this
|
|
||||||
->buildApplicationCrumbs($nav)
|
|
||||||
->addCrumb(
|
|
||||||
id(new PhabricatorCrumbView())
|
|
||||||
->setName(pht("Saved Queries"))
|
|
||||||
->setHref($this->getApplicationURI('/savedqueries/')));
|
|
||||||
|
|
||||||
$nav->setCrumbs($crumbs);
|
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
|
||||||
$nav,
|
|
||||||
array(
|
|
||||||
'title' => pht("Saved Queries"),
|
|
||||||
'device' => true,
|
|
||||||
'dust' => true,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -70,12 +70,8 @@ final class PhabricatorPasteSearchEngine
|
||||||
->setValue($author_tokens));
|
->setValue($author_tokens));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueryResultsPageURI($query_key) {
|
protected function getURI($path) {
|
||||||
return '/paste/query/'.$query_key.'/';
|
return '/paste/'.$path;
|
||||||
}
|
|
||||||
|
|
||||||
public function getQueryManagementURI() {
|
|
||||||
return '/paste/savedqueries/';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBuiltinQueryNames() {
|
public function getBuiltinQueryNames() {
|
||||||
|
|
|
@ -0,0 +1,272 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorApplicationSearchController
|
||||||
|
extends PhabricatorSearchBaseController {
|
||||||
|
|
||||||
|
private $searchEngine;
|
||||||
|
private $navigation;
|
||||||
|
private $queryKey;
|
||||||
|
|
||||||
|
public function setQueryKey($query_key) {
|
||||||
|
$this->queryKey = $query_key;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getQueryKey() {
|
||||||
|
return $this->queryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setNavigation(AphrontSideNavFilterView $navigation) {
|
||||||
|
$this->navigation = $navigation;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getNavigation() {
|
||||||
|
return $this->navigation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSearchEngine(
|
||||||
|
PhabricatorApplicationSearchEngine $search_engine) {
|
||||||
|
$this->searchEngine = $search_engine;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getSearchEngine() {
|
||||||
|
return $this->searchEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function validateDelegatingController() {
|
||||||
|
$parent = $this->getDelegatingController();
|
||||||
|
|
||||||
|
if (!$parent) {
|
||||||
|
throw new Exception(
|
||||||
|
"You must delegate to this controller, not invoke it directly.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$engine = $this->getSearchEngine();
|
||||||
|
if (!$engine) {
|
||||||
|
throw new Exception(
|
||||||
|
"Call setEngine() before delegating to this controller!");
|
||||||
|
}
|
||||||
|
|
||||||
|
$nav = $this->getNavigation();
|
||||||
|
if (!$nav) {
|
||||||
|
throw new Exception(
|
||||||
|
"Call setNavigation() before delegating to this controller!");
|
||||||
|
}
|
||||||
|
|
||||||
|
$engine->setViewer($this->getRequest()->getUser());
|
||||||
|
|
||||||
|
$parent = $this->getDelegatingController();
|
||||||
|
$interface = 'PhabricatorApplicationSearchResultsControllerInterface';
|
||||||
|
if (!$parent instanceof $interface) {
|
||||||
|
throw new Exception(
|
||||||
|
"Delegating controller must implement '{$interface}'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$this->validateDelegatingController();
|
||||||
|
|
||||||
|
$key = $this->getQueryKey();
|
||||||
|
if ($key == 'edit') {
|
||||||
|
return $this->processEditRequest();
|
||||||
|
} else {
|
||||||
|
return $this->processSearchRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processSearchRequest() {
|
||||||
|
$parent = $this->getDelegatingController();
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
$engine = $this->getSearchEngine();
|
||||||
|
$nav = $this->getNavigation();
|
||||||
|
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
return id(new AphrontRedirectResponse())->setURI(
|
||||||
|
$engine->getQueryResultsPageURI(
|
||||||
|
$engine->buildSavedQueryFromRequest($request)->getQueryKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$named_query = null;
|
||||||
|
$run_query = true;
|
||||||
|
$query_key = $this->queryKey;
|
||||||
|
if ($this->queryKey == 'advanced') {
|
||||||
|
$run_query = false;
|
||||||
|
$query_key = $request->getStr('query');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($engine->isBuiltinQuery($query_key)) {
|
||||||
|
$saved_query = $engine->buildSavedQueryFromBuiltin($query_key);
|
||||||
|
$named_query = $engine->getBuiltinQuery($query_key);
|
||||||
|
} else if ($query_key) {
|
||||||
|
$saved_query = id(new PhabricatorSavedQueryQuery())
|
||||||
|
->setViewer($user)
|
||||||
|
->withQueryKeys(array($query_key))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if (!$saved_query) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$named_query = id(new PhabricatorNamedQueryQuery())
|
||||||
|
->setViewer($user)
|
||||||
|
->withQueryKeys(array($saved_query->getQueryKey()))
|
||||||
|
->withEngineClassNames(array(get_class($engine)))
|
||||||
|
->withUserPHIDs(array($user->getPHID()))
|
||||||
|
->executeOne();
|
||||||
|
} else {
|
||||||
|
$saved_query = $engine->buildSavedQueryFromRequest($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
$nav->selectFilter(
|
||||||
|
'query/'.$saved_query->getQueryKey(),
|
||||||
|
'query/advanced');
|
||||||
|
|
||||||
|
$form = id(new AphrontFormView())
|
||||||
|
->setNoShading(true)
|
||||||
|
->setUser($user);
|
||||||
|
|
||||||
|
$engine->buildSearchForm($form, $saved_query);
|
||||||
|
|
||||||
|
$submit = id(new AphrontFormSubmitControl())
|
||||||
|
->setValue(pht('Execute Query'));
|
||||||
|
|
||||||
|
if ($run_query && !$named_query) {
|
||||||
|
$submit->addCancelButton(
|
||||||
|
'/search/edit/'.$saved_query->getQueryKey().'/',
|
||||||
|
pht('Save Custom Query...'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$form->appendChild($submit);
|
||||||
|
$filter_view = id(new AphrontListFilterView())->appendChild($form);
|
||||||
|
|
||||||
|
if ($run_query && $named_query) {
|
||||||
|
if ($named_query->getIsBuiltin()) {
|
||||||
|
$description = pht(
|
||||||
|
'Showing results for query "%s".',
|
||||||
|
$named_query->getQueryName());
|
||||||
|
} else {
|
||||||
|
$description = pht(
|
||||||
|
'Showing results for saved query "%s".',
|
||||||
|
$named_query->getQueryName());
|
||||||
|
}
|
||||||
|
|
||||||
|
$filter_view->setCollapsed(
|
||||||
|
pht('Edit Query...'),
|
||||||
|
pht('Hide Query'),
|
||||||
|
$description,
|
||||||
|
$this->getApplicationURI('query/advanced/?query='.$query_key));
|
||||||
|
}
|
||||||
|
|
||||||
|
$nav->appendChild($filter_view);
|
||||||
|
|
||||||
|
if ($run_query) {
|
||||||
|
$query = id(new PhabricatorPasteSearchEngine())
|
||||||
|
->buildQueryFromSavedQuery($saved_query);
|
||||||
|
|
||||||
|
$pager = new AphrontCursorPagerView();
|
||||||
|
$pager->readFromRequest($request);
|
||||||
|
$pastes = $query->setViewer($request->getUser())
|
||||||
|
->needContent(true)
|
||||||
|
->executeWithCursorPager($pager);
|
||||||
|
|
||||||
|
$list = $parent->renderResultsList($pastes);
|
||||||
|
$list->setPager($pager);
|
||||||
|
$list->setNoDataString(pht("No results found for this query."));
|
||||||
|
|
||||||
|
$nav->appendChild($list);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($named_query) {
|
||||||
|
$title = pht('Query: %s', $named_query->getQueryName());
|
||||||
|
} else {
|
||||||
|
$title = pht('Advanced Search');
|
||||||
|
}
|
||||||
|
|
||||||
|
$crumbs = $parent
|
||||||
|
->buildApplicationCrumbs()
|
||||||
|
->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName(pht("Search")));
|
||||||
|
|
||||||
|
$nav->setCrumbs($crumbs);
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
$nav,
|
||||||
|
array(
|
||||||
|
'title' => $title,
|
||||||
|
'device' => true,
|
||||||
|
'dust' => true,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processEditRequest() {
|
||||||
|
$parent = $this->getDelegatingController();
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
$engine = $this->getSearchEngine();
|
||||||
|
$nav = $this->getNavigation();
|
||||||
|
|
||||||
|
$named_queries = id(new PhabricatorNamedQueryQuery())
|
||||||
|
->setViewer($user)
|
||||||
|
->withUserPHIDs(array($user->getPHID()))
|
||||||
|
->withEngineClassNames(array(get_class($engine)))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$named_queries += $engine->getBuiltinQueries();
|
||||||
|
|
||||||
|
$list = new PhabricatorObjectItemListView();
|
||||||
|
$list->setUser($user);
|
||||||
|
|
||||||
|
foreach ($named_queries as $named_query) {
|
||||||
|
$date_created = phabricator_datetime(
|
||||||
|
$named_query->getDateCreated(),
|
||||||
|
$user);
|
||||||
|
|
||||||
|
$item = id(new PhabricatorObjectItemView())
|
||||||
|
->setHeader($named_query->getQueryName())
|
||||||
|
->setHref($engine->getQueryResultsPageURI($named_query->getQueryKey()));
|
||||||
|
|
||||||
|
if ($named_query->getIsBuiltin()) {
|
||||||
|
$item->addIcon('lock-grey', pht('Builtin'));
|
||||||
|
$item->setBarColor('grey');
|
||||||
|
} else {
|
||||||
|
$item->addIcon('none', $date_created);
|
||||||
|
$item->addAction(
|
||||||
|
id(new PhabricatorMenuItemView())
|
||||||
|
->setIcon('delete')
|
||||||
|
->setHref('/search/delete/'.$named_query->getQueryKey().'/')
|
||||||
|
->setWorkflow(true));
|
||||||
|
$item->addAction(
|
||||||
|
id(new PhabricatorMenuItemView())
|
||||||
|
->setIcon('edit')
|
||||||
|
->setHref('/search/edit/'.$named_query->getQueryKey().'/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$list->addItem($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
$list->setNoDataString(pht('No saved queries.'));
|
||||||
|
|
||||||
|
$crumbs = $parent
|
||||||
|
->buildApplicationCrumbs()
|
||||||
|
->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName(pht("Saved Queries"))
|
||||||
|
->setHref($engine->getQueryManagementURI()));
|
||||||
|
|
||||||
|
$nav->selectFilter('query/edit');
|
||||||
|
$nav->setCrumbs($crumbs);
|
||||||
|
$nav->appendChild($list);
|
||||||
|
|
||||||
|
return $parent->buildApplicationPage(
|
||||||
|
$nav,
|
||||||
|
array(
|
||||||
|
'title' => pht("Saved Queries"),
|
||||||
|
'device' => true,
|
||||||
|
'dust' => true,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -63,7 +63,9 @@ abstract class PhabricatorApplicationSearchEngine {
|
||||||
* @return string URI where the query can be executed.
|
* @return string URI where the query can be executed.
|
||||||
* @task uri
|
* @task uri
|
||||||
*/
|
*/
|
||||||
abstract public function getQueryResultsPageURI($query_key);
|
public function getQueryResultsPageURI($query_key) {
|
||||||
|
return $this->getURI('query/'.$query_key.'/');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +75,19 @@ abstract class PhabricatorApplicationSearchEngine {
|
||||||
* @return string URI where queries can be managed.
|
* @return string URI where queries can be managed.
|
||||||
* @task uri
|
* @task uri
|
||||||
*/
|
*/
|
||||||
abstract public function getQueryManagementURI();
|
public function getQueryManagementURI() {
|
||||||
|
return $this->getURI('query/edit/');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the URI to a path within the application. Used to construct default
|
||||||
|
* URIs for management and results.
|
||||||
|
*
|
||||||
|
* @return string URI to path.
|
||||||
|
* @task uri
|
||||||
|
*/
|
||||||
|
abstract protected function getURI($path);
|
||||||
|
|
||||||
|
|
||||||
public function newSavedQuery() {
|
public function newSavedQuery() {
|
||||||
|
@ -82,6 +96,36 @@ abstract class PhabricatorApplicationSearchEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function addNavigationItems(AphrontSideNavFilterView $nav) {
|
||||||
|
$viewer = $this->requireViewer();
|
||||||
|
|
||||||
|
$nav->addLabel(pht('Queries'));
|
||||||
|
|
||||||
|
$named_queries = id(new PhabricatorNamedQueryQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withUserPHIDs(array($viewer->getPHID()))
|
||||||
|
->withEngineClassNames(array(get_class($this)))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$named_queries = $named_queries + $this->getBuiltinQueries($viewer);
|
||||||
|
|
||||||
|
foreach ($named_queries as $query) {
|
||||||
|
$key = $query->getQueryKey();
|
||||||
|
$uri = $this->getQueryResultsPageURI($key);
|
||||||
|
$nav->addFilter('query/'.$key, $query->getQueryName(), $uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
$manage_uri = $this->getQueryManagementURI();
|
||||||
|
$nav->addFilter('query/edit', pht('Edit Queries...'), $manage_uri);
|
||||||
|
|
||||||
|
$nav->addLabel(pht('Search'));
|
||||||
|
$advanced_uri = $this->getQueryResultsPageURI('advanced');
|
||||||
|
$nav->addFilter('query/advanced', pht('Advanced Search'), $advanced_uri);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( Builtin Queries )---------------------------------------------------- */
|
/* -( Builtin Queries )---------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
interface PhabricatorApplicationSearchResultsControllerInterface {
|
||||||
|
|
||||||
|
public function renderResultsList(array $items);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue