Completed
Push — master ( a0071b...e33605 )
by Michael
12s
created

lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php (7 issues)

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\Utility\StaticClassNameConverter;
15
16
/**
17
 * Default hydrator cache for entities
18
 */
19
class DefaultEntityHydrator implements EntityHydrator
20
{
21
    /**
22
     * @var \Doctrine\ORM\EntityManagerInterface
23
     */
24
    private $em;
25
26
    /**
27
     * @var \Doctrine\ORM\UnitOfWork
28
     */
29
    private $uow;
30
31
    /**
32
     * @var mixed[]
33
     */
34
    private static $hints = [Query::HINT_CACHE_ENABLED => true];
35
36
    /**
37
     * @param \Doctrine\ORM\EntityManagerInterface $em The entity manager.
38
     */
39 209
    public function __construct(EntityManagerInterface $em)
40
    {
41 209
        $this->em  = $em;
42 209
        $this->uow = $em->getUnitOfWork();
43 209
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 117
    public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $entity)
49
    {
50 117
        $identifierFlattener = $this->em->getIdentifierFlattener();
51 117
        $persister           = $this->uow->getEntityPersister($metadata->getClassName());
52
53 117
        $data = $this->uow->getOriginalEntityData($entity);
54 117
        $data = array_merge($data, $persister->getIdentifier($entity)); // why update has no identifier values ?
55
56 117
        foreach ($metadata->getDeclaredPropertiesIterator() as $name => $association) {
57 117
            if (! isset($data[$name]) || $association instanceof FieldMetadata) {
58 117
                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
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

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,
0 ignored issues
show
$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

76
                    /** @scrutinizer ignore-type */ $targetClassMetadata,
Loading history...
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 117
        return new EntityCacheEntry($metadata->getClassName(), $data);
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142 41
    public function loadCacheEntry(
143
        ClassMetadata $metadata,
144
        EntityCacheKey $key,
145
        EntityCacheEntry $entry,
146
        $entity = null
147
    ) {
148 41
        $data  = $entry->data;
149 41
        $hints = self::$hints;
150
151 41
        if ($entity !== null) {
152 6
            $hints[Query::HINT_REFRESH]        = true;
153 6
            $hints[Query::HINT_REFRESH_ENTITY] = $entity;
154
        }
155
156 41
        foreach ($metadata->getDeclaredPropertiesIterator() as $name => $association) {
157 41
            if ($association instanceof FieldMetadata || ! isset($data[$name]) || ! $association->getCache()) {
0 ignored issues
show
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 41
                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
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
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
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

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
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 3
                $hints
189
            );
190
        }
191
192 41
        if ($entity !== null) {
193 6
            $this->uow->registerManaged($entity, $key->identifier, $data);
194
        }
195
196 41
        $result = $this->uow->createEntity($entry->class, $data, $hints);
197
198 41
        $this->uow->hydrationComplete();
199
200 41
        return $result;
201
    }
202
}
203