[RFC] Redirect to last available page strategy
Opened this issue · 4 comments
This is follow up of #60.
I want create redirect to last available page when trying open non-existent page (OutOfRangeCurrentPageException
). Currently I've code like this
<?php
namespace Metal\ProjectBundle\Pagerfanta\EventListener;
use Pagerfanta\Exception\NotValidCurrentPageException;
use Pagerfanta\Exception\OutOfRangeCurrentPageException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class HandleOutOfRangeCurrentPage implements EventSubscriberInterface
{
private $router;
public function __construct(UrlGeneratorInterface $router)
{
$this->router = $router;
}
/**
* @param GetResponseForExceptionEvent $event
*/
public function onException(GetResponseForExceptionEvent $event)
{
$rootException = $exception = $event->getException();
do {
if ($exception instanceof OutOfRangeCurrentPageException) {
preg_match('/"(\d+)"$/', $exception->getMessage(), $matches); // this hack can be easy removed: create field "maxAvailablePage" in exception class
$maxPage = $matches[1];
$request = $event->getRequest();
$url = $this->router->generate(
$request->attributes->get('_route'),
array_merge(
$request->attributes->get('_route_params'),
$request->query->all(),
array('page' => $maxPage) // we have hardcoded page parameter name here
),
true
);
$event->setResponse(RedirectResponse::create($url, 301));
return;
}
if ($exception instanceof NotValidCurrentPageException) {
$event->setException(new NotFoundHttpException('Page Not Found', $rootException));
return;
}
} while ($exception = $exception->getPrevious()); // Twig wraps actual exception into his own
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
KernelEvents::EXCEPTION => array('onException', 512)
);
}
}
As you can see from code above, main problem is that we cann't dehardcode parameter for page name. Has anybody any suggestions for how to deal with it?
I think, that we can create method like Form::handleRequest
, something like $pagerfanta->handleRequest($request, 'nameOfPageParameter')
and then use this parameter on route generation.
A good solution could be setting the max available page to the exception, which should be done on Pagerfanta itself. Would you like to create a PR? :)
I'm can create PR but max available page is not enough. We should to know whan route or query parameter used for page generation.
Aren't they on the request?
As you see it can be customized https://github.com/whiteoctober/WhiteOctoberPagerfantaBundle/blob/master/Twig/PagerfantaExtension.php#L105