diff --git a/core/modules/search/lib/Drupal/search/Controller/SearchController.php b/core/modules/search/lib/Drupal/search/Controller/SearchController.php index 8622341..18f38e3 100644 --- a/core/modules/search/lib/Drupal/search/Controller/SearchController.php +++ b/core/modules/search/lib/Drupal/search/Controller/SearchController.php @@ -7,25 +7,122 @@ namespace Drupal\search\Controller; +use Drupal\Core\Controller\ControllerBase; +use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\Core\Form\FormBuilderInterface; +use Drupal\search\SearchPluginManager; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; + /** * Route controller for search. */ -class SearchController { +class SearchController extends ControllerBase implements ContainerInjectionInterface { + + /** + * The search plugin manager. + * + * @var \Drupal\search\SearchPluginManager + */ + protected $searchManager; + + /** + * The form builder. + * + * @var \Drupal\Core\Form\FormBuilderInterface + */ + protected $formBuilder; + + /** + * Constructs a new search controller. + * + * @param \Drupal\search\SearchPluginManager $search_plugin_manager + * The search plugin manager. + * @param \Drupal\Core\Form\FormBuilderInterface $form_builder + * The form builder. + */ + public function __construct(SearchPluginManager $search_plugin_manager, FormBuilderInterface $form_builder) { + $this->searchManager = $search_plugin_manager; + $this->formBuilder = $form_builder; + } /** - * @todo Remove search_view(). + * {@inheritdoc} */ - public function searchView($keys) { - module_load_include('pages.inc', 'search'); - return search_view(NULL, $keys); + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin.manager.search'), + $container->get('form_builder') + ); } /** - * @todo Remove search_view(). + * Creates a render array for the search page. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object. + * @param string $plugin_id + * The ID of a search plugin. + * @param string $keys + * Search keywords. + * + * @return array|\Symfony\Component\HttpFoundation\RedirectResponse + * The search form and search results or redirect response. */ - public function searchViewPlugin($plugin_id, $keys) { - module_load_include('pages.inc', 'search'); - return search_view($plugin_id, $keys); + public function view(Request $request, $plugin_id = NULL, $keys = NULL) { + $info = FALSE; + $keys = trim($keys); + // Also try to pull search keywords out of the $_REQUEST variable to + // support old GET format of searches for existing links. + if (!$keys && $request->query->has('keys')) { + $keys = trim($request->query->get('keys')); + } + + if (!empty($plugin_id)) { + $active_plugin_info = $this->searchManager->getActiveDefinitions(); + if (isset($active_plugin_info[$plugin_id])) { + $info = $active_plugin_info[$plugin_id]; + } + } + + if (empty($plugin_id) || empty($info)) { + // No path or invalid path: find the default plugin. Note that if there + // are no enabled search plugins, this function should never be called, + // since hook_menu() would not have defined any search paths. + $info = search_get_default_plugin_info(); + // Redirect from bare /search or an invalid path to the default search + // path. + $path = 'search/' . $info['path']; + if ($keys) { + $path .= '/' . $keys; + } + + return $this->redirect('search.view_' . $info['id']); + } + $plugin = $this->searchManager->createInstance($plugin_id); + $plugin->setSearch($keys, $request->query->all(), $request->attributes->all()); + // Default results output is an empty string. + $results = array('#markup' => ''); + + // Process the search form. Note that if there is $_POST data, + // search_form_submit() will cause a redirect to search/[path]/[keys], + // which will get us back to this page callback. In other words, the search + // form submits with POST but redirects to GET. This way we can keep + // the search query URL clean as a whistle. + if ($request->request->has('form_id') || $request->request->get('form_id') != 'search_form') { + // Only search if there are keywords or non-empty conditions. + if ($plugin->isSearchExecutable()) { + // Log the search keys. + watchdog('search', 'Searched %type for %keys.', array('%keys' => $keys, '%type' => $info['title']), WATCHDOG_NOTICE, l(t('results'), 'search/' . $info['path'] . '/' . $keys)); + + // Collect the search results. + $results = $plugin->buildResults(); + } + } + // The form may be altered based on whether the search was run. + $build['search_form'] = $this->formBuilder->getForm('\Drupal\search\Form\SearchForm', $plugin); + $build['search_results'] = $results; + return $build; } } diff --git a/core/modules/search/lib/Drupal/search/Form/SearchForm.php b/core/modules/search/lib/Drupal/search/Form/SearchForm.php new file mode 100644 index 0000000..4101502 --- /dev/null +++ b/core/modules/search/lib/Drupal/search/Form/SearchForm.php @@ -0,0 +1,121 @@ +get('plugin.manager.search') + ); + } + + /** + * Constructs a search form. + * + * @param \Drupal\search\SearchPluginManager $search_plugin + * The search plugin manager. + */ + public function __construct(SearchPluginManager $search_plugin) { + $this->searchManager = $search_plugin; + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'search_form'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state, SearchInterface $plugin = NULL, $action = '', $prompt = NULL) { + $plugin_info = $plugin->getPluginDefinition(); + + if (!$action) { + $action = 'search/' . $plugin_info['path']; + } + if (!isset($prompt)) { + $prompt = $this->t('Enter your keywords'); + } + + $form['#action'] = $this->urlGenerator()->generateFromPath($action); + // Record the $action for later use in redirecting. + $form_state['action'] = $action; + $form['plugin_id'] = array( + '#type' => 'value', + '#value' => $plugin->getPluginId(), + ); + $form['basic'] = array( + '#type' => 'container', + '#attributes' => array( + 'class' => array('container-inline'), + ), + ); + $form['basic']['keys'] = array( + '#type' => 'search', + '#title' => $prompt, + '#default_value' => $plugin->getKeywords(), + '#size' => $prompt ? 40 : 20, + '#maxlength' => 255, + ); + // processed_keys is used to coordinate keyword passing between other forms + // that hook into the basic search form. + $form['basic']['processed_keys'] = array( + '#type' => 'value', + '#value' => '', + ); + $form['basic']['submit'] = array( + '#type' => 'submit', + '#value' => $this->t('Search'), + ); + // Allow the plugin to add to or alter the search form. + $plugin->searchFormAlter($form, $form_state); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, array &$form_state) { + form_set_value($form['basic']['processed_keys'], trim($form_state['values']['keys']), $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $keys = $form_state['values']['processed_keys']; + if ($keys == '') { + form_set_error('keys', t('Please enter some keywords.')); + // Fall through to the form redirect. + } + + $form_state['redirect'] = $form_state['action'] . '/' . $keys; + } +} diff --git a/core/modules/search/lib/Drupal/search/Routing/SearchRouteSubscriber.php b/core/modules/search/lib/Drupal/search/Routing/SearchRouteSubscriber.php index 0061d83..dfb634c 100644 --- a/core/modules/search/lib/Drupal/search/Routing/SearchRouteSubscriber.php +++ b/core/modules/search/lib/Drupal/search/Routing/SearchRouteSubscriber.php @@ -41,7 +41,7 @@ protected function routes(RouteCollection $collection) { foreach ($this->searchManager->getActiveDefinitions() as $plugin_id => $search_info) { $path = 'search/' . $search_info['path'] . '/{keys}'; $defaults = array( - '_content' => 'Drupal\search\Controller\SearchController::searchViewPlugin', + '_content' => 'Drupal\search\Controller\SearchController::view', 'plugin_id' => $plugin_id, 'keys' => '', ); diff --git a/core/modules/search/search.module b/core/modules/search/search.module index c7bed06..3fc2953 100644 --- a/core/modules/search/search.module +++ b/core/modules/search/search.module @@ -207,21 +207,6 @@ function search_get_default_plugin_info() { } /** - * Access callback: Determines access for a search page. - * - * @param string $plugin_id - * The name of a search plugin (e.g., 'node_search'). - * - * @return bool - * TRUE if a user has access to the search page; FALSE otherwise. - * - * @see search_menu() - */ -function _search_menu_access($plugin_id) { - return \Drupal::service('access_manager')->checkNamedRoute('search.view_' . $plugin_id); -} - -/** * Clears either a part of, or the entire search index. * * @param $sid @@ -655,60 +640,6 @@ function search_mark_for_reindex($type, $sid) { */ /** - * Form constructor for the search form. - * - * @param \Drupal\search\Plugin\SearchInterface $plugin - * A search plugin instance to render the form for. - * @param $action - * Form action. Defaults to "search/$path", where $path is the search path - * associated with the plugin in its definition. This will be run through - * url(). - * @param $prompt - * Label for the keywords field. Defaults to t('Enter your keywords') if - * NULL. Supply '' to omit. - * - * @see search_form_validate() - * @see search_form_submit() - * - * @ingroup forms - */ -function search_form($form, &$form_state, SearchInterface $plugin, $action = '', $prompt = NULL) { - - $plugin_info = $plugin->getPluginDefinition(); - - if (!$action) { - $action = 'search/' . $plugin_info['path']; - } - if (!isset($prompt)) { - $prompt = t('Enter your keywords'); - } - - $form['#action'] = url($action); - // Record the $action for later use in redirecting. - $form_state['action'] = $action; - $form['plugin_id'] = array('#type' => 'value', '#value' => $plugin->getPluginId()); - $form['basic'] = array('#type' => 'container', '#attributes' => array('class' => array('container-inline'))); - $form['basic']['keys'] = array( - '#type' => 'search', - '#title' => $prompt, - '#default_value' => $plugin->getKeywords(), - '#size' => $prompt ? 40 : 20, - '#maxlength' => 255, - ); - // processed_keys is used to coordinate keyword passing between other forms - // that hook into the basic search form. - $form['basic']['processed_keys'] = array('#type' => 'value', '#value' => ''); - $form['basic']['submit'] = array('#type' => 'submit', '#value' => t('Search')); - // Make sure the default validate and submit handlers are added. - $form['#validate'][] = 'search_form_validate'; - $form['#submit'][] = 'search_form_submit'; - // Allow the plugin to add to or alter the search form. - $plugin->searchFormAlter($form, $form_state); - - return $form; -} - -/** * Form constructor for the search block's search box. * * @param $form_id diff --git a/core/modules/search/search.pages.inc b/core/modules/search/search.pages.inc index 5b1e1a0..023a825 100644 --- a/core/modules/search/search.pages.inc +++ b/core/modules/search/search.pages.inc @@ -9,79 +9,6 @@ use Symfony\Component\HttpFoundation\RedirectResponse; /** - * Page callback: Presents the search form and/or search results. - * - * @param $plugin_id - * Search plugin_id to use for the search. - * @param $keys - * Keywords to use for the search. - * - * @deprecated Use \Drupal\search\Controller\SearchController::searchView() - */ -function search_view($plugin_id = NULL, $keys = '') { - $info = FALSE; - $keys = trim($keys); - // Also try to pull search keywords out of the $_REQUEST variable to - // support old GET format of searches for existing links. - if (!$keys && !empty($_REQUEST['keys'])) { - $keys = trim($_REQUEST['keys']); - } - - $manager = \Drupal::service('plugin.manager.search'); - if (!empty($plugin_id)) { - $active_plugin_info = $manager->getActiveDefinitions(); - if (isset($active_plugin_info[$plugin_id])) { - $info = $active_plugin_info[$plugin_id]; - } - } - - if (empty($plugin_id) || empty($info)) { - // No path or invalid path: find the default plugin. Note that if there - // are no enabled search plugins, this function should never be called, - // since hook_menu() would not have defined any search paths. - $info = search_get_default_plugin_info(); - // Redirect from bare /search or an invalid path to the default search path. - $path = 'search/' . $info['path']; - if ($keys) { - $path .= '/' . $keys; - } - return new RedirectResponse(url($path, array('absolute' => TRUE))); - } - $plugin = $manager->createInstance($plugin_id); - $request = \Drupal::request(); - $plugin->setSearch($keys, $request->query->all(), $request->attributes->all()); - // Default results output is an empty string. - $results = array('#markup' => ''); - // Process the search form. Note that if there is $_POST data, - // search_form_submit() will cause a redirect to search/[path]/[keys], - // which will get us back to this page callback. In other words, the search - // form submits with POST but redirects to GET. This way we can keep - // the search query URL clean as a whistle. - if (empty($_POST['form_id']) || $_POST['form_id'] != 'search_form') { - // Only search if there are keywords or non-empty conditions. - if ($plugin->isSearchExecutable()) { - // Log the search keys. - watchdog('search', 'Searched %type for %keys.', array('%keys' => $keys, '%type' => $info['title']), WATCHDOG_NOTICE, l(t('results'), 'search/' . $info['path'] . '/' . $keys)); - - // Collect the search results. - $results = $plugin->buildResults(); - } - } - // The form may be altered based on whether the search was run. - $build['search_form'] = drupal_get_form('search_form', $plugin); - $build['search_results'] = $results; - - return $build; -} - -/** - * Implements hook_theme_suggestions_HOOK(). - */ -function search_theme_suggestions_search_results(array $variables) { - return array('search_results__' . $variables['plugin_id']); -} - -/** * Prepares variables for search results templates. * * Default template: search-results.html.twig. @@ -163,31 +90,3 @@ function template_preprocess_search_result(&$variables) { $variables['info'] = implode(' - ', $info); } -/** - * Form validation handler for search_form(). - * - * As the search form collates keys from other modules hooked in via - * hook_form_alter, the validation takes place in search_form_submit(). - * search_form_validate() is used solely to set the 'processed_keys' form - * value for the basic search form. - * - * @see search_form_submit() - */ -function search_form_validate($form, &$form_state) { - form_set_value($form['basic']['processed_keys'], trim($form_state['values']['keys']), $form_state); -} - -/** - * Form submission handler for search_form(). - * - * @see search_form_validate() - */ -function search_form_submit($form, &$form_state) { - $keys = $form_state['values']['processed_keys']; - if ($keys == '') { - form_set_error('keys', t('Please enter some keywords.')); - // Fall through to the form redirect. - } - - $form_state['redirect'] = $form_state['action'] . '/' . $keys; -} diff --git a/core/modules/search/search.routing.yml b/core/modules/search/search.routing.yml index 6780e69..21e481e 100644 --- a/core/modules/search/search.routing.yml +++ b/core/modules/search/search.routing.yml @@ -1,14 +1,14 @@ search.settings: path: '/admin/config/search/settings' defaults: - _form: 'Drupal\search\Form\SearchSettingsForm' + _form: '\Drupal\search\Form\SearchSettingsForm' requirements: _permission: 'administer search' search.reindex_confirm: path: '/admin/config/search/settings/reindex' defaults: - _form: 'Drupal\search\Form\ReindexConfirm' + _form: '\Drupal\search\Form\ReindexConfirm' requirements: _permission: 'administer search' @@ -16,7 +16,7 @@ search.view: path: '/search/{plugin_id}' defaults: _title: 'Search' - _content: '\Drupal\search\Controller\SearchController::searchView' + _content: '\Drupal\search\Controller\SearchController::view' plugin_id: NULL keys: '' requirements: