¿Cómo volver a la página anterior?

¿Qué pasa si un usuario está llenando un formulario y su sesión expira? Para que no pierda los datos, antes de redirigir a la página de inicio de sesión, guardamos los datos en la sesión. En Nette, esto es pan comido.

La solicitud actual se puede guardar en la sesión usando el método storeRequest(), que devuelve su identificador en forma de una cadena corta. El método guarda el nombre del presentador actual, la vista y sus parámetros. En caso de que también se haya enviado un formulario, también se guarda el contenido de los campos (con la excepción de los archivos subidos).

La restauración de la solicitud la realiza el método restoreRequest($key), al que le pasamos el identificador obtenido. Este redirige al presentador y vista originales. Sin embargo, si la solicitud guardada contiene el envío de un formulario, pasa al presentador original mediante el método forward(), le pasa los valores previamente completados al formulario y lo vuelve a renderizar. De esta manera, el usuario tiene la posibilidad de reenviar el formulario y no se pierde ningún dato.

Es importante que restoreRequest() compruebe si el usuario recién conectado es el mismo que completó originalmente el formulario. Si no es así, descarta la solicitud y no hace nada.

Mostraremos todo con un ejemplo. Tenemos un presentador AdminPresenter, en el que se editan datos y en cuyo método startup() verificamos si el usuario ha iniciado sesión. Si no es así, lo redirigimos a SignPresenter. Al mismo tiempo, guardamos la solicitud actual y enviamos su clave a 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 presentador SignPresenter, además del formulario de inicio de sesión, contendrá también un parámetro persistente $backlink, en el que se escribirá la clave. Dado que el parámetro es persistente, se transferirá también después de enviar el formulario de inicio de sesión.

use Nette\Application\Attributes\Persistent;

class SignPresenter extends Nette\Application\UI\Presenter
{
	#[Persistent]
	public string $backlink = '';

	protected function createComponentSignInForm(): Form
	{
		$form = new Form;
		// ... añadimos los campos del formulario ...
		$form->onSuccess[] = [$this, 'signInFormSubmitted'];
		return $form;
	}

	public function signInFormSubmitted($form)
	{
		// ... aquí iniciamos sesión del usuario ...

		$this->restoreRequest($this->backlink);
		$this->redirect('Admin:');
	}
}

Pasamos la clave de la solicitud guardada al método restoreRequest() y este redirige (o avanza) al presentador original.

Sin embargo, si la clave no es válida (por ejemplo, ya no existe en la sesión), el método no hace nada. Por lo tanto, sigue la llamada $this->redirect('Admin:'), que redirige a AdminPresenter.