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

getIdentifierField()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
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 12
    public function __construct(ManagerRegistry $registry, $objectClass, array $options = array())
52
    {
53 12
        $this->registry    = $registry;
54 12
        $this->objectClass = $objectClass;
55 12
        $this->options     = array_merge($this->options, $options);
56 12
    }
57
58
    /**
59
     * Returns the object class that is used for conversion.
60
     *
61
     * @return string
62
     */
63 1
    public function getObjectClass()
64
    {
65 1
        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 7
    public function transform(array $elasticaObjects)
79
    {
80 7
        $ids = $highlights = array();
81 7
        foreach ($elasticaObjects as $elasticaObject) {
82 7
            $ids[] = $elasticaObject->getId();
83 7
            $highlights[$elasticaObject->getId()] = $elasticaObject->getHighlights();
84
        }
85
86 7
        $objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
87 7 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 1
            throw new \RuntimeException('Cannot find corresponding Doctrine objects for all Elastica results.');
89
        };
90
91 6
        $propertyAccessor = $this->propertyAccessor;
92 6
        $identifier = $this->options['identifier'];
93 6
        foreach ($objects as $object) {
94 5
            if ($object instanceof HighlightableModelInterface) {
95 4
                $id = $propertyAccessor->getValue($object, $identifier);
96 5
                $object->setElasticHighlights($highlights[$id]);
97
            }
98
        }
99
100
        // sort objects in the order of ids
101 6
        $idPos = array_flip($ids);
102 6 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 5
            return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
105 6
        });
106
107 6
        return $objects;
108
    }
109
110 2
    public function hybridTransform(array $elasticaObjects)
111
    {
112 2
        $indexedElasticaResults = array();
113 2
        foreach ($elasticaObjects as $elasticaObject) {
114 2
            $indexedElasticaResults[$elasticaObject->getId()] = $elasticaObject;
115
        }
116
117 2
        $objects = $this->transform($elasticaObjects);
118
119 2
        $result = array();
120 2
        foreach ($objects as $object) {
121 2
            $id = $this->propertyAccessor->getValue($object, $this->options['identifier']);
122 2
            $result[] = new HybridResult($indexedElasticaResults[$id], $object);
123
        }
124
125 2
        return $result;
126
    }
127
128
    /**
129
     * {@inheritDoc}
130
     */
131 1
    public function getIdentifierField()
132
    {
133 1
        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