3 namespace Drupal\search\Controller;
5 use Drupal\Core\Cache\CacheableDependencyInterface;
6 use Drupal\Core\Controller\ControllerBase;
7 use Drupal\Core\Render\RendererInterface;
8 use Drupal\search\Form\SearchPageForm;
9 use Drupal\search\SearchPageInterface;
10 use Drupal\search\SearchPageRepositoryInterface;
11 use Symfony\Component\DependencyInjection\ContainerInterface;
12 use Symfony\Component\HttpFoundation\Request;
15 * Route controller for search.
17 class SearchController extends ControllerBase {
20 * The search page repository.
22 * @var \Drupal\search\SearchPageRepositoryInterface
24 protected $searchPageRepository;
29 * @var \Psr\Log\LoggerInterface
36 * @var \Drupal\Core\Render\RendererInterface
41 * Constructs a new search controller.
43 * @param \Drupal\search\SearchPageRepositoryInterface $search_page_repository
44 * The search page repository.
45 * @param \Drupal\Core\Render\RendererInterface $renderer
48 public function __construct(SearchPageRepositoryInterface $search_page_repository, RendererInterface $renderer) {
49 $this->searchPageRepository = $search_page_repository;
50 $this->logger = $this->getLogger('search');
51 $this->renderer = $renderer;
57 public static function create(ContainerInterface $container) {
59 $container->get('search.search_page_repository'),
60 $container->get('renderer')
65 * Creates a render array for the search page.
67 * @param \Symfony\Component\HttpFoundation\Request $request
69 * @param \Drupal\search\SearchPageInterface $entity
70 * The search page entity.
73 * The search form and search results build array.
75 public function view(Request $request, SearchPageInterface $entity) {
77 $plugin = $entity->getPlugin();
79 // Build the form first, because it may redirect during the submit,
80 // and we don't want to build the results based on last time's request.
81 $build['#cache']['contexts'][] = 'url.query_args:keys';
82 if ($request->query->has('keys')) {
83 $keys = trim($request->query->get('keys'));
84 $plugin->setSearch($keys, $request->query->all(), $request->attributes->all());
87 $build['#title'] = $plugin->suggestedTitle();
88 $build['search_form'] = $this->formBuilder()->getForm(SearchPageForm::class, $entity);
90 // Build search results, if keywords or other search parameters are in the
91 // GET parameters. Note that we need to try the search if 'keys' is in
92 // there at all, vs. being empty, due to advanced search.
94 if ($request->query->has('keys')) {
95 if ($plugin->isSearchExecutable()) {
97 if ($this->config('search.settings')->get('logging')) {
98 $this->logger->notice('Searched %type for %keys.', ['%keys' => $keys, '%type' => $entity->label()]);
101 // Collect the search results.
102 $results = $plugin->buildResults();
105 // The search not being executable means that no keywords or other
106 // conditions were entered.
107 drupal_set_message($this->t('Please enter some keywords.'), 'error');
111 if (count($results)) {
112 $build['search_results_title'] = [
113 '#markup' => '<h2>' . $this->t('Search results') . '</h2>',
117 $build['search_results'] = [
118 '#theme' => ['item_list__search_results__' . $plugin->getPluginId(), 'item_list__search_results'],
119 '#items' => $results,
121 '#markup' => '<h3>' . $this->t('Your search yielded no results.') . '</h3>',
123 '#list_type' => 'ol',
125 'plugin' => $plugin->getPluginId(),
129 $this->renderer->addCacheableDependency($build, $entity);
130 if ($plugin instanceof CacheableDependencyInterface) {
131 $this->renderer->addCacheableDependency($build, $plugin);
134 // If this plugin uses a search index, then also add the cache tag tracking
135 // that search index, so that cached search result pages are invalidated
137 if ($plugin->getType()) {
138 $build['search_results']['#cache']['tags'][] = 'search_index';
139 $build['search_results']['#cache']['tags'][] = 'search_index:' . $plugin->getType();
150 * Creates a render array for the search help page.
152 * @param \Drupal\search\SearchPageInterface $entity
153 * The search page entity.
156 * The search help page.
158 public function searchHelp(SearchPageInterface $entity) {
161 $build['search_help'] = $entity->getPlugin()->getHelp();
167 * Redirects to a search page.
169 * This is used to redirect from /search to the default search page.
171 * @param \Drupal\search\SearchPageInterface $entity
172 * The search page entity.
174 * @return \Symfony\Component\HttpFoundation\RedirectResponse
175 * A redirect to the search page.
177 public function redirectSearchPage(SearchPageInterface $entity) {
178 return $this->redirect('search.view_' . $entity->id());
182 * Route title callback.
184 * @param \Drupal\search\SearchPageInterface $search_page
185 * The search page entity.
188 * The title for the search page edit form.
190 public function editTitle(SearchPageInterface $search_page) {
191 return $this->t('Edit %label search page', ['%label' => $search_page->label()]);
195 * Performs an operation on the search page entity.
197 * @param \Drupal\search\SearchPageInterface $search_page
198 * The search page entity.
200 * The operation to perform, usually 'enable' or 'disable'.
202 * @return \Symfony\Component\HttpFoundation\RedirectResponse
203 * A redirect back to the search settings page.
205 public function performOperation(SearchPageInterface $search_page, $op) {
206 $search_page->$op()->save();
208 if ($op == 'enable') {
209 drupal_set_message($this->t('The %label search page has been enabled.', ['%label' => $search_page->label()]));
211 elseif ($op == 'disable') {
212 drupal_set_message($this->t('The %label search page has been disabled.', ['%label' => $search_page->label()]));
215 $url = $search_page->urlInfo('collection');
216 return $this->redirect($url->getRouteName(), $url->getRouteParameters(), $url->getOptions());
220 * Sets the search page as the default.
222 * @param \Drupal\search\SearchPageInterface $search_page
223 * The search page entity.
225 * @return \Symfony\Component\HttpFoundation\RedirectResponse
226 * A redirect to the search settings page.
228 public function setAsDefault(SearchPageInterface $search_page) {
229 // Set the default page to this search page.
230 $this->searchPageRepository->setDefaultSearchPage($search_page);
232 drupal_set_message($this->t('The default search page is now %label. Be sure to check the ordering of your search pages.', ['%label' => $search_page->label()]));
233 return $this->redirect('entity.search_page.collection');