Come tornare a una pagina precedente?
Cosa succede se un utente sta compilando un form e la sua sessione di login scade? Per non perdere i dati, possiamo salvare nella sessione la richiesta corrente (dati del form compresi) prima di reindirizzare alla pagina di login. In Nette è sorprendentemente semplice.
La richiesta corrente si può salvare nella sessione con il metodo storeRequest(). Questo metodo restituisce un
identificatore univoco (una stringa breve) della richiesta salvata. Il metodo salva il nome del presenter corrente, la sua vista e
i suoi parametri. Se nell'ambito della richiesta è stato inviato un form, vengono salvati anche i valori inseriti nei campi
(esclusi i file caricati).
La richiesta si ripristina con il metodo restoreRequest($key), al quale passate l'identificatore ottenuto in
precedenza. Questo metodo reindirizza l'utente al presenter e alla vista originali. Se però la richiesta salvata comprendeva
l'invio di un form, restoreRequest() usa il metodo forward() invece di reindirizzare. Ripassa al form
i valori compilati in precedenza e ne permette il rendering. L'utente può così reinviare il form senza perdere i dati
inseriti.
Cosa essenziale, restoreRequest() verifica che l'utente appena connesso sia lo stesso che aveva inviato il form.
Se l'utente è diverso, la richiesta salvata non viene ripristinata e il metodo non fa nulla, il che aumenta la sicurezza.
Illustriamolo con un esempio. Consideriamo un AdminPresenter in cui si modificano dei dati. Il suo metodo
startup() verifica se l'utente è connesso. In caso contrario l'utente viene reindirizzato a
SignPresenter. Allo stesso tempo salviamo la richiesta corrente con storeRequest() e ne passiamo la
chiave (il $backlink) a 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 conterrà, oltre al form di login, un parametro persistente $backlink in cui è salvata
la chiave. Poiché il parametro è persistente, il suo valore si conserva anche dopo l'invio del form di login.
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;
// ... aggiunta dei campi del form ...
$form->onSuccess[] = $this->signInFormSuceeded(...);
return $form;
}
private function signInFormSuceeded($form)
{
// ... qui l'utente viene connesso ...
$this->restoreRequest($this->backlink);
$this->redirect('Admin:');
}
}
Passiamo la chiave ($this->backlink) della richiesta salvata al metodo restoreRequest(). Esso
reindirizza (o inoltra) poi l'utente al presenter e alla vista originali.
Se però la chiave non è valida (per esempio è scaduta dalla sessione), il metodo non fa nulla. La chiamata successiva
$this->redirect('Admin:') funge quindi da ripiego e reindirizza a una pagina predefinita, come
AdminPresenter.