Completed
Push — 3.1.x ( b8b6d2...fd2df9 )
by Karel
14:12 queued 11:28
created

hybridTransform()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 17
c 1
b 0
f 0
ccs 12
cts 12
cp 1
rs 9.4286
cc 3
eloc 10
nc 4
nop 1
crap 3
1
<?php
2
3
namespace FOS\ElasticaBundle\Doctrine;
4
5
use Doctrine\Common\Persistence\ManagerRegistry;
6
use FOS\ElasticaBundle\HybridResult;
7
use FOS\ElasticaBundle\Transformer\AbstractElasticaToModelTransformer as BaseTransformer;
8
use FOS\ElasticaBundle\Transformer\HighlightableModelInterface;
9
10
/**
11
 * Maps Elastica documents with Doctrine objects
12
 * This mapper assumes an exact match between
13
 * elastica documents ids and doctrine object ids.
14
 */
15
abstract class AbstractElasticaToModelTransformer extends BaseTransformer
16
{
17
    /**
18
     * Manager registry.
19
     *
20
     * @var ManagerRegistry
21
     */
22
    protected $registry = null;
23
24
    /**
25
     * Class of the model to map to the elastica documents.
26
     *
27
     * @var string
28
     */
29
    protected $objectClass = null;
30
31
    /**
32
     * Optional parameters.
33
     *
34
     * @var array
35
     */
36
    protected $options = array(
37
        'hydrate'        => true,
38
        'identifier'     => 'id',
39
        'ignore_missing' => false,
40
        'query_builder_method' => 'createQueryBuilder',
41
    );
42
43
    /**
44
     * Instantiates a new Mapper.
45
     *
46
     * @param ManagerRegistry $registry
47
     * @param string $objectClass
48
     * @param array  $options
49
     */
50 3
    public function __construct(ManagerRegistry $registry, $objectClass, array $options = array())
51
    {
52 3
        $this->registry    = $registry;
53 3
        $this->objectClass = $objectClass;
54 3
        $this->options     = array_merge($this->options, $options);
55 3
    }
56
57
    /**
58
     * Returns the object class that is used for conversion.
59
     *
60
     * @return string
61
     */
62
    public function getObjectClass()
63
    {
64
        return $this->objectClass;
65
    }
66
67
    /**
68
     * Transforms an array of elastica objects into an array of
69
     * model objects fetched from the doctrine repository.
70
     *
71
     * @param array $elasticaObjects of elastica objects
72
     *
73
     * @throws \RuntimeException
74
     *
75
     * @return array
76
     **/
77 1
    public function transform(array $elasticaObjects)
78
    {
79 1
        $ids = $highlights = array();
80 1
        foreach ($elasticaObjects as $elasticaObject) {
81 1
            $ids[] = $elasticaObject->getId();
82 1
            $highlights[$elasticaObject->getId()] = $elasticaObject->getHighlights();
83 1
        }
84
85 1
        $objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
86 1
        if (!$this->options['ignore_missing'] && count($objects) < count($elasticaObjects)) {
87
            throw new \RuntimeException('Cannot find corresponding Doctrine objects for all Elastica results.');
88
        };
89
90 1
        foreach ($objects as $object) {
91 1
            if ($object instanceof HighlightableModelInterface) {
92
                $object->setElasticHighlights($highlights[$object->getId()]);
93
            }
94 1
        }
95
96
        // sort objects in the order of ids
97 1
        $idPos = array_flip($ids);
98 1
        $identifier = $this->options['identifier'];
99 1
        usort($objects, $this->getSortingClosure($idPos, $identifier));
100
101 1
        return $objects;
102
    }
103
104 1
    public function hybridTransform(array $elasticaObjects)
105
    {
106 1
        $indexedElasticaResults = array();
107 1
        foreach ($elasticaObjects as $elasticaObject) {
108 1
            $indexedElasticaResults[$elasticaObject->getId()] = $elasticaObject;
109 1
        }
110
111 1
        $objects = $this->transform($elasticaObjects);
112
113 1
        $result = array();
114 1
        foreach ($objects as $object) {
115 1
            $id = $this->propertyAccessor->getValue($object, $this->options['identifier']);
116 1
            $result[] = new HybridResult($indexedElasticaResults[$id], $object);
117 1
        }
118
119 1
        return $result;
120
    }
121
122
    /**
123
     * {@inheritDoc}
124
     */
125
    public function getIdentifierField()
126
    {
127
        return $this->options['identifier'];
128
    }
129
130
    /**
131
     * Fetches objects by theses identifier values.
132
     *
133
     * @param array   $identifierValues ids values
134
     * @param Boolean $hydrate          whether or not to hydrate the objects, false returns arrays
135
     *
136
     * @return array of objects or arrays
137
     */
138
    abstract protected function findByIdentifiers(array $identifierValues, $hydrate);
139
}
140