From 8546c8f6d05eda56fc18c07b0b5dfe748d68918b Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Sat, 26 Oct 2013 14:17:27 -0700
Subject: [PATCH] Issue #1987806 by kim.pepper, disasm, vijaycs85,
 tim.plunkett: Convert search_view() to a new style controller.

---
 .../search/Controller/SearchController.php    | 115 +++++++++++++++--
 .../lib/Drupal/search/Form/SearchForm.php     | 121 ++++++++++++++++++
 .../search/Routing/SearchRouteSubscriber.php  |   2 +-
 core/modules/search/search.module             |  69 ----------
 core/modules/search/search.pages.inc          | 101 ---------------
 core/modules/search/search.routing.yml        |   6 +-
 6 files changed, 231 insertions(+), 183 deletions(-)
 create mode 100644 core/modules/search/lib/Drupal/search/Form/SearchForm.php

diff --git a/core/modules/search/lib/Drupal/search/Controller/SearchController.php b/core/modules/search/lib/Drupal/search/Controller/SearchController.php
index 8622341af4b9..18f38e3f4fe7 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 000000000000..410150272444
--- /dev/null
+++ b/core/modules/search/lib/Drupal/search/Form/SearchForm.php
@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\search\Form\SearchForm.
+ */
+
+namespace Drupal\search\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\search\Plugin\SearchInterface;
+use Drupal\search\SearchPluginManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a search form for site wide search.
+ */
+class SearchForm extends FormBase {
+
+  /**
+   * The search plugin manager.
+   *
+   * @var \Drupal\search\SearchPluginManager
+   */
+  protected $searchManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->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 0061d83ea0ed..dfb634c55757 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 c7bed0653a10..3fc29530a223 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -206,21 +206,6 @@ function search_get_default_plugin_info() {
   return reset($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.
  *
@@ -654,60 +639,6 @@ function search_mark_for_reindex($type, $sid) {
  * can easily find it.
  */
 
-/**
- * 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.
  *
diff --git a/core/modules/search/search.pages.inc b/core/modules/search/search.pages.inc
index 5b1e1a06153a..023a825f6c65 100644
--- a/core/modules/search/search.pages.inc
+++ b/core/modules/search/search.pages.inc
@@ -8,79 +8,6 @@
 use Drupal\Core\Language\Language;
 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.
  *
@@ -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 6780e69afd48..21e481e61261 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:
-- 
GitLab