Jak wrócić do poprzedniej strony?

Co jeśli użytkownik wypełni formularz, a jego login wygaśnie? Aby uniknąć utraty danych, zapisujemy je w sesji przed przekierowaniem na stronę logowania. W Nette jest to bułka z masłem.

Bieżące żądanie można zapisać do sesji za pomocą metody storeRequest(), która zwraca jego identyfikator jako krótki łańcuch. Metoda przechowuje nazwę bieżącego prezentera, widok i jego parametry. Jeśli formularz został również przesłany, zawartość pól (z wyjątkiem przesłanych plików) również zostanie zapisana.

Żądanie jest przywracane przez metodę restoreRequest($key), do której przekazujemy odzyskany identyfikator. Powoduje to przekierowanie do oryginalnego prezentera i widoku. Jeśli jednak zapisane żądanie zawiera przesłanie formularza, przekieruje do oryginalnego prezentera za pomocą metody forward(), przekaże poprzednio wypełnione wartości do formularza i pozwoli na jego ponowne narysowanie. Dzięki temu użytkownik może ponownie przesłać formularz i żadne dane nie zostaną utracone.

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

Zobrazujmy wszystko na przykładzie. Miejmy prezenter AdminPresenter, w którym edytowane są dane i w którego metodzie startup() sprawdzamy czy użytkownik jest zalogowany. Jeśli nie jest, przekierowujemy go na stronę SignPresenter. Jednocześnie zapisujemy bieżące żądanie i wysyłamy jego klucz na stronę SignPresenter.

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

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

Prezenter SignPresenter będzie zawierał, oprócz formularza logowania, trwały parametr $backlink, w który wpisywany jest klucz. Ponieważ parametr jest trwały, będzie przekazywany nawet po przesł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 podpisujemy użytkownika ...

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

Przekazujemy klucz zapisanego żądania do metody restoreRequest(), a ona przekierowuje (lub przekazuje) do oryginalnego prezentera.

Jeśli jednak klucz jest nieważny (na przykład nie istnieje już w sesji), metoda nie robi nic. Tak więc następnym wywołaniem jest $this->redirect('Admin:'), które przekierowuje do AdminPresenter.