Passed
Pull Request — master (#7581)
by
unknown
11:11
created

WhereInWalker::walkSelectStatement()   B

Complexity

Conditions 10
Paths 31

Size

Total Lines 76
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 42
CRAP Score 10.1953

Importance

Changes 0
Metric Value
cc 10
eloc 49
nc 31
nop 1
dl 0
loc 76
ccs 42
cts 48
cp 0.875
crap 10.1953
rs 7.246
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
namespace Doctrine\ORM\Tools\Pagination;
6
7
use Doctrine\ORM\Mapping\AssociationMetadata;
8
use Doctrine\ORM\Mapping\ToOneAssociationMetadata;
9
use Doctrine\ORM\Query\AST\ArithmeticExpression;
10
use Doctrine\ORM\Query\AST\ConditionalExpression;
11
use Doctrine\ORM\Query\AST\ConditionalFactor;
12
use Doctrine\ORM\Query\AST\ConditionalPrimary;
13
use Doctrine\ORM\Query\AST\ConditionalTerm;
14
use Doctrine\ORM\Query\AST\InExpression;
15
use Doctrine\ORM\Query\AST\InputParameter;
16
use Doctrine\ORM\Query\AST\NullComparisonExpression;
17
use Doctrine\ORM\Query\AST\PathExpression;
18
use Doctrine\ORM\Query\AST\SelectStatement;
19
use Doctrine\ORM\Query\AST\SimpleArithmeticExpression;
20
use Doctrine\ORM\Query\AST\WhereClause;
21
use Doctrine\ORM\Query\TreeWalkerAdapter;
22
use RuntimeException;
23
use function count;
24
use function reset;
25
26
/**
27
 * Replaces the whereClause of the AST with a WHERE id IN (:foo_1, :foo_2) equivalent.
28
 */
29
class WhereInWalker extends TreeWalkerAdapter
30
{
31
    /**
32
     * ID Count hint name.
33
     */
34
    public const HINT_PAGINATOR_ID_COUNT = 'doctrine.id.count';
35
36
    /**
37
     * Primary key alias for query.
38
     */
39
    public const PAGINATOR_ID_ALIAS = 'dpid';
40
41
    /**
42
     * Replaces the whereClause in the AST.
43
     *
44
     * Generates a clause equivalent to WHERE IN (:dpid_1, :dpid_2, ...)
45
     *
46
     * The parameter namespace (dpid) is defined by
47
     * the PAGINATOR_ID_ALIAS
48
     *
49
     * The total number of parameters is retrieved from
50
     * the HINT_PAGINATOR_ID_COUNT query hint.
51
     *
52
     * @throws RuntimeException
53
     */
54 59
    public function walkSelectStatement(SelectStatement $AST)
55
    {
56 59
        $queryComponents = $this->getQueryComponents();
57
        // Get the root entity and alias from the AST fromClause
58 59
        $from = $AST->fromClause->identificationVariableDeclarations;
59
60 59
        if (count($from) > 1) {
61
            throw new RuntimeException('Cannot count query which selects two FROM components, cannot make distinction');
62
        }
63
64 59
        $fromRoot  = reset($from);
65 59
        $rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
66 59
        $rootClass = $queryComponents[$rootAlias]['metadata'];
67 59
        $property  = $rootClass->getProperty($rootClass->getSingleIdentifierFieldName());
68 59
        $pathType  = PathExpression::TYPE_STATE_FIELD;
69
70 59
        if ($property instanceof AssociationMetadata) {
71
            $pathType = $property instanceof ToOneAssociationMetadata
72
                ? PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION
73
                : PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION;
74
        }
75
76 59
        $pathExpression = new PathExpression(
77 59
            PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
78 59
            $rootAlias,
79 59
            $property->getName()
80
        );
81
82 59
        $pathExpression->type = $pathType;
83
84 59
        $count = $this->getQuery()->getHint(self::HINT_PAGINATOR_ID_COUNT);
85
86 59
        if ($count > 0) {
87 59
            $arithmeticExpression                             = new ArithmeticExpression();
88 59
            $arithmeticExpression->simpleArithmeticExpression = new SimpleArithmeticExpression(
89 59
                [$pathExpression]
90
            );
91 59
            $expression                                       = new InExpression($arithmeticExpression);
92 59
            $expression->literals[]                           = new InputParameter(':' . self::PAGINATOR_ID_ALIAS);
93
        } else {
94
            $expression      = new NullComparisonExpression($pathExpression);
95
            $expression->not = false;
96
        }
97
98 59
        $conditionalPrimary                              = new ConditionalPrimary();
99 59
        $conditionalPrimary->simpleConditionalExpression = $expression;
100
101 59
        if ($AST->whereClause) {
102 10
            if ($AST->whereClause->conditionalExpression instanceof ConditionalTerm) {
0 ignored issues
show
introduced by
$AST->whereClause->conditionalExpression is never a sub-type of Doctrine\ORM\Query\AST\ConditionalTerm.
Loading history...
103 2
                $AST->whereClause->conditionalExpression->conditionalFactors[] = $conditionalPrimary;
104 8
            } elseif ($AST->whereClause->conditionalExpression instanceof ConditionalPrimary) {
0 ignored issues
show
introduced by
$AST->whereClause->conditionalExpression is never a sub-type of Doctrine\ORM\Query\AST\ConditionalPrimary.
Loading history...
105 5
                $AST->whereClause->conditionalExpression = new ConditionalExpression(
106 5
                    [new ConditionalTerm(
107
                        [
108 5
                            $AST->whereClause->conditionalExpression,
109 5
                            $conditionalPrimary,
110
                        ]
111
                    ),
112
                    ]
113
                );
114 3
            } elseif ($AST->whereClause->conditionalExpression instanceof ConditionalExpression
0 ignored issues
show
introduced by
$AST->whereClause->conditionalExpression is always a sub-type of Doctrine\ORM\Query\AST\ConditionalExpression.
Loading history...
115 3
                || $AST->whereClause->conditionalExpression instanceof ConditionalFactor
116
            ) {
117 3
                $tmpPrimary                              = new ConditionalPrimary();
118 3
                $tmpPrimary->conditionalExpression       = $AST->whereClause->conditionalExpression;
119 3
                $AST->whereClause->conditionalExpression = new ConditionalTerm(
0 ignored issues
show
Documentation Bug introduced by
It seems like new Doctrine\ORM\Query\A..., $conditionalPrimary)) of type Doctrine\ORM\Query\AST\ConditionalTerm is incompatible with the declared type Doctrine\ORM\Query\AST\ConditionalExpression of property $conditionalExpression.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
120
                    [
121 3
                        $tmpPrimary,
122 10
                        $conditionalPrimary,
123
                    ]
124
                );
125
            }
126
        } else {
127 49
            $AST->whereClause = new WhereClause(
128 49
                new ConditionalExpression(
129 49
                    [new ConditionalTerm([$conditionalPrimary])]
130
                )
131
            );
132
        }
133 59
    }
134
}
135