Failed Conditions
Pull Request — 2.8.x (#7919)
by
unknown
07:31
created

DefaultCache::containsEntity()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 10
ccs 6
cts 6
cp 1
crap 2
rs 10
c 0
b 0
f 0
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\ORM\Cache;
24
use Doctrine\Common\Util\ClassUtils;
25
use Doctrine\ORM\Mapping\ClassMetadata;
26
use Doctrine\ORM\EntityManagerInterface;
27
use Doctrine\ORM\Cache\Persister\CachedPersister;
28
use Doctrine\ORM\ORMInvalidArgumentException;
29
30
/**
31
 * Provides an API for querying/managing the second level cache regions.
32
 *
33
 * @since   2.5
34
 * @author  Fabio B. Silva <[email protected]>
35
 */
36
class DefaultCache implements Cache
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
     * @var \Doctrine\ORM\Cache\CacheFactory
50
     */
51
    private $cacheFactory;
52
53
    /**
54
     * @var \Doctrine\ORM\Cache\QueryCache[]
55
     */
56
    private $queryCaches = [];
57
58
    /**
59
     * @var \Doctrine\ORM\Cache\QueryCache
60
     */
61
    private $defaultQueryCache;
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 237
    public function __construct(EntityManagerInterface $em)
67
    {
68 237
        $this->em           = $em;
69 237
        $this->uow          = $em->getUnitOfWork();
70 237
        $this->cacheFactory = $em->getConfiguration()
71 237
            ->getSecondLevelCacheConfiguration()
72 237
            ->getCacheFactory();
73 237
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78 7
    public function getEntityCacheRegion($className)
79
    {
80 7
        $metadata  = $this->em->getClassMetadata($className);
81 7
        $persister = $this->uow->getEntityPersister($metadata->rootEntityName);
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...
82
83 7
        if ( ! ($persister instanceof CachedPersister)) {
84 6
            return null;
85
        }
86
87 1
        return $persister->getCacheRegion();
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93 2
    public function getCollectionCacheRegion($className, $association)
94
    {
95 2
        $metadata  = $this->em->getClassMetadata($className);
96 2
        $persister = $this->uow->getCollectionPersister($metadata->getAssociationMapping($association));
0 ignored issues
show
Bug introduced by
The method getAssociationMapping() does not exist on Doctrine\Common\Persistence\Mapping\ClassMetadata. Did you maybe mean getAssociationNames()? ( Ignorable by Annotation )

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

96
        $persister = $this->uow->getCollectionPersister($metadata->/** @scrutinizer ignore-call */ getAssociationMapping($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...
97
98 2
        if ( ! ($persister instanceof CachedPersister)) {
99 2
            return null;
100
        }
101
102
        return $persister->getCacheRegion();
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 54
    public function containsEntity($className, $identifier)
109
    {
110 54
        $metadata   = $this->em->getClassMetadata($className);
111 54
        $persister  = $this->uow->getEntityPersister($metadata->rootEntityName);
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...
112
113 54
        if ( ! ($persister instanceof CachedPersister)) {
114 53
            return false;
115
        }
116
117 1
        return $persister->getCacheRegion()->contains($this->buildEntityCacheKey($metadata, $identifier));
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123 1
    public function evictEntity($className, $identifier)
124
    {
125 1
        $metadata  = $this->em->getClassMetadata($className);
126 1
        $persister = $this->uow->getEntityPersister($metadata->rootEntityName);
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...
127
128 1
        if ( ! ($persister instanceof CachedPersister)) {
129 1
            return;
130
        }
131
132
        $persister->getCacheRegion()->evict($this->buildEntityCacheKey($metadata, $identifier));
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138 21
    public function evictEntityRegion($className)
139
    {
140 21
        $metadata  = $this->em->getClassMetadata($className);
141 21
        $persister = $this->uow->getEntityPersister($metadata->rootEntityName);
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...
142
143 21
        if ( ! ($persister instanceof CachedPersister)) {
144 21
            return;
145
        }
146
147
        $persister->getCacheRegion()->evictAll();
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153 33
    public function evictEntityRegions()
154
    {
155 33
        $metadatas = $this->em->getMetadataFactory()->getAllMetadata();
156
157 33
        foreach ($metadatas as $metadata) {
158 33
            $persister = $this->uow->getEntityPersister($metadata->rootEntityName);
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...
159
160 33
            if ( ! ($persister instanceof CachedPersister)) {
161 33
                continue;
162
            }
163
164 1
            $persister->getCacheRegion()->evictAll();
165
        }
166 33
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171 5
    public function containsCollection($className, $association, $ownerIdentifier)
172
    {
173 5
        $metadata  = $this->em->getClassMetadata($className);
174 5
        $persister = $this->uow->getCollectionPersister($metadata->getAssociationMapping($association));
175
176 5
        if ( ! ($persister instanceof CachedPersister)) {
177 5
            return false;
178
        }
179
180
        return $persister->getCacheRegion()->contains($this->buildCollectionCacheKey($metadata, $association, $ownerIdentifier));
181
    }
182
183
    /**
184
     * {@inheritdoc}
185
     */
186 1
    public function evictCollection($className, $association, $ownerIdentifier)
187
    {
188 1
        $metadata  = $this->em->getClassMetadata($className);
189 1
        $persister = $this->uow->getCollectionPersister($metadata->getAssociationMapping($association));
190
191 1
        if ( ! ($persister instanceof CachedPersister)) {
192 1
            return;
193
        }
194
195
        $persister->getCacheRegion()->evict($this->buildCollectionCacheKey($metadata, $association, $ownerIdentifier));
196
    }
197
198
    /**
199
     * {@inheritdoc}
200
     */
201 8
    public function evictCollectionRegion($className, $association)
202
    {
203 8
        $metadata  = $this->em->getClassMetadata($className);
204 8
        $persister = $this->uow->getCollectionPersister($metadata->getAssociationMapping($association));
205
206 8
        if ( ! ($persister instanceof CachedPersister)) {
207 8
            return;
208
        }
209
210
        $persister->getCacheRegion()->evictAll();
211
    }
212
213
    /**
214
     * {@inheritdoc}
215
     */
216 31
    public function evictCollectionRegions()
217
    {
218 31
        $metadatas = $this->em->getMetadataFactory()->getAllMetadata();
219
220 31
        foreach ($metadatas as $metadata) {
221
222 31
            foreach ($metadata->associationMappings as $association) {
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...
223
224 31
                if ( ! $association['type'] & ClassMetadata::TO_MANY) {
225
                    continue;
226
                }
227
228 31
                $persister = $this->uow->getCollectionPersister($association);
229
230 31
                if ( ! ($persister instanceof CachedPersister)) {
231 31
                    continue;
232
                }
233
234 31
                $persister->getCacheRegion()->evictAll();
235
            }
236
        }
237 31
    }
238
239
    /**
240
     * {@inheritdoc}
241
     */
242 1
    public function containsQuery($regionName)
243
    {
244 1
        return isset($this->queryCaches[$regionName]);
245
    }
246
247
    /**
248
     * {@inheritdoc}
249
     */
250 3
    public function evictQueryRegion($regionName = null)
251
    {
252 3
        if ($regionName === null && $this->defaultQueryCache !== null) {
253 1
            $this->defaultQueryCache->clear();
254
255 1
            return;
256
        }
257
258 3
        if (isset($this->queryCaches[$regionName])) {
259 1
            $this->queryCaches[$regionName]->clear();
260
        }
261 3
    }
262
263
    /**
264
     * {@inheritdoc}
265
     */
266 33
    public function evictQueryRegions()
267
    {
268 33
        $this->getQueryCache()->clear();
269
270 33
        foreach ($this->queryCaches as $queryCache) {
271 1
            $queryCache->clear();
272
        }
273 33
    }
274
275
    /**
276
     * {@inheritdoc}
277
     */
278 36
    public function getQueryCache($regionName = null)
279
    {
280 36
        if ($regionName === null) {
281 35
            return $this->defaultQueryCache ?:
282 35
                $this->defaultQueryCache = $this->cacheFactory->buildQueryCache($this->em);
283
        }
284
285 2
        if ( ! isset($this->queryCaches[$regionName])) {
286 2
            $this->queryCaches[$regionName] = $this->cacheFactory->buildQueryCache($this->em, $regionName);
287
        }
288
289 2
        return $this->queryCaches[$regionName];
290
    }
291
292
     /**
293
     * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata   The entity metadata.
294
     * @param mixed                               $identifier The entity identifier.
295
     *
296
     * @return \Doctrine\ORM\Cache\EntityCacheKey
297
     */
298 1
    private function buildEntityCacheKey(ClassMetadata $metadata, $identifier)
299
    {
300 1
        if ( ! is_array($identifier)) {
301 1
            $identifier = $this->toIdentifierArray($metadata, $identifier);
302
        }
303
304 1
        return new EntityCacheKey($metadata->rootEntityName, $identifier);
305
    }
306
307
    /**
308
     * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata        The entity metadata.
309
     * @param string                              $association     The field name that represents the association.
310
     * @param mixed                               $ownerIdentifier The identifier of the owning entity.
311
     *
312
     * @return \Doctrine\ORM\Cache\CollectionCacheKey
313
     */
314
    private function buildCollectionCacheKey(ClassMetadata $metadata, $association, $ownerIdentifier)
315
    {
316
        if ( ! is_array($ownerIdentifier)) {
317
            $ownerIdentifier = $this->toIdentifierArray($metadata, $ownerIdentifier);
318
        }
319
320
        return new CollectionCacheKey($metadata->rootEntityName, $association, $ownerIdentifier);
321
    }
322
323
    /**
324
     * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata   The entity metadata.
325
     * @param mixed                               $identifier The entity identifier.
326
     *
327
     * @return array
328
     */
329 2
    private function toIdentifierArray(ClassMetadata $metadata, $identifier)
330
    {
331 2
        if (is_object($identifier) && $this->em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($identifier))) {
332
            $identifier = $this->uow->getSingleIdentifierValue($identifier);
333
334
            if ($identifier === null) {
335
                throw ORMInvalidArgumentException::invalidIdentifierBindingEntity();
336
            }
337
        }
338
339 2
        return [$metadata->identifier[0] => $identifier];
340
    }
341
342
}
343