custom validator not called when field not empty

时间:2016-04-12 00:28:03

标签: forms validation symfony

I have a project with 2 entities having links to a User, using FosUserBundle. Here is one entity:

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

To check that the email is not already in use, I have created a custom validator:

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: ~

when I submit an empty form, the validator is called. When I submit any value in the email field, it is not called at all.

Here is the code from the controller:

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 }

I've tried a number of other validator setups, none of these seem to be checked:

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: ~

2 个答案:

答案 0 :(得分:1)

如果您未指定任何验证组,这必须适合您:

AgriHealth\AhpBundle\Entity\Vet:
    constraints:
        - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
            fields: email_canonical
            repositoryMethod: YOUR_REPOSITORY_METHOD
            errorPath: email

答案 1 :(得分:0)

这实际上是由我在实体内创建用户对象引起的。

这显然是不好的做法,因为它打破了验证!