Completed
Pull Request — 2.1 (#1324)
by Vincent
03:18
created

QueryBuilderHelper   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 4

Importance

Changes 0
Metric Value
wmc 9
lcom 0
cbo 4
dl 0
loc 66
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A addJoinOnce() 0 19 4
A getExistingJoin() 0 17 4
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\Query\Expr\Join;
17
use Doctrine\ORM\QueryBuilder;
18
19
/**
20
 * @author Vincent Chalamon <[email protected]>
21
 *
22
 * @internal
23
 */
24
final class QueryBuilderHelper
25
{
26
    private function __construct()
27
    {
28
    }
29
30
    /**
31
     * Adds a join to the queryBuilder if none exists.
32
     *
33
     * @param QueryBuilder                $queryBuilder
34
     * @param QueryNameGeneratorInterface $queryNameGenerator
35
     * @param string                      $alias
36
     * @param string                      $association        the association field
37
     * @param string|null                 $joinType           the join type (left join / inner join)
38
     * @param string|null                 $conditionType
39
     * @param string|null                 $condition
40
     *
41
     * @return string the new association alias
42
     */
43
    public static function addJoinOnce(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $alias, string $association, $joinType = null, $conditionType = null, $condition = null): string
44
    {
45
        $join = self::getExistingJoin($queryBuilder, $alias, $association);
46
47
        if (null === $join) {
48
            $associationAlias = $queryNameGenerator->generateJoinAlias($association);
49
            $query = sprintf('%s.%s', $alias, $association);
50
51
            if (Join::LEFT_JOIN === $joinType || true === QueryChecker::hasLeftJoin($queryBuilder)) {
52
                $queryBuilder->leftJoin($query, $associationAlias, $conditionType, $condition);
53
            } else {
54
                $queryBuilder->innerJoin($query, $associationAlias, $conditionType, $condition);
55
            }
56
        } else {
57
            $associationAlias = $join->getAlias();
58
        }
59
60
        return $associationAlias;
61
    }
62
63
    /**
64
     * Get the existing join from queryBuilder DQL parts.
65
     *
66
     * @param QueryBuilder $queryBuilder
67
     * @param string       $alias
68
     * @param string       $association  the association field
69
     *
70
     * @return Join|null
71
     */
72
    private static function getExistingJoin(QueryBuilder $queryBuilder, string $alias, string $association)
73
    {
74
        $parts = $queryBuilder->getDQLPart('join');
75
76
        if (!isset($parts['o'])) {
77
            return null;
78
        }
79
80
        foreach ($parts['o'] as $join) {
81
            /** @var Join $join */
82
            if (sprintf('%s.%s', $alias, $association) === $join->getJoin()) {
83
                return $join;
84
            }
85
        }
86
87
        return null;
88
    }
89
}
90