@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PhabricatorSearchController
4 extends PhabricatorSearchBaseController {
5
6 const SCOPE_CURRENT_APPLICATION = 'application';
7
8 public function shouldAllowPublic() {
9 return true;
10 }
11
12 /**
13 * @return PhabricatorStandardPageView|AphrontRedirectResponse
14 */
15 public function handleRequest(AphrontRequest $request) {
16 $viewer = $this->getViewer();
17 $query = $request->getStr('query');
18
19 if ($request->getStr('jump') != 'no' && phutil_nonempty_string($query)) {
20 $jump_uri = id(new PhabricatorDatasourceEngine())
21 ->setViewer($viewer)
22 ->newJumpURI($query);
23
24 if ($jump_uri !== null) {
25 return id(new AphrontRedirectResponse())->setURI($jump_uri);
26 }
27 }
28
29 $engine = new PhabricatorSearchApplicationSearchEngine();
30 $engine->setViewer($viewer);
31
32 // If we're coming from primary search, do some special handling to
33 // interpret the scope selector and query.
34 if ($request->getBool('search:primary')) {
35
36 // If there's no query, just take the user to advanced search.
37 if (!phutil_nonempty_string($query)) {
38 $advanced_uri = '/search/query/advanced/';
39 return id(new AphrontRedirectResponse())->setURI($advanced_uri);
40 }
41
42 // First, load or construct a template for the search by examining
43 // the current search scope.
44 $scope = $request->getStr('search:scope');
45 $saved = null;
46
47 if ($scope == self::SCOPE_CURRENT_APPLICATION) {
48 $application = id(new PhabricatorApplicationQuery())
49 ->setViewer($viewer)
50 ->withClasses(array($request->getStr('search:application')))
51 ->executeOne();
52 if ($application) {
53 $types = $application->getApplicationSearchDocumentTypes();
54 if ($types) {
55 $saved = id(new PhabricatorSavedQuery())
56 ->setEngineClassName(get_class($engine))
57 ->setParameter('types', $types)
58 ->setParameter('statuses', array('open'));
59 }
60 }
61 }
62
63 if (!$saved && !$engine->isBuiltinQuery($scope)) {
64 $saved = id(new PhabricatorSavedQueryQuery())
65 ->setViewer($viewer)
66 ->withQueryKeys(array($scope))
67 ->executeOne();
68 }
69
70 if (!$saved) {
71 if (!$engine->isBuiltinQuery($scope)) {
72 $scope = 'all';
73 }
74 $saved = $engine->buildSavedQueryFromBuiltin($scope);
75 }
76
77 // Add the user's query, then save this as a new saved query and send
78 // the user to the results page.
79 $saved->setParameter('query', $query);
80
81 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
82 try {
83 $saved->setID(null)->save();
84 } catch (AphrontDuplicateKeyQueryException $ex) {
85 // Ignore, this is just a repeated search.
86 }
87 unset($unguarded);
88
89 $query_key = $saved->getQueryKey();
90 $results_uri = $engine->getQueryResultsPageURI($query_key).'#R';
91 return id(new AphrontRedirectResponse())->setURI($results_uri);
92 }
93
94 $controller = id(new PhabricatorApplicationSearchController())
95 ->setQueryKey($request->getURIData('queryKey'))
96 ->setSearchEngine($engine)
97 ->setNavigation($this->buildSideNavView());
98
99 return $this->delegateToController($controller);
100 }
101
102 /**
103 * @return AphrontSideNavFilterView
104 */
105 public function buildSideNavView($for_app = false) {
106 $viewer = $this->getViewer();
107
108 $nav = new AphrontSideNavFilterView();
109 $nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
110
111 id(new PhabricatorSearchApplicationSearchEngine())
112 ->setViewer($viewer)
113 ->addNavigationItems($nav->getMenu());
114
115 $nav->selectFilter(null);
116
117 return $nav;
118 }
119
120}