source: pro-violet-viettel/sourcecode/application/libraries/Doctrine/ORM/Tools/Pagination/Paginator.php @ 345

Last change on this file since 345 was 345, checked in by quyenla, 11 years ago

collaborator page

File size: 5.4 KB
Line 
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 LGPL. For more information, see
17 * <http://www.doctrine-project.org>.
18 */
19
20namespace Doctrine\ORM\Tools\Pagination;
21
22use Doctrine\ORM\QueryBuilder;
23use Doctrine\ORM\Query;
24use Doctrine\ORM\NoResultException;
25use Doctrine\ORM\Tools\Pagination\WhereInWalker;
26use Doctrine\ORM\Tools\Pagination\CountWalker;
27use Countable;
28use IteratorAggregate;
29use ArrayIterator;
30
31/**
32 * Paginator
33 *
34 * The paginator can handle various complex scenarios with DQL.
35 *
36 * @author Pablo Díez <pablodip@gmail.com>
37 * @author Benjamin Eberlei <kontakt@beberlei.de>
38 * @license New BSD
39 */
40class Paginator implements \Countable, \IteratorAggregate
41{
42    /**
43     * @var Query
44     */
45    private $query;
46
47    /**
48     * @var bool
49     */
50    private $fetchJoinCollection;
51
52    /**
53     * @var int
54     */
55    private $count;
56
57    /**
58     * Constructor.
59     *
60     * @param Query|QueryBuilder $query A Doctrine ORM query or query builder.
61     * @param Boolean $fetchJoinCollection Whether the query joins a collection (true by default).
62     */
63    public function __construct($query, $fetchJoinCollection = true)
64    {
65        if ($query instanceof QueryBuilder) {
66            $query = $query->getQuery();
67        }
68
69        $this->query = $query;
70        $this->fetchJoinCollection = (Boolean) $fetchJoinCollection;
71    }
72
73    /**
74     * Returns the query
75     *
76     * @return Query
77     */
78    public function getQuery()
79    {
80        return $this->query;
81    }
82
83    /**
84     * Returns whether the query joins a collection.
85     *
86     * @return Boolean Whether the query joins a collection.
87     */
88    public function getFetchJoinCollection()
89    {
90        return $this->fetchJoinCollection;
91    }
92
93    /**
94     * {@inheritdoc}
95     */
96    public function count()
97    {
98        if ($this->count === null) {
99            /* @var $countQuery Query */
100            $countQuery = $this->cloneQuery($this->query);
101
102            if ( ! $countQuery->getHint(CountWalker::HINT_DISTINCT)) {
103                $countQuery->setHint(CountWalker::HINT_DISTINCT, true);
104            }
105
106            $countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker'));
107            $countQuery->setFirstResult(null)->setMaxResults(null);
108
109            try {
110                $data =  $countQuery->getScalarResult();
111                $data = array_map('current', $data);
112                $this->count = array_sum($data);
113            } catch(NoResultException $e) {
114                $this->count = 0;
115            }
116        }
117        return $this->count;
118    }
119
120    /**
121     * {@inheritdoc}
122     */
123    public function getIterator()
124    {
125        $offset = $this->query->getFirstResult();
126        $length = $this->query->getMaxResults();
127
128        if ($this->fetchJoinCollection) {
129            $subQuery = $this->cloneQuery($this->query);
130            $subQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker'))
131                ->setFirstResult($offset)
132                ->setMaxResults($length);
133
134            $ids = array_map('current', $subQuery->getScalarResult());
135
136            $whereInQuery = $this->cloneQuery($this->query);
137            // don't do this for an empty id array
138            if (count($ids) > 0) {
139                $namespace = WhereInWalker::PAGINATOR_ID_ALIAS;
140
141                $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker'));
142                $whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids));
143                $whereInQuery->setFirstResult(null)->setMaxResults(null);
144                foreach ($ids as $i => $id) {
145                    $i++;
146                    $whereInQuery->setParameter("{$namespace}_{$i}", $id);
147                }
148            }
149
150            $result = $whereInQuery->getResult($this->query->getHydrationMode());
151        } else {
152            $result = $this->cloneQuery($this->query)
153                ->setMaxResults($length)
154                ->setFirstResult($offset)
155                ->getResult($this->query->getHydrationMode())
156            ;
157        }
158        return new \ArrayIterator($result);
159    }
160
161    /**
162     * Clones a query.
163     *
164     * @param Query $query The query.
165     *
166     * @return Query The cloned query.
167     */
168    private function cloneQuery(Query $query)
169    {
170        /* @var $cloneQuery Query */
171        $cloneQuery = clone $query;
172        $cloneQuery->setParameters($query->getParameters());
173        foreach ($query->getHints() as $name => $value) {
174            $cloneQuery->setHint($name, $value);
175        }
176
177        return $cloneQuery;
178    }
179}
180
Note: See TracBrowser for help on using the repository browser.