programing

Symfony2 - 내장된 양식 유형에 대해 유효성 검사가 작동하지 않음

goodsources 2022. 10. 30. 11:13
반응형

Symfony2 - 내장된 양식 유형에 대해 유효성 검사가 작동하지 않음

2개의 엔티티(사용자 및 프로파일)를 조합한 폼이 있습니다.

검증은 사용자 엔티티에서 제공되는 폼의 첫 번째 부분에서 기능하는 것으로 보이며 폼의 기반이 됩니다.

프로파일유형은 UserType 안에 포함됩니다.폼이 올바르게 렌더링되어 올바른 정보가 표시되므로 프로파일엔티티에 올바르게 연결되어 있는 것 같습니다.ProfileType에서 검증이 깨진 것뿐입니다.

왜 한쪽이 검증되고 다른 한쪽이 검증되지 않는지 아십니까?

아래 코드:

Validation.yml

DEMO\DemoBundle\Entity\User\Profile:
    properties:
        address1:
            - NotBlank: { groups: [profile] }
        name:
            - NotBlank: { groups: [profile] }
        companyName:
            - NotBlank: { groups: [profile] }

DEMO\DemoBundle\Entity\User\User:
    properties:
        username:
            - NotBlank:
                groups: profile
                message: Username cannot be left blank.
        email:
            - NotBlank:
                groups: profile
                message: Email cannot be left blank
            - Email:
                groups: profile
                message: The email "{{ value }}" is not a valid email.
                checkMX: true
        password:
            - MaxLength: { limit: 20, message: "Your password must not exceed {{ limit }} characters." }
            - MinLength: { limit: 4, message: "Your password must have at least {{ limit }} characters." }
            - NotBlank: ~

UserType.php

namespace DEMO\DemoBundle\Form\Type\User;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormError;

use DEMO\DemoBundle\Form\Type\User\ProfileType;

class UserType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder->add('username');
        $builder->add('email');
        $builder->add('profile', new ProfileType());
    }

    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'DEMO\DemoBundle\Entity\User\User',
            'validation_groups' => array('profile')
        );
    }

    public function getName()
    {
        return 'user';
    }
}

ProfileType.php

namespace DEMO\DemoBundle\Form\Type\User;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormError;

class ProfileType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder->add('name');
        $builder->add('companyName', null, array('label' => 'Company Name'));
        $builder->add('address1', null, array('label' => 'Address 1'));
        $builder->add('address2', null, array('label' => 'Address 2'));
        $builder->add('city');
        $builder->add('county');
        $builder->add('postcode');
        $builder->add('telephone');
    }

    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'DEMO\DemoBundle\Entity\User\Profile',
        );
    }

    public function getName()
    {
        return 'profile';
    }
}

컨트롤러

$user = $this->get('security.context')->getToken()->getUser();

        $form = $this->createForm(new UserType(), $user);

        if ($request->getMethod() == 'POST') {
            $form->bindRequest($request);

            if ($form->isValid()) {
                // Get $_POST data and submit to DB
                $em = $this->getDoctrine()->getEntityManager();
                $em->persist($user);
                $em->flush();

                // Set "success" flash notification
                $this->get('session')->setFlash('success', 'Profile saved.');
            }

        }

        return $this->render('DEMODemoBundle:User\Dashboard:profile.html.twig', array('form' => $form->createView()));

한 시대를 검색해봤더니 그게 더 많은걸려진다는 걸'cascade_validation' => true에게setDefaults()(스레드에서 이미 언급한 바와 같이) 이를 수정한 부모 유형의 클래스에 배열이 있습니다.이로 인해 엔티티 제약 조건 검증이 양식에 표시된 자식 유형으로 트리거됩니다.

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(            
        ...
        'cascade_validation' => true,
    ));
}

컬렉션의 경우 다음 항목도 추가해야 합니다.'cascade_validation' => true에게$options예를 들어, 폼의 컬렉션 필드에 대한 배열입니다.

$builder->add('children', 'collection', array(
    'type'         => new ChildType(),
    'cascade_validation' => true,
));

그러면 컬렉션에서 사용되는 하위 엔티티에서와 마찬가지로 UniqueEntity 검증이 수행됩니다.

Symfony 3.0 이후를 사용하는 사용자를 위한 주의사항:cascade_validation옵션이 삭제되었습니다.대신 내장된 양식에 대해 다음을 사용하십시오.

$builder->add('embedded_data', CustomFormType::class, array(
    'constraints' => array(new Valid()),
));

주제에서 벗어난 답변(Symfony 3 vs. 2)으로 이 오래된 스레드를 추가하게 되어 죄송합니다만, 여기서 이 정보를 찾으면 오늘 몇 시간을 절약할 수 있었습니다.

양식 유형 설명서에 따라 다음을 사용할 수도 있습니다.Valid대신 제약cascade_validation선택.

$builder->add('children', 'collection', array(
    'type'        => new ChildType(),
    'constraints' => array(new Valid()),
));

소유자 엔티티의 예:

/**
 * @var Collection
 *
 * @ORM\OneToMany(targetEntity="Child", ...)
 * @Assert\Valid()
 */
