我在集合中使用自定义类验证器时出现问题。它找到了错误,获得了良好的属性路径,但是将其发送到父表单。 它导致错误在父表单中列出,而不是集合中的每个子项...
某些代码更具相关性:
validation.yml
My\SuperBundle\Entity\Event:
properties:
conflictComment:
- NotNull: ~ # this property constraint got the right property path in the right form !
constraints:
- My\SuperBundle\Validator\DateIsAvailable: ~ # this one got the right property path, but in the parent form.
MultiEventType.php,获取子表单错误的父表单
$builder
->add('events', 'collection', array(
'type' => new \My\SuperBundle\Form\Type\EventDateType()
));
...
'data_class' => 'My\SuperBundle\Form\Model\MultiEvent'
EventDateType.php,应该收到错误的集合
$required = false;
$builder
->add('begin', 'datetime', array(
'date_widget' => 'single_text',
'time_widget' => 'text',
'date_format' => 'dd/MM/yyyy',
'label' => 'form.date.begin')
)
->add('automatic', 'checkbox', compact('required'))
->add('conflictComment', 'textarea', compact('required'));
...
'data_class' => '\My\SuperBundle\Entity\Event'
DateIsAvailableValidator.php
namespace My\SuperBundle\Validator;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class DateIsAvailableValidator extends ConstraintValidator
{
private $container;
public function __construct($container)
{
$this->container = $container;
}
public function isValid($event, Constraint $constraint)
{
$this->setMessage($constraint->message);
return false;
}
}
属性路径类似于 children [events] [0] .data ,但在 form_errors(multiEventForm.events)上呈现,而不是 form_errors(原型)< / strong>因为它应该在我的模板中用于收集行...
有没有办法以正确的形式获取错误或是错误?
答案 0 :(得分:1)
好的,这就是我绕过这个问题所做的:
只需创建一个扩展名即可以正确的格式呈现错误:
SubformExtension.php
<?php
namespace My\SuperBundle\Twig;
use Symfony\Component\Form\FormView;
use Twig_Environment;
use Twig_Extension;
use Twig_Function_Method;
/**
* Add methods to render into the appropriate form
*
* @author Jérémy Hubert <jhubert@eskape.fr>
*/
class SubformExtension extends Twig_Extension
{
/**
* {@inheritdoc}
*/
public function initRuntime(Twig_Environment $environment)
{
$this->environment = $environment;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'subform_extension';
}
/**
* {@inheritdoc}
*/
public function getFunctions()
{
return array(
'subform_errors' => new Twig_Function_Method($this, 'renderErrors', array('is_safe' => array('html'))),
);
}
/**
* Render errors handled by parent form of a collection in the right subform
* @param FormView $view The Child/Collection form which should handle the error
* @param string $template Template used to render the error message
*
* @return string
*/
public function renderErrors(FormView $view, $template = null)
{
// Get the root form, where our (sub)collection errors bubbled
$parentForm = $view;
do {
$parentForm = $parentForm->getParent()->getParent();
} while ($parentForm->hasParent());
$parentForm = $parentForm->getVars();
// Seeking property path
$fieldName = $view->get('full_name');
$validationName = '[' . preg_replace('/^[a-zA-Z_]*/', 'children', $fieldName) . '.data]';
// Render errors
$html = '';
foreach ($parentForm['errors'] as $error) {
if (false !== strpos($error->getMessageTemplate(), $validationName)) {
$message = str_replace($validationName, '', $error->getMessageTemplate());
if (null !== $template) {
$html .= $this->environment->render($template, compact('message'));
} else {
$html .= $message;
}
}
}
return $html;
}
}
services.yml
parameters:
twig.extension.subform.class: My\SuperBundle\Twig\SubformExtension
services:
twig.extension.subform:
class: %twig.extension.subform.class%
tags:
- { name: twig.extension }
errorMessage.html.twig(使用Twitter Bootstrap)
<div class="alert alert-error no-margin-bottom">
<div class="align-center">
<i class="icon-chevron-down pull-left"></i>
{{ message }}
<i class="icon-chevron-down pull-right"></i>
</div>
</div>
在我的收藏原型中:
{{ subform_errors(prototype, 'MySuperBundle:Message:errorMessage.html.twig') }}
希望这有帮助,而不是提出任何更好的解决方案。