Completed
Push — master ( 8c259e...a3e53b )
by Guilherme
27:10 queued 12:02
created

DefaultEntityHydrator::loadCacheEntry()   B

Complexity

Conditions 11
Paths 38

Size

Total Lines 59
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 11.0036

Importance

Changes 0
Metric Value
cc 11
eloc 33
c 0
b 0
f 0
nc 38
nop 4
dl 0
loc 59
ccs 31
cts 32
cp 0.9688
crap 11.0036
rs 7.3166

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
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Cache;
6
7
use Doctrine\ORM\EntityManagerInterface;
8
use Doctrine\ORM\Mapping\ClassMetadata;
9
use Doctrine\ORM\Mapping\FetchMode;
10
use Doctrine\ORM\Mapping\FieldMetadata;
11
use Doctrine\ORM\Mapping\OneToOneAssociationMetadata;
12
use Doctrine\ORM\Mapping\ToOneAssociationMetadata;
13
use Doctrine\ORM\Query;
14
use Doctrine\ORM\UnitOfWork;
15
use Doctrine\ORM\Utility\StaticClassNameConverter;
16
use function array_merge;
17
18
/**
19
 * Default hydrator cache for entities
20
 */
21
class DefaultEntityHydrator implements EntityHydrator
22
{
23
    /** @var EntityManagerInterface */
24
    private $em;
25
26
    /** @var UnitOfWork */
27
    private $uow;
28
29
    /** @var mixed[] */
30
    private static $hints = [Query::HINT_CACHE_ENABLED => true];
31
32
    /**
33
     * @param EntityManagerInterface $em The entity manager.
34
     */
35 210
    public function __construct(EntityManagerInterface $em)
36
    {
37 210
        $this->em  = $em;
38 210
        $this->uow = $em->getUnitOfWork();
39 210
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44 118
    public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $entity)
45
    {
46 118
        $identifierFlattener = $this->em->getIdentifierFlattener();
47 118
        $persister           = $this->uow->getEntityPersister($metadata->getClassName());
48
49 118
        $data = $this->uow->getOriginalEntityData($entity);
50 118
        $data = array_merge($data, $persister->getIdentifier($entity)); // why update has no identifier values ?
51
52 118
        if ($metadata->isVersioned()) {
53 1
            $data[$metadata->versionProperty->getName()] = $metadata->versionProperty->getValue($entity);
54
        }
55
56 118
        foreach ($metadata->getPropertiesIterator() as $name => $association) {
57 118
            if (! isset($data[$name]) || $association instanceof FieldMetadata) {
58 118
                continue;
59
            }
60
61 70
            if (! $association instanceof ToOneAssociationMetadata) {
62 59
                unset($data[$name]);
63
64 59
                continue;
65
            }
66
67 69
            $targetEntity        = $association->getTargetEntity();
68 69
            $targetClassMetadata = $this->em->getClassMetadata($targetEntity);
69 69
            $targetPersister     = $this->uow->getEntityPersister($targetEntity);
70
71 69
            if (! $association->getCache()) {
72 5
                $owningAssociation = ! $association->isOwningSide()
73 1
                    ? $targetClassMetadata->getProperty($association->getMappedBy())
0 ignored issues
show
Bug introduced by
The method getProperty() does not exist on Doctrine\Persistence\Mapping\ClassMetadata. ( Ignorable by Annotation )

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

73
                    ? $targetClassMetadata->/** @scrutinizer ignore-call */ getProperty($association->getMappedBy())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
74 5
                    : $association;
75 5
                $associationIds    = $identifierFlattener->flattenIdentifier(
76 5
                    $targetClassMetadata,
77 5
                    $targetPersister->getIdentifier($data[$name])
78
                );
79
80 5
                unset($data[$name]);
81
82 5
                foreach ($associationIds as $fieldName => $fieldValue) {
83
                    // $fieldName = "name"
84
                    // $fieldColumnName = "custom_name"
85 5
                    $property = $targetClassMetadata->getProperty($fieldName);
86
87 5
                    if ($property instanceof FieldMetadata) {
88 5
                        foreach ($owningAssociation->getJoinColumns() as $joinColumn) {
89
                            // $joinColumnName = "custom_name"
90
                            // $joinColumnReferencedColumnName = "other_side_of_assoc_column_name"
91 5
                            if ($joinColumn->getReferencedColumnName() !== $property->getColumnName()) {
92
                                continue;
93
                            }
94
95 5
                            $data[$joinColumn->getColumnName()] = $fieldValue;
96
97 5
                            break;
98
                        }
99
100 5
                        continue;
101
                    }
102
103 1
                    $targetAssociation = $targetClassMetadata->getProperty($fieldName);
104
105 1
                    foreach ($association->getJoinColumns() as $assocJoinColumn) {
106 1
                        foreach ($targetAssociation->getJoinColumns() as $targetAssocJoinColumn) {
107 1
                            if ($assocJoinColumn->getReferencedColumnName() !== $targetAssocJoinColumn->getColumnName()) {
108 1
                                continue;
109
                            }
110
111 1
                            $data[$assocJoinColumn->getColumnName()] = $fieldValue;
112
                        }
113
                    }
114
                }
115
116 5
                continue;
117
            }
118
119 65
            if (! $association->isPrimaryKey()) {
120 64
                $targetClass = StaticClassNameConverter::getClass($data[$name]);
121 64
                $targetId    = $this->uow->getEntityIdentifier($data[$name]);
122 64
                $data[$name] = new AssociationCacheEntry($targetClass, $targetId);
123
124 64
                continue;
125
            }
126
127
            // handle association identifier
128 5
            $targetId = $this->em->getIdentifierFlattener()->flattenIdentifier(
129 5
                $targetClassMetadata,
130 5
                $targetPersister->getIdentifier($data[$name])
131
            );
132
133 5
            $data[$name] = new AssociationCacheEntry($targetEntity, $targetId);
134
        }
135
136 118
        return new EntityCacheEntry($metadata->getClassName(), $data);
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142 42
    public function loadCacheEntry(
143
        ClassMetadata $metadata,
144
        EntityCacheKey $key,
145
        EntityCacheEntry $entry,
146
        $entity = null
147
    ) {
148 42
        $data  = $entry->data;
149 42
        $hints = self::$hints;
150
151 42
        if ($entity !== null) {
152 6
            $hints[Query::HINT_REFRESH]        = true;
153 6
            $hints[Query::HINT_REFRESH_ENTITY] = $entity;
154
        }
155
156 42
        foreach ($metadata->getPropertiesIterator() as $name => $association) {
157 42
            if ($association instanceof FieldMetadata || ! isset($data[$name]) || ! $association->getCache()) {
0 ignored issues
show
Bug introduced by
The method getCache() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata or Doctrine\ORM\Mapping\EmbeddedClassMetadata. ( Ignorable by Annotation )

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

157
            if ($association instanceof FieldMetadata || ! isset($data[$name]) || ! $association->/** @scrutinizer ignore-call */ getCache()) {
Loading history...
158 42
                continue;
159
            }
160
161 28
            $assocClass  = $data[$name]->class;
162 28
            $assocId     = $data[$name]->identifier;
163
            $isEagerLoad = (
164 28
                $association->getFetchMode() === FetchMode::EAGER ||
0 ignored issues
show
Bug introduced by
The method getFetchMode() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

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

164
                $association->/** @scrutinizer ignore-call */ 
165
                              getFetchMode() === FetchMode::EAGER ||
Loading history...
165 28
                ($association instanceof OneToOneAssociationMetadata && ! $association->isOwningSide())
166
            );
167
168 28
            if (! $isEagerLoad) {
169 26
                $data[$name] = $this->em->getReference($assocClass, $assocId);
170
171 26
                continue;
172
            }
173
174 3
            $targetEntity   = $association->getTargetEntity();
0 ignored issues
show
Bug introduced by
The method getTargetEntity() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

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

174
            /** @scrutinizer ignore-call */ 
175
            $targetEntity   = $association->getTargetEntity();
Loading history...
175 3
            $assocMetadata  = $this->em->getClassMetadata($targetEntity);
176 3
            $assocKey       = new EntityCacheKey($assocMetadata->getRootClassName(), $assocId);
0 ignored issues
show
Bug introduced by
The method getRootClassName() does not exist on Doctrine\Persistence\Mapping\ClassMetadata. ( Ignorable by Annotation )

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

176
            $assocKey       = new EntityCacheKey($assocMetadata->/** @scrutinizer ignore-call */ getRootClassName(), $assocId);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
177 3
            $assocPersister = $this->uow->getEntityPersister($targetEntity);
178 3
            $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

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