В предыдущем вопросе (Symfony Проверьте, не является ли хотя бы одно из двух полей пустым при проверке формы ) Я попросил помощи для проверки формы с помощью Callback. Ответ, данный @hous, был правильным, но он не работает для элементов в CollectionType, поэтому я открываю новый вопрос.
Основываясь на предыдущем ответе, я сделал следующее:
Вот моя форма "мама":
class BookingVisitorType extends AbstractType
{
private $router;
private $translator;
public function __construct()
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('visitors', CollectionType::class, [
'entry_type' => VisitorType::class,
'label' => 'entity.booking.visitors',
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'by_reference' => false,
'entry_options' => [
'label' => false,
'delete-url' => $options['visitor-delete-url']
],
'constraints' =>[
new Count([
'min' => 1,
'minMessage' => 'validator.visitor.at-least-one-visitor',
'max' => $options['numberOfPlaces'],
'maxMessage' => 'validator.visitor.cannot-have-more-visitor-than-spaces',
'exactMessage' => 'validator.visitor.exact-message'
])
]
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Booking::class,
'numberOfPlaces' => 1,
'visitor-delete-url' => ''
]);
}
}
Вот моя форма "сын":
class VisitorType extends AbstractType
{
private $phone;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstName', TextType::class, [
'label' => 'entity.visitor.first-name',
'constraints' => [
new NotBlank(),
new Length([
'min' => 2,
'max' => 255
]),
new Regex([
'pattern' => "/[\pL\s\-]*/",
'message' => 'validator.visitor.not-valide-first-name'
])
]
])
->add('phone', TextType::class, [
'label' => 'entity.visitor.phone-number',
'required' => false,
'constraints' => [
new Regex([
'pattern' => "/[0-9\s\.\+]*/",
'message' => 'validator.visitor.not-valide-phone-number'
]),
new Callback(function($phone, ExecutionContextInterface $context){
$this->phone = $phone;
}),
]
])
->add('email', TextType::class, [
'label' => 'entity.visitor.email',
'required' => false,
'constraints' => [
new Email(),
new Callback(function($email, ExecutionContextInterface $context){
if ($this->phone == null && $email == null) {
$context->buildViolation('validator.visitor.email-or-phone-required')->addViolation();
}
}),
]
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Visitor::class,
'error_bubbling' => false,
'delete-url' => '',
]);
}
}
Мой "заказ" (сокращенный) класс:
/**
* @ORM\Entity(repositoryClass="App\Repository\BookingRepository")
*/
class Booking
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Visitor", mappedBy="booking", orphanRemoval=true, cascade={"persist"})
* @Assert\Valid
*/
private $visitors;
}
И, наконец, мой «сокращенный» класс: на значение телефона, а затем проверьте его с ограничением обратного вызова в поле электронной почты, но это не кажется "хорошей практикой".
Если я только пытаюсь вызвать ограничение обратного вызова, я получаю следующее сообщение об ошибке : "Предупреждение: get_class () ожидает, что параметр 1 будет объектом, задана строка"
Любая помощь приветствуется!