Jak wrócić do poprzedniej strony?

Co jeśli użytkownik wypełnia formularz i jego sesja wygaśnie? Aby nie stracił danych, przed przekierowaniem na stronę logowania zapiszemy żądanie w sesji. W Nette to bułka z masłem.

Aktualne żądanie można zapisać w sesji za pomocą metody storeRequest(), która zwraca jego identyfikator w postaci krótkiego ciągu znaków. Metoda zapisuje nazwę aktualnego presentera, widoku i jego parametrów. W przypadku, gdy został również wysłany formularz, zapisywana jest także zawartość pól (z wyjątkiem przesłanych plików).

Przywrócenie żądania wykonuje metoda restoreRequest($key), której przekazujemy uzyskany identyfikator. Przekierowuje ona na pierwotny presenter i akcję. Jeśli jednak zapisane żądanie zawiera wysłanie formularza, przechodzi na pierwotny presenter metodą forward(), przekazuje formularzowi wcześniej wypełnione wartości i pozwala go ponownie wyrenderować. Użytkownik ma w ten sposób możliwość ponownego wysłania formularza i żadne dane się nie tracą.

Ważne jest, że restoreRequest() sprawdza, czy nowo zalogowany użytkownik jest tym samym, który pierwotnie wypełniał formularz. Jeśli nie, żądanie odrzuca i nic nie robi.

Pokażemy wszystko na przykładzie. Mamy presenter AdminPresenter, w którym edytuje się dane i w którego metodzie startup() weryfikujemy, czy użytkownik jest zalogowany. Jeśli nie, przekierowujemy go na SignPresenter. Jednocześnie zapisujemy aktualne żądanie i jego klucz wysyłamy do SignPresenter.

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

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

Presenter SignPresenter będzie oprócz formularza logowania zawierał również parametr persistentny $backlink, do którego zapisze się klucz. Ponieważ parametr jest persistentny, będzie przenoszony również po odesłaniu formularza logowania.

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;
		// ... dodajemy pola formularza ...
		$form->onSuccess[] = [$this, 'signInFormSubmitted'];
		return $form;
	}

	public function signInFormSubmitted($form)
	{
		// ... tutaj logujemy użytkownika ...

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

Metodzie restoreRequest() przekazujemy klucz zapisanego żądania, a ona przekierowuje (lub przechodzi) na pierwotny presenter.

Jeśli jednak klucz jest nieprawidłowy (na przykład już nie istnieje w sesji), metoda nic nie robi. Następuje więc wywołanie $this->redirect('Admin:'), które przekierowuje na AdminPresenter.