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