Как вернуться к предыдущей странице?

Что, если пользователь заполняет форму, а его сессия истекает? Чтобы он не потерял данные, перед перенаправлением на страницу входа мы сохраним данные в сессию. В Nette это совершенно просто.

Текущий запрос можно сохранить в сессию с помощью метода storeRequest(), который возвращает его идентификатор в виде короткой строки. Метод сохраняет имя текущего презентера, представление и его параметры. В случае, если была отправлена и форма, сохраняется также содержимое полей (за исключением загруженных файлов).

Восстановление запроса выполняет метод restoreRequest($key), которому мы передаем полученный идентификатор. Он перенаправляет на исходный презентер и представление. Однако, если сохраненный запрос содержит отправку формы, он перейдет на исходный презентер методом forward(), передаст форме ранее заполненные значения и позволит ее снова отрисовать. Таким образом, пользователь имеет возможность повторно отправить форму, и никакие данные не теряются.

Важно, что restoreRequest() проверяет, является ли вновь вошедший пользователь тем же, кто изначально заполнял форму. Если нет, запрос отбрасывается, и ничего не происходит.

Покажем все на примере. Пусть у нас есть презентер AdminPresenter, в котором редактируются данные и в методе startup() которого проверяется, авторизован ли пользователь. Если нет, перенаправляем его на SignPresenter. Одновременно сохраняем текущий запрос и его ключ отправляем в SignPresenter.

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

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

Презентер SignPresenter будет содержать, помимо формы для входа, также персистентный параметр $backlink, в который запишется ключ. Поскольку параметр персистентный, он будет передаваться и после отправки формы входа.

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;
		// ... добавляем поля формы ...
		$form->onSuccess[] = [$this, 'signInFormSubmitted'];
		return $form;
	}

	public function signInFormSubmitted($form)
	{
		// ... здесь авторизуем пользователя ...

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

Методу restoreRequest() передаем ключ сохраненного запроса, и он перенаправляет (или переходит) на исходный презентер.

Однако, если ключ недействителен (например, его уже нет в сессии), метод ничего не делает. Затем следует вызов $this->redirect('Admin:'), который перенаправляет на AdminPresenter.