Form::cleanErrors() neodstraní chyby z prvků formuláře

- mkrause
 - Člen | 20
 
Ahoj Davide,
v jednom specifickém případě používáme public metodu
cleanErrors v třídě Form, ovšem výsledkem je
poměrně matoucí chování. Jde o případ, kdy provádíme jisté manipulace
s daty mezi voláním $form->isSubmitted() a
$form->isValid(). isSubmitted totiž už interně
provede validaci, která může skončit s chybami, ty ale následné
zpracování může odstranit (konkrétně jde o to, že čistíme HTML
vložené do WYSIWYG editoru z Wordu od jeho balastu). Proto provedeme
zhruba toto:
	if ($form->isSubmitted()) {
		$form->cleanErrors();
		$form["html"]->setValue($this->cleanHtml($form["html"]->getValue());
		if ($form->isValid()) {
			...
		}
	}
Pokud je HTML i po pročištění nevalidní, případně existují jiné
chyby, volání $form->isValid() by je teoreticky mělo opět ve
formuláři nastavit. Bohužel se tak nestane, protože`
$form->cleanErrors()` vyčistí jen svoje pole chyb, ale ne už interní pole
chyb potomků (formulářových prvků). U těch pak druhá validace chybu
zjistí, ale chyba se považuje za duplicitní a už se nepřidává ani
nepropaguje do rodiče, tedy do formuláře. Napadají mě dvě řešení:
- ve 
Form::cleanErrors()volat stejnou metody i ze všech potomků - ve 
FormControl::addError()aplikovat kontrolu duplicity chybových hlášek pouze pro účely přidání do interního pole$errors, ale chybu vždy propagovat do rodiče a kontrolu duplicity v globálním pohledu celého formuláře ponechat na něm 
Co je lepší nechám na Tobě. My jsme si prozatím interně opatchovali
Form, takže metoda cleanErrors vypadá takto:
	/**
	 * @return void
	 */
	public function cleanErrors()
	{
		$this->errors = array();
		foreach ($this->getGroups() as $group) {
			if (!$group->getControls()) {
				continue;
			}
			foreach ($group->getControls() as $control) {
				$control->cleanErrors();
			}
		}
		foreach ($this->getControls() as $control) {
			$control->cleanErrors();
		}
		$this->valid = NULL;
	}
				
- David Grudl
 - Nette Core | 8285
 
Asi bude vhodnější to druhé řešení, protože by pak vznikla nekonzistence, proč Form::getErrors() a hasError() taky neprochází potomky. Je to implementované.
ps. ten cyklus foreach ($this->getGroups() by tam ani nemusel
být, $this->getControls() by mělo projít všechny
komponenty.