1

I'm simply trying to validate a form (with no entity attached) with one field "username". I want to check if the username exists or not. If it doesn't a proper message has to be displayed at form errors level (or form field errors level, I don't care that much).

Here is the relevant part of my controller:

$formGlobalSearch=$this->createFormBuilder()
->add('username', 'text', array('constraints' => new UsernameExists()))
->add('role', 'choice', array('choices' => $rolesListForForm,'required' => false, 'placeholder' => 'Choose a role', 'label' => false, ))
->add('submitUsername', 'submit', array('label' => 'Search username globally'))
->getForm();

$formGlobalSearch->handleRequest($request);

if ($formGlobalSearch->isValid())
    {
    // do something in the DB and refresh current page
    }

return $this->render(//all the stuff needed to render my page//);
}

Here is the relevant part of service.yml

validator.unique.UsernameExists:
    class: AppBundle\Validator\Constraints\UsernameExists
    tags:
        - { name: validator.constraint_validator, alias: UsernameExists }

Here is the validator class:

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class UsernameExists extends Constraint
{
public $message = 'The username "%string%" does not exist.';

public function validatedBy()
{
    return 'UsernameExists';
}
}

Here is the validator:

<?php
namespace AppBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class UsernameExistsValidator extends ConstraintValidator
{
public function validate($value)
    {
    $globalUserToAdd = $this->getDoctrine()->getRepository('AppBundle:User')->findOneBy(
        array('username' => $value, 'enabled' => true)
        );

    if ($globalUserToAdd == null) //I did not find the user
        {
        $this->context->buildViolation($constraint->message)
            ->setParameter('%string%', $value)
            ->addViolation();
        }
    }
}

The class and the validator are in the directory "AppBundle\Validator\Constraints"

I'm getting the following error:

Expected argument of type "Symfony\Component\Validator\ConstraintValidatorInterface", "AppBundle\Validator\Constraints\UsernameExists" given

I of course have the following on top of my controller:

use AppBundle\Validator\Constraints\UsernameExists;

If I add the following to service.yml

arguments: ["string"]

I get the error:

No default option is configured for constraint AppBundle\Validator\Constraints\UsernameExists

2
  • 1
    btw, you must inject the doctrine service for get the user repository Commented Jan 5, 2015 at 14:56
  • What Matteo said - you can't just use $this->getDoctrine()->getRepository('AppBundle:User') inside your class...that only works if you're in the Controller. Commented Jan 5, 2015 at 17:13

2 Answers 2

0

try changing:

public function validatedBy()
{
    return 'UsernameExists';
}

validator.unique.UsernameExists:
    class: AppBundle\Validator\Constraints\UsernameExists

to:

public function validatedBy()
{
    return 'UsernameExistsValidator';
}

validator.unique.UsernameExists:
    class: AppBundle\Validator\Constraints\UsernameExistsValidator
Sign up to request clarification or add additional context in comments.

Comments

0

Merging (partially) the suggestions and debugging a bit more here is the final code.

Validator:

<?php
namespace AppBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Doctrine\ORM\EntityManager;

class UsernameExistsValidator extends ConstraintValidator
{

public function __construct(EntityManager $em) //added
{
    $this->em = $em;
}

public function validate($value, Constraint $constraint)
    {
    $em = $this->em;
    $globalUserToAdd = $em->getRepository('AppBundle:User')->findOneBy(
        array('username' => $value, 'enabled' => true)
        );

    if ($globalUserToAdd == null) //I did not find the user
        {
        $this->context->buildViolation($constraint->message)
            ->setParameter('%string%', $value)
            ->addViolation();
        }
    }
}

service.yml

validator.unique.UsernameExists:
    class: AppBundle\Validator\Constraints\UsernameExistsValidator
    arguments: [ @doctrine.orm.entity_manager, "string"]
    tags:
        - { name: validator.constraint_validator, alias: UsernameExists }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.