Symfony2-проверка не работает для встроенного типа формы



у меня есть форма, которая объединяет две сущности (Пользователь и профиль).



проверка, кажется, работает на первой части формы, которая приходит из сущности пользователя и является основой формы.



тип профиля включен в тип пользователя. Форма отображается правильно и отображает правильную информацию, поэтому кажется, что она правильно подключена к объекту профиля. Это просто проверка, которая нарушается на типе профиля.



любая идея о том, почему один часть подтвердит, а другая нет?



код ниже:



проверка.в формате YML



DEMODemoBundleEntityUserProfile:
properties:
address1:
- NotBlank: { groups: [profile] }
name:
- NotBlank: { groups: [profile] }
companyName:
- NotBlank: { groups: [profile] }

DEMODemoBundleEntityUserUser:
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 DEMODemoBundleFormTypeUser;

use SymfonyComponentFormAbstractType;
use SymfonyComponentFormCallbackValidator;
use SymfonyComponentFormFormBuilder;
use SymfonyComponentFormFormError;

use DEMODemoBundleFormTypeUserProfileType;

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' => 'DEMODemoBundleEntityUserUser',
'validation_groups' => array('profile')
);
}

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


ProfileType.php



namespace DEMODemoBundleFormTypeUser;

use SymfonyComponentFormAbstractType;
use SymfonyComponentFormCallbackValidator;
use SymfonyComponentFormFormBuilder;
use SymfonyComponentFormFormError;

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' => 'DEMODemoBundleEntityUserProfile',
);
}

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:UserDashboard:profile.html.twig', array('form' => $form->createView()));
687   8  

8 ответов:

Я провел возраст поиска и обнаружил, что он добавляет '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 ограничение вместо .

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

пример из сущности владельца:

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

принадлежит Symfony 2.3

работа со встроенными формами и группами проверки может быть довольно болезненной: Аннотация @Assert\Valid() не работает для меня (без групп это нормально). Вставить 'cascade_validation' = > true на DefaultOptions является ключом. Вам не нужно повторять это на ->Добавить(). Будьте осторожны: проверка 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,
    ));
}
(...)

и последний CollectionType

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 если существует.

вы используете YML или аннотации?

я попробовал применить cascade_validation опция на моем родительском классе формы, но проверка все еще не происходит. Прочитав немного документации, я пошел в app/config/config.yml и обнаружил, что enable_annotations под framework->validation был установлен до правда. По-видимому, если это правда, служба проверки no loner не читает никакой проверки.файла в формате YML. Поэтому я просто изменил его на ложные, и теперь форма проверяет нормально.

Я искал то же самое, и вот что я нашел

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 и он работает.

из моего контроллера:

$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();

четвертый параметр в :: createNamedBuilder -array('cascade_validation' => true))

Comments

    Ничего не найдено.