• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 15133993414

20 May 2025 09:30AM UTC coverage: 26.313% (-1.2%) from 27.493%
15133993414

Pull #7161

github

web-flow
Merge e2c03d45f into 5459ba375
Pull Request #7161: fix(metadata): infer parameter string type from schema

0 of 2 new or added lines in 1 file covered. (0.0%)

11019 existing lines in 363 files now uncovered.

12898 of 49018 relevant lines covered (26.31%)

34.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.67
/src/Doctrine/Orm/Util/QueryChecker.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
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\Doctrine\Orm\Util;
15

16
use Doctrine\ORM\Mapping\ClassMetadata;
17
use Doctrine\ORM\Query\Expr\Join;
18
use Doctrine\ORM\QueryBuilder;
19
use Doctrine\Persistence\ManagerRegistry;
20

21
/**
22
 * Utility functions for working with Doctrine ORM query.
23
 *
24
 * @author Teoh Han Hui <teohhanhui@gmail.com>
25
 * @author Vincent Chalamon <vincentchalamon@gmail.com>
26
 *
27
 * @internal
28
 */
29
final class QueryChecker
30
{
31
    private function __construct()
32
    {
33
    }
×
34

35
    /**
36
     * Determines whether the QueryBuilder uses a HAVING clause.
37
     */
38
    public static function hasHavingClause(QueryBuilder $queryBuilder): bool
39
    {
UNCOV
40
        return null !== $queryBuilder->getDQLPart('having');
104✔
41
    }
42

43
    /**
44
     * Determines whether the QueryBuilder has any root entity with foreign key identifier.
45
     */
46
    public static function hasRootEntityWithForeignKeyIdentifier(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry): bool
47
    {
UNCOV
48
        foreach ($queryBuilder->getRootEntities() as $rootEntity) {
104✔
49
            /** @var ClassMetadata $rootMetadata */
UNCOV
50
            $rootMetadata = $managerRegistry
104✔
UNCOV
51
                ->getManagerForClass($rootEntity)
104✔
UNCOV
52
                ->getClassMetadata($rootEntity);
104✔
53

UNCOV
54
            if ($rootMetadata->containsForeignIdentifier) {
104✔
55
                return true;
×
56
            }
57
        }
58

UNCOV
59
        return false;
104✔
60
    }
61

62
    /**
63
     * Determines whether the QueryBuilder has any composite identifier.
64
     */
65
    public static function hasRootEntityWithCompositeIdentifier(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry): bool
66
    {
UNCOV
67
        foreach ($queryBuilder->getRootEntities() as $rootEntity) {
104✔
68
            /** @var ClassMetadata $rootMetadata */
UNCOV
69
            $rootMetadata = $managerRegistry
104✔
UNCOV
70
                ->getManagerForClass($rootEntity)
104✔
UNCOV
71
                ->getClassMetadata($rootEntity);
104✔
72

UNCOV
73
            if ($rootMetadata->isIdentifierComposite) {
104✔
74
                return true;
×
75
            }
76
        }
77

UNCOV
78
        return false;
104✔
79
    }
80

81
    /**
82
     * Determines whether the QueryBuilder has a limit on the maximum number of results.
83
     */
84
    public static function hasMaxResults(QueryBuilder $queryBuilder): bool
85
    {
UNCOV
86
        return null !== $queryBuilder->getMaxResults();
104✔
87
    }
88

89
    /**
90
     * Determines whether the QueryBuilder has ORDER BY on a column from a fetch joined to-many association.
91
     */
92
    public static function hasOrderByOnFetchJoinedToManyAssociation(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry): bool
93
    {
94
        if (
UNCOV
95
            0 === \count($queryBuilder->getDQLPart('join'))
104✔
UNCOV
96
            || 0 === \count($orderByParts = $queryBuilder->getDQLPart('orderBy'))
104✔
97
        ) {
UNCOV
98
            return false;
102✔
99
        }
100

UNCOV
101
        $rootAliases = $queryBuilder->getRootAliases();
2✔
102

UNCOV
103
        $orderByAliases = [];
2✔
104

UNCOV
105
        foreach ($orderByParts as $orderBy) {
2✔
UNCOV
106
            foreach ($orderBy->getParts() as $part) {
2✔
UNCOV
107
                if (str_contains((string) $part, '.')) {
2✔
UNCOV
108
                    [$alias] = explode('.', (string) $part);
1✔
109

UNCOV
110
                    $orderByAliases[] = $alias;
1✔
111
                }
112
            }
113
        }
114

UNCOV
115
        $orderByAliases = array_diff($orderByAliases, $rootAliases);
2✔
UNCOV
116
        if (0 === \count($orderByAliases)) {
2✔
UNCOV
117
            return false;
2✔
118
        }
119

120
        $allAliases = $queryBuilder->getAllAliases();
×
121

122
        foreach ($orderByAliases as $orderByAlias) {
×
123
            $inToManyContext = false;
×
124

125
            foreach (QueryBuilderHelper::traverseJoins($orderByAlias, $queryBuilder, $managerRegistry) as $alias => [$metadata, $association]) {
×
126
                if ($inToManyContext && \in_array($alias, $allAliases, true)) {
×
127
                    return true;
×
128
                }
129

130
                if (null !== $association && $metadata->isCollectionValuedAssociation($association)) {
×
131
                    $inToManyContext = true;
×
132
                }
133
            }
134
        }
135

136
        return false;
×
137
    }
138

139
    /**
140
     * Determines whether the QueryBuilder already has a left join.
141
     */
142
    public static function hasLeftJoin(QueryBuilder $queryBuilder): bool
143
    {
144
        foreach ($queryBuilder->getDQLPart('join') as $joins) {
×
145
            foreach ($joins as $join) {
×
146
                if (Join::LEFT_JOIN === $join->getJoinType()) {
×
147
                    return true;
×
148
                }
149
            }
150
        }
151

152
        return false;
×
153
    }
154

155
    /**
156
     * Determines whether the QueryBuilder has a joined to-many association.
157
     */
158
    public static function hasJoinedToManyAssociation(QueryBuilder $queryBuilder, ManagerRegistry $managerRegistry): bool
159
    {
160
        if (
UNCOV
161
            0 === (is_countable($queryBuilder->getDQLPart('join')) ? \count($queryBuilder->getDQLPart('join')) : 0)
104✔
162
        ) {
UNCOV
163
            return false;
102✔
164
        }
165

UNCOV
166
        $joinAliases = array_diff($queryBuilder->getAllAliases(), $queryBuilder->getRootAliases());
2✔
UNCOV
167
        if (0 === \count($joinAliases)) {
2✔
168
            return false;
×
169
        }
170

UNCOV
171
        foreach ($joinAliases as $joinAlias) {
2✔
UNCOV
172
            foreach (QueryBuilderHelper::traverseJoins($joinAlias, $queryBuilder, $managerRegistry) as $alias => [$metadata, $association]) {
2✔
UNCOV
173
                if (null !== $association && $metadata->isCollectionValuedAssociation($association)) {
2✔
UNCOV
174
                    return true;
1✔
175
                }
176
            }
177
        }
178

UNCOV
179
        return false;
1✔
180
    }
181
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc