AbstractEntityPersister   F
last analyzed

Complexity

Total Complexity 86

Size/Duplication

Total Lines 629
Duplicated Lines 0 %

Test Coverage

Coverage 98.32%

Importance

Changes 0
Metric Value
eloc 212
dl 0
loc 629
ccs 234
cts 238
cp 0.9832
rs 2
c 0
b 0
f 0
wmc 86

33 Methods

Rating   Name   Duplication   Size   Complexity  
A getIdentifier() 0 3 1
A loadToOneEntity() 0 3 1
A lock() 0 3 1
A setIdentifier() 0 3 1
A getResultSetMapping() 0 3 1
A expandCriteriaParameters() 0 3 1
A getColumnValue() 0 3 1
A getClassMetadata() 0 3 1
A getEntityHydrator() 0 3 1
A getCountSQL() 0 3 1
A getOwningTable() 0 3 1
A refresh() 0 3 1
A getCacheRegion() 0 3 1
A count() 0 3 1
A getInsertSQL() 0 3 1
A expandParameters() 0 3 1
A getOneToManyCollection() 0 7 1
A __construct() 0 17 1
A getManyToManyCollection() 0 7 1
B load() 0 48 11
A loadManyToManyCollection() 0 35 5
A loadOneToManyCollection() 0 34 5
B loadCriteria() 0 34 6
A getSelectSQL() 0 9 1
A exists() 0 11 3
A getSelectConditionStatementSQL() 0 7 1
A storeEntityCache() 0 17 4
A insert() 0 5 1
B storeJoinedAssociations() 0 33 9
A getHash() 0 7 2
A loadAll() 0 31 6
A buildCollectionCacheKey() 0 6 1
C loadById() 0 51 12

How to fix   Complexity   

Complex Class

