【发布时间】:2016-04-12 00:28:02
【问题描述】:
我有一个项目,其中包含 2 个实体,它们使用 FosUserBundle 链接到一个用户。这是一个实体:
AgriHealth\AhpBundle\Entity\Vet:
type: entity
oneToOne:
user:
targetEntity: User
joinColumn:
name: user_id
referencedColumnName: id
table: vet
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
firstname:
type: string
length: 100
lastname:
type: string
length: 100
mobile:
type: string
length: 15
nullable: true
email:
type: string
length: 80
user_id:
type: integer
为了检查电子邮件是否未被使用,我创建了一个自定义验证器:
AgriHealth\AhpBundle\Entity\Vet:
properties:
firstname:
- NotBlank: ~
- Length:
min: 2
max: 100
minMessage: "Your first name must be at least {{ limit }} characters long"
maxMessage: "Your first name cannot be longer than {{ limit }} characters long"
lastname:
- NotBlank: ~
- Length:
min: 2
max: 100
minMessage: "Your last name must be at least {{ limit }} characters long"
maxMessage: "Your last name cannot be longer than {{ limit }} characters long"
mobile:
- Length:
min: 2
max: 15
minMessage: "Your phone number must be at least {{ limit }} characters long"
maxMessage: "Your phone number cannot be longer than {{ limit }} characters long"
email:
- AgriHealth\AhpBundle\Validator\Constraints\UniqueEmailAll: ~
- Email:
message: The email "{{ value }}" is not a valid email.
checkMX: true
- NotBlank: ~
clinic:
- NotBlank: ~
当我提交一个空表单时,会调用验证器。当我在电子邮件字段中提交任何值时,根本不会调用它。
这是来自控制器的代码:
public function createAction(Request $request)
{
$entity = $this->getNewVet();
$entity->setDoctrine( $this->getDoctrine() );//@todo needs to happen before handle requests NEEDS TEST
$entity->setContainer( $this->getContainer() );
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
if ($entity->getUser()){//@todo NEEDS TEST
if (sizeof($entity->getClinics())){
$entity->getUser()->setRoles( array('ROLE_CLINIC_ADMIN') );
}else{
$entity->getUser()->setRoles( array('ROLE_VET') );
}
}
$em->persist( $entity );
$em->flush();
return $this->redirect($this->generateUrl('vet'));
}
return $this->render('AgriHealthAhpBundle:Vet:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
private function createCreateForm(Vet $entity)
{
$vetType = new VetType();
$vetType
->setUser($this->getUser())
->setClinicQueryBuilder( $this->getClinicRepository()->createQueryBuilder('c') )
->setSecurityContext( $this->get( 'security.context' ) );
$form = $this->createForm($vetType, $entity, array(
'action' => $this->generateUrl('vet_create'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstname', 'text', array(
'help' => '',
'required' => true,
'label' => 'First Name'
))
->add('lastname', 'text', array(
'help' => '',
'required' => true,
'label' => 'Last Name'
))
->add('mobile', 'text', array(
'help' => ''
))
->add('email', 'text', array(
'help' => 'Only one address please',
'required' => true
));
if ($this->getSecurityContext()->isGranted('ROLE_CLINIC_ADMIN')) {
$builder
->add('clinic', 'entity', array(
'class' => 'AgriHealthAhpBundle:Clinic',
'query_builder' => $this->getClinicQueryBuilder()
))
->add('clinics', 'entity', array(
'class' => 'AgriHealthAhpBundle:Clinic',
'query_builder' => $this->getClinicQueryBuilder(),
'multiple' => true,
'attr' => array(
'size' => 25
),
'required' => false,
'label' => 'Controls Clinics'
));
}
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AgriHealth\AhpBundle\Entity\Vet'
));
}
/**
* @return string
*/
public function getName()
{
return 'agrihealth_ahpbundle_vet';
}
services.yml:
services:
agri_health.twig.form_extension:
class: AgriHealth\AhpBundle\Twig\FormExtension
tags:
- { name: twig.extension }
agri_health.form_type_extension:
class: AgriHealth\AhpBundle\Form\Extension\FormTypeExtension
tags:
- { name: form.type_extension, alias: form }
validator.unique.unique_email_all_validator:
class: AgriHealth\AhpBundle\Validator\Constraints\UniqueEmailAllValidator
tags:
- { name: validator.constraint_validator, alias: unique_email_all }
我尝试了许多其他验证器设置,但似乎都没有检查:
AgriHealth\AhpBundle\Entity\Vet:
properties:
email:
- UniqueEntity:
repositoryMethod: checkFosUserEmail
- AgriHealth\AhpBundle\Validator\Constraints\UniqueEmailAll: ~
- Email:
message: The email "{{ value }}" is not a valid email.
checkMX: true
- NotBlank: ~
clinic:
- NotBlank: ~
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: email
message: 'This port is already in use on that host.'
constraints:
- FOS\UserBundle\Validator\Unique:
property: usernameCanonical
message: 'This username already exists. Please choose another one.'
AgriHealth\AhpBundle\Entity\User:
properties:
email_canonical:
- UniqueEntity: ~
【问题讨论】:
-
Symfony 有一个
UniqueEntity验证器,您可以使用它来代替编写自定义验证器。见symfony.com/doc/current/reference/constraints/UniqueEntity.html -
我需要验证电子邮件在 2 个实体中是唯一的,而不是一个
-
您是否按照here 的描述成功将验证器注册为服务?
-
@mattheo 我相信,当我的调试器在其中停止时,只有当电子邮件为空时。将在大约 2 小时内粘贴 services.yml
-
@jdog 你可以使用
UniqueEntity验证器并指定repository method你可以编写一个查询来检查每2个实体
标签: forms validation symfony