Как вернуться на предыдущую страницу?
Что произойдёт, если пользователь заполняет форму, а его сессия входа истечёт? Чтобы не потерять данные, мы можем сохранить текущий запрос (включая данные формы) в сессию перед перенаправлением на страницу входа. В Nette это на удивление просто.
Текущий запрос можно сохранить в сессию методом storeRequest(). Этот
метод возвращает уникальный идентификатор (короткую строку)
сохранённого запроса. Метод сохраняет имя текущего презентера, его
представление и параметры. Если в составе запроса была отправлена
форма, сохраняются и значения, введённые в поля (кроме загруженных
файлов).
Запрос восстанавливается методом restoreRequest($key), которому вы
передаёте полученный ранее идентификатор. Этот метод перенаправляет
пользователя обратно в исходные презентер и представление. Однако
если сохранённый запрос содержал отправку формы, restoreRequest()
вместо перенаправления использует метод forward(). Он передаёт в
форму ранее заполненные значения и позволяет отрисовать её снова.
Благодаря этому пользователь может отправить форму заново, не потеряв
введённые данные.
Принципиально важно, что restoreRequest() проверяет, является ли
только что вошедший пользователь тем же самым, который изначально
отправил форму. Если пользователь другой, сохранённый запрос не
восстанавливается, и метод ничего не делает, что повышает
безопасность.
Проиллюстрируем это примером. Представьте AdminPresenter, где
редактируются данные. Его метод startup() проверяет, вошёл ли
пользователь. Если нет, пользователь перенаправляется в
SignPresenter. Одновременно мы сохраняем текущий запрос через
storeRequest() и передаём его ключ ($backlink) в 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->signInFormSuceeded(...);
return $form;
}
private function signInFormSuceeded($form)
{
// ... здесь выполняем вход пользователя ...
$this->restoreRequest($this->backlink);
$this->redirect('Admin:');
}
}
Мы передаём ключ ($this->backlink) сохранённого запроса в метод
restoreRequest(). Он затем перенаправляет (или перебрасывает)
пользователя обратно в исходные презентер и представление.
Однако если ключ недействителен (например, истёк в сессии), метод
ничего не делает. Поэтому последующий вызов $this->redirect('Admin:')
служит запасным вариантом и перенаправляет на страницу по умолчанию,
например в AdminPresenter.