vendor/bundles/Pagerfanta/Adapter/DoctrineORMAdapter.php
author cavaliet
Fri, 21 Oct 2011 17:10:54 +0200
changeset 15 99ad73ef7385
permissions -rw-r--r--
first step for tag list and add Pagerfanta for paginator
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
     1
<?php
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
     2
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
     3
/*
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
     4
 * This file is part of the Pagerfanta package.
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
     5
 *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
     6
 * (c) Pablo Díez <pablodip@gmail.com>
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
     7
 *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
     8
 * For the full copyright and license information, please view the LICENSE
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
     9
 * file that was distributed with this source code.
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    10
 */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    11
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    12
namespace Pagerfanta\Adapter;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    13
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    14
use Doctrine\ORM\QueryBuilder;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    15
use Doctrine\ORM\Query;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    16
use Doctrine\ORM\NoResultException;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    17
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    18
/**
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    19
 * DoctrineORMAdapter.
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    20
 *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    21
 * @author Pablo Díez <pablodip@gmail.com>
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    22
 * @author Benjamin Eberlei <kontakt@beberlei.de>
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    23
 *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    24
 * @api
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    25
 */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    26
class DoctrineORMAdapter implements AdapterInterface
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    27
{
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    28
    /**
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    29
     * @var Query
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    30
     */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    31
    private $query;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    32
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    33
    private $fetchJoinCollection;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    34
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    35
    /**
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    36
     * Constructor.
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    37
     *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    38
     * @param Query|QueryBuilder $query               A Doctrine ORM query or query builder.
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    39
     * @param Boolean            $fetchJoinCollection Whether the query joins a collection (false by default).
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    40
     *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    41
     * @api
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    42
     */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    43
    public function __construct($query, $fetchJoinCollection = false)
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    44
    {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    45
        if ($query instanceof QueryBuilder) {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    46
            $query = $query->getQuery();
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    47
        }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    48
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    49
        $this->query = $query;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    50
        $this->fetchJoinCollection = (Boolean) $fetchJoinCollection;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    51
    }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    52
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    53
    /**
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    54
     * Returns the query
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    55
     *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    56
     * @return Query
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    57
     *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    58
     * @api
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    59
     */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    60
    public function getQuery()
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    61
    {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    62
        return $this->query;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    63
    }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    64
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    65
    /**
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    66
     * Returns whether the query joins a collection.
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    67
     *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    68
     * @return Boolean Whether the query joins a collection.
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    69
     */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    70
    public function getFetchJoinCollection()
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    71
    {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    72
        return $this->fetchJoinCollection;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    73
    }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    74
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    75
    /**
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    76
     * {@inheritdoc}
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    77
     */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    78
    public function getNbResults()
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    79
    {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    80
        /* @var $countQuery Query */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    81
        $countQuery = $this->cloneQuery($this->query);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    82
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    83
        $countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Pagerfanta\Adapter\DoctrineORM\CountWalker'));
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    84
        $countQuery->setFirstResult(null)->setMaxResults(null);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    85
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    86
        try {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    87
            $data =  $countQuery->getScalarResult();
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    88
            $data = array_map('current', $data);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    89
            return array_sum($data);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    90
        } catch(NoResultException $e) {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    91
            return 0;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    92
        }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    93
    }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    94
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    95
    /**
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    96
     * {@inheritdoc}
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    97
     */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    98
    public function getSlice($offset, $length)
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
    99
    {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   100
        if ($this->fetchJoinCollection) {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   101
            $subQuery = $this->cloneQuery($this->query);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   102
            $subQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Pagerfanta\Adapter\DoctrineORM\LimitSubqueryWalker'))
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   103
                ->setFirstResult($offset)
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   104
                ->setMaxResults($length);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   105
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   106
            $ids = array_map('current', $subQuery->getScalarResult());
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   107
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   108
            $whereInQuery = $this->cloneQuery($this->query);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   109
            // don't do this for an empty id array
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   110
            if (count($ids) > 0) {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   111
                $namespace = 'pg_';
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   112
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   113
                $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Pagerfanta\Adapter\DoctrineORM\WhereInWalker'));
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   114
                $whereInQuery->setHint('id.count', count($ids));
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   115
                $whereInQuery->setHint('pg.ns', $namespace);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   116
                $whereInQuery->setFirstResult(null)->setMaxResults(null);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   117
                foreach ($ids as $i => $id) {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   118
                    $i++;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   119
                    $whereInQuery->setParameter("{$namespace}_{$i}", $id);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   120
                }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   121
            }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   122
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   123
            return $whereInQuery->getResult($this->query->getHydrationMode());
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   124
        }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   125
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   126
        return $this->cloneQuery($this->query)
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   127
            ->setMaxResults($length)
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   128
            ->setFirstResult($offset)
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   129
            ->getResult($this->query->getHydrationMode())
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   130
        ;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   131
    }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   132
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   133
    /**
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   134
     * Clones a query.
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   135
     *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   136
     * @param Query $query The query.
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   137
     *
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   138
     * @return Query The cloned query.
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   139
     */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   140
    private function cloneQuery(Query $query)
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   141
    {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   142
        /* @var $cloneQuery Query */
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   143
        $cloneQuery = clone $query;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   144
        $cloneQuery->setParameters($query->getParameters());
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   145
        foreach ($query->getHints() as $name => $value) {
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   146
            $cloneQuery->setHint($name, $value);
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   147
        }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   148
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   149
        return $cloneQuery;
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   150
    }
99ad73ef7385 first step for tag list and add Pagerfanta for paginator
cavaliet
parents:
diff changeset
   151
}