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

Что делать, если пользователь заполнил форму, а срок действия его логина истек? Чтобы избежать потери данных, мы сохраняем их в сессии перед перенаправлением на страницу входа в систему. В 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.