3

我在集合中使用自定义类验证器时遇到问题。它发现错误,获取良好的属性路径,但将其发送到父表单。它导致错误列在父表单中,而不是集合的每个子表单中......

一些更相关的代码:

验证.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(prototype),因为它应该在我的集合行模板中......

有没有办法以正确的形式获取错误,或者这是一个错误?

4

1 回答 1

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;
    }

}

服务.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') }}

希望这会有所帮助,但没有提出任何更好的解决方案。

于 2012-10-24T07:10:01.980 回答