private $children

저도 똑같은 걸 찾고 있었는데 여기 제가 찾은 게 있어요

http://symfony.com/doc/master/book/forms.html#forms-embedding-single-object

다음과 같이 주 엔티티에 하위 엔티티의 유효성을 검사하도록 지시해야 합니다.

/**
 * @Assert\Type(type="AppBundle\Entity\Category")
 * @Assert\Valid()
 */
 private $subentity;

나는 이것을 symfony 2.8로 테스트했고 효과가 있다.

YML 또는 주석을 사용하고 있습니까?

이 기능을 사용해 보았습니다.cascade_validation부모 폼클래스의 옵션이지만 검증은 아직 이루어지지 않았습니다.나는 약간의 문서를 읽고 나서app/config/config.yml알고 보니enable_annotations아래framework->validationtrue로 설정되었습니다.이것이 사실이라면 검증 서비스 no loner는 validation.yml 파일을 읽지 않습니다.그래서 그냥 false로 변경했는데 폼은 정상적으로 유효합니다.

Symfony 2.3에 속함

임베디드 폼과 검증 그룹을 사용하는 것은 매우 번거로울 수 있습니다.주석 @Assert\Valid()는 나에게는 기능하지 않습니다(그룹 없이도 괜찮습니다).DefaultOptions에 'true_validation' => true를 삽입합니다.->add()에서 이 작업을 반복할 필요가 없습니다.주의: HTML 5 검증은 검증 그룹과 함께 동작하지 않습니다.

예:

2개의 주소의 컬렉션.둘 다 1:1 단방향입니다.각각 다른(!) 검증 그룹을 가집니다.

  class TestCollection{

//(...)

/**
 * @var string
 * @Assert\NotBlank(groups={"parentValGroup"})
 * @ORM\Column(name="name", type="string", length=255, nullable=true)
 */
protected $name;

/**
 * @var \Demo\Bundle\Entity\TestAddress  
 * @Assert\Type(type="Demo\Bundle\Entity\TestAddress")
 * @ORM\OneToOne(targetEntity="TestAddress",cascade={"persist","remove"},orphanRemoval=true)
 * @ORM\JoinColumn(name="billing_address__id", referencedColumnName="id")
 */
protected $billingAddress;

/**
 * @var \Demo\Bundle\Entity\TestAddress
 * @Assert\Type(type="Demo\Bundle\Entity\TestAddress")
 * @ORM\OneToOne(targetEntity="TestAddress",cascade={"persist","remove"}, orphanRemoval=true)
 * @ORM\JoinColumn(name="shipping_address__id", referencedColumnName="id")
 */ 
protected $shippingAddress;

//(...)
}

주소 엔티티

class TestAddress {
/**
 * @var string
 * @Assert\NotBlank(groups={"firstname"})
 * @ORM\Column(name="firstname", type="string", length=255, nullable=true)
 */
private $firstname;

/**
 * @var string
 * @Assert\NotBlank(groups={"lastname"})
 * @ORM\Column(name="lastname", type="string", length=255, nullable=true)
 */
private $lastname;

/**
 * @var string
 * @Assert\Email(groups={"firstname","lastname"}) 
 * @ORM\Column(name="email", type="string", length=255, nullable=true)
 */
private $email;

주소 유형 - 유효성 검사 그룹 변경 기능

class TestAddressType extends AbstractType {    
protected $validation_group=['lastname'];//switch group

public function __construct($validation_group=null) {
    if($validation_group!=null) $this->validation_group=$validation_group;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    //disable html5 validation: it suchs with groups 

    $builder
        ->add('firstname',null,array('required'=>false))
        ->add('lastname',null,array('required'=>false))
        ->add('email',null,array('required'=>false))
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Demo\Bundle\Entity\TestAddress',           
        'validation_groups' => $this->validation_group,
    ));
}
(...)

그리고 마지막 컬렉션유형

class TestCollectionType extends AbstractType { 

public function buildForm(FormBuilderInterface $builder, array $options)
{   $builder
        ->add('name')           
        ->add('billingAddress', new TestAddressType(['lastname','firstname']))
        ->add('shippingAddress', new TestAddressType(['firstname']))            
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Demo\Bundle\Entity\TestCollection',
        'validation_groups' => array('parentValGroup'),         
        'cascade_validation' => true
    ));
}

//(...)    

도움이 되었으면 좋겠는데..

해서 더해야 요.validation_groups 안에서ProfiletType합니다.data_class존재하는 경우.

컨트롤러에서:

$form = $this->get('form.factory')
        ->createNamedBuilder('form_data', 'form', $item, array('cascade_validation' => true))
        ->add('data', new ItemDataType())
        ->add('assets', new ItemAssetsType($this->locale))
        ->add('contact', new ItemContactType())
        ->add('save', 'submit',
            array(
                'label' => 'Save',
                'attr' => array('class' => 'btn')
            )
        )
        ->getForm();

- 의 네 번째 : createNameBuilder -array('cascade_validation' => true))

언급URL : https://stackoverflow.com/questions/10138505/symfony2-validation-not-working-for-embedded-form-type

반응형