Consider the following simple Doctrine entity:
1 2 3 4 5 6 7 8 9 10
use Doctrine\ORM\Mapping as ORM;
/** @ORM\Entity */
class SomeEntity
{
// ...
/** @ORM\Column(length=4) */
public $pinCode;
}
Will the following code result in a validation error?
1 2 3
$entity = new SomeEntity();
$entity->pinCode = '1234567890';
$violationList = $validator->validate($entity);
The answer is ... no. Surprisingly, many Symfony developers still don't
realize that the Doctrine mapping configuration (e.g. @ORM\Column(length=4)
)
doesn't actually validate anything. This config is just a hint for the Doctrine
schema generator. This can lead to usability and even security issues.
In Symfony 4.3 we improved this by introducing automatic validation based on Doctrine mapping. That's why in Symfony 4.3, the previous example would have produced the following result:
1 2 3 4 5 6
$violationList = $validator->validate($entity);
var_dump((string) $violationList);
// Object(App\Entity\SomeEntity).columnLength:\n
// This value is too long. It should have 4 characters or less.
// (code d94b19cc-114f-4f44-9cc4-4138e80a87b9)\n
This new feature introspects mappings like @ORM\Column(length=4)
to add the
related @Assert\Length(max=4)
validation automatically to that same
property. Specifically, the following validations are automated:
Doctrine mapping | Automatic validation constraint |
---|---|
nullable=false |
@Assert\NotNull |
type=... |
@Assert\Type(...) |
unique=true |
@UniqueEntity |
length=... |
@Assert\Length(...) |
The automatic validation of nullable=false
and type=...
requires to have
the PropertyInfo component installed. Also, this new feature will be disabled
by default, but enabled for new projects.
Since the Form component as well as API Platform internally use the Validator component, all your forms and web APIs will also automatically benefit from these automatic constraints.
Lastly, keep in mind that, although this automatic validation is convenient, it's not enough for most applications, so you will still need to manually configure more Symfony validation constraints.
Nice job !
Awesome
Seems to be a nice new feature :)
As it will be opt-in (so disabled by default for existing Sf apps) could you add the required configuration for existing apps? Thanks :)
I guess the validation constraint for the doctrine mapping of nullable=false should be Assert\NotNull rather than for doctrine mapping of nullable=true ?
@Oliver yes! that was a mistake and it's now fixed.
@Jonathan the code to make this configurable in DoctrineBundle is still pending. I'll update the post when it's merged. Thanks.
Very clever, nice job
Symfony 4.3 is going to be really awesome! 🎉
Love it!
Very nice addition, thanks!
length doesn‘t actually validate anything?
Oh boy, I have to overthink my whole application
It would be nice to mention in the post how exactly to enable/disable this feature
@Tito the option to enable/disable this feature is not ready yet. See https://github.com/doctrine/DoctrineBundle/pull/939 We'll update the blog post when this is ready.
awesome....
Awesome feature! Nice job, thanks
Nice job ! The minimum validation requirements are now free ! Thanks.
Nice and useful update ! Can't wait to put hands on Symfony 4.3 :D
Looks nice for the common case.
But ... how does this handle custom field types that extend basic field types? Not that I would do this, but assuming I would extend an int type to store the year of something and the phpvalue would be a DateTime. Or I have some Object (in php) that is mapped to some string with known max length (in db)? I could have a length attribute in the definition, but the value might be an object. Are lifecycle handlers run before/after validation? Can this "magic" validation be enabled/disabled globally only? What if the db field is not nullable (-> NotBlank?) but the mapper of the custom type will ensure that it is not null? or the lifecycle handler does ensure this?
I see so many edge cases with this ... and have the feeling it would be better to explicitly state that doctrine annotations are not validation constraints (which seems somewhat obvious...).
Agree every point with Jochen Taeschner. I did this feature time ago for Symfony 3, but I have to roll it back because I faced many issues, including those Jochen said above. Finally, I decided to create a validator command to check for Doctrine metadata on entity fields and to check if it has the corresponding validation constraints or not, so I can avoid that problem when necessary, and I can annotate when not necessary (and why). Appart from what Jochen said, I faced those problems:
This is great. Even for us who knew that Validation should be added separately, it was still easy to forget and a general pain in the ass. Thanks so much for doing this automatically :) Makes our lives easier and our apps more consistent
This is good for Symfony developers that unaware of validations.