Jak po odeslání formuláře zobrazit stejnou stránku?

Jsme na stránce se článkem a potřebujeme uživatele přihlásit. Máme formulář na více místech a po odeslání chceme na místo původní.

Přesně na to se hodí storeRequest a restoreRequest, které nám umožní se vrátit. V těchto případech Vám odpadnout starosti s přemýšlením nad $this->redirect(...).

Praktickou ukázku přesměrování na požadovanou stránku po úspěšném přihlášení naleznete v příkladu CD-collection v distribuci Nette. Konkrétně:

Zde si ve zkratce ukážeme, jak fungují. Metoda Nette\Application\UI\Presenter::storeRequest() uloží aktuální request od uživatele se všemi jeho parametry a vrátí textový klíč, pod kterým jej můžeme opět vyvolat.

DashboardPresenter obsluhuje spoustu akcí, které upravují data. Takže na jeho začátku, v metodě startup se podíváme, jestli je uživatel přihlášen. Pokud není, tak ho přesměrujeme na SignPresenter.

class DashboardPresenter extends BasePresenter
{
    protected function startup()
    {
        parent::startup();

        if (!$this->user->isLoggedIn()) {
            if ($this->user->logoutReason === Nette\Security\IUserStorage::INACTIVITY) {
                $this->flashMessage('You have been signed out due to inactivity. Please sign in again.');
            }
            $this->redirect('Sign:in', ['backlink' => $this->storeRequest()]);
        }
    }

    // ...
}

SignPresenter obsahuje formulář na přihlášení a jeho zpracování. Také je velice důležitý persistentní parametr $backlink, který se nám bude přenášet i přes odeslání formuláře.

class SignPresenter extends BasePresenter
{
    /** @persistent */
    public $backlink = '';

    protected function createComponentSignInForm()
    {
        $form = new Nette\Application\UI\Form;
        // políčka formuláře ...
        $form->onSuccess[] = [$this, 'signInFormSubmitted'];
        return $form;
    }

    public function signInFormSubmitted($form)
    {
        // přihlášení ...
        $this->restoreRequest($this->backlink);
        $this->redirect('Dashboard:');
    }

    // ...
}

Metoda Nette\Application\UI\Presenter::restoreRequest() přijímá klíč requestu, který jsme si uložili dříve. Pokud pod klíčem nic nenajde, tak nebude dělat nic a přijde na řadu „výchozí přesměrování“.

Pokud uložený request spouští signál, tak se po obnovení provede jako obyčejně. Výjimkou je signál submit pro odeslání formuláře. Ten při zpracování signálu explicitně kontroluje, zda se jedná o obnovený request, a pokud ano, signál ignoruje.