Error při validaci formuláře

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
jik
Člen | 146
+
0
-

Zdravím,
mám formulář

	protected function createComponentCreatecommentForm() {
		$form = new Form;
...
		$form->addText('antispam', $this->antispam->question,30,30)->setRequired()->addRule(Form::PATTERN,'Nesprávné zadání antispamu. ', $this->antispam->answer);
		$form->addProtection('Vypršel časový limit, odešlete formulář znovu');
		$form->addSubmit('save', 'Ulož');
		$form->onSuccess[] = [$this, 'createcommentFormSubmitted'];
		$form->onError[] = function() use ($form) {
			dump($form->getErrors());
		};
		return $form;
	}

V případě, že je chybně zadaný antispam, je vše v pořádku a formulář mi to omlátí o hlavu. Ale v případě, že je antispam zadaný správně, vyletí onError:
`array (1)
0 ⇒ "Nesprávné zadání antispamu. " (32)`
V čem dělám chybu?
Děkuji a zdravím

jik
Člen | 146
+
0
-

Nechápu to: Mám tabulku antispam, ta obsahuje dvojice otázka-odpověď. Při zobrazení formuláře (komponenty) udělám náhodný výběr a ve formuláři se objeví otázka a ve validaci je požadovaná odpověď. Pokud formulář vyplním nesprávně, chová se to jak má a vyskočí okno, že podmínka splněna není. Ale když zadám (i napoprvé) správnou hodnotu, validací sice projde, jenomže vzápětí jakoby nově načetl náhodný záznam z antispamu a návrat z formuláře je s chybou, protože validace je již nesprávná.
Pokud ponechám v tabulce antispam pouze dvě stejné otázky a odpovědi, pracuje správně. Tedy chybu vrátí a správné zadání projde na onSucces. Zatím mám tedy dojem, jakoby se formulář (komponenta, nebo spíše celá strana) načítal během validace znovu, znovu se vyhledal náhodný záznam z antispamu a potom mu někde při návratu nehraje pravidlo a vrací se onError.
Tomu jsem se neúspěšně snažil zabránit takto:

	public $antispam;

	protected function startup() {
		parent::startup();
		if (!$this->antispam) {
			$nrecs = $this->s_antispam->getNrecs();
			$id    = random_int (1, $nrecs);
			$this->antispam = $this->s_antispam->getRecord($id);
		}
	}

	protected function createComponentCreatecommentForm() {
		$form = $this->createcommentFormFactory->create('page', $this->id, $this->antispam);
		$form->onFormSuccess[] = function () {
			$this->redirect('Homepage:page', $this->id, 0);
			$this->antispam = false;
		};
		return $form;
	}
CZechBoY
Člen | 3608
+
+1
-

Ulož si někam to IDečko otázky a odpovědi… takhle se ti při vygenerování formu vybere jiná otázka než při ověření.

jik
Člen | 146
+
0
-

To vlastně je ta public $antispam. Tu předávám v presenteru do komponenty:

	protected function createComponentCreatecommentForm() {
		$form = $this->createcommentFormFactory->create('page', $this->id, $this->antispam);
		$form->onFormSuccess[] = function () {
			$this->redirect('Homepage:page', $this->id, 0);
			$this->antispam = false;
		};
		return $form;
	}

	protected function createComponentCreatecomment() {
		$comment = new Control\CreatecommentControl;
		return $comment;
	}

a v komponentě to vypadá takto:

	public $table, $id, $antispam;

	public function __construct($table, $id, $antispam,
								App\Model\...	) {
		$this->antispam   = $antispam;
		$this->table      = $table;
		$this->id         = $id;
	}

	protected function createComponentCreatecommentForm() {
...
		return $form;
	}

	public function createcommentFormSubmitted($form, $values) {
...
		$this->onFormSuccess();
	}

interface ICreatecommentFormFactory {
	/**
	 * @param $createcommentParam
	 * @return CreatecommentForm
	 */
	function create($table, $id, $antispam);
}

Takto předpokládám, že ten $antispam předávám do komponenty jen jednou. Zatím to vypadá, že ještě před návratem z formuláře dostanu jiný záznam.

CZechBoY
Člen | 3608
+
0
-

Já to většinou dělám tak, že si do url předám nějakej klíč do nějakýho key-value úložiště (většinou session) a do toho úložiště si pod tím klíčem uložím nějakou tajnou informaci (v tomhle případě to může být buď odpověď+otázka nebo IDčko tý dvojice). Po použití tý otázky hlavně smaž tu tajnou informaci, aby se k ní už nikdo pod tím klíčem nedostal – jinak si může útočník furt dávat stejnou otázku a dá i stejnou odpověď žejo :-)).