Symfony-CollectionType字段中的唯一实体?
我有一个包含collectionType的formBuilder。我希望能够在电子邮件字段上设置一个约束,以确保当用户验证时,表单中多次没有相同的电子邮件地址 我已经: RegistrationCollectionType.phpSymfony-CollectionType字段中的唯一实体?,symfony,validation,collections,constraints,unique,Symfony,Validation,Collections,Constraints,Unique,我有一个包含collectionType的formBuilder。我希望能够在电子邮件字段上设置一个约束,以确保当用户验证时,表单中多次没有相同的电子邮件地址 我已经: RegistrationCollectionType.php $builder ->add('utilisateurs', CollectionType::class, [ 'entry_type' => RegistrationType::class,
$builder
->add('utilisateurs', CollectionType::class, [
'entry_type' => RegistrationType::class,
'entry_options' => [
'label' => false,
'entreprise' => $entreprise,
],
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'by_reference' => true,
'prototype' => true,
'label' => false,
'attr' => [
'class' => 'my-selector',
'label' => false,
],
'by_reference' => false,
])
;
class RegistrationCollection
{
private $utilisateurs = [];
public function getUtilisateurs(): ?array
{
return $this->utilisateurs;
}
public function setUtilisateurs(?array $utilisateurs): self
{
$this->utilisateurs = $utilisateurs;
return $this;
}
}
->add('email', EmailType::class, [
'attr' => [
'placeholder' => "Adresse email"
],
])
与他的班级:
RegistrationCollection.php
$builder
->add('utilisateurs', CollectionType::class, [
'entry_type' => RegistrationType::class,
'entry_options' => [
'label' => false,
'entreprise' => $entreprise,
],
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'by_reference' => true,
'prototype' => true,
'label' => false,
'attr' => [
'class' => 'my-selector',
'label' => false,
],
'by_reference' => false,
])
;
class RegistrationCollection
{
private $utilisateurs = [];
public function getUtilisateurs(): ?array
{
return $this->utilisateurs;
}
public function setUtilisateurs(?array $utilisateurs): self
{
$this->utilisateurs = $utilisateurs;
return $this;
}
}
->add('email', EmailType::class, [
'attr' => [
'placeholder' => "Adresse email"
],
])
在与我的用户实体关联的我的RegistrationType.php中,我:
RegistrationType.php
$builder
->add('utilisateurs', CollectionType::class, [
'entry_type' => RegistrationType::class,
'entry_options' => [
'label' => false,
'entreprise' => $entreprise,
],
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'by_reference' => true,
'prototype' => true,
'label' => false,
'attr' => [
'class' => 'my-selector',
'label' => false,
],
'by_reference' => false,
])
;
class RegistrationCollection
{
private $utilisateurs = [];
public function getUtilisateurs(): ?array
{
return $this->utilisateurs;
}
public function setUtilisateurs(?array $utilisateurs): self
{
$this->utilisateurs = $utilisateurs;
return $this;
}
}
->add('email', EmailType::class, [
'attr' => [
'placeholder' => "Adresse email"
],
])
现在,如果我有效,我已经:
SQLSTATE[23000]:完整性约束冲突:1062 du
冠军杯ahahs@mail.fr“倒酒”UNIQ_8D93D649E7927C74
您可以创建自定义验证约束
class UniqueEmailValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if (!$constraint instanceof UniqueEmail) {
throw new UnexpectedTypeException($constraint, UniqueEmail::class);
}
if (!\is_array($value) && !$value instanceof \IteratorAggregate) {
throw new UnexpectedValueException($value, 'array|IteratorAggregate');
}
$emails = [];
foreach ($value as $element) {
if (\in_array($element->getEmail(), $emails, true)) {
$this->context->buildViolation($constraint->message)
->addViolation();
return;
}
$emails[] = $element->getEmail();
}
}
}
并向属性中添加验证注释
class RegistrationCollection
{
/**
* @AppAssert\UniqueEmailValidator
*/
private $utilisateurs = [];
public function getUtilisateurs(): ?array
{
return $this->utilisateurs;
}
public function setUtilisateurs(?array $utilisateurs): self
{
$this->utilisateurs = $utilisateurs;
return $this;
}
}
我保留了自定义约束的想法,但它不仅适用于电子邮件,而且适用于我们想要唯一的任何字段:
#App\Validator\Constraints\UniqueProperty.php
<?php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class UniqueProperty extends Constraint
{
public $message = 'This collection should contain only elements with uniqe value.';
public $propertyPath;
public function validatedBy()
{
return UniquePropertyValidator::class;
}
}
它工作得很好,只是我不能将错误定位到子字段。系统地说,错误将传递给父实体,因此错误将被全部覆盖
我尝试在验证器中重定向到相关子实体的字段,但没有做什么,错误继续将所有内容置于上面
在我的表单类型中,我尝试禁用错误\u冒泡,但事情是一样的
->add('utilisateurs', CollectionType::class, [
'entry_type' => RegistrationType::class,
'entry_options' => [
'label' => false,
'entreprise' => $entreprise,
],
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'by_reference' => true,
'prototype' => true,
'label' => false,
'attr' => [
'class' => 'my-selector',
'label' => false,
],
'by_reference' => false,
'error_bubbling' => false,
])
;
谢谢你的帮助,我保留了你的想法,但是我做了一个新的回答来提供更多的细节谢谢!要将子字段作为目标
->atPath(sprintf('[%s].%s',$key,$constraint->propertyPath))
应该可以工作。