View source
<?php
namespace Drupal\search_api_page\Controller;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Language\LanguageInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\ParseMode\ParseModePluginManager;
use Drupal\search_api\Query\ResultSetInterface;
use Drupal\search_api\SearchApiException;
use Drupal\search_api_page\Entity\SearchApiPage;
use Drupal\search_api_page\SearchApiPageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Pager\PagerManagerInterface;
class SearchApiPageController extends ControllerBase {
protected $parseModePluginManager;
protected $pagerManager;
public function __construct(ParseModePluginManager $parseModePluginManager, PagerManagerInterface $pagerManager) {
$this->parseModePluginManager = $parseModePluginManager;
$this->pagerManager = $pagerManager;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.search_api.parse_mode'), $container
->get('pager.manager'));
}
public function page(Request $request, $search_api_page_name, $keys = '') {
$search_api_page = $this
->entityTypeManager()
->getStorage('search_api_page')
->load($search_api_page_name);
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();
$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);
}
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;
}
protected function createItemRenderArray(ItemInterface $item, SearchApiPageInterface $search_api_page) {
try {
$originalObject = $item
->getOriginalObject();
if ($originalObject === NULL) {
return [];
}
$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;
}
protected function finishBuild(array $build, SearchApiPageInterface $searchApiPage, ResultSetInterface $result = NULL) {
$this
->moduleHandler()
->alter('search_api_page', $build, $result, $searchApiPage);
return $build;
}
protected function prepareQuery(Request $request, SearchApiPageInterface $search_api_page) {
$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());
$parse_mode = $this->parseModePluginManager
->createInstance($search_api_page
->getParseMode());
$query
->setParseMode($parse_mode);
$langcode = $this
->languageManager()
->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
->getId();
$query
->setLanguages([
$langcode,
LanguageInterface::LANGCODE_NOT_SPECIFIED,
]);
$query
->setFulltextFields($search_api_page
->getSearchedFields());
return $query;
}
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);
}
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);
}
public function title(Request $request, $search_api_page_name = NULL, $keys = '') {
if ($search_api_page_name === NULL) {
return $this
->t('Search');
}
$search_api_page = SearchApiPage::load($search_api_page_name);
return $search_api_page
->label();
}
}