Advertisement
Guest User

Untitled

a guest
Apr 6th, 2020
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 3.99 KB | None | 0 0
  1. <?php
  2.  
  3.  
  4. namespace App\Elasticsearch\DataProvider;
  5.  
  6.  
  7. use ApiPlatform\Core\Bridge\Elasticsearch\DataProvider\Extension\RequestBodySearchCollectionExtensionInterface;
  8. use ApiPlatform\Core\Bridge\Elasticsearch\Metadata\Document\Factory\DocumentMetadataFactoryInterface;
  9. use ApiPlatform\Core\DataProvider\ContextAwareCollectionDataProviderInterface;
  10. use ApiPlatform\Core\DataProvider\Pagination;
  11. use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
  12. use Doctrine\ORM\EntityManagerInterface;
  13. use Elasticsearch\Client;
  14.  
  15. /**
  16.  * Class ElasticsearchCollectionDataProvider
  17.  * @package App\Elasticsearch\DataProvider
  18.  */
  19. class ElasticsearchCollectionDataProvider implements ContextAwareCollectionDataProviderInterface, RestrictedDataProviderInterface
  20. {
  21.     public const CONTEXT_ENTITY_CLASS = 'entity_class';
  22.     public const CONTEXT_ELASTICSEARCH_CLASS = 'elasticsearch_class';
  23.  
  24.     /** @var EntityManagerInterface */
  25.     private $entityManager;
  26.  
  27.     /** @var Client */
  28.     private $client;
  29.  
  30.     /** @var DocumentMetadataFactoryInterface */
  31.     private $documentMetadataFactory;
  32.  
  33.     /** @var Pagination */
  34.     private $pagination;
  35.  
  36.     /** @var iterable|RequestBodySearchCollectionExtensionInterface[] */
  37.     private $collectionExtensions;
  38.  
  39.     public function __construct(
  40.         EntityManagerInterface $entityManager,
  41.         Client $client,
  42.         DocumentMetadataFactoryInterface $documentMetadataFactory,
  43.         Pagination $pagination,
  44.         iterable $collectionExtensions = []
  45.     )
  46.     {
  47.         $this->entityManager = $entityManager;
  48.         $this->client = $client;
  49.         $this->documentMetadataFactory = $documentMetadataFactory;
  50.         $this->pagination = $pagination;
  51.         $this->collectionExtensions = $collectionExtensions;
  52.     }
  53.  
  54.     /**
  55.      * {@inheritDoc}
  56.      * @throws \ApiPlatform\Core\Bridge\Elasticsearch\Exception\IndexNotFoundException
  57.      */
  58.     public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
  59.     {
  60.         $entityClassName = $context[self::CONTEXT_ENTITY_CLASS];
  61.         $searchClassName = $context[self::CONTEXT_ELASTICSEARCH_CLASS];
  62.  
  63.         $documentMetadata = $this->documentMetadataFactory->create($searchClassName);
  64.         $body = [];
  65.  
  66.         foreach ($this->collectionExtensions as $collectionExtension) {
  67.             $body = $collectionExtension->applyToCollection($body, $searchClassName, $operationName, $context);
  68.         }
  69.  
  70.         if (!isset($body['query']) && !isset($body['aggs'])) {
  71.             $body['query'] = ['match_all' => new \stdClass()];
  72.         }
  73.  
  74.         $body['_source'] = ['id'];
  75.  
  76.         $limit = $body['size'] = $body['size'] ?? $this->pagination->getLimit($entityClassName, $operationName, $context);
  77.         $offset = $body['from'] = $body['from'] ?? $this->pagination->getOffset($entityClassName, $operationName, $context);
  78.  
  79.         $documents = $this->client->search([
  80.             'index' => $documentMetadata->getIndex(),
  81.             'type' => $documentMetadata->getType(),
  82.             'body' => $body,
  83.         ]);
  84.  
  85.         $ids = [];
  86.  
  87.         foreach ($documents['hits']['hits'] as $document) {
  88.             $ids[] = $document['_source']['id'];
  89.         }
  90.  
  91.         $queryBuilder = null;
  92.  
  93.         if (count($ids) > 0) {
  94.             $idsList = implode("', '", $ids);
  95.             $idsList = "'{$idsList}'";
  96.  
  97.             $queryBuilder = $this->entityManager->createQueryBuilder();
  98.  
  99.             $queryBuilder
  100.                 ->from($entityClassName, 't')
  101.                 ->select('t')
  102.                 ->where($queryBuilder->expr()->in('t.id', $ids))
  103.                 ->orderBy("FIELD(t.id, {$idsList})");
  104.         }
  105.  
  106.         return new Paginator($queryBuilder, $documents, $limit, $offset);
  107.     }
  108.  
  109.     /** @inheritDoc */
  110.     public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
  111.     {
  112.         return $operationName === 'search'; //isset($context[self::CONTEXT_ELASTICSEARCH_CLASS]);
  113.     }
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement