How to Return to an Earlier Page?
What if a user fills out a form and his login expires? To avoid losing the data, we save the data in the session before redirecting to the login page. In Nette, this is a piece of cake.
The current request can be stored in the session using the storeRequest()
method, which returns its identifier as
a short string. The method stores the name of the current presenter, the view and its parameters. If a form was also submitted,
the values of the fields (except for the uploaded files) are also saved.
The request is restored by the restoreRequest($key)
method, to which we pass the retrieved identifier. This
redirects to the original presenter and view. However, if the saved request contains a form submission, it will forward to the
original presenter using method forward()
, pass the previously filled values to the form and let it be redrawn. This
allows the user to resubmit the form and no data is lost.
Importantly, restoreRequest()
checks that the newly logged in user is the same one who originally filled out the
form. If not, it discards the request and does nothing.
Let's demonstrate everything with an example. Let's have a presenter AdminPresenter
in which data is being
edited and whose method startup()
checks if the user is logged in. If he is not, we redirect him to
SignPresenter
. At the same time, we save the current request and send its key to SignPresenter
.
class AdminPresenter extends Nette\Application\UI\Presenter
{
protected function startup()
{
parent::startup();
if (!$this->user->isLoggedIn()) {
$this->redirect('Sign:in', ['backlink' => $this->storeRequest()]);
}
}
}
The SignPresenter
presenter will contain a persistent $backlink
parameter to which the key is
written, in addition to the log-in form. Since the parameter is persistent, it will be carried over even after the login form is
submitted.
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;
// ... add form fields ...
$form->onSuccess[] = [$this, 'signInFormSubmitted'];
return $form;
}
public function signInFormSubmitted($form)
{
// ... here we sign the user in ...
$this->restoreRequest($this->backlink);
$this->redirect('Admin:');
}
}
We pass the key of the saved request to the restoreRequest()
method and it redirects (or forwards) to the original
presenter.
However, if the key is invalid (for example, no longer exists in the session), the method does nothing. So the next call is
$this->redirect('Admin:')
, which redirects to AdminPresenter
.