Я придумал это решение. Он отлично работает с последней версией Symfony 2.4.
Я постараюсь дать некоторые пояснения.
Использование отдельного валидатора
Я думаю, что использовать отдельную проверку для проверки сущностей и возвращать сообщения о нарушении ограничений, как это предлагают другие авторы, — плохая идея.
Вам нужно будет вручную проверить все объекты, указать группы проверки и т. д. Со сложными иерархическими формами это вообще непрактично и быстро выйдет из-под контроля.
Таким образом, вы будете проверять форму дважды: один раз с формой и один раз с отдельным валидатором. Это плохая идея с точки зрения производительности.
Я предлагаю рекурсивно перебирать тип формы с его дочерними элементами для сбора сообщений об ошибках.
Использование некоторых предложенных методов с эксклюзивным оператором IF
Некоторые ответы, предложенные другими авторами, содержат взаимоисключающие операторы IF, такие как: if ($form->count() > 0)
или if ($form->hasChildren())
.
Насколько я вижу, каждая форма может иметь ошибки, а также дочерние элементы. Я не эксперт по компоненту Symfony Forms, но на практике вы не получите некоторых ошибок самой формы, таких как ошибка защиты CSRF или лишние поля эм> ошибка. Предлагаю убрать это разделение.
Использование денормализованной структуры результата
Некоторые авторы предлагают помещать все ошибки в простой массив. Таким образом, все сообщения об ошибках самой формы и ее дочерних элементов будут добавлены в один и тот же массив с разными стратегиями индексации: на основе чисел для собственных ошибок типа и на основе имен для дочерних ошибок. Я предлагаю использовать нормализованную структуру данных вида:
errors:
- "Self error"
- "Another self error"
children
- "some_child":
errors:
- "Children error"
- "Another children error"
children
- "deeper_child":
errors:
- "Children error"
- "Another children error"
- "another_child":
errors:
- "Children error"
- "Another children error"
Таким образом, результат может быть легко повторен позже.
Мое решение
Итак, вот мое решение этой проблемы:
use Symfony\Component\Form\Form;
/**
* @param Form $form
* @return array
*/
protected function getFormErrors(Form $form)
{
$result = [];
// No need for further processing if form is valid.
if ($form->isValid()) {
return $result;
}
// Looking for own errors.
$errors = $form->getErrors();
if (count($errors)) {
$result['errors'] = [];
foreach ($errors as $error) {
$result['errors'][] = $error->getMessage();
}
}
// Looking for invalid children and collecting errors recursively.
if ($form->count()) {
$childErrors = [];
foreach ($form->all() as $child) {
if (!$child->isValid()) {
$childErrors[$child->getName()] = $this->getFormErrors($child);
}
}
if (count($childErrors)) {
$result['children'] = $childErrors;
}
}
return $result;
}
Я надеюсь, что это поможет кому-то.
person
Slava Fomin II
schedule
28.04.2014