/**
* Validates the form and its domain object.
*
* @param FormInterface $form A FormInterface instance
*/
public function validate(FormInterface $form)
{
if ($form->isRoot()) {
$mapping = array();
$forms = array();
$this->buildFormPathMapping($form, $mapping);
$this->buildDataPathMapping($form, $mapping);
$this->buildNamePathMapping($form, $forms);
$this->resolveMappingPlaceholders($mapping, $forms);
// Validate the form in group "Default"
// Validation of the data in the custom group is done by validateData(),
// which is constrained by the Execute constraint
if ($form->hasAttribute('validation_constraint')) {
$violations = $this->validator->validateValue($form->getData(), $form->getAttribute('validation_constraint'), self::getFormValidationGroups($form));
if ($violations) {
foreach ($violations as $violation) {
$propertyPath = new PropertyPath($violation->getPropertyPath());
$template = $violation->getMessageTemplate();
$parameters = $violation->getMessageParameters();
$error = new FormError($template, $parameters);
$child = $form;
foreach ($propertyPath->getElements() as $element) {
$children = $child->getChildren();
if (!isset($children[$element])) {
if ($form->isSynchronized()) {
$form->addError($error);
}
break;
}
$child = $children[$element];
}
if ($child->isSynchronized()) {
$child->addError($error);
}
}
}
} elseif (count($violations = $this->validator->validate($form))) {
foreach ($violations as $violation) {
$propertyPath = $violation->getPropertyPath();
$template = $violation->getMessageTemplate();
$parameters = $violation->getMessageParameters();
$error = new FormError($template, $parameters);
foreach ($mapping as $mappedPath => $child) {
if (preg_match($mappedPath, $propertyPath)) {
if ($child->isSynchronized()) {
$child->addError($error);
}
continue 2;
}
}
if ($form->isSynchronized()) {
$form->addError($error);
}
}
}
}
}