public function IndexResource::process in JSON:API Search API 8
Process the resource request.
Parameters
\Symfony\Component\HttpFoundation\Request $request: The request.
\Drupal\search_api\IndexInterface $index: The index.
Return value
\Drupal\jsonapi\ResourceResponse The response.
Throws
\Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
\Drupal\Component\Plugin\Exception\PluginNotFoundException
\Drupal\search_api\SearchApiException
\Drupal\Component\Plugin\Exception\PluginException
File
- src/
Resource/ IndexResource.php, line 79
Class
- IndexResource
- JSON:API Resource to return Search API index results.
Namespace
Drupal\jsonapi_search_api\ResourceCode
public function process(Request $request, IndexInterface $index) : ResourceResponse {
$cacheability = new CacheableMetadata();
// Ensure that different pages will be cached separately.
$cacheability
->addCacheContexts([
'url.query_args:page',
]);
$cacheability
->addCacheContexts([
'url.query_args:filter',
]);
$cacheability
->addCacheContexts([
'url.query_args:sort',
]);
// Ensure changes to the index invalidate cache.
$cacheability
->addCacheableDependency($index);
// Make sure the index list cache tag is present.
$cacheability
->addCacheTags([
'search_api_list:' . $index
->id(),
]);
$query = $index
->query();
// Set the search ID so we can identify that these queries are coming from
// JSON:API.
$query
->setSearchId(strtr('jsonapi_search_api:!index', [
'!index' => $index
->id(),
]));
// Derive any pagination options from the query params or use defaults.
$pagination = $this
->getPagination($request);
if ($pagination
->getSize() <= 0) {
throw new CacheableBadRequestHttpException($cacheability, sprintf('The page size needs to be a positive integer.'));
}
$query
->range($pagination
->getOffset(), $pagination
->getSize());
if ($request->query
->has(Filter::KEY_NAME)) {
$this
->applyFiltersToQuery($request, $query, $cacheability);
}
if ($request->query
->has('sort')) {
$this
->applySortingToQuery($request, $query, $cacheability);
}
// Get the results and convert to JSON:API resource object data.
try {
$results = $query
->execute();
} catch (SearchApiException $exception) {
throw new CacheableBadRequestHttpException($cacheability, $exception
->getMessage());
}
// Load all entities at once, for better performance.
$results
->preLoadResultItems();
$result_entities = array_map(static function (ItemInterface $item) {
return $item
->getOriginalObject()
->getValue();
}, $results
->getResultItems());
$primary_data = $this
->createCollectionDataFromEntities(array_values($result_entities));
$primary_data
->setTotalCount((int) $results
->getResultCount());
$pager_links = $this
->getPagerLinks($request, $pagination, $primary_data
->getTotalCount(), count($result_entities));
// @todo remove after https://www.drupal.org/project/jsonapi_resources/issues/3120437
$meta = [
'count' => $primary_data
->getTotalCount(),
];
// Dispatch an event to allow other modules to modify the meta.
$event = new AddSearchMetaEvent($query, $results, $meta);
$meta = $this->eventDispatcher
->dispatch(Events::ADD_SEARCH_META, $event)
->getMeta();
$response = $this
->createJsonapiResponse($primary_data, $request, 200, [], $pager_links, $meta);
$response
->addCacheableDependency($cacheability);
return $response;
}