Skip to content

Commit

Permalink
34.2.Custom Validator{Configuring the Annotation; Configuring your An…
Browse files Browse the repository at this point in the history
…notation Properties}

Configuring the Annotation
Ok: let's bring this generated code to life! Step 1: make sure your annotation class - UniqueUser - is ready to go. In general, an annotation can either be added above a class or above a property. Well, you can also add annotations above methods - that works pretty similar to properties.
If you add a validation annotation above your class, then during validation, the value that's passed to that validator is the entire object. If you add it above a property, then the value that's passed is just that property's value. So, if you need access to multiple fields on an object for validation, then you'll need to create an annotation that can be used above the class. In this situation, I'm going to delete @UniqueEntity and, instead, add the new annotation above my $email property: @uniqueuser. Hit tab to auto-complete that and get the use statement.
Nice! Now, go back to your annotation class, we need to do a bit more work. To follow an example, press shift+ shift and open the core NotBlank annotation class. See that @target() annotation above the class? This is a special annotation... that configures, um, the annotation system! @target tells the annotation system where your annotation is allowed to be used. Copy that and paste it above our class. This says that it's okay for this annotation to be used above a property, above a method or even inside of another annotation... which is a bit more of a complex case, but we'll leave it.
What if you instead want your annotation to be put above a class? Open the UniqueEntity class as an example. Yep, you would use the CLASS target. The other thing you would need to do is override the getTargets() method. Wait, why is there an @target annotation and a getTargets() method - isn't that redundant? Basically, yep! These provide more or less the same info to two different systems: the annotation system and the validation system. The getTargets() method defaults to PROPERTY - so you only need to override it if your annotation should be applied to a class.

Configuring your Annotation Properties
Phew! The last thing we need to do inside of UniqueUser is give it a better default $message: we'll set it to the same thing that we have above our User class: I think you've already registered. Paste that and... cool!
If you need to be able to configure more things on your annotation - just create more public properties on UniqueUser. Any properties on this class can be set or overridden as options when using the annotation. In UserRegistrationFormModel, I won't do it now, but we could add a message= option: that string would ultimately be set on the message property.
Before we try this, go to UniqueUserValidator. See the setParameter() line? The makes it possible to add wildcards to your message - like:

  The email {{ value }} is already registered

We could keep that, but since I'm not going to use it, I'll remove it. And... cool! With this setup, when we submit, this validator will be called and it will always fail. That's a good start. Let's try it!
  • Loading branch information
petrero committed Feb 9, 2020
1 parent 9381f25 commit e651daf
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 9 deletions.
9 changes: 2 additions & 7 deletions src/Form/Model/UserRegistrationFormModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@

namespace App\Form\Model;

use App\Validator\UniqueUser;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
* @UniqueEntity(
* fields={"email"},
* message="I think you're already registered!"
* )
*/
class UserRegistrationFormModel {
/**
* @Assert\NotBlank(message="Please enter an email")
* @Assert\Email()
* @UniqueUser()
*/
public $email;
/**
Expand Down
3 changes: 2 additions & 1 deletion src/Validator/UniqueUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

/**
* @Annotation
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*/
class UniqueUser extends Constraint {
/*
* Any public properties become valid options for the annotation.
* Then, use these in your validator class.
*/
public $message = 'The value "{{ value }}" is not valid.';
public $message = 'I think you\'re already registered!';
}
1 change: 0 additions & 1 deletion src/Validator/UniqueUserValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public function validate($value, Constraint $constraint) {

// TODO: implement the validation here
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $value)
->addViolation();
}
}

0 comments on commit e651daf

Please sign in to comment.