Completed
Pull Request — master (#1051)
by Karel
07:59
created

AbstractElasticaToModelTransformer::transform()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 31
Code Lines 18

Duplication

Lines 7
Ratio 22.58 %

Code Coverage

Tests 17
CRAP Score 6.042

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 7
loc 31
ccs 17
cts 19
cp 0.8947
rs 8.439
c 1
b 0
f 0
cc 6
eloc 18
nc 8
nop 1
crap 6.042
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
        'hints'        => array(),
38
        'hydrate'        => true,
39
        'identifier'     => 'id',
40
        'ignore_missing' => false,
41
        'query_builder_method' => 'createQueryBuilder',
42
    );
43
44
    /**
45
     * Instantiates a new Mapper.
46
     *
47
     * @param ManagerRegistry $registry
48
     * @param string $objectClass
49
     * @param array  $options
50
     */
51 4
    public function __construct(ManagerRegistry $registry, $objectClass, array $options = array())
52
    {
53 4
        $this->registry    = $registry;
54 4
        $this->objectClass = $objectClass;
55 4
        $this->options     = array_merge($this->options, $options);
56 4
    }
57
58
    /**
59
     * Returns the object class that is used for conversion.
60
     *
61
     * @return string
62
     */
63
    public function getObjectClass()
64
    {
65
        return $this->objectClass;
66
    }
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 1
    public function transform(array $elasticaObjects)
79
    {
80 1
        $ids = $highlights = array();
81 1
        foreach ($elasticaObjects as $elasticaObject) {
82 1
            $ids[] = $elasticaObject->getId();
83 1
            $highlights[$elasticaObject->getId()] = $elasticaObject->getHighlights();
84
        }
85
86 1
        $objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
87 1 View Code Duplication
        if (!$this->options['ignore_missing'] && count($objects) < count($elasticaObjects)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
88
            throw new \RuntimeException('Cannot find corresponding Doctrine objects for all Elastica results.');
89
        };
90
91 1
        $propertyAccessor = $this->propertyAccessor;
92 1
        $identifier = $this->options['identifier'];
93 1
        foreach ($objects as $object) {
94 1
            if ($object instanceof HighlightableModelInterface) {
95
                $id = $propertyAccessor->getValue($object, $identifier);
96 1
                $object->setElasticHighlights($highlights[$id]);
97
            }
98
        }
99
100
        // sort objects in the order of ids
101 1
        $idPos = array_flip($ids);
102 1 View Code Duplication
        usort($objects, function($a, $b) use ($idPos, $identifier, $propertyAccessor)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
103
        {
104 1
            return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
105 1
        });
106
107 1
        return $objects;
108
    }
109
110 1
    public function hybridTransform(array $elasticaObjects)
111
    {
112 1
        $indexedElasticaResults = array();
113 1
        foreach ($elasticaObjects as $elasticaObject) {
114 1
            $indexedElasticaResults[$elasticaObject->getId()] = $elasticaObject;
115
        }
116
117 1
        $objects = $this->transform($elasticaObjects);
118
119 1
        $result = array();
120 1
        foreach ($objects as $object) {
121 1
            $id = $this->propertyAccessor->getValue($object, $this->options['identifier']);
122 1
            $result[] = new HybridResult($indexedElasticaResults[$id], $object);
123
        }
124
125 1
        return $result;
126
    }
127
128
    /**
129
     * {@inheritDoc}
130
     */
131
    public function getIdentifierField()
132
    {
133
        return $this->options['identifier'];
134
    }
135
136
    /**
137
     * Fetches objects by theses identifier values.
138
     *
139
     * @param array   $identifierValues ids values
140
     * @param Boolean $hydrate          whether or not to hydrate the objects, false returns arrays
141
     *
142
     * @return array of objects or arrays
143
     */
144
    abstract protected function findByIdentifiers(array $identifierValues, $hydrate);
145
}
146