Como retornar a uma página anterior?

E se o usuário estiver preenchendo um formulário e sua sessão expirar? Para que ele não perca os dados, antes de redirecionar para a página de login, salvamos os dados na sessão. No Nette, isso é muito fácil.

A requisição atual pode ser salva na sessão usando o método storeRequest(), que retorna seu identificador na forma de uma string curta. O método salva o nome do presenter atual, a view e seus parâmetros. Caso um formulário também tenha sido enviado, o conteúdo dos campos também é salvo (com exceção dos arquivos enviados).

A restauração da requisição é feita pelo método restoreRequest($key), ao qual passamos o identificador obtido. Ele redireciona para o presenter e view originais. No entanto, se a requisição salva contiver o envio de um formulário, ele vai para o presenter original usando o método forward(), passa os valores preenchidos anteriormente para o formulário e o renderiza novamente. O usuário tem assim a possibilidade de reenviar o formulário e nenhum dado é perdido.

É importante que restoreRequest() verifique se o usuário recém-logado é o mesmo que preencheu o formulário originalmente. Se não for, ele descarta a requisição e não faz nada.

Vamos mostrar tudo com um exemplo. Temos um presenter AdminPresenter, no qual os dados são editados e em cujo método startup() verificamos se o usuário está logado. Se não estiver, o redirecionamos para SignPresenter. Ao mesmo tempo, salvamos a requisição atual e enviamos sua chave para SignPresenter.

class AdminPresenter extends Nette\Application\UI\Presenter
{
	protected function startup()
	{
		parent::startup();

		if (!$this->user->isLoggedIn()) {
			$this->redirect('Sign:in', ['backlink' => $this->storeRequest()]);
		}
	}
}

O presenter SignPresenter conterá, além do formulário de login, também um parâmetro persistente $backlink, no qual a chave será escrita. Como o parâmetro é persistente, ele será transmitido mesmo após o envio do formulário de login.

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;
		// ... adicionamos os campos do formulário ...
		$form->onSuccess[] = [$this, 'signInFormSubmitted'];
		return $form;
	}

	public function signInFormSubmitted($form)
	{
		// ... aqui fazemos o login do usuário ...

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

Passamos a chave da requisição salva para o método restoreRequest() e ele redireciona (ou avança) para o presenter original.

No entanto, se a chave for inválida (por exemplo, não existir mais na sessão), o método não faz nada. Segue-se então a chamada $this->redirect('Admin:'), que redireciona para AdminPresenter.