Chapters
41 Chapters
|
4:45:40
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3
Subscribe to download the code!Compatible PHP versions: ^7.1.3
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
16.
UniqueEntity & Validation Directly on Form Fields
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.10.2
"doctrine/doctrine-bundle": "^1.6.10", // 1.10.2
"doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // v2.0.0
"doctrine/orm": "^2.5.11", // v2.7.2
"knplabs/knp-markdown-bundle": "^1.7", // 1.7.0
"knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
"knplabs/knp-time-bundle": "^1.8", // 1.8.0
"nexylan/slack-bundle": "^2.0,<2.2.0", // v2.0.0
"php-http/guzzle6-adapter": "^1.1", // v1.1.1
"phpdocumentor/reflection-docblock": "^3.0|^4.0", // 4.3.0
"sensio/framework-extra-bundle": "^5.1", // v5.2.1
"stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
"symfony/asset": "^4.0", // v4.1.6
"symfony/cache": "^3.3|^4.0", // v4.1.6
"symfony/console": "^4.0", // v4.1.6
"symfony/flex": "^1.0", // v1.21.6
"symfony/form": "^4.0", // v4.1.6
"symfony/framework-bundle": "^4.0", // v4.1.6
"symfony/property-access": "^3.3|^4.0", // v4.1.6
"symfony/property-info": "^3.3|^4.0", // v4.1.6
"symfony/security-bundle": "^4.0", // v4.1.6
"symfony/serializer": "^3.3|^4.0", // v4.1.6
"symfony/twig-bundle": "^4.0", // v4.1.6
"symfony/validator": "^4.0", // v4.1.6
"symfony/web-server-bundle": "^4.0", // v4.1.6
"symfony/yaml": "^4.0", // v4.1.6
"twig/extensions": "^1.5" // v1.5.2
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0", // 3.0.2
"easycorp/easy-log-handler": "^1.0.2", // v1.0.7
"fzaninotto/faker": "^1.7", // v1.8.0
"symfony/debug-bundle": "^3.3|^4.0", // v4.1.6
"symfony/dotenv": "^4.0", // v4.1.6
"symfony/maker-bundle": "^1.0", // v1.8.0
"symfony/monolog-bundle": "^3.0", // v3.3.0
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.1.6
"symfony/stopwatch": "^3.3|^4.0", // v4.1.6
"symfony/var-dumper": "^3.3|^4.0", // v4.1.6
"symfony/web-profiler-bundle": "^3.3|^4.0" // v4.1.6
}
}
20 Comments
Why am I getting 500 errors instead of just showing the errors to the user ?
InvalidArgumentException HTTP 500 Internal Server Error<br />Expected argument of type "string", "NULL" given at property path "username".I have the Assert on the User and using the same code as you
@Assert\NotBlank(message="Please enter a username")<b>Edit : Turns out you need to allow your class to be in an invalid state to let Symfony manage errors for forms bound to entities. You have to set the return type of your methods to "?string" for example, even if the property is required and should never be null. This lets Symfony set the property to an invalid value (like null for an email adress) and then errors will show up on your form</b>
Hey Leif,
Yes, you're correct! It's required by design by validator. Though, you can bypass allowing entity to be in invalid state with form DTO: https://symfonycasts.com/sc... - it will be further in this course. But this way requires more work, so it's still controversial question.
Thank you for sharing your solution with others btw!
Cheers!
@Assert is not working for me.
Hey @Farry7!
Sorry to hear that! Are you getting an error? Or is it simply not working? Also make sure that you've installed the validator component - composer require validator - there was one other comment that made me think that this *could* be a possible problem.
Cheers!
Getting: Expected argument of type "string", "null" given at property path "username".
Instead of: form with error labels after submitted
Hello Guys! My validations are not working in the form. Another person that seems to have the same problem solve by adding a question mark to the type the getter is returning, something like: "getUsername(): ?string" to the entity getter.
Hey Gabriel F.
If you have this error on form submitting, then it's caused by
setUsername(string $username)and to solve it you need to add question mark to it like:setUsername(?string $username).IIRC latest version of maker bundle adds nullable mark to getter and setter by default.
Cheers!
How can I allow users to change info on their profile without asking them to retype the password?
This is also a problem for admins that manages user data when there is a password field there.
Hey lesleyfernandes!
GREAT question. Validation groups :). Basically, when you create the "profile" form, you can set that form's validation group to something like "update". Then you can use groups to make the NotBlank on password not checked for the edit profile form.
We have a nice example of this inside API Platform: https://symfonycasts.com/sc... - it's not using a form, but it shows how you can group some your constraints. The only difference in your case is that you will need to configure your edit profile form to validate in, for example, the "update" and "Default" groups - https://symfony.com/doc/cur...
Let me know if that helps!
Cheers!
I am creating form in controller without binding it to entity (using data_class). Like follow
I want to add constraint based on action something like below
Hey Peter K.!
Cool question :). I had to do some digging - and I think this can be done easily (it's just not a case I had thought of before)! Here's my idea:
1) Pass a
constraintsoption... but to the entire form itself - not just a single field. You'll do this down in configureOptions().2) Inside this, use the
new Callback()and pass this a Closure. I think it will look like this:I'm making several assumptions here... so I could be totally wrong. But, if you have a few minutes, let me know. It's actually a really compelling idea - a custom function for extra validation on your form type. I would love this to work :).
Cheers!
Thanks weaverryan
I have it working when I create separate form entity with just these 2 fields.
However I couldnt figure it out how would I do that in controller.
where would you paste above code for this form in controller?
Hey Peter K.!
Ooh, good question :). The 2nd option to
createFormBuilder()are the options you're passing to the form. And in a form class, theconfigureOptionsis how you pass option to the form. So basically, in addition to'csrf_protection' => false, you should also pass aconstraintskey in that array, set to the big thing in the first example.But let me know if it gives you any trouble ;).
Cheers!
Thanks working like a swiss watch
Hi Ryan,
i am trying to add 1 more Unique User Validation rule for a username...
<u><i>src/Entity/User.php</i></u>`
/**
*/
`
<u><i>src/Form/Model/UserRegistrationFormModel.php</i></u>`
`
Testing my Registration form, validation works for "<i>email</i>" but <b>NOT </b>for "<i>username</i>"
and what is funny :
i am still getting the "I think you're already registered!" message
although i changed it to "This email is already registered!"
even after <i>cache:clear</i>
any hints?
Hey Polychronis
Where does the
@UniqueUserconstraint comes from? Anyways, you only need to define theUniqueEntityconstraint at the top of your class and that's it. Try removing that@UniqueUserfrom each property and remove the cache manually (just in case)rm -rf var/cache/*Cheers!
Thanks for the hint !
Got confused between
- validating a form tied to an entity
- validating a form tied to a model
I am searching for an example how a user can update his password, with two password fields which have to be equal an the user has to confirm the change with his old password. This is my form builder:
`
`
Hey Markus B.!
Ah, excellent question! There are a few parts to the answer:
1) For the two password fields, use the RepeatedType. That is a built-in Symfony type that allows you to have "one field" that is actually two fields, and they must match each other else they will fail validation automatically. Super handy. We have an older (Symfony 3) tutorial that shows this - https://symfonycasts.com/screencast/symfony3-security/user-registration-form
2) For validating that the old password is "correct", you could go the "cheap" way and do this logic in your controller after submit (the downside being that you'd need to manually send some error string to the template and render it). Or, you could add a
constraintsoption toplainOldPassword. You'll need to create a custom validation constraint (usebin/console make:validator) and point the constraint at it - e.g.Then, in your
MatchesPasswordValidatorclass, you can autowire theUserPasswordEncoderInterfaceservice and use itsisPasswordValid()method to check. You'll need to get current User object for this. It'll look something like this:So, there are a few steps involved :). Let us know if this helps!
Cheers!
Hi Ryan,
I have 2 questions:
First one is regarding custom validation. I would like to have a password that contains at least 8 characters and then at least 1 upper, 1 lower, 1 number & 1 special character? How would I do this? I believe I need some sort of my own validator.
Second question is controlling some Validation Annotation in entity by software settings(.env) for example.
Lets say at the moment application supports maximum 8 characters. So I have in my entity NotBlank max 8 but now other client decided to support 9 characters. Obviously I dont want to create another version where the only difference will be NotBlank max 9 Annotation.
Would you recommend in this case to not use Annotation and define validation rules directly in FormType class? Is there a way to have variables in annotation. Lets say NotBlank(min = $myMinVariableFromDotEnv)?
Thanks
Hey Peter K.!
> First one is regarding custom validation. I would like to have a password that contains at least 8 characters and then at least 1 upper, 1 lower, 1 number & 1 special character? How would I do this? I believe I need some sort of my own validator.
I would either use the Regex constraint (https://symfony.com/doc/cur... or the Callback constraint... if the Regex is too ugly :).
> Second question is controlling some Validation Annotation in entity by software settings(.env) for example.
THIS *would* require a custom validation constraint (which we do talk about later in this tutorial). With a custom validation constraint, you have a "validator", which is a service. Because of that, we can use dependency injection to "inject" your custom rules, for example, from .env. This would mean, for example, that you would have some new @Password annotation, which would ultimately call your custom validation constraint, where you could apply the dynamic logic.
Let me know if this all makes sense! Cool questions!
Cheers!
"Houston: no signs of life"
Start the conversation!