Completed
Pull Request — master (#611)
by Kévin
04:54 queued 01:40
created

hasRootEntityWithCompositeIdentifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
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
    public static function hasRootEntityWithForeignKeyIdentifier(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry) : bool
46
    {
47
        return self::hasRootEntityWithIdentifier($queryBuilder, $managerRegistry, true);
48
    }
49
50
    /**
51
     * Determines whether the query builder has any composite identifier.
52
     *
53
     * @param QueryBuilder    $queryBuilder
54
     * @param ManagerRegistry $managerRegistry
55
     *
56
     * @return bool
57
     */
58
    public static function hasRootEntityWithCompositeIdentifier(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry) : bool
59
    {
60
        return self::hasRootEntityWithIdentifier($queryBuilder, $managerRegistry, false);
61
    }
62
63
    private static function hasRootEntityWithIdentifier(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry, $foreign) : bool
64
    {
65
        foreach ($queryBuilder->getRootEntities() as $rootEntity) {
66
            $rootMetadata = $managerRegistry
67
                ->getManagerForClass($rootEntity)
68
                ->getClassMetadata($rootEntity);
69
70
            if ($foreign ? $rootMetadata->isIdentifierComposite : $rootMetadata->containsForeignIdentifier) {
71
                return true;
72
            }
73
        }
74
75
        return false;
76
    }
77
78
    /**
79
     * Determines whether the query builder has the maximum number of results specified.
80
     *
81
     * @param QueryBuilder $queryBuilder
82
     *
83
     * @return bool
84
     */
85
    public static function hasMaxResults(QueryBuilder $queryBuilder) : bool
86
    {
87
        return null !== $queryBuilder->getMaxResults();
88
    }
89
90
    /**
91
     * Determines whether the query builder has ORDER BY on entity joined through
92
     * to-many association.
93
     *
94
     * @param QueryBuilder    $queryBuilder
95
     * @param ManagerRegistry $managerRegistry
96
     *
97
     * @return bool
98
     */
99
    public static function hasOrderByOnToManyJoin(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry) : bool
100
    {
101
        if (
102
            empty($orderByParts = $queryBuilder->getDQLPart('orderBy')) ||
103
            empty($joinParts = $queryBuilder->getDQLPart('join'))
104
        ) {
105
            return false;
106
        }
107
108
        $orderByAliases = [];
109
        foreach ($orderByParts as $orderBy) {
110
            $parts = QueryNameGenerator::getOrderByParts($orderBy);
111
112
            foreach ($parts as $part) {
113
                if (false !== ($pos = strpos($part, '.'))) {
114
                    $alias = substr($part, 0, $pos);
115
116
                    $orderByAliases[$alias] = true;
117
                }
118
            }
119
        }
120
121
        if (!empty($orderByAliases)) {
122
            foreach ($joinParts as $rootAlias => $joins) {
123
                foreach ($joins as $join) {
124
                    $alias = QueryNameGenerator::getJoinAlias($join);
125
126
                    if (isset($orderByAliases[$alias])) {
127
                        $relationship = QueryNameGenerator::getJoinRelationship($join);
128
129
                        $relationshipParts = explode('.', $relationship);
130
                        $parentAlias = $relationshipParts[0];
131
                        $association = $relationshipParts[1];
132
133
                        $parentMetadata = QueryNameGenerator::getClassMetadataFromJoinAlias($parentAlias, $queryBuilder, $managerRegistry);
134
135
                        if ($parentMetadata->isCollectionValuedAssociation($association)) {
136
                            return true;
137
                        }
138
                    }
139
                }
140
            }
141
        }
142
143
        return false;
144
    }
145
}
146