Passed
Pull Request — master (#7311)
by
unknown
09:29
created

applyGroupRestriction()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 52
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 28
nc 5
nop 4
dl 0
loc 52
rs 9.1608
c 1
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\DataProvider\Extension;
8
9
use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
10
use ApiPlatform\Doctrine\Orm\Extension\QueryItemExtensionInterface;
11
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
12
use ApiPlatform\Metadata\Operation;
13
use Chamilo\CoreBundle\Entity\ResourceRestrictToGroupContextInterface;
14
use Doctrine\ORM\QueryBuilder;
15
use Symfony\Component\HttpFoundation\RequestStack;
16
17
final class GroupContextQueryExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
18
{
19
    public function __construct(
20
        private readonly RequestStack $requestStack,
21
    ) {}
22
23
    public function applyToCollection(
24
        QueryBuilder $queryBuilder,
25
        QueryNameGeneratorInterface $queryNameGenerator,
26
        string $resourceClass,
27
        Operation $operation = null,
28
        array $context = []
29
    ): void {
30
        $this->applyGroupRestriction($queryBuilder, $queryNameGenerator, $resourceClass, $operation);
31
    }
32
33
    public function applyToItem(
34
        QueryBuilder $queryBuilder,
35
        QueryNameGeneratorInterface $queryNameGenerator,
36
        string $resourceClass,
37
        array $identifiers,
38
        Operation $operation = null,
39
        array $context = []
40
    ): void {
41
        $this->applyGroupRestriction($queryBuilder, $queryNameGenerator, $resourceClass, $operation);
42
    }
43
44
    private function applyGroupRestriction(
45
        QueryBuilder $queryBuilder,
46
        QueryNameGeneratorInterface $queryNameGenerator,
47
        string $resourceClass,
48
        ?Operation $operation
49
    ): void {
50
        // When API output is a DTO, $resourceClass may not be the entity class.
51
        $effectiveClass = $operation?->getClass() ?? $resourceClass;
52
53
        if (!is_a($effectiveClass, ResourceRestrictToGroupContextInterface::class, true)) {
54
            return;
55
        }
56
57
        $request = $this->requestStack->getMainRequest() ?? $this->requestStack->getCurrentRequest();
58
        if (null === $request) {
59
            return;
60
        }
61
62
        $gid = $request->query->getInt('gid', 0);
63
64
        $rootAliases = $queryBuilder->getRootAliases();
65
        if (empty($rootAliases)) {
66
            return;
67
        }
68
69
        $rootAlias = $rootAliases[0];
70
71
        $rnAlias = $queryNameGenerator->generateJoinAlias('resourceNode');
72
        $queryBuilder->join(sprintf('%s.resourceNode', $rootAlias), $rnAlias);
73
        $queryBuilder->distinct();
74
        if ($gid > 0) {
75
            $rlAlias = $queryNameGenerator->generateJoinAlias('resourceLinks');
76
            $queryBuilder->join(sprintf('%s.resourceLinks', $rnAlias), $rlAlias);
77
78
            // Match group by identifier to avoid association-vs-int issues
79
            $queryBuilder
80
                ->andWhere(sprintf('IDENTITY(%s.group) = :gid', $rlAlias))
81
                ->setParameter('gid', $gid);
82
83
            return;
84
        }
85
86
        // gid = 0 -> exclude any resource that has at least one group link
87
        $rlGroupAlias = $queryNameGenerator->generateJoinAlias('groupLinks');
88
        $queryBuilder->leftJoin(
89
            sprintf('%s.resourceLinks', $rnAlias),
90
            $rlGroupAlias,
91
            'WITH',
92
            sprintf('%s.group IS NOT NULL', $rlGroupAlias)
93
        );
94
95
        $queryBuilder->andWhere(sprintf('%s.id IS NULL', $rlGroupAlias));
96
    }
97
}
98