Como voltar a uma página anterior?

E se um usuário preenche um formulário e seu login expira? Para evitar perder os dados, salvamos os dados na sessão antes de redirecionar para a página de login. Em Nette, isto é canja.

A solicitação atual pode ser armazenada na sessão usando o método storeRequest(), que retorna seu identificador como uma cadeia curta. O método armazena o nome do apresentador atual, a vista e seus parâmetros. Se um formulário também foi submetido, os valores dos campos (exceto os arquivos carregados) também são salvos.

O pedido é restaurado pelo método restoreRequest($key), ao qual passamos o identificador recuperado. Isto é redirecionado para o apresentador e visualização originais. Entretanto, se a solicitação salva contiver uma apresentação do formulário, ela será encaminhada ao apresentador original pelo método forward(), passando os valores previamente preenchidos para o formulário e deixando-o ser redesenhado. Isto permite que o usuário submeta novamente o formulário e nenhum dado seja perdido.

É importante destacar que restoreRequest() verifica que o usuário recém-identificado é o mesmo que preencheu originalmente o formulário. Caso contrário, ele descarta o pedido e não faz nada.

Vamos demonstrar tudo com um exemplo. Vamos ter um apresentador AdminPresenter no qual os dados estão sendo editados e cujo método startup() verifica se o usuário está logado. Se ele não estiver, nós o redirecionamos para SignPresenter. Ao mesmo tempo, salvamos o pedido 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 apresentador SignPresenter conterá um parâmetro persistente $backlink no qual a chave está escrita, além do formulário de log-in. Como o parâmetro é persistente, ele será transportado mesmo depois que o formulário de login for enviado.

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

	public function signInFormSubmitted($form)
	{
		// ... aqui nós assinamos o usuário em ...

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

Passamos a chave do pedido salvo para o método restoreRequest() e ele redireciona (ou encaminha) para o apresentador original.

Entretanto, se a chave é inválida (por exemplo, não existe mais na sessão), o método não faz nada. Portanto, a próxima chamada é $this->redirect('Admin:'), que redireciona para AdminPresenter.