Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- namespace App\Elasticsearch\DataProvider;
- use ApiPlatform\Core\Bridge\Elasticsearch\DataProvider\Extension\RequestBodySearchCollectionExtensionInterface;
- use ApiPlatform\Core\Bridge\Elasticsearch\Metadata\Document\Factory\DocumentMetadataFactoryInterface;
- use ApiPlatform\Core\DataProvider\ContextAwareCollectionDataProviderInterface;
- use ApiPlatform\Core\DataProvider\Pagination;
- use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
- use Doctrine\ORM\EntityManagerInterface;
- use Elasticsearch\Client;
- /**
- * Class ElasticsearchCollectionDataProvider
- * @package App\Elasticsearch\DataProvider
- */
- class ElasticsearchCollectionDataProvider implements ContextAwareCollectionDataProviderInterface, RestrictedDataProviderInterface
- {
- public const CONTEXT_ENTITY_CLASS = 'entity_class';
- public const CONTEXT_ELASTICSEARCH_CLASS = 'elasticsearch_class';
- /** @var EntityManagerInterface */
- private $entityManager;
- /** @var Client */
- private $client;
- /** @var DocumentMetadataFactoryInterface */
- private $documentMetadataFactory;
- /** @var Pagination */
- private $pagination;
- /** @var iterable|RequestBodySearchCollectionExtensionInterface[] */
- private $collectionExtensions;
- public function __construct(
- EntityManagerInterface $entityManager,
- Client $client,
- DocumentMetadataFactoryInterface $documentMetadataFactory,
- Pagination $pagination,
- iterable $collectionExtensions = []
- )
- {
- $this->entityManager = $entityManager;
- $this->client = $client;
- $this->documentMetadataFactory = $documentMetadataFactory;
- $this->pagination = $pagination;
- $this->collectionExtensions = $collectionExtensions;
- }
- /**
- * {@inheritDoc}
- * @throws \ApiPlatform\Core\Bridge\Elasticsearch\Exception\IndexNotFoundException
- */
- public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
- {
- $entityClassName = $context[self::CONTEXT_ENTITY_CLASS];
- $searchClassName = $context[self::CONTEXT_ELASTICSEARCH_CLASS];
- $documentMetadata = $this->documentMetadataFactory->create($searchClassName);
- $body = [];
- foreach ($this->collectionExtensions as $collectionExtension) {
- $body = $collectionExtension->applyToCollection($body, $searchClassName, $operationName, $context);
- }
- if (!isset($body['query']) && !isset($body['aggs'])) {
- $body['query'] = ['match_all' => new \stdClass()];
- }
- $body['_source'] = ['id'];
- $limit = $body['size'] = $body['size'] ?? $this->pagination->getLimit($entityClassName, $operationName, $context);
- $offset = $body['from'] = $body['from'] ?? $this->pagination->getOffset($entityClassName, $operationName, $context);
- $documents = $this->client->search([
- 'index' => $documentMetadata->getIndex(),
- 'type' => $documentMetadata->getType(),
- 'body' => $body,
- ]);
- $ids = [];
- foreach ($documents['hits']['hits'] as $document) {
- $ids[] = $document['_source']['id'];
- }
- $queryBuilder = null;
- if (count($ids) > 0) {
- $idsList = implode("', '", $ids);
- $idsList = "'{$idsList}'";
- $queryBuilder = $this->entityManager->createQueryBuilder();
- $queryBuilder
- ->from($entityClassName, 't')
- ->select('t')
- ->where($queryBuilder->expr()->in('t.id', $ids))
- ->orderBy("FIELD(t.id, {$idsList})");
- }
- return new Paginator($queryBuilder, $documents, $limit, $offset);
- }
- /** @inheritDoc */
- public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
- {
- return $operationName === 'search'; //isset($context[self::CONTEXT_ELASTICSEARCH_CLASS]);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement