Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

[RFC] Redirect to last available page strategy #96

Open
Koc opened this issue Sep 15, 2014 · 4 comments
Open

[RFC] Redirect to last available page strategy #96

Koc opened this issue Sep 15, 2014 · 4 comments

Comments

@Koc
Copy link

Koc commented Sep 15, 2014

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.

@pablodip
Copy link
Contributor

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? :)

@Koc
Copy link
Author

Koc commented Sep 19, 2014

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.

@pablodip
Copy link
Contributor

Aren't they on the request?

@Koc
Copy link
Author

Koc commented Sep 19, 2014

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants