Completed
Push — master ( ec265b...65ebad )
by Luís
14s
created

DefaultEntityHydrator::buildCacheEntry()   D

Complexity

Conditions 16
Paths 30

Size

Total Lines 93
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 49
CRAP Score 16.002

Importance

Changes 0
Metric Value
cc 16
eloc 49
nc 30
nop 3
dl 0
loc 93
rs 4.8736
c 0
b 0
f 0
ccs 49
cts 50
cp 0.98
crap 16.002

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
    /**
24
     * @var EntityManagerInterface
25
     */
26
    private $em;
27
28
    /**
29
     * @var UnitOfWork
30
     */
31
    private $uow;
32
33
    /**
34
     * @var mixed[]
35
     */
36
    private static $hints = [Query::HINT_CACHE_ENABLED => true];
37
38
    /**
39
     * @param EntityManagerInterface $em The entity manager.
40
     */
41 210
    public function __construct(EntityManagerInterface $em)
42
    {
43 210
        $this->em  = $em;
44 210
        $this->uow = $em->getUnitOfWork();
45 210
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 118
    public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $entity)
51
    {
52 118
        $identifierFlattener = $this->em->getIdentifierFlattener();
53 118
        $persister           = $this->uow->getEntityPersister($metadata->getClassName());
54
55 118
        $data = $this->uow->getOriginalEntityData($entity);
56 118
        $data = array_merge($data, $persister->getIdentifier($entity)); // why update has no identifier values ?
57
58 118
        if ($metadata->isVersioned()) {
59 1
            $data[$metadata->versionProperty->getName()] = $metadata->versionProperty->getValue($entity);
60
        }
61
62 118
        foreach ($metadata->getDeclaredPropertiesIterator() as $name => $association) {
63 118
            if (! isset($data[$name]) || $association instanceof FieldMetadata) {
64 118
                continue;
65
            }
66
67 70
            if (! $association instanceof ToOneAssociationMetadata) {
68 59
                unset($data[$name]);
69
70 59
                continue;
71
            }
72
73 69
            $targetEntity        = $association->getTargetEntity();
74 69
            $targetClassMetadata = $this->em->getClassMetadata($targetEntity);
75 69
            $targetPersister     = $this->uow->getEntityPersister($targetEntity);
76
77 69
            if (! $association->getCache()) {
78 5
                $owningAssociation = ! $association->isOwningSide()
79 1
                    ? $targetClassMetadata->getProperty($association->getMappedBy())
0 ignored issues
show
Bug introduced by
The method getProperty() does not exist on Doctrine\Common\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

79
                    ? $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...
80 5
                    : $association;
81 5
                $associationIds    = $identifierFlattener->flattenIdentifier(
82 5
                    $targetClassMetadata,
0 ignored issues
show
Bug introduced by
$targetClassMetadata of type Doctrine\Common\Persistence\Mapping\ClassMetadata is incompatible with the type Doctrine\ORM\Mapping\ClassMetadata expected by parameter $class of Doctrine\ORM\Utility\Ide...er::flattenIdentifier(). ( Ignorable by Annotation )

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

82
                    /** @scrutinizer ignore-type */ $targetClassMetadata,
Loading history...
83 5
                    $targetPersister->getIdentifier($data[$name])
84
                );
85
86 5
                unset($data[$name]);
87
88 5
                foreach ($associationIds as $fieldName => $fieldValue) {
89
                    // $fieldName = "name"
90
                    // $fieldColumnName = "custom_name"
91 5
                    $property = $targetClassMetadata->getProperty($fieldName);
92
93 5
                    if ($property instanceof FieldMetadata) {
94 5
                        foreach ($owningAssociation->getJoinColumns() as $joinColumn) {
95
                            // $joinColumnName = "custom_name"
96
                            // $joinColumnReferencedColumnName = "other_side_of_assoc_column_name"
97 5
                            if ($joinColumn->getReferencedColumnName() !== $property->getColumnName()) {
98
                                continue;
99
                            }
100
101 5
                            $data[$joinColumn->getColumnName()] = $fieldValue;
102
103 5
                            break;
104
                        }
105
106 5
                        continue;
107
                    }
108
109 1
                    $targetAssociation = $targetClassMetadata->getProperty($fieldName);
110
111 1
                    foreach ($association->getJoinColumns() as $assocJoinColumn) {
112 1
                        foreach ($targetAssociation->getJoinColumns() as $targetAssocJoinColumn) {
113 1
                            if ($assocJoinColumn->getReferencedColumnName() !== $targetAssocJoinColumn->getColumnName()) {
114 1
                                continue;
115
                            }
116
117 1
                            $data[$assocJoinColumn->getColumnName()] = $fieldValue;
118
                        }
119
                    }
120
                }
121
122 5
                continue;
123
            }
124
125 65
            if (! $association->isPrimaryKey()) {
126 64
                $targetClass = StaticClassNameConverter::getClass($data[$name]);
127 64
                $targetId    = $this->uow->getEntityIdentifier($data[$name]);
128 64
                $data[$name] = new AssociationCacheEntry($targetClass, $targetId);
129
130 64
                continue;
131
            }
132
133
            // handle association identifier
134 5
            $targetId = $this->em->getIdentifierFlattener()->flattenIdentifier(
135 5
                $targetClassMetadata,
136 5
                $targetPersister->getIdentifier($data[$name])
137
            );
138
139 5
            $data[$name] = new AssociationCacheEntry($targetEntity, $targetId);
140
        }
141
142 118
        return new EntityCacheEntry($metadata->getClassName(), $data);
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148 42
    public function loadCacheEntry(
149
        ClassMetadata $metadata,
150
        EntityCacheKey $key,
151
        EntityCacheEntry $entry,
152
        $entity = null
153
    ) {
154 42
        $data  = $entry->data;
155 42
        $hints = self::$hints;
156
157 42
        if ($entity !== null) {
158 6
            $hints[Query::HINT_REFRESH]        = true;
159 6
            $hints[Query::HINT_REFRESH_ENTITY] = $entity;
160
        }
161
162 42
        foreach ($metadata->getDeclaredPropertiesIterator() as $name => $association) {
163 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

163
            if ($association instanceof FieldMetadata || ! isset($data[$name]) || ! $association->/** @scrutinizer ignore-call */ getCache()) {
Loading history...
164 42
                continue;
165
            }
166
167 28
            $assocClass  = $data[$name]->class;
168 28
            $assocId     = $data[$name]->identifier;
169
            $isEagerLoad = (
170 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

170
                $association->/** @scrutinizer ignore-call */ 
171
                              getFetchMode() === FetchMode::EAGER ||
Loading history...
171 28
                ($association instanceof OneToOneAssociationMetadata && ! $association->isOwningSide())
172
            );
173
174 28
            if (! $isEagerLoad) {
175 26
                $data[$name] = $this->em->getReference($assocClass, $assocId);
176
177 26
                continue;
178
            }
179
180 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

180
            /** @scrutinizer ignore-call */ 
181
            $targetEntity   = $association->getTargetEntity();
Loading history...
181 3
            $assocMetadata  = $this->em->getClassMetadata($targetEntity);
182 3
            $assocKey       = new EntityCacheKey($assocMetadata->getRootClassName(), $assocId);
0 ignored issues
show
Bug introduced by
The method getRootClassName() does not exist on Doctrine\Common\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

182
            $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...
183 3
            $assocPersister = $this->uow->getEntityPersister($targetEntity);
184 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

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