Comment revenir à une page précédente ?
Que se passe-t-il si un utilisateur remplit un formulaire et que sa session de connexion expire ? Pour éviter la perte de données, nous pouvons enregistrer la requête courante (données du formulaire comprises) dans la session avant de rediriger vers la page de connexion. Dans Nette, c'est étonnamment simple.
La requête courante peut être stockée dans la session à l'aide de la méthode storeRequest(). Cette méthode
renvoie un identifiant unique (une courte chaîne) de la requête stockée. Elle enregistre le nom du presenter courant, sa vue et
ses paramètres. Si un formulaire a été envoyé dans le cadre de la requête, les valeurs saisies dans les champs sont
également enregistrées (à l'exception des fichiers envoyés).
La requête se restaure à l'aide de la méthode restoreRequest($key), à laquelle vous passez l'identifiant
obtenu précédemment. Cette méthode redirige l'utilisateur vers le presenter et la vue d'origine. Si la requête stockée
comportait cependant l'envoi d'un formulaire, restoreRequest() utilise la méthode forward() au lieu de
rediriger. Elle repasse au formulaire les valeurs précédemment saisies et lui permet d'être rendu à nouveau. L'utilisateur
peut ainsi renvoyer le formulaire sans perdre les données saisies.
Point essentiel : restoreRequest() vérifie que l'utilisateur nouvellement connecté est bien celui qui avait
envoyé le formulaire à l'origine. S'il s'agit d'un autre utilisateur, la requête stockée n'est pas restaurée et la méthode
ne fait rien, ce qui renforce la sécurité.
Illustrons cela par un exemple. Prenons un AdminPresenter dans lequel des données sont modifiées. Sa méthode
startup() vérifie que l'utilisateur est connecté. Si ce n'est pas le cas, l'utilisateur est redirigé vers
SignPresenter. Nous stockons en même temps la requête courante à l'aide de storeRequest() et passons
sa clé (le $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()]);
}
}
}
Le SignPresenter contiendra, outre le formulaire de connexion, un paramètre persistant $backlink où
la clé est stockée. Comme le paramètre est persistant, sa valeur est conservée même après l'envoi du formulaire de
connexion.
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;
// ... ajout des champs du formulaire ...
$form->onSuccess[] = $this->signInFormSuceeded(...);
return $form;
}
private function signInFormSuceeded($form)
{
// ... connexion de l'utilisateur ici ...
$this->restoreRequest($this->backlink);
$this->redirect('Admin:');
}
}
Nous passons la clé ($this->backlink) de la requête stockée à la méthode restoreRequest().
Celle-ci redirige alors (ou fait un forward) l'utilisateur vers le presenter et la vue d'origine.
Si la clé n'est cependant pas valide (par exemple parce qu'elle a expiré de la session), la méthode ne fait rien. L'appel
suivant $this->redirect('Admin:') sert donc de repli et redirige vers une page par défaut comme
AdminPresenter.