Skip to content

Instantly share code, notes, and snippets.

@iggyster
Last active July 16, 2024 12:52
Show Gist options
  • Save iggyster/1a6762462c883acfa62059b0e8ead5ba to your computer and use it in GitHub Desktop.
Save iggyster/1a6762462c883acfa62059b0e8ead5ba to your computer and use it in GitHub Desktop.
How to handle a NativeQuery for the KNP paginator
<?php
declare(strict_types=1);
namespace AppBundle\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\NativeQuery;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\Query\ResultSetMapping;
use Knp\Component\Pager\Event\ItemsEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class PaginateNativeQuerySubscriber implements EventSubscriberInterface
{
private EntityManagerInterface $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
'knp_pager.items' => ['handle', 1],
];
}
public function handle(ItemsEvent $event): void
{
if (!$event->target instanceof NativeQuery) {
return;
}
$this->setCount($event);
$this->setItems($event);
$event->stopPropagation();
}
private function setCount(ItemsEvent $event): void
{
$sql = $event->target->getSQL();
$rsm = new ResultSetMapping();
$rsm->addScalarResult('amount', 'count', 'integer');
$counter = $this->em->createNativeQuery('SELECT COUNT(1) as amount FROM (('.$sql.') c)', $rsm);
$counter->setParameters($event->target->getParameters());
try {
$event->count = (int) $counter->getSingleScalarResult();
} catch (NonUniqueResultException $exception) {
$event->count = 0;
}
}
private function setItems(ItemsEvent $event): void
{
$event->items = $event->target->getArrayResult();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment