Failed Conditions
Pull Request — master (#1922)
by chihiro
36:51
created

CountWalker::walkSelectStatement()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 40
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 4.0406

Importance

Changes 0
Metric Value
cc 4
eloc 23
nc 4
nop 1
dl 0
loc 40
ccs 19
cts 22
cp 0.8636
crap 4.0406
rs 8.5806
c 0
b 0
f 0
1
<?php
2
/**
3
 * Doctrine ORM
4
 *
5
 * LICENSE
6
 *
7
 * This source file is subject to the new BSD license that is bundled
8
 * with this package in the file LICENSE.txt.
9
 * If you did not receive a copy of the license and are unable to
10
 * obtain it through the world-wide-web, please send an email
11
 * to [email protected] so I can send you a copy immediately.
12
 */
13
14
namespace Eccube\Doctrine\ORM\Tools\Pagination;
15
16
use Doctrine\ORM\Query\TreeWalkerAdapter;
17
use Doctrine\ORM\Query\AST\SelectStatement;
18
use Doctrine\ORM\Query\AST\SelectExpression;
19
use Doctrine\ORM\Query\AST\PathExpression;
20
use Doctrine\ORM\Query\AST\AggregateExpression;
21
22
/**
23
 * Replaces the selectClause of the AST with a COUNT statement.
24
 *
25
 * @category    DoctrineExtensions
26
 * @package     DoctrineExtensions\Paginate
27
 * @author      David Abdemoulaie <[email protected]>
28
 * @copyright   Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
29
 * @license     http://hobodave.com/license.txt New BSD License
30
 */
31
class CountWalker extends TreeWalkerAdapter
32
{
33
    /**
34
     * Distinct mode hint name.
35
     */
36
    const HINT_DISTINCT = 'doctrine_paginator.distinct';
37
38
    /**
39
     * Walks down a SelectStatement AST node, modifying it to retrieve a COUNT.
40
     *
41
     * @param SelectStatement $AST
42
     *
43
     * @return void
44
     *
45
     * @throws \RuntimeException
46
     */
47 11
    public function walkSelectStatement(SelectStatement $AST)
48
    {
49 11
        if ($AST->havingClause) {
50
            throw new \RuntimeException('Cannot count query that uses a HAVING clause. Use the output walkers for pagination');
51
        }
52
53 11
        $queryComponents = $this->_getQueryComponents();
54
        // Get the root entity and alias from the AST fromClause
55 11
        $from = $AST->fromClause->identificationVariableDeclarations;
56
        
0 ignored issues
show
introduced by
Please trim any trailing whitespace
Loading history...
57 11
        if (count($from) > 1) {
58
            throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
59
        }
60
       
0 ignored issues
show
introduced by
Please trim any trailing whitespace
Loading history...
61 11
        $fromRoot            = reset($from);
62 11
        $rootAlias           = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
63 11
        $rootClass           = $queryComponents[$rootAlias]['metadata'];
64 11
        $identifierFieldName = $rootClass->getSingleIdentifierFieldName();
65
66 11
        $pathType = PathExpression::TYPE_STATE_FIELD;
67 11
        if (isset($rootClass->associationMappings[$identifierFieldName])) {
68
            $pathType = PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION;
69
        }
70
71 11
        $pathExpression = new PathExpression(
72 11
            PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $rootAlias,
73
            $identifierFieldName
74
        );
75 11
        $pathExpression->type = $pathType;
76
77 11
        $distinct = $this->_getQuery()->getHint(self::HINT_DISTINCT);
78 11
        $AST->selectClause->selectExpressions = array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
79 11
            new SelectExpression(
80 11
                new AggregateExpression('count', $pathExpression, $distinct), null
81
            )
82
        );
83
84
        // ORDER BY is not needed, only increases query execution through unnecessary sorting.
85 11
        $AST->orderByClause = null;
86
    }
87
}
88
89