¿Cómo volver a una página anterior?
¿Qué pasa si un usuario está rellenando un formulario y su sesión de acceso caduca? Para no perder los datos, podemos guardar la petición actual (incluidos los datos del formulario) en la sesión antes de redirigir a la página de acceso. En Nette esto es sorprendentemente fácil.
La petición actual se puede guardar en la sesión con el método storeRequest(). Este método devuelve un
identificador único (una cadena corta) de la petición guardada. El método guarda el nombre del presenter actual, su vista y sus
parámetros. Si como parte de la petición se envió un formulario, se guardan también los valores introducidos en los campos
(salvo los archivos subidos).
La petición se restaura con el método restoreRequest($key), al que se le pasa el identificador obtenido antes.
Este método redirige al usuario de vuelta al presenter y la vista originales. Sin embargo, si la petición guardada incluía el
envío de un formulario, restoreRequest() usa el método forward() en lugar de redirigir. Devuelve al
formulario los valores rellenados anteriormente y permite renderizarlo de nuevo. Así, el usuario puede volver a enviar el
formulario sin perder ninguno de los datos introducidos.
Es crucial que restoreRequest() comprueba que el usuario recién conectado es el mismo que envió originalmente el
formulario. Si es otro usuario, la petición guardada no se restaura y el método no hace nada, lo que refuerza la seguridad.
Ilustrémoslo con un ejemplo. Imagine un AdminPresenter en el que se editan datos. Su método
startup() comprueba si el usuario está conectado. Si no lo está, se le redirige al SignPresenter. Al
mismo tiempo guardamos la petición actual con storeRequest() y le pasamos su clave (el $backlink) al
SignPresenter.
class AdminPresenter extends Nette\Application\UI\Presenter
{
protected function startup()
{
parent::startup();
if (!$this->user->isLoggedIn()) {
$this->redirect('Sign:in', ['backlink' => $this->storeRequest()]);
}
}
}
El SignPresenter contendrá, además del formulario de acceso, un parámetro persistente $backlink
donde se guarda la clave. Como el parámetro es persistente, su valor se conserva incluso después de enviar el formulario de
acceso.
use Nette\Application\Attributes\Persistent;
class SignPresenter extends Nette\Application\UI\Presenter
{
#[Persistent]
public string $backlink = '';
protected function createComponentSignInForm()
{
$form = new Nette\Application\UI\Form;
// ... añadir los campos del formulario ...
$form->onSuccess[] = $this->signInFormSuceeded(...);
return $form;
}
private function signInFormSuceeded($form)
{
// ... aquí se autentica al usuario ...
$this->restoreRequest($this->backlink);
$this->redirect('Admin:');
}
}
Al método restoreRequest() le pasamos la clave ($this->backlink) de la petición guardada. El
método redirige (o hace forward) al usuario de vuelta al presenter y la vista originales.
Si la clave no es válida (por ejemplo, porque ha caducado en la sesión), el método no hace nada. Por eso la llamada
siguiente $this->redirect('Admin:') actúa como plan B y redirige a una página predeterminada, como el
AdminPresenter.