Completed
Pull Request — master (#6354)
by COLE
10:36
created

WhereInWalker::walkSelectStatement()   C

Complexity

Conditions 9
Paths 21

Size

Total Lines 76
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 40
CRAP Score 9.0608

Importance

Changes 0
Metric Value
dl 0
loc 76
ccs 40
cts 44
cp 0.9091
rs 5.8219
c 0
b 0
f 0
cc 9
eloc 45
nc 21
nop 1
crap 9.0608

How to fix   Long Method   

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
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\ORM\Tools\Pagination;
21
22
use Doctrine\ORM\Query\AST\ArithmeticExpression;
23
use Doctrine\ORM\Query\AST\SimpleArithmeticExpression;
24
use Doctrine\ORM\Query\TreeWalkerAdapter;
25
use Doctrine\ORM\Query\AST\SelectStatement;
26
use Doctrine\ORM\Query\AST\PathExpression;
27
use Doctrine\ORM\Query\AST\InExpression;
28
use Doctrine\ORM\Query\AST\NullComparisonExpression;
29
use Doctrine\ORM\Query\AST\InputParameter;
30
use Doctrine\ORM\Query\AST\ConditionalPrimary;
31
use Doctrine\ORM\Query\AST\ConditionalTerm;
32
use Doctrine\ORM\Query\AST\ConditionalExpression;
33
use Doctrine\ORM\Query\AST\ConditionalFactor;
34
use Doctrine\ORM\Query\AST\WhereClause;
35
36
/**
37
 * Replaces the whereClause of the AST with a WHERE id IN (:foo_1, :foo_2) equivalent.
38
 *
39
 * @category    DoctrineExtensions
40
 * @package     DoctrineExtensions\Paginate
41
 * @author      David Abdemoulaie <[email protected]>
42
 * @copyright   Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
43
 * @license     http://hobodave.com/license.txt New BSD License
44
 */
45
class WhereInWalker extends TreeWalkerAdapter
46
{
47
    /**
48
     * ID Count hint name.
49
     */
50
    const HINT_PAGINATOR_ID_COUNT = 'doctrine.id.count';
51
52
    /**
53
     * Primary key alias for query.
54
     */
55
    const PAGINATOR_ID_ALIAS = 'dpid';
56
57
    /**
58
     * Replaces the whereClause in the AST.
59
     *
60
     * Generates a clause equivalent to WHERE IN (:dpid_1, :dpid_2, ...)
61
     *
62
     * The parameter namespace (dpid) is defined by
63
     * the PAGINATOR_ID_ALIAS
64
     *
65
     * The total number of parameters is retrieved from
66
     * the HINT_PAGINATOR_ID_COUNT query hint.
67
     *
68
     * @param SelectStatement $AST
69
     *
70
     * @return void
71
     *
72
     * @throws \RuntimeException
73
     */
74 11
    public function walkSelectStatement(SelectStatement $AST)
75
    {
76 11
        $queryComponents = $this->_getQueryComponents();
77
        // Get the root entity and alias from the AST fromClause
78 11
        $from = $AST->fromClause->identificationVariableDeclarations;
79
80 11
        if (count($from) > 1) {
81
            throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
82
        }
83
84 11
        $fromRoot            = reset($from);
85 11
        $rootAlias           = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
86 11
        $rootClass           = $queryComponents[$rootAlias]['metadata'];
87 11
        $identifierFieldName = $rootClass->getSingleIdentifierFieldName();
88
89 11
        $pathType = PathExpression::TYPE_STATE_FIELD;
90 11
        if (isset($rootClass->associationMappings[$identifierFieldName])) {
91
            $pathType = PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION;
92
        }
93
94 11
        $pathExpression       = new PathExpression(PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $rootAlias, $identifierFieldName);
95 11
        $pathExpression->type = $pathType;
96
97 11
        $count = $this->_getQuery()->getHint(self::HINT_PAGINATOR_ID_COUNT);
98
99 11
        if ($count > 0) {
100 11
            $arithmeticExpression = new ArithmeticExpression();
101 11
            $arithmeticExpression->simpleArithmeticExpression = new SimpleArithmeticExpression(
102 11
                [$pathExpression]
103
            );
104 11
            $expression = new InExpression($arithmeticExpression);
105 11
            $expression->literals[] = new InputParameter(":" . self::PAGINATOR_ID_ALIAS);
106
107
        } else {
108
            $expression = new NullComparisonExpression($pathExpression);
109
            $expression->not = false;
110
        }
111
112 11
        $conditionalPrimary = new ConditionalPrimary;
113 11
        $conditionalPrimary->simpleConditionalExpression = $expression;
114 11
        if ($AST->whereClause) {
115 7
            if ($AST->whereClause->conditionalExpression instanceof ConditionalTerm) {
116 2
                $AST->whereClause->conditionalExpression->conditionalFactors[] = $conditionalPrimary;
117 5
            } elseif ($AST->whereClause->conditionalExpression instanceof ConditionalPrimary) {
118 2
                $AST->whereClause->conditionalExpression = new ConditionalExpression(
119
                    [
120 2
                        new ConditionalTerm(
121
                            [
122 2
                                $AST->whereClause->conditionalExpression,
123 2
                                $conditionalPrimary
124
                            ]
125
                        )
126
                    ]
127
                );
128 3
            } elseif ($AST->whereClause->conditionalExpression instanceof ConditionalExpression
129 3
                || $AST->whereClause->conditionalExpression instanceof ConditionalFactor
130
            ) {
131 3
                $tmpPrimary = new ConditionalPrimary;
132 3
                $tmpPrimary->conditionalExpression = $AST->whereClause->conditionalExpression;
133 3
                $AST->whereClause->conditionalExpression = new ConditionalTerm(
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Doctrine\ORM\Query\..., $conditionalPrimary)) of type object<Doctrine\ORM\Query\AST\ConditionalTerm> is incompatible with the declared type object<Doctrine\ORM\Quer...\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...
134
                    [
135 3
                        $tmpPrimary,
136 7
                        $conditionalPrimary
137
                    ]
138
                );
139
            }
140
        } else {
141 4
            $AST->whereClause = new WhereClause(
142 4
                new ConditionalExpression(
143
                    [
144 4
                        new ConditionalTerm([$conditionalPrimary])
145
                    ]
146
                )
147
            );
148
        }
149 11
    }
150
}
151