Complex classes like AbstractEntityPersister often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AbstractEntityPersister, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Cache\Persister\Entity;
6
7
use Doctrine\Common\Collections\Criteria;
8
use Doctrine\ORM\Cache;
9
use Doctrine\ORM\Cache\CollectionCacheKey;
10
use Doctrine\ORM\Cache\EntityCacheKey;
11
use Doctrine\ORM\Cache\EntityHydrator;
12
use Doctrine\ORM\Cache\Logging\CacheLogger;
13
use Doctrine\ORM\Cache\Persister\CachedPersister;
14
use Doctrine\ORM\Cache\QueryCacheKey;
15
use Doctrine\ORM\Cache\Region;
16
use Doctrine\ORM\Cache\TimestampCacheKey;
17
use Doctrine\ORM\Cache\TimestampRegion;
18
use Doctrine\ORM\EntityManagerInterface;
19
use Doctrine\ORM\Mapping\AssociationMetadata;
20
use Doctrine\ORM\Mapping\ClassMetadata;
21
use Doctrine\ORM\Mapping\ClassMetadataFactory;
22
use Doctrine\ORM\Mapping\FetchMode;
23
use Doctrine\ORM\Mapping\ManyToManyAssociationMetadata;
24
use Doctrine\ORM\Mapping\OneToManyAssociationMetadata;
25
use Doctrine\ORM\Mapping\ToOneAssociationMetadata;
26
use Doctrine\ORM\PersistentCollection;
27
use Doctrine\ORM\Persisters\Entity\EntityPersister;
28
use Doctrine\ORM\Utility\StaticClassNameConverter;
29
use function serialize;
30
use function sha1;
31
32
abstract class AbstractEntityPersister implements CachedEntityPersister
33
{
34
    /** @var EntityManagerInterface */
35
    protected $em;
36
37
    /** @var ClassMetadataFactory */
38
    protected $metadataFactory;
39
40
    /** @var EntityPersister */
41
    protected $persister;
42
43
    /** @var ClassMetadata */
44
    protected $class;
45
46
    /** @var mixed[][] */
47
    protected $queuedCache = [];
48
49
    /** @var Region */
50
    protected $region;
51
52
    /** @var TimestampRegion */
53
    protected $timestampRegion;
54
55
    /** @var TimestampCacheKey */
56
    protected $timestampKey;
57
58
    /** @var EntityHydrator */
59
    protected $hydrator;
60
61
    /** @var Cache */
62
    protected $cache;
63
64
    /** @var CacheLogger */
65
    protected $cacheLogger;
66
67
    /** @var string */
68
    protected $regionName;
69
70
    /**
71
     * Associations configured as FetchMode::EAGER, as well as all inverse one-to-one associations.
72
     *
73
     * @var string[]|null
74
     */
75
    protected $joinedAssociations;
76
77
    /**
78
     * @param EntityPersister        $persister The entity persister to cache.
79
     * @param Region                 $region    The entity cache region.
80
     * @param EntityManagerInterface $em        The entity manager.
81
     * @param ClassMetadata          $class     The entity metadata.
82
     */
83 203
    public function __construct(EntityPersister $persister, Region $region, EntityManagerInterface $em, ClassMetadata $class)
84
    {
85 203
        $configuration = $em->getConfiguration();
86 203
        $cacheConfig   = $configuration->getSecondLevelCacheConfiguration();
87 203
        $cacheFactory  = $cacheConfig->getCacheFactory();
88
89 203
        $this->em              = $em;
90 203
        $this->class           = $class;
91 203
        $this->region          = $region;
92 203
        $this->persister       = $persister;
93 203
        $this->cache           = $em->getCache();
94 203
        $this->regionName      = $region->getName();
95 203
        $this->metadataFactory = $em->getMetadataFactory();
96 203
        $this->cacheLogger     = $cacheConfig->getCacheLogger();
97 203
        $this->timestampRegion = $cacheFactory->getTimestampRegion();
98 203
        $this->hydrator        = $cacheFactory->buildEntityHydrator($em, $class);
99 203
        $this->timestampKey    = new TimestampCacheKey($this->class->getRootClassName());
100 203
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105 3
    public function getSelectSQL(
106
        $criteria,
107
        ?AssociationMetadata $association = null,
108
        $lockMode = null,
109
        $limit = null,
110
        $offset = null,
111
        array $orderBy = []
112
    ) {
113 3
        return $this->persister->getSelectSQL($criteria, $association, $lockMode, $limit, $offset, $orderBy);
114
    }
115
116
    /**
117
     * {@inheritDoc}
118
     */
119
    public function getCountSQL($criteria = [])
120
    {
121
        return $this->persister->getCountSQL($criteria);
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127 9
    public function getInsertSQL()
128
    {
129 9
        return $this->persister->getInsertSQL();
0 ignored issues
show
Bug introduced by
The method getInsertSQL() does not exist on Doctrine\ORM\Persisters\Entity\EntityPersister. It seems like you code against a sub-type of said class. However, the method does not exist in Doctrine\ORM\Cache\Persi...y\CachedEntityPersister. Are you sure you never get one of those? ( Ignorable by Annotation )

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

129
        return $this->persister->/** @scrutinizer ignore-call */ getInsertSQL();
Loading history...
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135 17
    public function getResultSetMapping()
136
    {
137 17
        return $this->persister->getResultSetMapping();
138
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143 3
    public function getSelectConditionStatementSQL(
144
        $field,
145
        $value,
146
        ?AssociationMetadata $association = null,
147
        $comparison = null
148
    ) {
149 3
        return $this->persister->getSelectConditionStatementSQL($field, $value, $association, $comparison);
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155 4
    public function exists($entity, ?Criteria $extraConditions = null)
156
    {
157 4
        if ($extraConditions === null) {
158 4
            $key = new EntityCacheKey($this->class->getRootClassName(), $this->getIdentifier($entity));
159
160 4
            if ($this->region->contains($key)) {
161 1
                return true;
162
            }
163
        }
164
165 4
        return $this->persister->exists($entity, $extraConditions);
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171 125
    public function getCacheRegion()
172
    {
173 125
        return $this->region;
174
    }
175
176
    /**
177
     * @return EntityHydrator
178
     */
179 45
    public function getEntityHydrator()
180
    {
181 45
        return $this->hydrator;
182
    }
183
184
    /**
185
     * {@inheritdoc}
186
     */
187 38
    public function storeEntityCache($entity, EntityCacheKey $key)
188
    {
189 38
        $class     = $this->class;
190 38
        $className = StaticClassNameConverter::getClass($entity);
191
192 38
        if ($className !== $this->class->getClassName()) {
193 3
            $class = $this->metadataFactory->getMetadataFor($className);
194
        }
195
196 38
        $entry  = $this->hydrator->buildCacheEntry($class, $key, $entity);
197 38
        $cached = $this->region->put($key, $entry);
198
199 38
        if ($this->cacheLogger && $cached) {
200 24
            $this->cacheLogger->entityCachePut($this->regionName, $key);
201
        }
202
203 38
        return $cached;
204
    }
205
206
    /**
207
     * @param object $entity
208
     */
209 29
    private function storeJoinedAssociations($entity)
210
    {
211 29
        if ($this->joinedAssociations === null) {
212 29
            $associations = [];
213
214 29
            foreach ($this->class->getPropertiesIterator() as $association) {
215 29
                if ($association instanceof ToOneAssociationMetadata &&
216 29
                    $association->getCache() &&
217 29
                    ($association->getFetchMode() === FetchMode::EAGER || ! $association->isOwningSide())) {
218 2
                    $associations[] = $association->getName();
219
                }
220
            }
221
222 29
            $this->joinedAssociations = $associations;
223
        }
224
225 29
        $uow = $this->em->getUnitOfWork();
226
227 29
        foreach ($this->joinedAssociations as $name) {
228 2
            $association  = $this->class->getProperty($name);
229 2
            $assocEntity  = $association->getValue($entity);
230 2
            $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\EmbeddedMetadata or 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

230
            /** @scrutinizer ignore-call */ 
231
            $targetEntity = $association->getTargetEntity();
Loading history...
231
232 2
            if ($assocEntity === null) {
233
                continue;
234
            }
235
236 2
            $assocId        = $uow->getEntityIdentifier($assocEntity);
237 2
            $assocMetadata  = $this->metadataFactory->getMetadataFor($targetEntity);
238 2
            $assocKey       = new EntityCacheKey($assocMetadata->getRootClassName(), $assocId);
239 2
            $assocPersister = $uow->getEntityPersister($targetEntity);
240
241 2
            $assocPersister->storeEntityCache($assocEntity, $assocKey);
0 ignored issues
show
Bug introduced by
The method storeEntityCache() 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

241
            $assocPersister->/** @scrutinizer ignore-call */ 
242
                             storeEntityCache($assocEntity, $assocKey);
Loading history...
242
        }
243 29
    }
244
245
    /**
246
     * Generates a string of currently query
247
     *
248
     * @param string  $query
249
     * @param string  $criteria
250
     * @param mixed[] $orderBy
251
     * @param int     $limit
252
     * @param int     $offset
253
     *
254
     * @return string
255
     */
256 17
    protected function getHash($query, $criteria, ?array $orderBy = null, $limit = null, $offset = null)
257
    {
258 17
        [$params] = $criteria instanceof Criteria
0 ignored issues
show
introduced by
$criteria is never a sub-type of Doctrine\Common\Collections\Criteria.
Loading history...
259 6
            ? $this->persister->expandCriteriaParameters($criteria)
260 17
            : $this->persister->expandParameters($criteria);
0 ignored issues
show
Bug introduced by
$criteria of type string is incompatible with the type array<mixed,mixed> expected by parameter $criteria of Doctrine\ORM\Persisters\...ter::expandParameters(). ( Ignorable by Annotation )

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

260
            : $this->persister->expandParameters(/** @scrutinizer ignore-type */ $criteria);
Loading history...
261
262 17
        return sha1($query . serialize($params) . serialize($orderBy) . $limit . $offset);
263
    }
264
265
    /**
266
     * {@inheritdoc}
267
     */
268 3
    public function expandParameters($criteria)
269
    {
270 3
        return $this->persister->expandParameters($criteria);
271
    }
272
273
    /**
274
     * {@inheritdoc}
275
     */
276 3
    public function expandCriteriaParameters(Criteria $criteria)
277
    {
278 3
        return $this->persister->expandCriteriaParameters($criteria);
279
    }
280
281
    /**
282
     * {@inheritdoc}
283
     */
284 14
    public function getClassMetadata()
285
    {
286 14
        return $this->persister->getClassMetadata();
287
    }
288
289
    /**
290
     * {@inheritdoc}
291
     */
292 3
    public function getManyToManyCollection(
293
        ManyToManyAssociationMetadata $association,
294
        $sourceEntity,
295
        $offset = null,
296
        $limit = null
297
    ) {
298 3
        return $this->persister->getManyToManyCollection($association, $sourceEntity, $offset, $limit);
299
    }
300
301
    /**
302
     * {@inheritdoc}
303
     */
304 3
    public function getOneToManyCollection(
305
        OneToManyAssociationMetadata $association,
306
        $sourceEntity,
307
        $offset = null,
308
        $limit = null
309
    ) {
310 3
        return $this->persister->getOneToManyCollection($association, $sourceEntity, $offset, $limit);
311
    }
312
313
    /**
314
     * {@inheritdoc}
315
     */
316 3
    public function getOwningTable($fieldName)
317
    {
318 3
        return $this->persister->getOwningTable($fieldName);
0 ignored issues
show
Bug introduced by
The method getOwningTable() 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...AbstractEntityPersister. ( Ignorable by Annotation )

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

318
        return $this->persister->/** @scrutinizer ignore-call */ getOwningTable($fieldName);
Loading history...
319
    }
320
321
    /**
322
     * {@inheritdoc}
323
     */
324 117
    public function getIdentifier($entity) : array
325
    {
326 117
        return $this->persister->getIdentifier($entity);
327
    }
328
329
    /**
330
     * {@inheritdoc}
331
     */
332 45
    public function setIdentifier($entity, array $id) : void
333
    {
334 45
        $this->persister->setIdentifier($entity, $id);
335 45
    }
336
337
    /**
338
     * {@inheritdoc}
339
     */
340 59
    public function getColumnValue($entity, string $columnName)
341
    {
342 59
        return $this->persister->getColumnValue($entity, $columnName);
343
    }
344
345
    /**
346
     * {@inheritdoc}
347
     */
348 99
    public function insert($entity)
349
    {
350 99
        $this->queuedCache['insert'][] = $entity;
351
352 99
        $this->persister->insert($entity);
353 99
    }
354
355
    /**
356
     * {@inheritdoc}
357
     */
358 6
    public function load(
359
        array $criteria,
360
        $entity = null,
361
        ?AssociationMetadata $association = null,
362
        array $hints = [],
363
        $lockMode = null,
364
        $limit = null,
365
        ?array $orderBy = null
366
    ) {
367 6
        if ($entity !== null || $association !== null || ! empty($hints) || $lockMode !== null) {
368 3
            return $this->persister->load($criteria, $entity, $association, $hints, $lockMode, $limit, $orderBy);
0 ignored issues
show
Bug introduced by
It seems like $orderBy can also be of type null; however, parameter $orderBy of Doctrine\ORM\Persisters\...EntityPersister::load() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

368
            return $this->persister->load($criteria, $entity, $association, $hints, $lockMode, $limit, /** @scrutinizer ignore-type */ $orderBy);
Loading history...
369
        }
370
371
        //handle only EntityRepository#findOneBy
372 3
        $query      = $this->persister->getSelectSQL($criteria, null, null, $limit, null, $orderBy);
0 ignored issues
show
Bug introduced by
It seems like $orderBy can also be of type null; however, parameter $orderBy of Doctrine\ORM\Persisters\...rsister::getSelectSQL() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

372
        $query      = $this->persister->getSelectSQL($criteria, null, null, $limit, null, /** @scrutinizer ignore-type */ $orderBy);
Loading history...
373 3
        $hash       = $this->getHash($query, $criteria, null, null, null);
0 ignored issues
show
Bug introduced by
$criteria of type array is incompatible with the type string expected by parameter $criteria of Doctrine\ORM\Cache\Persi...ityPersister::getHash(). ( Ignorable by Annotation )

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

373
        $hash       = $this->getHash($query, /** @scrutinizer ignore-type */ $criteria, null, null, null);
Loading history...
374 3
        $rsm        = $this->getResultSetMapping();
375 3
        $queryKey   = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
376 3
        $queryCache = $this->cache->getQueryCache($this->regionName);
377 3
        $result     = $queryCache->get($queryKey, $rsm);
378
379 3
        if ($result !== null) {
380 3
            if ($this->cacheLogger) {
381 3
                $this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
382
            }
383
384 3
            return $result[0];
385
        }
386
387 3
        $result = $this->persister->load($criteria, $entity, $association, $hints, $lockMode, $limit, $orderBy);
388
389 3
        if ($result === null) {
390
            return null;
391
        }
392
393 3
        $cached = $queryCache->put($queryKey, $rsm, [$result]);
394
395 3
        if ($this->cacheLogger) {
396 3
            if ($result) {
0 ignored issues
show
introduced by
$result is of type object, thus it always evaluated to true.
Loading history...
397 3
                $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
398
            }
399
400 3
            if ($cached) {
401 3
                $this->cacheLogger->queryCachePut($this->regionName, $queryKey);
402
            }
403
        }
404
405 3
        return $result;
406
    }
407
408
    /**
409
     * {@inheritdoc}
410
     */
411 8
    public function loadAll(array $criteria = [], array $orderBy = [], $limit = null, $offset = null)
412
    {
413 8
        $query      = $this->persister->getSelectSQL($criteria, null, null, $limit, $offset, $orderBy);
414 8
        $hash       = $this->getHash($query, $criteria, null, null, null);
0 ignored issues
show
Bug introduced by
$criteria of type array is incompatible with the type string expected by parameter $criteria of Doctrine\ORM\Cache\Persi...ityPersister::getHash(). ( Ignorable by Annotation )

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

414
        $hash       = $this->getHash($query, /** @scrutinizer ignore-type */ $criteria, null, null, null);
Loading history...
415 8
        $rsm        = $this->getResultSetMapping();
416 8
        $queryKey   = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
417 8
        $queryCache = $this->cache->getQueryCache($this->regionName);
418 8
        $result     = $queryCache->get($queryKey, $rsm);
419
420 8
        if ($result !== null) {
421 5
            if ($this->cacheLogger) {
422 5
                $this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
423
            }
424
425 5
            return $result;
426
        }
427
428 8
        $result = $this->persister->loadAll($criteria, $orderBy, $limit, $offset);
429 8
        $cached = $queryCache->put($queryKey, $rsm, $result);
430
431 8
        if ($this->cacheLogger) {
432 5
            if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array<mixed,mixed> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
433 5
                $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
434
            }
435
436 5
            if ($cached) {
437 5
                $this->cacheLogger->queryCachePut($this->regionName, $queryKey);
438
            }
439
        }
440
441 8
        return $result;
442
    }
443
444
    /**
445
     * {@inheritdoc}
446
     */
447 48
    public function loadById(array $identifier, $entity = null)
448
    {
449 48
        $cacheKey   = new EntityCacheKey($this->class->getRootClassName(), $identifier);
450 48
        $cacheEntry = $this->region->get($cacheKey);
451 48
        $class      = $this->class;
452
453 48
        if ($cacheEntry !== null) {
454 40
            if ($cacheEntry->class !== $this->class->getClassName()) {
0 ignored issues
show
Bug introduced by
Accessing class on the interface Doctrine\ORM\Cache\CacheEntry suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
455 3
                $class = $this->metadataFactory->getMetadataFor($cacheEntry->class);
456
            }
457
458 40
            $entity = $this->hydrator->loadCacheEntry($class, $cacheKey, $cacheEntry, $entity);
459
460 40
            if ($entity !== null) {
461 40
                if ($this->cacheLogger) {
462 40
                    $this->cacheLogger->entityCacheHit($this->regionName, $cacheKey);
463
                }
464
465 40
                return $entity;
466
            }
467
        }
468
469 33
        $entity = $this->persister->loadById($identifier, $entity);
470
471 33
        if ($entity === null) {
472 2
            return null;
473
        }
474
475 33
        $class     = $this->class;
476 33
        $className = StaticClassNameConverter::getClass($entity);
477
478 33
        if ($className !== $this->class->getClassName()) {
479 4
            $class = $this->metadataFactory->getMetadataFor($className);
480
        }
481
482 33
        $cacheEntry = $this->hydrator->buildCacheEntry($class, $cacheKey, $entity);
483 33
        $cached     = $this->region->put($cacheKey, $cacheEntry);
484
485 33
        if ($cached && ($this->joinedAssociations === null || $this->joinedAssociations)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->joinedAssociations of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
486 29
            $this->storeJoinedAssociations($entity);
487
        }
488
489 33
        if ($this->cacheLogger) {
490 30
            if ($cached) {
491 29
                $this->cacheLogger->entityCachePut($this->regionName, $cacheKey);
492
            }
493
494 30
            $this->cacheLogger->entityCacheMiss($this->regionName, $cacheKey);
495
        }
496
497 33
        return $entity;
498
    }
499
500
    /**
501
     * {@inheritDoc}
502
     */
503 2
    public function count($criteria = [])
504
    {
505 2
        return $this->persister->count($criteria);
506
    }
507
508
    /**
509
     * {@inheritdoc}
510
     */
511 6
    public function loadCriteria(Criteria $criteria)
512
    {
513 6
        $orderBy     = $criteria->getOrderings();
514 6
        $limit       = $criteria->getMaxResults();
515 6
        $offset      = $criteria->getFirstResult();
516 6
        $query       = $this->persister->getSelectSQL($criteria);
517 6
        $hash        = $this->getHash($query, $criteria, $orderBy, $limit, $offset);
0 ignored issues
show
Bug introduced by
$criteria of type Doctrine\Common\Collections\Criteria is incompatible with the type string expected by parameter $criteria of Doctrine\ORM\Cache\Persi...ityPersister::getHash(). ( Ignorable by Annotation )

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

517
        $hash        = $this->getHash($query, /** @scrutinizer ignore-type */ $criteria, $orderBy, $limit, $offset);
Loading history...
518 6
        $rsm         = $this->getResultSetMapping();
519 6
        $queryKey    = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
520 6
        $queryCache  = $this->cache->getQueryCache($this->regionName);
521 6
        $cacheResult = $queryCache->get($queryKey, $rsm);
522
523 6
        if ($cacheResult !== null) {
524 3
            if ($this->cacheLogger) {
525 3
                $this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
526
            }
527
528 3
            return $cacheResult;
529
        }
530
531 6
        $result = $this->persister->loadCriteria($criteria);
532 6
        $cached = $queryCache->put($queryKey, $rsm, $result);
533
534 6
        if ($this->cacheLogger) {
535 3
            if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array<mixed,mixed> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
536 3
                $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
537
            }
538
539 3
            if ($cached) {
540 3
                $this->cacheLogger->queryCachePut($this->regionName, $queryKey);
541
            }
542
        }
543
544 6
        return $result;
545
    }
546
547
    /**
548
     * {@inheritdoc}
549
     */
550 7
    public function loadManyToManyCollection(
551
        ManyToManyAssociationMetadata $association,
552
        $sourceEntity,
553
        PersistentCollection $collection
554
    ) {
555 7
        $uow       = $this->em->getUnitOfWork();
556 7
        $persister = $uow->getCollectionPersister($association);
557 7
        $hasCache  = ($persister instanceof CachedPersister);
558 7
        $key       = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $key is dead and can be removed.
Loading history...
559
560 7
        if (! $hasCache) {
561 3
            return $this->persister->loadManyToManyCollection($association, $sourceEntity, $collection);
562
        }
563
564 4
        $ownerId = $uow->getEntityIdentifier($collection->getOwner());
565 4
        $key     = $this->buildCollectionCacheKey($association, $ownerId);
566 4
        $list    = $persister->loadCollectionCache($collection, $key);
0 ignored issues
show
Bug introduced by
The method loadCollectionCache() does not exist on Doctrine\ORM\Persisters\...ion\CollectionPersister. It seems like you code against a sub-type of Doctrine\ORM\Persisters\...ion\CollectionPersister such as Doctrine\ORM\Cache\Persi...chedCollectionPersister. ( Ignorable by Annotation )

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

566
        /** @scrutinizer ignore-call */ 
567
        $list    = $persister->loadCollectionCache($collection, $key);
Loading history...
Bug introduced by
The method loadCollectionCache() does not exist on Doctrine\ORM\Cache\Persister\CachedPersister. It seems like you code against a sub-type of Doctrine\ORM\Cache\Persister\CachedPersister such as Doctrine\ORM\Cache\Persi...chedCollectionPersister. ( Ignorable by Annotation )

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

566
        /** @scrutinizer ignore-call */ 
567
        $list    = $persister->loadCollectionCache($collection, $key);
Loading history...
567
568 4
        if ($list !== null) {
569 4
            if ($this->cacheLogger) {
570 4
                $this->cacheLogger->collectionCacheHit($persister->getCacheRegion()->getName(), $key);
571
            }
572
573 4
            return $list;
574
        }
575
576 2
        $list = $this->persister->loadManyToManyCollection($association, $sourceEntity, $collection);
577
578 2
        $persister->storeCollectionCache($key, $list);
0 ignored issues
show
Bug introduced by
The method storeCollectionCache() does not exist on Doctrine\ORM\Cache\Persister\CachedPersister. It seems like you code against a sub-type of Doctrine\ORM\Cache\Persister\CachedPersister such as Doctrine\ORM\Cache\Persi...chedCollectionPersister. ( Ignorable by Annotation )

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

578
        $persister->/** @scrutinizer ignore-call */ 
579
                    storeCollectionCache($key, $list);
Loading history...
Bug introduced by
The method storeCollectionCache() does not exist on Doctrine\ORM\Persisters\...ion\CollectionPersister. It seems like you code against a sub-type of Doctrine\ORM\Persisters\...ion\CollectionPersister such as Doctrine\ORM\Cache\Persi...chedCollectionPersister. ( Ignorable by Annotation )

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

578
        $persister->/** @scrutinizer ignore-call */ 
579
                    storeCollectionCache($key, $list);
Loading history...
579
580 2
        if ($this->cacheLogger) {
581 2
            $this->cacheLogger->collectionCacheMiss($persister->getCacheRegion()->getName(), $key);
582
        }
583
584 2
        return $list;
585
    }
586
587
    /**
588
     * {@inheritdoc}
589
     */
590 17
    public function loadOneToManyCollection(
591
        OneToManyAssociationMetadata $association,
592
        $sourceEntity,
593
        PersistentCollection $collection
594
    ) {
595 17
        $uow       = $this->em->getUnitOfWork();
596 17
        $persister = $uow->getCollectionPersister($association);
597 17
        $hasCache  = ($persister instanceof CachedPersister);
598
599 17
        if (! $hasCache) {
600 3
            return $this->persister->loadOneToManyCollection($association, $sourceEntity, $collection);
601
        }
602
603 14
        $ownerId = $uow->getEntityIdentifier($collection->getOwner());
604 14
        $key     = $this->buildCollectionCacheKey($association, $ownerId);
605 14
        $list    = $persister->loadCollectionCache($collection, $key);
606
607 14
        if ($list !== null) {
608 11
            if ($this->cacheLogger) {
609 11
                $this->cacheLogger->collectionCacheHit($persister->getCacheRegion()->getName(), $key);
610
            }
611
612 11
            return $list;
613
        }
614
615 13
        $list = $this->persister->loadOneToManyCollection($association, $sourceEntity, $collection);
616
617 13
        $persister->storeCollectionCache($key, $list);
618
619 13
        if ($this->cacheLogger) {
620 13
            $this->cacheLogger->collectionCacheMiss($persister->getCacheRegion()->getName(), $key);
621
        }
622
623 13
        return $list;
624
    }
625
626
    /**
627
     * {@inheritdoc}
628
     */
629 5
    public function loadToOneEntity(ToOneAssociationMetadata $association, $sourceEntity, array $identifier = [])
630
    {
631 5
        return $this->persister->loadToOneEntity($association, $sourceEntity, $identifier);
632
    }
633
634
    /**
635
     * {@inheritdoc}
636
     */
637 3
    public function lock(array $criteria, $lockMode)
638
    {
639 3
        $this->persister->lock($criteria, $lockMode);
640 3
    }
641
642
    /**
643
     * {@inheritdoc}
644
     */
645 3
    public function refresh(array $id, $entity, $lockMode = null)
646
    {
647 3
        $this->persister->refresh($id, $entity, $lockMode);
648 3
    }
649
650
    /**
651
     * @param mixed[] $ownerId
652
     *
653
     * @return CollectionCacheKey
654
     */
655 18
    protected function buildCollectionCacheKey(AssociationMetadata $association, $ownerId)
656
    {
657
        /** @var ClassMetadata $metadata */
658 18
        $metadata = $this->metadataFactory->getMetadataFor($association->getSourceEntity());
659
660 18
        return new CollectionCacheKey($metadata->getRootClassName(), $association->getName(), $ownerId);
661
    }
662
}
663