Failed Conditions
CANCELLED  
Pull Request — 2.6 (#7180)
by Ben
07:44
created

DefaultEntityHydrator::buildCacheEntry()   C

Complexity

Conditions 15
Paths 36

Size

Total Lines 79
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 37
CRAP Score 15.9061

Importance

Changes 0
Metric Value
cc 15
eloc 43
nc 36
nop 3
dl 0
loc 79
rs 5.9166
c 0
b 0
f 0
ccs 37
cts 44
cp 0.8409
crap 15.9061

How to fix   Long Method    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 209
    public function __construct(EntityManagerInterface $em)
64
    {
65 209
        $this->em   = $em;
66 209
        $this->uow  = $em->getUnitOfWork();
67 209
        $this->identifierFlattener = new IdentifierFlattener($em->getUnitOfWork(), $em->getMetadataFactory());
68 209
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73 109
    public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $entity)
74
    {
75 109
        $data = $this->uow->getOriginalEntityData($entity);
76 109
        $data = array_merge($data, $metadata->getIdentifierValues($entity)); // why update has no identifier values ?
77
78 109
        if ($metadata->isVersioned) {
79 1
            $data[$metadata->versionField] = $metadata->getFieldValue($entity, $metadata->versionField);
80
        }
81
82 109
        foreach ($metadata->associationMappings as $name => $assoc) {
83 62
            if ( ! isset($data[$name])) {
84 18
                continue;
85
            }
86
87 61
            if ( ! ($assoc['type'] & ClassMetadata::TO_ONE)) {
88 51
                unset($data[$name]);
89
90 51
                continue;
91
            }
92
93 60
            if ( ! isset($assoc['cache'])) {
94 3
                $targetClassMetadata = $this->em->getClassMetadata($assoc['targetEntity']);
95 3
                $owningAssociation   = ( ! $assoc['isOwningSide'])
96 1
                    ? $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 3
                    : $assoc;
98 3
                $associationIds      = $this->identifierFlattener->flattenIdentifier(
99 3
                    $targetClassMetadata,
100 3
                    $targetClassMetadata->getIdentifierValues($data[$name])
101
                );
102
103 3
                unset($data[$name]);
104
105 3
                foreach ($associationIds as $fieldName => $fieldValue) {
106 3
                    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 3
                        $fieldMapping = $targetClassMetadata->fieldMappings[$fieldName];
108
109 3
                        $data[$owningAssociation['targetToSourceKeyColumns'][$fieldMapping['columnName']]] = $fieldValue;
110
111 3
                        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 3
                continue;
124
            }
125
126 58
            if ( ! isset($assoc['id'])) {
127 58
                $targetClass = ClassUtils::getClass($data[$name]);
128 58
                $targetId    = $this->uow->getEntityIdentifier($data[$name]);
129 58
                $data[$name] = new AssociationCacheEntry($targetClass, $targetId);
130
131 58
                continue;
132
            }
133
134
            // handle association identifier
135 4
            $targetId = is_object($data[$name]) && $this->uow->isInIdentityMap($data[$name])
136 4
                ? $this->uow->getEntityIdentifier($data[$name])
137 4
                : $data[$name];
138
139
            // @TODO - fix it !
140
            // handle UnitOfWork#createEntity hash generation
141 4
            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 4
            $data[$name] = new AssociationCacheEntry($assoc['targetEntity'], $targetId);
149
        }
150
151 109
        return new EntityCacheEntry($metadata->name, $data);
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157 36
    public function loadCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, EntityCacheEntry $entry, $entity = null)
158
    {
159 36
        $data  = $entry->data;
160 36
        $hints = self::$hints;
161
162 36
        if ($entity !== null) {
163 5
            $hints[Query::HINT_REFRESH]         = true;
164 5
            $hints[Query::HINT_REFRESH_ENTITY]  = $entity;
165
        }
166
167 36
        foreach ($metadata->associationMappings as $name => $assoc) {
168 28
            if ( ! isset($assoc['cache']) ||  ! isset($data[$name])) {
169 22
                continue;
170
            }
171
172 25
            $assocClass     = $data[$name]->class;
173 25
            $assocId        = $data[$name]->identifier;
174 25
            $isEagerLoad    = ($assoc['fetch'] === ClassMetadata::FETCH_EAGER || ($assoc['type'] === ClassMetadata::ONE_TO_ONE && ! $assoc['isOwningSide']));
175
176 25
            if ( ! $isEagerLoad) {
177 24
                $data[$name] = $this->em->getReference($assocClass, $assocId);
178
179 24
                continue;
180
            }
181
182 1
            $assocMetadata  = $this->em->getClassMetadata($assoc['targetEntity']);
183 1
            $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 1
            $assocPersister = $this->uow->getEntityPersister($assoc['targetEntity']);
185 1
            $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 1
            $assocEntry     = $assocRegion->get($assocKey);
187
188 1
            if ($assocEntry === null) {
189
                return null;
190
            }
191
192 1
            $data[$name] = $this->uow->createEntity($assocEntry->class, $assocEntry->resolveAssociationEntries($this->em), $hints);
193
        }
194
195 36
        if ($entity !== null) {
196 5
            $this->uow->registerManaged($entity, $key->identifier, $data);
197
        }
198
199 36
        $result = $this->uow->createEntity($entry->class, $data, $hints);
200
201 36
        $this->uow->hydrationComplete();
202
203 36
        return $result;
204
    }
205
}
206