Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / lib / Doctrine / ORM / Tools / Pagination / LimitSubqueryWalker.php
1 <?php
2
3 /**
4  * Doctrine ORM
5  *
6  * LICENSE
7  *
8  * This source file is subject to the new BSD license that is bundled
9  * with this package in the file LICENSE. This license can also be viewed
10  * at http://hobodave.com/license.txt
11  *
12  * @category    DoctrineExtensions
13  * @package     DoctrineExtensions\Paginate
14  * @author      David Abdemoulaie <dave@hobodave.com>
15  * @copyright   Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
16  * @license     http://hobodave.com/license.txt New BSD License
17  */
18
19 namespace Doctrine\ORM\Tools\Pagination;
20
21 use Doctrine\DBAL\Types\Type,
22     Doctrine\ORM\Query\TreeWalkerAdapter,
23     Doctrine\ORM\Query\AST\SelectStatement,
24     Doctrine\ORM\Query\AST\SelectExpression,
25     Doctrine\ORM\Query\AST\PathExpression,
26     Doctrine\ORM\Query\AST\AggregateExpression;
27
28 /**
29  * Replaces the selectClause of the AST with a SELECT DISTINCT root.id equivalent
30  *
31  * @category    DoctrineExtensions
32  * @package     DoctrineExtensions\Paginate
33  * @author      David Abdemoulaie <dave@hobodave.com>
34  * @copyright   Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
35  * @license     http://hobodave.com/license.txt New BSD License
36  */
37 class LimitSubqueryWalker extends TreeWalkerAdapter
38 {
39     /**
40      * ID type hint
41      */
42     const IDENTIFIER_TYPE = 'doctrine_paginator.id.type';
43
44     /**
45      * @var int Counter for generating unique order column aliases
46      */
47     private $_aliasCounter = 0;
48
49     /**
50      * Walks down a SelectStatement AST node, modifying it to retrieve DISTINCT ids
51      * of the root Entity
52      *
53      * @param SelectStatement $AST
54      * @return void
55      */
56     public function walkSelectStatement(SelectStatement $AST)
57     {
58         $parent = null;
59         $parentName = null;
60         $selectExpressions = array();
61
62         foreach ($this->_getQueryComponents() as $dqlAlias => $qComp) {
63             // preserve mixed data in query for ordering
64             if (isset($qComp['resultVariable'])) {
65                 $selectExpressions[] = new SelectExpression($qComp['resultVariable'], $dqlAlias);
66                 continue;
67             }
68
69             if ($qComp['parent'] === null && $qComp['nestingLevel'] == 0) {
70                 $parent = $qComp;
71                 $parentName = $dqlAlias;
72                 continue;
73             }
74         }
75
76         $identifier = $parent['metadata']->getSingleIdentifierFieldName();
77         if (isset($parent['metadata']->associationMappings[$identifier])) {
78             throw new \RuntimeException("Paginating an entity with foreign key as identifier only works when using the Output Walkers. Call Paginator#setUseOutputWalkers(true) before iterating the paginator.");
79         }
80
81         $this->_getQuery()->setHint(
82             self::IDENTIFIER_TYPE,
83             Type::getType($parent['metadata']->getTypeOfField($identifier))
84         );
85
86         $pathExpression = new PathExpression(
87             PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
88             $parentName,
89             $identifier
90         );
91         $pathExpression->type = PathExpression::TYPE_STATE_FIELD;
92
93         array_unshift($selectExpressions, new SelectExpression($pathExpression, '_dctrn_id'));
94         $AST->selectClause->selectExpressions = $selectExpressions;
95
96         if (isset($AST->orderByClause)) {
97             foreach ($AST->orderByClause->orderByItems as $item) {
98                 if ($item->expression instanceof PathExpression) {
99                     $pathExpression = new PathExpression(
100                         PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
101                         $item->expression->identificationVariable,
102                         $item->expression->field
103                     );
104                     $pathExpression->type = PathExpression::TYPE_STATE_FIELD;
105                     $AST->selectClause->selectExpressions[] = new SelectExpression(
106                         $pathExpression,
107                         '_dctrn_ord' . $this->_aliasCounter++
108                     );
109                 }
110             }
111         }
112
113         $AST->selectClause->isDistinct = true;
114     }
115
116 }
117
118
119