<?php
namespace Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Doctrine\ORM\Query\Parameter;
use Knp\Component\Pager\Event\ItemsEvent;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\Helper as QueryHelper;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\CountWalker;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\WhereInWalker;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\LimitSubqueryWalker;
use Doctrine\ORM\Query;
use Doctrine\ORM\Tools\Pagination\CountWalker as DoctrineCountWalker;
use Doctrine\ORM\Tools\Pagination\WhereInWalker as DoctrineWhereInWalker;
use Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker as DoctrineLimitSubqueryWalker;
/**
* @deprecated see UsesPaginator
**/
class QuerySubscriber implements EventSubscriberInterface
{
/**
* Used if user set the count manually
*/
const HINT_COUNT = 'knp_paginator.count';
public function items(ItemsEvent $event)
{
if ($event->target instanceof Query) {
// process count
$useDoctrineWalkers = false;
$useDoctrineOutputWalker = false;
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.3.0', '>=')) {
$useDoctrineWalkers = true;
$useDoctrineOutputWalker = true;
} else if (version_compare(\Doctrine\ORM\Version::VERSION, '2.2.0', '>=')) {
$useDoctrineWalkers = true;
}
if (($count = $event->target->getHint(self::HINT_COUNT)) !== false) {
$event->count = intval($count);
} else {
$countQuery = QueryHelper::cloneQuery($event->target);
if ($useDoctrineOutputWalker) {
$treeWalker = 'Doctrine\ORM\Tools\Pagination\CountOutputWalker';
$countQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, $treeWalker);
} else if ($useDoctrineWalkers) {
QueryHelper::addCustomTreeWalker($countQuery, 'Doctrine\ORM\Tools\Pagination\CountWalker');
} else {
$treeWalker = 'Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\CountWalker';
QueryHelper::addCustomTreeWalker($countQuery, $treeWalker);
}
if ($useDoctrineWalkers) {
$countQuery->setHint(
DoctrineCountWalker::HINT_DISTINCT,
$event->options[PaginatorInterface::DISTINCT]
);
} else {
$countQuery->setHint(
CountWalker::HINT_DISTINCT,
$event->options[PaginatorInterface::DISTINCT]
);
}
$countQuery
->setFirstResult(null)
->setMaxResults(null)
;
$countQuery->getEntityManager()->getConfiguration()->addCustomHydrationMode('asIs',
'Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\AsIsHydrator');
$countResult = $countQuery->getResult('asIs');
$event->count = intval(current(current($countResult)));
}
// process items
$result = null;
if ($event->count) {
if ($event->options[PaginatorInterface::DISTINCT]) {
$limitSubQuery = QueryHelper::cloneQuery($event->target);
$limitSubQuery
->setFirstResult($event->getOffset())
->setMaxResults($event->getLimit())
->useQueryCache(false)
;
QueryHelper::addCustomTreeWalker($limitSubQuery, $useDoctrineWalkers ?
'Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker' :
'Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\LimitSubqueryWalker'
);
$ids = array_map('current', $limitSubQuery->getScalarResult());
// create where-in query
$whereInQuery = QueryHelper::cloneQuery($event->target);
QueryHelper::addCustomTreeWalker($whereInQuery, $useDoctrineWalkers ?
'Doctrine\ORM\Tools\Pagination\WhereInWalker' :
'Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\WhereInWalker'
);
$whereInQuery
->setHint($useDoctrineWalkers ?
DoctrineWhereInWalker::HINT_PAGINATOR_ID_COUNT :
WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids)
)
->setFirstResult(null)
->setMaxResults(null)
;
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.3.0', '>=') && count($ids) > 0) {
$whereInQuery->setParameter(WhereInWalker::PAGINATOR_ID_ALIAS, $ids);
} else {
$type = $limitSubQuery->getHint($useDoctrineWalkers ?
DoctrineLimitSubqueryWalker::IDENTIFIER_TYPE :
LimitSubqueryWalker::IDENTIFIER_TYPE
);
$idAlias = $useDoctrineWalkers ?
DoctrineWhereInWalker::PAGINATOR_ID_ALIAS :
WhereInWalker::PAGINATOR_ID_ALIAS
;
foreach ($ids as $i => $id) {
$whereInQuery->setParameter(
$idAlias . '_' . ++$i,
$id,
$type->getName()
);
}
}
$result = $whereInQuery->execute();
} else {
$event->target
->setFirstResult($event->getOffset())
->setMaxResults($event->getLimit())
;
$result = $event->target->execute();
}
} else {
$result = array(); // count is 0
}
$event->items = $result;
$event->stopPropagation();
}
}
public static function getSubscribedEvents()
{
return array(
'knp_pager.items' => array('items', 0)
);
}
}