diff --git a/src/applications/search/controller/PhabricatorSearchController.php b/src/applications/search/controller/PhabricatorSearchController.php index 1b22ad1a2f..cc05e9c5f4 100644 --- a/src/applications/search/controller/PhabricatorSearchController.php +++ b/src/applications/search/controller/PhabricatorSearchController.php @@ -1,121 +1,122 @@ queryKey = idx($data, 'queryKey'); } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); if ($request->getStr('jump') != 'no') { $pref_jump = PhabricatorUserPreferences::PREFERENCE_SEARCHBAR_JUMP; if ($viewer->loadPreferences($pref_jump, 1)) { $response = PhabricatorJumpNavHandler::getJumpResponse( $viewer, $request->getStr('query')); if ($response) { return $response; } } } $engine = new PhabricatorSearchApplicationSearchEngine(); $engine->setViewer($viewer); // If we're coming from primary search, do some special handling to // interpret the scope selector and query. if ($request->getBool('search:primary')) { // If there's no query, just take the user to advanced search. if (!strlen($request->getStr('query'))) { $advanced_uri = '/search/query/advanced/'; return id(new AphrontRedirectResponse())->setURI($advanced_uri); } // First, load or construct a template for the search by examining // the current search scope. $scope = $request->getStr('search:scope'); $saved = null; if ($scope == self::SCOPE_CURRENT_APPLICATION) { $application = id(new PhabricatorApplicationQuery()) ->setViewer($viewer) ->withClasses(array($request->getStr('search:application'))) ->executeOne(); if ($application) { $types = $application->getApplicationSearchDocumentTypes(); if ($types) { $saved = id(new PhabricatorSavedQuery()) ->setEngineClassName(get_class($engine)) - ->setParameter('types', $types); + ->setParameter('types', $types) + ->setParameter('statuses', array('open')); } } } if (!$saved && !$engine->isBuiltinQuery($scope)) { $saved = id(new PhabricatorSavedQueryQuery()) ->setViewer($viewer) ->withQueryKeys(array($scope)) ->executeOne(); } if (!$saved) { if (!$engine->isBuiltinQuery($scope)) { $scope = 'all'; } $saved = $engine->buildSavedQueryFromBuiltin($scope); } // Add the user's query, then save this as a new saved query and send // the user to the results page. $saved->setParameter('query', $request->getStr('query')); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); try { $saved->setID(null)->save(); } catch (AphrontDuplicateKeyQueryException $ex) { // Ignore, this is just a repeated search. } unset($unguarded); $query_key = $saved->getQueryKey(); $results_uri = $engine->getQueryResultsPageURI($query_key).'#R'; return id(new AphrontRedirectResponse())->setURI($results_uri); } $controller = id(new PhabricatorApplicationSearchController()) ->setQueryKey($this->queryKey) ->setSearchEngine($engine) ->setNavigation($this->buildSideNavView()); return $this->delegateToController($controller); } public function buildSideNavView($for_app = false) { $viewer = $this->getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); id(new PhabricatorSearchApplicationSearchEngine()) ->setViewer($viewer) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } } diff --git a/src/view/page/menu/PhabricatorMainMenuSearchView.php b/src/view/page/menu/PhabricatorMainMenuSearchView.php index 3373cdc653..700f9db445 100644 --- a/src/view/page/menu/PhabricatorMainMenuSearchView.php +++ b/src/view/page/menu/PhabricatorMainMenuSearchView.php @@ -1,223 +1,223 @@ application = $application; return $this; } public function getApplication() { return $this->application; } public function getID() { if (!$this->id) { $this->id = celerity_generate_unique_node_id(); } return $this->id; } public function render() { $user = $this->user; $target_id = celerity_generate_unique_node_id(); $search_id = $this->getID(); $button_id = celerity_generate_unique_node_id(); $input = phutil_tag( 'input', array( 'type' => 'text', 'name' => 'query', 'id' => $search_id, 'autocomplete' => 'off', )); $target = javelin_tag( 'div', array( 'id' => $target_id, 'class' => 'phabricator-main-menu-search-target', ), ''); $search_datasource = new PhabricatorSearchDatasource(); $scope_key = PhabricatorUserPreferences::PREFERENCE_SEARCH_SCOPE; Javelin::initBehavior( 'phabricator-search-typeahead', array( 'id' => $target_id, 'input' => $search_id, 'button' => $button_id, 'src' => $search_datasource->getDatasourceURI(), 'limit' => 10, 'placeholder' => pht('Search'), 'scopeUpdateURI' => '/settings/adjust/?key='.$scope_key, )); $primary_input = phutil_tag( 'input', array( 'type' => 'hidden', 'name' => 'search:primary', 'value' => 'true', )); $search_text = javelin_tag( 'span', array( 'aural' => true, ), pht('Search')); $selector = $this->buildModeSelector(); $form = phabricator_form( $user, array( 'action' => '/search/', 'method' => 'POST', ), phutil_tag_div('phabricator-main-menu-search-container', array( $input, phutil_tag( 'button', array( 'id' => $button_id, 'class' => 'phui-icon-view phui-font-fa fa-search', ), $search_text), $selector, $primary_input, $target, ))); return $form; } private function buildModeSelector() { $viewer = $this->getUser(); $items = array(); $items[] = array( 'name' => pht('Search'), ); $items[] = array( 'icon' => 'fa-globe', 'name' => pht('Search All Documents'), 'value' => 'all', ); $application_value = null; $application_icon = 'fa-file-o'; $application = $this->getApplication(); if ($application) { $application_value = get_class($application); if ($application->getApplicationSearchDocumentTypes()) { $application_icon = $application->getFontIcon(); } } $items[] = array( 'icon' => $application_icon, 'name' => pht('Search Current Application'), 'value' => PhabricatorSearchController::SCOPE_CURRENT_APPLICATION, ); $items[] = array( 'name' => pht('Saved Queries'), ); $engine = id(new PhabricatorSearchApplicationSearchEngine()) ->setViewer($viewer); $engine_queries = $engine->loadEnabledNamedQueries(); $query_map = mpull($engine_queries, 'getQueryName', 'getQueryKey'); foreach ($query_map as $query_key => $query_name) { if ($query_key == 'all') { // Skip the builtin "All" query since it's redundant with the default // setting. continue; } $items[] = array( - 'icon' => 'fa-search', + 'icon' => 'fa-certificate', 'name' => $query_name, 'value' => $query_key, ); } $items[] = array( 'name' => pht('More Options'), ); $items[] = array( 'icon' => 'fa-search-plus', 'name' => pht('Advanced Search'), 'href' => '/search/query/advanced/', ); /* TODO: Write this. $items[] = array( 'icon' => 'fa-book', 'name' => pht('User Guide: Search'), 'href' => PhabricatorEnv::getDoclink('User Guide: Search'), ); */ $scope_key = PhabricatorUserPreferences::PREFERENCE_SEARCH_SCOPE; $current_value = $viewer->loadPreferences()->getPreference( $scope_key, 'all'); $current_icon = 'fa-globe'; foreach ($items as $item) { if (idx($item, 'value') == $current_value) { $current_icon = $item['icon']; break; } } $selector = id(new PHUIButtonView()) ->addClass('phabricator-main-menu-search-dropdown') ->addSigil('global-search-dropdown') ->setMetadata( array( 'items' => $items, 'icon' => $current_icon, 'value' => $current_value, )) ->setIcon( id(new PHUIIconView()) ->addSigil('global-search-dropdown-icon') ->setIconFont($current_icon)) ->setDropdown(true); $input = javelin_tag( 'input', array( 'type' => 'hidden', 'sigil' => 'global-search-dropdown-input', 'name' => 'search:scope', 'value' => $current_value, )); $application_input = javelin_tag( 'input', array( 'type' => 'hidden', 'sigil' => 'global-search-dropdown-app', 'name' => 'search:application', 'value' => $application_value, )); return array($selector, $input, $application_input); } }