class SearchApiPageController in Search API Pages 8
Defines a controller to serve search pages.
Hierarchy
- class \Drupal\Core\Controller\ControllerBase implements ContainerInjectionInterface uses LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\search_api_page\Controller\SearchApiPageController
Expanded class hierarchy of SearchApiPageController
1 file declares its use of SearchApiPageController
- SearchApiPageRoutes.php in src/
Routing/ SearchApiPageRoutes.php
File
- src/
Controller/ SearchApiPageController.php, line 21
Namespace
Drupal\search_api_page\ControllerView source
class SearchApiPageController extends ControllerBase {
/**
* The parse mode plugin manager.
*
* @var \Drupal\search_api\ParseMode\ParseModePluginManager
*/
protected $parseModePluginManager;
/**
* The parse mode pager manager.
*
* @var Drupal\Core\Pager\PagerManagerInterface
*/
protected $pagerManager;
/**
* SearchApiPageController constructor.
*
* @param \Drupal\search_api\ParseMode\ParseModePluginManager $parseModePluginManager
* The parse mode plugin manager.
* @param Drupal\Core\Pager\PagerManagerInterface $pagerManager
* The parse mode pager manager.
*/
public function __construct(ParseModePluginManager $parseModePluginManager, PagerManagerInterface $pagerManager) {
$this->parseModePluginManager = $parseModePluginManager;
$this->pagerManager = $pagerManager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.search_api.parse_mode'), $container
->get('pager.manager'));
}
/**
* Page callback.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
* @param string $search_api_page_name
* The search api page name.
* @param string $keys
* The search word.
*
* @return array
* The page render array.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\search_api\SearchApiException
*/
public function page(Request $request, $search_api_page_name, $keys = '') {
/* @var $search_api_page \Drupal\search_api_page\SearchApiPageInterface */
$search_api_page = $this
->entityTypeManager()
->getStorage('search_api_page')
->load($search_api_page_name);
// Keys can be in the query.
if (!$search_api_page
->getCleanUrl()) {
$keys = $request
->get('keys');
}
$build['#theme'] = 'search_api_page';
if ($search_api_page
->showSearchForm()) {
$build = $this
->addSearchForm($build, $search_api_page, $keys);
}
if (empty($keys) && !$search_api_page
->showAllResultsWhenNoSearchIsPerformed()) {
return $this
->finishBuild($build, $search_api_page);
}
$query = $this
->prepareQuery($request, $search_api_page);
if (!empty($keys)) {
$query
->keys($keys);
}
$result = $query
->execute();
/* @var $items \Drupal\search_api\Item\ItemInterface[] */
$items = $result
->getResultItems();
$results = [];
foreach ($items as $item) {
$rendered = $this
->createItemRenderArray($item, $search_api_page);
if ($rendered === []) {
continue;
}
$results[] = $rendered;
}
if (empty($results)) {
return $this
->finishBuildWithoutResults($build, $search_api_page);
}
return $this
->finishBuildWithResults($build, $result, $results, $search_api_page);
}
/**
* Adds the search form to the build.
*
* @param array $build
* The build to add the form to.
* @param \Drupal\search_api_page\SearchApiPageInterface $search_api_page
* The search api page.
* @param mixed $keys
* The search word.
*
* @return array
* The build with the search form added to it.
*/
protected function addSearchForm(array $build, SearchApiPageInterface $search_api_page, $keys) {
$block_form = \Drupal::getContainer()
->get('block_form.search_api_page');
$block_form
->setPageId($search_api_page
->id());
$args = [
'keys' => $keys,
];
$build['#form'] = $this
->formBuilder()
->getForm($block_form, $args);
return $build;
}
/**
* Creates a render array for the given result item.
*
* @param \Drupal\search_api\Item\ItemInterface $item
* The item to render.
* @param \Drupal\search_api_page\SearchApiPageInterface $search_api_page
* The search api page.
*
* @return array
* A render array for the given result item.
*/
protected function createItemRenderArray(ItemInterface $item, SearchApiPageInterface $search_api_page) {
try {
$originalObject = $item
->getOriginalObject();
if ($originalObject === NULL) {
return [];
}
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $originalObject
->getValue();
} catch (SearchApiException $e) {
return [];
}
if (!$entity) {
return [];
}
$viewedResult = [];
if ($search_api_page
->renderAsViewModes()) {
$datasource_id = 'entity:' . $entity
->getEntityTypeId();
$bundle = $entity
->bundle();
$viewMode = $search_api_page
->getViewModeConfig()
->getViewMode($datasource_id, $bundle);
$viewedResult = $this
->entityTypeManager()
->getViewBuilder($entity
->getEntityTypeId())
->view($entity, $viewMode);
$viewedResult['#search_api_excerpt'] = $item
->getExcerpt();
}
if ($search_api_page
->renderAsSnippets()) {
$viewedResult = [
'#theme' => 'search_api_page_result',
'#item' => $item,
'#entity' => $entity,
];
}
$metadata = CacheableMetadata::createFromRenderArray($viewedResult);
$metadata
->addCacheContexts([
'url.path',
]);
$metadata
->addCacheTags([
'search_api_page.style',
]);
$metadata
->applyTo($viewedResult);
return $viewedResult;
}
/**
* Finishes the build.
*
* @param array $build
* An array containing all page elements.
* @param \Drupal\search_api_page\SearchApiPageInterface $searchApiPage
* The Search API page entity.
* @param \Drupal\search_api\Query\ResultSetInterface $result
* Search API result.
*
* @return array
* An array containing all page elements.
*/
protected function finishBuild(array $build, SearchApiPageInterface $searchApiPage, ResultSetInterface $result = NULL) {
$this
->moduleHandler()
->alter('search_api_page', $build, $result, $searchApiPage);
// TODO caching dependencies.
// @see https://www.drupal.org/project/search_api_page/issues/2754411.
return $build;
}
/**
* Prepares the search query.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
* @param \Drupal\search_api_page\SearchApiPageInterface $search_api_page
* The search api page.
*
* @return \Drupal\search_api\Query\QueryInterface
* The prepared query.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\search_api\SearchApiException
*/
protected function prepareQuery(Request $request, SearchApiPageInterface $search_api_page) {
/* @var $search_api_index \Drupal\search_api\IndexInterface */
$search_api_index = $this
->entityTypeManager()
->getStorage('search_api_index')
->load($search_api_page
->getIndex());
$query = $search_api_index
->query([
'limit' => $search_api_page
->getLimit(),
'offset' => $request
->get('page') !== NULL ? $request
->get('page') * $search_api_page
->getLimit() : 0,
]);
$query
->setSearchID('search_api_page:' . $search_api_page
->id());
/** @var \Drupal\search_api\ParseMode\ParseModeInterface $parse_mode */
$parse_mode = $this->parseModePluginManager
->createInstance($search_api_page
->getParseMode());
$query
->setParseMode($parse_mode);
// Add filter for current language.
$langcode = $this
->languageManager()
->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
->getId();
$query
->setLanguages([
$langcode,
LanguageInterface::LANGCODE_NOT_SPECIFIED,
]);
$query
->setFulltextFields($search_api_page
->getSearchedFields());
return $query;
}
/**
* Adds the no results text and then finishes the build.
*
* @param array $build
* The build to finish.
* @param \Drupal\search_api_page\SearchApiPageInterface $searchApiPage
* The Search API page entity.
*
* @return array
* The finished build render array.
*/
protected function finishBuildWithoutResults(array $build, SearchApiPageInterface $searchApiPage) {
$build['#no_results_found'] = [
'#markup' => $this
->t('Your search yielded no results.'),
];
$build['#search_help'] = [
'#markup' => $this
->t('<ul>
<li>Check if your spelling is correct.</li>
<li>Remove quotes around phrases to search for each word individually. <em>bike shed</em> will often show more results than <em>"bike shed"</em>.</li>
<li>Consider loosening your query with <em>OR</em>. <em>bike OR shed</em> will often show more results than <em>bike shed</em>.</li>
</ul>'),
];
return $this
->finishBuild($build, $searchApiPage);
}
/**
* Adds the results to the given build and then finishes it.
*
* @param array $build
* The build.
* @param \Drupal\search_api\Query\ResultSetInterface $result
* Search API result.
* @param array $results
* The result item render arrays.
* @param \Drupal\search_api_page\SearchApiPageInterface $search_api_page
* The search api page.
*
* @return array
* The finished build.
*/
protected function finishBuildWithResults(array $build, ResultSetInterface $result, array $results, SearchApiPageInterface $search_api_page) {
$build['#search_title'] = [
'#markup' => $this
->t('Search results'),
];
$build['#no_of_results'] = [
'#markup' => $this
->formatPlural($result
->getResultCount(), '1 result found', '@count results found'),
];
$build['#results'] = $results;
$this->pagerManager
->createPager($result
->getResultCount(), $search_api_page
->getLimit());
$build['#pager'] = [
'#type' => 'pager',
];
return $this
->finishBuild($build, $search_api_page, $result);
}
/**
* Title callback.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
* @param string $search_api_page_name
* The search api page name.
* @param string $keys
* The search word.
*
* @return string
* The page title.
*/
public function title(Request $request, $search_api_page_name = NULL, $keys = '') {
// Provide a default title if no search API page name is provided.
if ($search_api_page_name === NULL) {
return $this
->t('Search');
}
/* @var $search_api_page \Drupal\search_api_page\SearchApiPageInterface */
$search_api_page = SearchApiPage::load($search_api_page_name);
return $search_api_page
->label();
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ControllerBase:: |
protected | property | The configuration factory. | |
ControllerBase:: |
protected | property | The current user service. | 1 |
ControllerBase:: |
protected | property | The entity form builder. | |
ControllerBase:: |
protected | property | The entity manager. | |
ControllerBase:: |
protected | property | The entity type manager. | |
ControllerBase:: |
protected | property | The form builder. | 2 |
ControllerBase:: |
protected | property | The key-value storage. | 1 |
ControllerBase:: |
protected | property | The language manager. | 1 |
ControllerBase:: |
protected | property | The module handler. | 2 |
ControllerBase:: |
protected | property | The state service. | |
ControllerBase:: |
protected | function | Returns the requested cache bin. | |
ControllerBase:: |
protected | function | Retrieves a configuration object. | |
ControllerBase:: |
private | function | Returns the service container. | |
ControllerBase:: |
protected | function | Returns the current user. | 1 |
ControllerBase:: |
protected | function | Retrieves the entity form builder. | |
ControllerBase:: |
protected | function | Retrieves the entity manager service. | |
ControllerBase:: |
protected | function | Retrieves the entity type manager. | |
ControllerBase:: |
protected | function | Returns the form builder service. | 2 |
ControllerBase:: |
protected | function | Returns a key/value storage collection. | 1 |
ControllerBase:: |
protected | function | Returns the language manager service. | 1 |
ControllerBase:: |
protected | function | Returns the module handler. | 2 |
ControllerBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
ControllerBase:: |
protected | function | Returns the state storage service. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
SearchApiPageController:: |
protected | property | The parse mode pager manager. | |
SearchApiPageController:: |
protected | property | The parse mode plugin manager. | |
SearchApiPageController:: |
protected | function | Adds the search form to the build. | |
SearchApiPageController:: |
public static | function |
Instantiates a new instance of this class. Overrides ControllerBase:: |
|
SearchApiPageController:: |
protected | function | Creates a render array for the given result item. | |
SearchApiPageController:: |
protected | function | Finishes the build. | |
SearchApiPageController:: |
protected | function | Adds the no results text and then finishes the build. | |
SearchApiPageController:: |
protected | function | Adds the results to the given build and then finishes it. | |
SearchApiPageController:: |
public | function | Page callback. | |
SearchApiPageController:: |
protected | function | Prepares the search query. | |
SearchApiPageController:: |
public | function | Title callback. | |
SearchApiPageController:: |
public | function | SearchApiPageController constructor. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |