vendor/friendsofsymfony/elastica-bundle/src/Doctrine/AbstractElasticaToModelTransformer.php line 95

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the FOSElasticaBundle package.
  4.  *
  5.  * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace FOS\ElasticaBundle\Doctrine;
  11. use Doctrine\Persistence\ManagerRegistry;
  12. use FOS\ElasticaBundle\HybridResult;
  13. use FOS\ElasticaBundle\Transformer\AbstractElasticaToModelTransformer as BaseTransformer;
  14. use FOS\ElasticaBundle\Transformer\HighlightableModelInterface;
  15. /**
  16.  * Maps Elastica documents with Doctrine objects
  17.  * This mapper assumes an exact match between
  18.  * elastica documents ids and doctrine object ids.
  19.  */
  20. abstract class AbstractElasticaToModelTransformer extends BaseTransformer
  21. {
  22.     /**
  23.      * Manager registry.
  24.      *
  25.      * @var ManagerRegistry
  26.      */
  27.     protected $registry null;
  28.     /**
  29.      * Class of the model to map to the elastica documents.
  30.      *
  31.      * @var string
  32.      */
  33.     protected $objectClass null;
  34.     /**
  35.      * Optional parameters.
  36.      *
  37.      * @var array
  38.      */
  39.     protected $options = [
  40.         'hints' => [],
  41.         'hydrate' => true,
  42.         'identifier' => 'id',
  43.         'ignore_missing' => false,
  44.         'query_builder_method' => 'createQueryBuilder',
  45.     ];
  46.     /**
  47.      * Instantiates a new Mapper.
  48.      *
  49.      * @param ManagerRegistry $registry
  50.      * @param string          $objectClass
  51.      * @param array           $options
  52.      */
  53.     public function __construct(ManagerRegistry $registry$objectClass, array $options = [])
  54.     {
  55.         $this->registry $registry;
  56.         $this->objectClass $objectClass;
  57.         $this->options array_merge($this->options$options);
  58.     }
  59.     /**
  60.      * Returns the object class that is used for conversion.
  61.      *
  62.      * @return string
  63.      */
  64.     public function getObjectClass()
  65.     {
  66.         return $this->objectClass;
  67.     }
  68.     /**
  69.      * Transforms an array of elastica objects into an array of
  70.      * model objects fetched from the doctrine repository.
  71.      *
  72.      * @param array $elasticaObjects of elastica objects
  73.      *
  74.      * @throws \RuntimeException
  75.      *
  76.      * @return array
  77.      **/
  78.     public function transform(array $elasticaObjects)
  79.     {
  80.         $ids $highlights = [];
  81.         foreach ($elasticaObjects as $elasticaObject) {
  82.             $ids[] = $elasticaObject->getId();
  83.             $highlights[$elasticaObject->getId()] = $elasticaObject->getHighlights();
  84.         }
  85.         $objects $this->findByIdentifiers($ids$this->options['hydrate']);
  86.         $objectsCnt count($objects);
  87.         $elasticaObjectsCnt count($elasticaObjects);
  88.         $propertyAccessor $this->propertyAccessor;
  89.         $identifier $this->options['identifier'];
  90.         if (!$this->options['ignore_missing'] && $objectsCnt $elasticaObjectsCnt) {
  91.             $missingIds array_diff($idsarray_map(function ($object) use ($propertyAccessor$identifier) {
  92.                 return $propertyAccessor->getValue($object$identifier);
  93.             }, $objects));
  94.             throw new \RuntimeException(sprintf('Cannot find corresponding Doctrine objects (%d) for all Elastica results (%d). Missing IDs: %s. IDs: %s'$objectsCnt$elasticaObjectsCntimplode(', '$missingIds), implode(', '$ids)));
  95.         }
  96.         foreach ($objects as $object) {
  97.             if ($object instanceof HighlightableModelInterface) {
  98.                 $id $propertyAccessor->getValue($object$identifier);
  99.                 $object->setElasticHighlights($highlights[(string) $id]);
  100.             }
  101.         }
  102.         // sort objects in the order of ids
  103.         $idPos array_flip($ids);
  104.         usort(
  105.             $objects,
  106.             function ($a$b) use ($idPos$identifier$propertyAccessor) {
  107.                 if ($this->options['hydrate']) {
  108.                     return $idPos[(string) $propertyAccessor->getValue(
  109.                         $a,
  110.                         $identifier
  111.                     )] > $idPos[(string) $propertyAccessor->getValue($b$identifier)];
  112.                 }
  113.                 return $idPos[$a[$identifier]] > $idPos[$b[$identifier]];
  114.             }
  115.         );
  116.         return $objects;
  117.     }
  118.     public function hybridTransform(array $elasticaObjects)
  119.     {
  120.         $indexedElasticaResults = [];
  121.         foreach ($elasticaObjects as $elasticaObject) {
  122.             $indexedElasticaResults[(string) $elasticaObject->getId()] = $elasticaObject;
  123.         }
  124.         $objects $this->transform($elasticaObjects);
  125.         $result = [];
  126.         foreach ($objects as $object) {
  127.             if ($this->options['hydrate']) {
  128.                 $id $this->propertyAccessor->getValue($object$this->options['identifier']);
  129.             } else {
  130.                 $id $object[$this->options['identifier']];
  131.             }
  132.             $result[] = new HybridResult($indexedElasticaResults[(string) $id], $object);
  133.         }
  134.         return $result;
  135.     }
  136.     /**
  137.      * {@inheritdoc}
  138.      */
  139.     public function getIdentifierField()
  140.     {
  141.         return $this->options['identifier'];
  142.     }
  143.     /**
  144.      * Fetches objects by theses identifier values.
  145.      *
  146.      * @param array $identifierValues ids values
  147.      * @param bool  $hydrate          whether or not to hydrate the objects, false returns arrays
  148.      *
  149.      * @return array of objects or arrays
  150.      */
  151.     abstract protected function findByIdentifiers(array $identifierValues$hydrate);
  152. }