前のページに戻る方法は?

ユーザーがフォームに入力中にログインセッションが切れたらどうしますか?データを失わないように、ログインページにリダイレクトする前にデータをセッションに保存します。Netteではこれは非常に簡単です。

現在のリクエストは storeRequest() メソッドを使用してセッションに保存でき、その識別子を短い文字列として返します。このメソッドは、現在のPresenterの名前、ビュー、およびそのパラメータを保存します。 フォームも送信された場合、フィールドの内容も保存されます(アップロードされたファイルを除く)。

リクエストの復元は restoreRequest($key) メソッドによって行われ、取得した識別子を渡します。これは元のPresenterとビューにリダイレクトします。ただし、保存されたリクエストにフォーム送信が含まれている場合、元のPresenterには forward() メソッドで移動し、以前に入力された値をフォームに渡し、再度レンダリングさせます。これにより、ユーザーはフォームを再度送信する機会があり、データは失われません。

重要なのは、restoreRequest() が新しくログインしたユーザーが最初にフォームに入力したユーザーと同じであるかどうかを確認することです。そうでない場合、リクエストは破棄され、何も行われません。

例で説明しましょう。データを編集する AdminPresenter があり、その startup() メソッドでユーザーがログインしているかどうかを確認します。ログインしていない場合は、SignPresenter にリダイレクトします。同時に、現在のリクエストを保存し、そのキーを 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 は、ログインフォームに加えて、キーが書き込まれる永続パラメータ $backlink も含みます。パラメータは永続的であるため、ログインフォームの送信後も転送されます。

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;
		// ... フォームコントロールを追加 ...
		$form->onSuccess[] = [$this, 'signInFormSubmitted'];
		return $form;
	}

	public function signInFormSubmitted($form)
	{
		// ... ここでユーザーをログインさせます ...

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

保存されたリクエストのキーを restoreRequest() メソッドに渡し、元のPresenterにリダイレクト(または移動)します。

ただし、キーが無効な場合(たとえば、セッションに存在しなくなった場合)、メソッドは何も行いません。したがって、AdminPresenter にリダイレクトする $this->redirect('Admin:') の呼び出しが続きます。