Completed
Pull Request — master (#504)
by Antoine
03:27
created

hasRootEntityWithCompositeIdentifier()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 14
Ratio 100 %
Metric Value
dl 14
loc 14
rs 9.4285
cc 3
eloc 8
nc 3
nop 2
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
namespace ApiPlatform\Core\Bridge\Doctrine\Orm\Util;
13
14
use Doctrine\Common\Persistence\ManagerRegistry;
15
use Doctrine\ORM\QueryBuilder;
16
17
/**
18
 * Utility functions for working with Doctrine ORM query.
19
 *
20
 * @author Teoh Han Hui <[email protected]>
21
 * @author Vincent Chalamon <[email protected]>
22
 */
23
abstract class QueryChecker
24
{
25
    /**
26
     * Determines whether the query builder uses a HAVING clause.
27
     *
28
     * @param QueryBuilder $queryBuilder
29
     *
30
     * @return bool
31
     */
32
    public static function hasHavingClause(QueryBuilder $queryBuilder) : bool
33
    {
34
        return !empty($queryBuilder->getDQLPart('having'));
35
    }
36
37
    /**
38
     * Determines whether the query builder has any root entity with foreign key identifier.
39
     *
40
     * @param QueryBuilder    $queryBuilder
41
     * @param ManagerRegistry $managerRegistry
42
     *
43
     * @return bool
44
     */
45 View Code Duplication
    public static function hasRootEntityWithForeignKeyIdentifier(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry) : bool
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
46
    {
47
        foreach ($queryBuilder->getRootEntities() as $rootEntity) {
48
            $rootMetadata = $managerRegistry
49
                ->getManagerForClass($rootEntity)
50
                ->getClassMetadata($rootEntity);
51
52
            if ($rootMetadata->containsForeignIdentifier) {
53
                return true;
54
            }
55
        }
56
57
        return false;
58
    }
59
60
    /**
61
     * Determines whether the query builder has any composite identifier.
62
     *
63
     * @param QueryBuilder    $queryBuilder
64
     * @param ManagerRegistry $managerRegistry
65
     *
66
     * @return bool
67
     */
68 View Code Duplication
    public static function hasRootEntityWithCompositeIdentifier(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry) : bool
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
69
    {
70
        foreach ($queryBuilder->getRootEntities() as $rootEntity) {
71
            $rootMetadata = $managerRegistry
72
                ->getManagerForClass($rootEntity)
73
                ->getClassMetadata($rootEntity);
74
75
            if ($rootMetadata->isIdentifierComposite) {
76
                return true;
77
            }
78
        }
79
80
        return false;
81
    }
82
83
    /**
84
     * Determines whether the query builder has the maximum number of results specified.
85
     *
86
     * @param QueryBuilder $queryBuilder
87
     *
88
     * @return bool
89
     */
90
    public static function hasMaxResults(QueryBuilder $queryBuilder) : bool
91
    {
92
        return null !== $queryBuilder->getMaxResults();
93
    }
94
95
    /**
96
     * Determines whether the query builder has ORDER BY on entity joined through
97
     * to-many association.
98
     *
99
     * @param QueryBuilder    $queryBuilder
100
     * @param ManagerRegistry $managerRegistry
101
     *
102
     * @return bool
103
     */
104
    public static function hasOrderByOnToManyJoin(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry) : bool
105
    {
106
        if (
107
            empty($orderByParts = $queryBuilder->getDQLPart('orderBy')) ||
108
            empty($joinParts = $queryBuilder->getDQLPart('join'))
109
        ) {
110
            return false;
111
        }
112
113
        $orderByAliases = [];
114
        foreach ($orderByParts as $orderBy) {
115
            $parts = QueryNameGenerator::getOrderByParts($orderBy);
116
117
            foreach ($parts as $part) {
118
                if (false !== ($pos = strpos($part, '.'))) {
119
                    $alias = substr($part, 0, $pos);
120
121
                    $orderByAliases[$alias] = true;
122
                }
123
            }
124
        }
125
126
        if (!empty($orderByAliases)) {
127
            foreach ($joinParts as $rootAlias => $joins) {
128
                foreach ($joins as $join) {
129
                    $alias = QueryNameGenerator::getJoinAlias($join);
130
131
                    if (isset($orderByAliases[$alias])) {
132
                        $relationship = QueryNameGenerator::getJoinRelationship($join);
133
134
                        $relationshipParts = explode('.', $relationship);
135
                        $parentAlias = $relationshipParts[0];
136
                        $association = $relationshipParts[1];
137
138
                        $parentMetadata = QueryNameGenerator::getClassMetadataFromJoinAlias($parentAlias, $queryBuilder, $managerRegistry);
139
140
                        if ($parentMetadata->isCollectionValuedAssociation($association)) {
141
                            return true;
142
                        }
143
                    }
144
                }
145
            }
146
        }
147
148
        return false;
149
    }
150
}
151