Uložení routy posledního requestu [symfony]
Scénář
Chci přesměrovat na poslední request. Mám formulář dostupný z více stránek a po odeslání chci uživatele vrátit na stránku, ze které na formulář přišel.
Řešení #1: HTTP Referer
Pravopisně správná varianta je Referrer, nicméně nenapadný překlep v RFC 1945 (specifikace HTTP/1.0) se rozšířil natolik, že v kontextu HTTP je většinou potřeba použít variantu Referer.
<?php
use Symfony\Component\HttpFoundation\RedirectResponse;
class Controller
{
public function refererAction()
{
$referer = $request->headers->get('referer');
return new RedirectResponse($referer);
}
}
Potíží s HTTP Refererem je, že nemusí být v požadavku dostupný. Druhé řešení je o něco robustnější a ukládá poslední routu v session.
Řešení #2: Poslední routa v session
Spolehlivějším než spoléhat na HTTP_REFERER
je uložit si poslední nalezenou routu do sessiony. Aby se uložila při každém požadavku, vytvoříme EventListener
, který se vyvolá při každé kernel.request
události. Na stejné události je navěšený i RouterListener
, který se stará o vybrání správné routy. Je tedy potřeba nově vytvořenému dát menší prioritu, aby se stihla vybrat. RouterListener má prioritu 32, v konfiguraci je teda potřeba dát menší.
services:
smf_example.last_route_event_listener:
class: SmfBlog\ExampleBundle\EventListener\LastRouteListener
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 30 }
<?php
namespace SmfBlog\ExampleBundle\EventListener;
use Symfony\Component\HttpFoundation\Session;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
class LastRouteListener
{
public function onKernelRequest(GetResponseEvent $event)
{
// Do not save subrequests
if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
return;
}
$request = $event->getRequest();
$session = $request->getSession();
$routeName = $request->get('_route');
$routeParams = $request->get('_route_params');
if ($routeName[0] == '_') {
return;
}
$routeData = ['name' => $routeName, 'params' => $routeParams];
// Do not save same matched route twice
$thisRoute = $session->get('this_route', []);
if ($thisRoute == $routeData) {
return;
}
$session->set('last_route', $thisRoute);
$session->set('this_route', $routeData);
}
}