Zprávy z modelu do formuláře

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

Problém: Z formuláře vyberu data (Form::getValues()) a předám je modelu, například aby si je uložil (DibiTable::insert()). Model zjistí, že přese všechna validační pravidla ta data stále nejsou v pořádku. Jak tuto informaci předat zpět do formuláře?

Momentálně to dělám takhle:

try {
    $model->insert($form->getValues());
} catch (Exception $e) {
    $form->addError($e->__toString());
}

Jenže tím se přidá taková obecná chyba. Chyba, která nepatří žádné konkrétní položce. Někdy to stačí (když nastane nějaká DibiException), pokud ale v modelu provádím nějakou vlastní složitější validaci, tak mi ta možnost označit určitou položku docela schází.

Napadlo mě, že by se mohla ustanovit nějaká speciální výjimka, která by tyto informace nesla:

public function insert($data)
{
    if ($data["field1"] není validní) {
        $e = new InputException;
        $e->addError("Zpráva", "field1");
        throw $e;
    }
}

A pak by se to odchytávalo nějak takhle (formulář by si ty chyby uměl z té výjimky vycucnout):

try {
    $model->insert($form->getValues());
} catch (InputException $e) {
    $form->importErrors($e);
} catch (Exception $e) {
    $form->addError($e->__toString());
}

Zatím je to jenom nápad, ale myslím, že něco takového by vůbec nemuselo být špatné. Co myslíte?

David Grudl
Nette Core | 8218
+
0
-

Ve „starých“ formulářích bylo možné jako druhý parametr metody addError() uvést název položky, ke které byla zpráva přiřazena. U nových formulářů mají metodu addError() už i jednotlivé položky:

$form['field1']->addError('Not valid');

ad výjimky: něco podobného funguje v nových formulářích. Existuje tu podpora uživatelských validátorů (jako callbacky). Ty v případě negativního výsledku vrátí FALSE.

function myValidator($control, $arg)
{
    return $control->value <> 123;
}

$form = new Form();
$form->addText('field', 'Číslo:')
    ->addRule('myValidator', 'Chybová zpráva');

V PHP 5.3 půjde uživatelské validátory zapisovat i takto:

$form = new Form();
$form->addText('number', 'Číslo:')
    ->addRule(
        function ($control) { return (bool) $control->value % 2; },
        'Zadané číslo není dostatečně liché'
    );