Nette Documentation Preview

syntax
Jak se vrátit k dřívější stránce?
*********************************

.[perex]
Co když uživatel vyplňuje formulář a vyprší mu přihlášení? Aby o data nepřišel, před přesměrováním na přihlašovací stránku data uložíme do session. V Nette to je úplná hračka.

Aktuální požadavek lze uložit do session pomocí metody `storeRequest()`, která vrátí jeho identifikátor v podobě krátkého řetězce. Metoda uloží název aktuálního presenteru, view a jeho parametry.
V případě, že byl odeslán i formulář, uloží se také obsah políček (s výjimkou uploadovaných souborů).

Obnovení požadavku provádí metoda `restoreRequest($key)`, které předáme získaný identifikátor. Ta přesměruje na původní presenter a view. Pokud však uložený požadavek obsahuje odeslání formuláře, na původní presenter přejde metodou `forward()`, formuláři předá dříve vyplněné hodnoty a nechá jej znovu vykreslit. Uživatel tak má možnost formulář opětovně odeslat a žádná data se neztratí.

Důležité je, že `restoreRequest()` kontroluje, zda nově přihlášený uživatel je tentýž, co formulář původně vyplňoval. Pokud ne, požadavek zahodí a nic neudělá.

Ukážeme si vše na příkladu. Mějme presenter `AdminPresenter`, ve kterém se editují data a v jehož metodě `startup()` ověřujeme, zda je uživatel přihlášen. Pokud není, přesměrujeme jej na `SignPresenter`. Zároveň si uložíme aktuální požadavek a jeho klíč odešleme do `SignPresenter`.

```php
class AdminPresenter extends Nette\Application\UI\Presenter
{
	protected function startup()
	{
		parent::startup();

		if (!$this->user->isLoggedIn()) {
			$this->redirect('Sign:in', ['backlink' => $this->storeRequest()]);
		}
	}
}
```

Presenter `SignPresenter` bude krom formuláře pro přihlášení obsahovat i persistentní parametr `$backlink`, do kterého se klíč zapíše. Jelikož parametr je persistentní, bude se přenášet i po odeslání přihlašovacího formuláře.


```php
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;
		// ... přidáme políčka formuláře ...
		$form->onSuccess[] = [$this, 'signInFormSubmitted'];
		return $form;
	}

	public function signInFormSubmitted($form)
	{
		// ... tady uživatele přihlásíme ...

		$this->restoreRequest($this->backlink);
		$this->redirect('Admin:');
	}
}
```

Metodě `restoreRequest()` předáme klíč uloženého požadavku a ona přesměruje (nebo přejde) na původní presenter.

Pokud je ale klíč neplatný (například už v session neexistuje), metoda neudělá nic. Následuje tedy volání `$this->redirect('Admin:')`, které přesměruje na `AdminPresenter`.

{{priority: -1}}
{{sitename: Best Practices}}

Jak se vrátit k dřívější stránce?

Co když uživatel vyplňuje formulář a vyprší mu přihlášení? Aby o data nepřišel, před přesměrováním na přihlašovací stránku data uložíme do session. V Nette to je úplná hračka.

Aktuální požadavek lze uložit do session pomocí metody storeRequest(), která vrátí jeho identifikátor v podobě krátkého řetězce. Metoda uloží název aktuálního presenteru, view a jeho parametry. V případě, že byl odeslán i formulář, uloží se také obsah políček (s výjimkou uploadovaných souborů).

Obnovení požadavku provádí metoda restoreRequest($key), které předáme získaný identifikátor. Ta přesměruje na původní presenter a view. Pokud však uložený požadavek obsahuje odeslání formuláře, na původní presenter přejde metodou forward(), formuláři předá dříve vyplněné hodnoty a nechá jej znovu vykreslit. Uživatel tak má možnost formulář opětovně odeslat a žádná data se neztratí.

Důležité je, že restoreRequest() kontroluje, zda nově přihlášený uživatel je tentýž, co formulář původně vyplňoval. Pokud ne, požadavek zahodí a nic neudělá.

Ukážeme si vše na příkladu. Mějme presenter AdminPresenter, ve kterém se editují data a v jehož metodě startup() ověřujeme, zda je uživatel přihlášen. Pokud není, přesměrujeme jej na SignPresenter. Zároveň si uložíme aktuální požadavek a jeho klíč odešleme do SignPresenter.

class AdminPresenter extends Nette\Application\UI\Presenter
{
	protected function startup()
	{
		parent::startup();

		if (!$this->user->isLoggedIn()) {
			$this->redirect('Sign:in', ['backlink' => $this->storeRequest()]);
		}
	}
}

Presenter SignPresenter bude krom formuláře pro přihlášení obsahovat i persistentní parametr $backlink, do kterého se klíč zapíše. Jelikož parametr je persistentní, bude se přenášet i po odeslání přihlašovacího formuláře.

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;
		// ... přidáme políčka formuláře ...
		$form->onSuccess[] = [$this, 'signInFormSubmitted'];
		return $form;
	}

	public function signInFormSubmitted($form)
	{
		// ... tady uživatele přihlásíme ...

		$this->restoreRequest($this->backlink);
		$this->redirect('Admin:');
	}
}

Metodě restoreRequest() předáme klíč uloženého požadavku a ona přesměruje (nebo přejde) na původní presenter.

Pokud je ale klíč neplatný (například už v session neexistuje), metoda neudělá nic. Následuje tedy volání $this->redirect('Admin:'), které přesměruje na AdminPresenter.