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