Completed
Push — master ( 20bd58...8a579b )
by Kévin
13:04
created

EagerLoadingTrait   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 3
dl 0
loc 60
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A shouldOperationForceEager() 0 14 4
B hasFetchEagerAssociation() 0 22 5
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace ApiPlatform\Core\Bridge\Doctrine\Orm\Util;
15
16
use Doctrine\ORM\EntityManager;
17
use Doctrine\ORM\Mapping\ClassMetadataInfo;
18
19
/**
20
 * @author Antoine Bluchet <[email protected]>
21
 *
22
 * @internal
23
 */
24
trait EagerLoadingTrait
25
{
26
    private $forceEager;
27
    private $resourceMetadataFactory;
28
29
    /**
30
     * Checks if an operation has a `force_eager` attribute.
31
     *
32
     * @param string $resourceClass
33
     * @param array  $options
34
     *
35
     * @return bool
36
     */
37
    private function shouldOperationForceEager(string $resourceClass, array $options): bool
38
    {
39
        $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
40
41
        if (isset($options['collection_operation_name'])) {
42
            $forceEager = $resourceMetadata->getCollectionOperationAttribute($options['collection_operation_name'], 'force_eager', null, true);
43
        } elseif (isset($options['item_operation_name'])) {
44
            $forceEager = $resourceMetadata->getItemOperationAttribute($options['item_operation_name'], 'force_eager', null, true);
45
        } else {
46
            $forceEager = $resourceMetadata->getAttribute('force_eager');
47
        }
48
49
        return is_bool($forceEager) ? $forceEager : $this->forceEager;
50
    }
51
52
    /**
53
     * Checkes if the class has an associationMapping with FETCH=EAGER.
54
     *
55
     * @param EntityManager     $em
56
     * @param ClassMetadataInfo $classMetadata
57
     * @param array             $checked       array cache of tested metadata classes
58
     *
59
     * @return bool
60
     */
61
    private function hasFetchEagerAssociation(EntityManager $em, ClassMetadataInfo $classMetadata, array &$checked = []): bool
62
    {
63
        $checked[] = $classMetadata->name;
64
65
        foreach ($classMetadata->associationMappings as $mapping) {
66
            if (ClassMetadataInfo::FETCH_EAGER === $mapping['fetch']) {
67
                return true;
68
            }
69
70
            $related = $em->getClassMetadata($mapping['targetEntity']);
71
72
            if (in_array($related->name, $checked, true)) {
73
                continue;
74
            }
75
76
            if (true === $this->hasFetchEagerAssociation($em, $related, $checked)) {
77
                return true;
78
            }
79
        }
80
81
        return false;
82
    }
83
}
84