Failed Conditions
Pull Request — 2.6 (#7882)
by
unknown
06:45
created

DefaultEntityHydrator::loadCacheEntry()   B

Complexity

Conditions 10
Paths 38

Size

Total Lines 47
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 28.656

Importance

Changes 0
Metric Value
eloc 27
c 0
b 0
f 0
dl 0
loc 47
ccs 12
cts 28
cp 0.4286
rs 7.6666
cc 10
nc 38
nop 4
crap 28.656

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the MIT license. For more information, see
18
 * <http://www.doctrine-project.org>.
19
 */
20
21
namespace Doctrine\ORM\Cache;
22
23
use Doctrine\Common\Util\ClassUtils;
24
25
use Doctrine\ORM\Query;
26
use Doctrine\ORM\Mapping\ClassMetadata;
27
use Doctrine\ORM\EntityManagerInterface;
28
use Doctrine\ORM\Utility\IdentifierFlattener;
29
30
/**
31
 * Default hydrator cache for entities
32
 *
33
 * @since   2.5
34
 * @author  Fabio B. Silva <[email protected]>
35
 */
36
class DefaultEntityHydrator implements EntityHydrator
37
{
38
    /**
39
     * @var \Doctrine\ORM\EntityManagerInterface
40
     */
41
    private $em;
42
43
    /**
44
     * @var \Doctrine\ORM\UnitOfWork
45
     */
46
    private $uow;
47
48
    /**
49
     * The IdentifierFlattener used for manipulating identifiers
50
     *
51
     * @var \Doctrine\ORM\Utility\IdentifierFlattener
52
     */
53
    private $identifierFlattener;
54
55
    /**
56
     * @var array
57
     */
58
    private static $hints = [Query::HINT_CACHE_ENABLED => true];
59
60
    /**
61
     * @param \Doctrine\ORM\EntityManagerInterface $em The entity manager.
62
     */
63 160
    public function __construct(EntityManagerInterface $em)
64
    {
65 160
        $this->em   = $em;
66 160
        $this->uow  = $em->getUnitOfWork();
67 160
        $this->identifierFlattener = new IdentifierFlattener($em->getUnitOfWork(), $em->getMetadataFactory());
68 160
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73 57
    public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $entity)
74
    {
75 57
        $data = $this->uow->getOriginalEntityData($entity);
76 57
        $data = array_merge($data, $metadata->getIdentifierValues($entity)); // why update has no identifier values ?
77
78 57
        if ($metadata->isVersioned) {
79 1
            $data[$metadata->versionField] = $metadata->getFieldValue($entity, $metadata->versionField);
80
        }
81
82 57
        foreach ($metadata->associationMappings as $name => $assoc) {
83 9
            if ( ! isset($data[$name])) {
84 9
                continue;
85
            }
86
87 8
            if ( ! ($assoc['type'] & ClassMetadata::TO_ONE)) {
88 2
                unset($data[$name]);
89
90 2
                continue;
91
            }
92
93 8
            if ( ! isset($assoc['cache'])) {
94
                $targetClassMetadata = $this->em->getClassMetadata($assoc['targetEntity']);
95
                $owningAssociation   = ( ! $assoc['isOwningSide'])
96
                    ? $targetClassMetadata->associationMappings[$assoc['mappedBy']]
0 ignored issues
show
Bug introduced by
Accessing associationMappings on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
97
                    : $assoc;
98
                $associationIds      = $this->identifierFlattener->flattenIdentifier(
99
                    $targetClassMetadata,
100
                    $targetClassMetadata->getIdentifierValues($data[$name])
101
                );
102
103
                unset($data[$name]);
104
105
                foreach ($associationIds as $fieldName => $fieldValue) {
106
                    if (isset($targetClassMetadata->fieldMappings[$fieldName])) {
0 ignored issues
show
Bug introduced by
Accessing fieldMappings on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
107
                        $fieldMapping = $targetClassMetadata->fieldMappings[$fieldName];
108
109
                        $data[$owningAssociation['targetToSourceKeyColumns'][$fieldMapping['columnName']]] = $fieldValue;
110
111
                        continue;
112
                    }
113
114
                    $targetAssoc = $targetClassMetadata->associationMappings[$fieldName];
115
116
                    foreach($assoc['targetToSourceKeyColumns'] as $referencedColumn => $localColumn) {
117
                        if (isset($targetAssoc['sourceToTargetKeyColumns'][$referencedColumn])) {
118
                            $data[$localColumn] = $fieldValue;
119
                        }
120
                    }
121
                }
122
123
                continue;
124
            }
125
126 8
            if ( ! isset($assoc['id'])) {
127 8
                $targetClass = ClassUtils::getClass($data[$name]);
128 8
                $targetId    = $this->uow->getEntityIdentifier($data[$name]);
129 8
                $data[$name] = new AssociationCacheEntry($targetClass, $targetId);
130
131 8
                continue;
132
            }
133
134
            // handle association identifier
135
            $targetId = is_object($data[$name]) && $this->uow->isInIdentityMap($data[$name])
136
                ? $this->uow->getEntityIdentifier($data[$name])
137
                : $data[$name];
138
139
            // @TODO - fix it !
140
            // handle UnitOfWork#createEntity hash generation
141
            if ( ! is_array($targetId)) {
142
                $data[reset($assoc['joinColumnFieldNames'])] = $targetId;
143
144
                $targetEntity = $this->em->getClassMetadata($assoc['targetEntity']);
145
                $targetId     = [$targetEntity->identifier[0] => $targetId];
0 ignored issues
show
Bug introduced by
Accessing identifier on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
146
            }
147
148
            $data[$name] = new AssociationCacheEntry($assoc['targetEntity'], $targetId);
149
        }
150
151 57
        return new EntityCacheEntry($metadata->name, $data);
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157 6
    public function loadCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, EntityCacheEntry $entry, $entity = null)
158
    {
159 6
        $data  = $entry->data;
160 6
        $hints = self::$hints;
161
162 6
        if ($entity !== null) {
163 1
            $hints[Query::HINT_REFRESH]         = true;
164 1
            $hints[Query::HINT_REFRESH_ENTITY]  = $entity;
165
        }
166
167 6
        foreach ($metadata->associationMappings as $name => $assoc) {
168
            if ( ! isset($assoc['cache']) ||  ! isset($data[$name])) {
169
                continue;
170
            }
171
172
            $assocClass     = $data[$name]->class;
173
            $assocId        = $data[$name]->identifier;
174
            $isEagerLoad    = ($assoc['fetch'] === ClassMetadata::FETCH_EAGER || ($assoc['type'] === ClassMetadata::ONE_TO_ONE && ! $assoc['isOwningSide']));
175
176
            if ( ! $isEagerLoad) {
177
                $data[$name] = $this->em->getReference($assocClass, $assocId);
178
179
                continue;
180
            }
181
182
            $assocMetadata  = $this->em->getClassMetadata($assoc['targetEntity']);
183
            $assocKey       = new EntityCacheKey($assocMetadata->rootEntityName, $assocId);
0 ignored issues
show
Bug introduced by
Accessing rootEntityName on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
184
            $assocPersister = $this->uow->getEntityPersister($assoc['targetEntity']);
185
            $assocRegion    = $assocPersister->getCacheRegion();
0 ignored issues
show
Bug introduced by
The method getCacheRegion() does not exist on Doctrine\ORM\Persisters\Entity\EntityPersister. It seems like you code against a sub-type of Doctrine\ORM\Persisters\Entity\EntityPersister such as Doctrine\ORM\Cache\Persi...y\CachedEntityPersister. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

185
            /** @scrutinizer ignore-call */ 
186
            $assocRegion    = $assocPersister->getCacheRegion();
Loading history...
186
            $assocEntry     = $assocRegion->get($assocKey);
187
188
            if ($assocEntry === null) {
189
                return null;
190
            }
191
192
            $data[$name] = $this->uow->createEntity($assocEntry->class, $assocEntry->resolveAssociationEntries($this->em), $hints);
193
        }
194
195 6
        if ($entity !== null) {
196 1
            $this->uow->registerManaged($entity, $key->identifier, $data);
197
        }
198
199 6
        $result = $this->uow->createEntity($entry->class, $data, $hints);
200
201 6
        $this->uow->hydrationComplete();
202
203 6
        return $result;
204
    }
205
}
206