-->

我怎么能违反添加到收藏?(How can I add a violation to a collec

2019-06-26 14:58发布

我的形式如下:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $factory = $builder->getFormFactory();

    $builder->add('name');

    $builder->add('description');

    $builder->add('manufacturers', null, array(
        'required' => false
    ));

    $builder->add('departments', 'collection', array(
        'type' => new Department
    ));
}

我对形式表示调用实体类的验证:

    if (!$valid) {
        $this->context->addViolationAtSubPath('departments', $constraint->message);
    }

这只会在子路径添加一个“全球性”的错误的形式,而不是错误。 我想这是因为部门是一家集嵌入另一个FormType。

如果我改变departments到其他的领域之一,它工作正常。

我怎样才能得到这个错误出现在正确的地方? 我相信它会正常工作,如果我的错误是在集合中的一个单一的实体,从而在孩子的形式呈现,但我的标准是,违反发生,如果没有集合中的实体被标记为活动的,因此需要要在父级别。

Answer 1:

默认情况下,形式可以选择“error_bubbling”设置为true ,这将导致你刚才所描述的行为。 如果你希望他们保持自己的错误,你可以关闭此选项个别形式。

$builder->add('departments', 'collection', array(
    'type' => new Department,
    'error_bubbling' => false,
));


Answer 2:

我一直在Symfony的3.3,在这里我想验证整个集合,但错误传递给适当的集合元素/场这个问题摔跤。 集合被添加到由此形式:

        $form->add('grades', CollectionType::class,
            [
                'label'         => 'student.grades.label',
                'allow_add'     => true,
                'allow_delete'  => true,
                'entry_type'    => StudentGradeType::class,
                'attr'          => [
                    'class' => 'gradeList',
                    'help'  => 'student.grades.help',
                ],
                'entry_options'  => [
                    'systemYear' => $form->getConfig()->getOption('systemYear'),
                ],
                'constraints'    => [
                    new Grades(),
                ],
            ]
        );

该StudentGradeType是:

<?php

namespace Busybee\Management\GradeBundle\Form;

use Busybee\Core\CalendarBundle\Entity\Grade;
use Busybee\Core\SecurityBundle\Form\DataTransformer\EntityToStringTransformer;
use Busybee\Core\TemplateBundle\Type\SettingChoiceType;
use Busybee\Management\GradeBundle\Entity\StudentGrade;
use Busybee\People\StudentBundle\Entity\Student;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class StudentGradeType extends AbstractType
{
    /**
     * @var ObjectManager
     */
    private $om;

    /**
     * StaffType constructor.
     *
     * @param ObjectManager $om
     */
    public function __construct(ObjectManager $om)
    {
        $this->om = $om;
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('status', SettingChoiceType::class,
                [
                    'setting_name' => 'student.enrolment.status',
                    'label'        => 'grades.label.status',
                    'placeholder'  => 'grades.placeholder.status',
                    'attr'         => [
                        'help' => 'grades.help.status',
                    ],
                ]
            )
            ->add('student', HiddenType::class)
            ->add('grade', EntityType::class,
                [
                    'class'         => Grade::class,
                    'choice_label'  => 'gradeYear',
                    'query_builder' => function (EntityRepository $er) {
                        return $er->createQueryBuilder('g')
                            ->orderBy('g.year', 'DESC')
                            ->addOrderBy('g.sequence', 'ASC');
                    },
                    'placeholder'   => 'grades.placeholder.grade',
                    'label'         => 'grades.label.grade',
                    'attr'          => [
                        'help' => 'grades.help.grade',
                    ],
                ]
            );

        $builder->get('student')->addModelTransformer(new EntityToStringTransformer($this->om, Student::class));

    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver
            ->setDefaults(
                [
                    'data_class'         => StudentGrade::class,
                    'translation_domain' => 'BusybeeStudentBundle',
                    'systemYear'         => null,
                    'error_bubbling'     => true,
                ]
            );
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'grade_by_student';
    }


}

和验证的样子:

 namespace Busybee\Management\GradeBundle\Validator\Constraints; use Busybee\Core\CalendarBundle\Entity\Year; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; class GradesValidator extends ConstraintValidator { public function validate($value, Constraint $constraint) { if (empty($value)) return; $current = 0; $year = []; foreach ($value->toArray() as $q=>$grade) { if (empty($grade->getStudent()) || empty($grade->getGrade())) { $this->context->buildViolation('student.grades.empty') ->addViolation(); return $value; } if ($grade->getStatus() === 'Current') { $current++; if ($current > 1) { $this->context->buildViolation('student.grades.current') ->atPath('['.strval($q).']') // could do a single atPath with a value of "[".strval($q)."].status" ->atPath('status') // full path = children['grades'].data[1].status ->addViolation(); return $value; } } $gy = $grade->getGradeYear(); if (! is_null($gy)) { $year[$gy] = empty($year[$gy]) ? 1 : $year[$gy] + 1 ; if ($year[$gy] > 1) { $this->context->buildViolation('student.grades.year') ->atPath('['.strval($q).']') ->atPath('grade') ->addViolation(); return $value; } } } } } 

这导致错误被添加到字段中集合作为每附着图像的元件。

克雷格



Answer 3:

我有非常相似的情况。 我有一个自定义表单CollectionType(与DataTransformers内,等...),我需要一个二选一的元素和标记他们的什么是错的,并打印在视图。

我作出这样的解决方案在ConstraintValidator(我自定义的验证):

验证器必须靶向CLASS_CONSTRAINT工作或的PropertyPath不起作用。

public function validate($value, Constraint $constraint) {
    /** @var Form $form */
    $form = $this->context->getRoot();
    $studentsForm = $form->get("students"); //CollectionType's name in the root Type
    $rootPath = $studentsForm->getPropertyPath()->getElement(0);

    /** @var Form $studentForm */
    foreach($studentsForm as $studentForm){
        //Iterate over the items in the collection type
        $studentPath = $studentForm->getPropertyPath()->getElement(0);

        //Get the data typed on the item (in my case, it use an DataTransformer and i can get an User object from the child TextType)
        /** @var User $user */
        $user = $studentForm->getData();

        //Validate your data
        $email = $user->getEmail();
        $user = $userRepository->findByEmailAndCentro($email, $centro);

        if(!$user){
            //If your data is wrong build the violation from the propertyPath getted from the item Type
            $this->context->buildViolation($constraint->message)
                ->atPath($rootPath)
                ->atPath(sprintf("[%s]", $studentPath))
                ->atPath("email") //That last is the name property on the item Type
                ->addViolation();
        }
    }
}

只是我验证agains集合中的表单元素和构建是错误的集合中使用的PropertyPath从项目的违规行为。



文章来源: How can I add a violation to a collection?