Failed Conditions
Push — master ( 82c91a...ddb3cd )
by Guilherme
15:32 queued 12:12
created

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

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Cache;
6
7
use Doctrine\ORM\Cache;
8
use Doctrine\ORM\Cache\Persister\CachedPersister;
9
use Doctrine\ORM\EntityManagerInterface;
10
use Doctrine\ORM\Mapping\ClassMetadata;
11
use Doctrine\ORM\Mapping\ToManyAssociationMetadata;
12
use Doctrine\ORM\ORMInvalidArgumentException;
13
use Doctrine\ORM\Utility\StaticClassNameConverter;
14
15
/**
16
 * Provides an API for querying/managing the second level cache regions.
17
 */
18
class DefaultCache implements Cache
19
{
20
    /**
21
     * @var \Doctrine\ORM\EntityManagerInterface
22
     */
23
    private $em;
24
25
    /**
26
     * @var \Doctrine\ORM\UnitOfWork
27
     */
28
    private $uow;
29
30
    /**
31
     * @var \Doctrine\ORM\Cache\CacheFactory
32
     */
33
    private $cacheFactory;
34
35
    /**
36
     * @var \Doctrine\ORM\Cache\QueryCache[]
37
     */
38
    private $queryCaches = [];
39
40
    /**
41
     * @var \Doctrine\ORM\Cache\QueryCache
42
     */
43
    private $defaultQueryCache;
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 279
    public function __construct(EntityManagerInterface $em)
49
    {
50 279
        $this->em           = $em;
51 279
        $this->uow          = $em->getUnitOfWork();
52 279
        $this->cacheFactory = $em->getConfiguration()
53 279
            ->getSecondLevelCacheConfiguration()
54 279
            ->getCacheFactory();
55 279
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60 25
    public function getEntityCacheRegion($className)
61
    {
62 25
        $metadata  = $this->em->getClassMetadata($className);
63 25
        $persister = $this->uow->getEntityPersister($metadata->getRootClassName());
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

63
        $persister = $this->uow->getEntityPersister($metadata->/** @scrutinizer ignore-call */ getRootClassName());

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...
64
65 25
        if (! ($persister instanceof CachedPersister)) {
66 5
            return null;
67
        }
68
69 25
        return $persister->getCacheRegion();
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 6
    public function getCollectionCacheRegion($className, $association)
76
    {
77 6
        $metadata  = $this->em->getClassMetadata($className);
78 6
        $persister = $this->uow->getCollectionPersister($metadata->getProperty($association));
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

78
        $persister = $this->uow->getCollectionPersister($metadata->/** @scrutinizer ignore-call */ getProperty($association));

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...
79
80 6
        if (! ($persister instanceof CachedPersister)) {
81 1
            return null;
82
        }
83
84 6
        return $persister->getCacheRegion();
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90 68
    public function containsEntity($className, $identifier)
91
    {
92 68
        $metadata  = $this->em->getClassMetadata($className);
93 68
        $persister = $this->uow->getEntityPersister($metadata->getRootClassName());
94
95 68
        if (! ($persister instanceof CachedPersister)) {
96 4
            return false;
97
        }
98
99 68
        return $persister->getCacheRegion()->contains($this->buildEntityCacheKey($metadata, $identifier));
0 ignored issues
show
$metadata of type Doctrine\Common\Persistence\Mapping\ClassMetadata is incompatible with the type Doctrine\ORM\Mapping\ClassMetadata expected by parameter $metadata of Doctrine\ORM\Cache\Defau...::buildEntityCacheKey(). ( Ignorable by Annotation )

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

99
        return $persister->getCacheRegion()->contains($this->buildEntityCacheKey(/** @scrutinizer ignore-type */ $metadata, $identifier));
Loading history...
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105 4
    public function evictEntity($className, $identifier)
106
    {
107 4
        $metadata  = $this->em->getClassMetadata($className);
108 4
        $persister = $this->uow->getEntityPersister($metadata->getRootClassName());
109
110 4
        if (! ($persister instanceof CachedPersister)) {
111 1
            return;
112
        }
113
114 4
        $persister->getCacheRegion()->evict($this->buildEntityCacheKey($metadata, $identifier));
0 ignored issues
show
$metadata of type Doctrine\Common\Persistence\Mapping\ClassMetadata is incompatible with the type Doctrine\ORM\Mapping\ClassMetadata expected by parameter $metadata of Doctrine\ORM\Cache\Defau...::buildEntityCacheKey(). ( Ignorable by Annotation )

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

114
        $persister->getCacheRegion()->evict($this->buildEntityCacheKey(/** @scrutinizer ignore-type */ $metadata, $identifier));
Loading history...
115 4
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120 29
    public function evictEntityRegion($className)
121
    {
122 29
        $metadata  = $this->em->getClassMetadata($className);
123 29
        $persister = $this->uow->getEntityPersister($metadata->getRootClassName());
124
125 29
        if (! ($persister instanceof CachedPersister)) {
126 2
            return;
127
        }
128
129 29
        $persister->getCacheRegion()->evictAll();
130 29
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135 48
    public function evictEntityRegions()
136
    {
137 48
        $metadatas = $this->em->getMetadataFactory()->getAllMetadata();
138
139 48
        foreach ($metadatas as $metadata) {
140 48
            $persister = $this->uow->getEntityPersister($metadata->getRootClassName());
141
142 48
            if (! ($persister instanceof CachedPersister)) {
143 48
                continue;
144
            }
145
146 48
            $persister->getCacheRegion()->evictAll();
147
        }
148 48
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153 18
    public function containsCollection($className, $association, $ownerIdentifier)
154
    {
155 18
        $metadata  = $this->em->getClassMetadata($className);
156 18
        $persister = $this->uow->getCollectionPersister($metadata->getProperty($association));
157
158 18
        if (! ($persister instanceof CachedPersister)) {
159 1
            return false;
160
        }
161
162 18
        return $persister->getCacheRegion()->contains($this->buildCollectionCacheKey($metadata, $association, $ownerIdentifier));
0 ignored issues
show
$metadata of type Doctrine\Common\Persistence\Mapping\ClassMetadata is incompatible with the type Doctrine\ORM\Mapping\ClassMetadata expected by parameter $metadata of Doctrine\ORM\Cache\Defau...ildCollectionCacheKey(). ( Ignorable by Annotation )

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

162
        return $persister->getCacheRegion()->contains($this->buildCollectionCacheKey(/** @scrutinizer ignore-type */ $metadata, $association, $ownerIdentifier));
Loading history...
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168 2
    public function evictCollection($className, $association, $ownerIdentifier)
169
    {
170 2
        $metadata  = $this->em->getClassMetadata($className);
171 2
        $persister = $this->uow->getCollectionPersister($metadata->getProperty($association));
172
173 2
        if (! ($persister instanceof CachedPersister)) {
174 1
            return;
175
        }
176
177 2
        $persister->getCacheRegion()->evict($this->buildCollectionCacheKey($metadata, $association, $ownerIdentifier));
0 ignored issues
show
$metadata of type Doctrine\Common\Persistence\Mapping\ClassMetadata is incompatible with the type Doctrine\ORM\Mapping\ClassMetadata expected by parameter $metadata of Doctrine\ORM\Cache\Defau...ildCollectionCacheKey(). ( Ignorable by Annotation )

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

177
        $persister->getCacheRegion()->evict($this->buildCollectionCacheKey(/** @scrutinizer ignore-type */ $metadata, $association, $ownerIdentifier));
Loading history...
178 2
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183 9
    public function evictCollectionRegion($className, $association)
184
    {
185 9
        $metadata  = $this->em->getClassMetadata($className);
186 9
        $persister = $this->uow->getCollectionPersister($metadata->getProperty($association));
187
188 9
        if (! ($persister instanceof CachedPersister)) {
189 1
            return;
190
        }
191
192 9
        $persister->getCacheRegion()->evictAll();
193 9
    }
194
195
    /**
196
     * {@inheritdoc}
197
     */
198 46
    public function evictCollectionRegions()
199
    {
200 46
        $metadatas = $this->em->getMetadataFactory()->getAllMetadata();
201
202 46
        foreach ($metadatas as $metadata) {
203 46
            foreach ($metadata->getDeclaredPropertiesIterator() as $association) {
0 ignored issues
show
The method getDeclaredPropertiesIterator() 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

203
            foreach ($metadata->/** @scrutinizer ignore-call */ getDeclaredPropertiesIterator() as $association) {

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...
204 46
                if (! $association instanceof ToManyAssociationMetadata) {
205 46
                    continue;
206
                }
207
208 46
                $persister = $this->uow->getCollectionPersister($association);
209
210 46
                if (! ($persister instanceof CachedPersister)) {
211 46
                    continue;
212
                }
213
214 46
                $persister->getCacheRegion()->evictAll();
215
            }
216
        }
217 46
    }
218
219
    /**
220
     * {@inheritdoc}
221
     */
222 1
    public function containsQuery($regionName)
223
    {
224 1
        return isset($this->queryCaches[$regionName]);
225
    }
226
227
    /**
228
     * {@inheritdoc}
229
     */
230 3
    public function evictQueryRegion($regionName = null)
231
    {
232 3
        if ($regionName === null && $this->defaultQueryCache !== null) {
233 1
            $this->defaultQueryCache->clear();
234
235 1
            return;
236
        }
237
238 3
        if (isset($this->queryCaches[$regionName])) {
239 1
            $this->queryCaches[$regionName]->clear();
240
        }
241 3
    }
242
243
    /**
244
     * {@inheritdoc}
245
     */
246 47
    public function evictQueryRegions()
247
    {
248 47
        $this->getQueryCache()->clear();
249
250 47
        foreach ($this->queryCaches as $queryCache) {
251 1
            $queryCache->clear();
252
        }
253 47
    }
254
255
    /**
256
     * {@inheritdoc}
257
     */
258 64
    public function getQueryCache($regionName = null)
259
    {
260 64
        if ($regionName === null) {
261 60
            return $this->defaultQueryCache ?:
262 60
                $this->defaultQueryCache = $this->cacheFactory->buildQueryCache($this->em);
263
        }
264
265 14
        if (! isset($this->queryCaches[$regionName])) {
266 14
            $this->queryCaches[$regionName] = $this->cacheFactory->buildQueryCache($this->em, $regionName);
267
        }
268
269 14
        return $this->queryCaches[$regionName];
270
    }
271
272
    /**
273
     * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata   The entity metadata.
274
     * @param mixed                               $identifier The entity identifier.
275
     *
276
     * @return \Doctrine\ORM\Cache\EntityCacheKey
277
     */
278 69
    private function buildEntityCacheKey(ClassMetadata $metadata, $identifier)
279
    {
280 69
        if (! is_array($identifier)) {
281 67
            $identifier = $this->toIdentifierArray($metadata, $identifier);
282
        }
283
284 69
        return new EntityCacheKey($metadata->getRootClassName(), $identifier);
285
    }
286
287
    /**
288
     * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata        The entity metadata.
289
     * @param string                              $association     The field name that represents the association.
290
     * @param mixed                               $ownerIdentifier The identifier of the owning entity.
291
     *
292
     * @return \Doctrine\ORM\Cache\CollectionCacheKey
293
     */
294 19
    private function buildCollectionCacheKey(ClassMetadata $metadata, $association, $ownerIdentifier)
295
    {
296 19
        if (! is_array($ownerIdentifier)) {
297 19
            $ownerIdentifier = $this->toIdentifierArray($metadata, $ownerIdentifier);
298
        }
299
300 19
        return new CollectionCacheKey($metadata->getRootClassName(), $association, $ownerIdentifier);
301
    }
302
303
    /**
304
     * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata   The entity metadata.
305
     * @param mixed                               $identifier The entity identifier.
306
     *
307
     * @return mixed[]
308
     */
309 74
    private function toIdentifierArray(ClassMetadata $metadata, $identifier)
310
    {
311 74
        if (is_object($identifier) && $this->em->getMetadataFactory()->hasMetadataFor(StaticClassNameConverter::getClass($identifier))) {
312
            $identifier = $this->uow->getSingleIdentifierValue($identifier);
313
314
            if ($identifier === null) {
315
                throw ORMInvalidArgumentException::invalidIdentifierBindingEntity();
316
            }
317
        }
318
319 74
        return [$metadata->identifier[0] => $identifier];
320
    }
321
}
322