Let's convert the form validation logic of users to validation constraints + test that. We can keep the existing form validation in place until we leverage the entity validation for forms and remove it then.
| Comment | File | Size | Author |
|---|---|---|---|
| #36 | user-validation-2002162-36.patch | 19.77 KB | klausi |
| #34 | user-validation-2002162-34.patch | 19.77 KB | klausi |
| #23 | profiling.inc_.txt | 412 bytes | klausi |
| #22 | user-validation-2002162-22.patch | 20.4 KB | klausi |
| #22 | user-validation-2002162-22-interdiff.txt | 1.46 KB | klausi |
Comments
Comment #1
eugene.ilyin commentedHello.
DrupalSib team (Russia, Novosibirsk) want to implements this on today code sprint.
Comment #2
eugene.ilyin commentedWe could not solve this problem completely. We have progress, but many questions remain. We made an temporary patch where using @todo for marking of our questions. We need help to finish this task.
Comment #4
podaroktagging
Comment #5
fagoPlease see for the patch in #2002152: Implement entity validation based on symfony validator for a working example and implement it analogously.
Note, that #2002152: Implement entity validation based on symfony validator contains the foundational constraints you'll need, so best just base any work on this on the patch over there.
Comment #6
berdirAnd the User NG conversion from #1818570: Convert users to the new Entity Field API that you started doing in here. You'll need these two things to start with this.
Comment #7
eugene.ilyin commentedThank you, but I will have time for it only in next weekend (June 8, 9)
Comment #8
klausiGetting started here with user name and email validation.
Comment #10
klausiImported the email_field fixes from #2002158: Convert form validation of comments to entity validation, implemented the unique constraint for user name and e-mail. Centralized the user name validation into constraints and factored that out of user_validate_name().
Comment #11
klausiAdded tests for the remaining user base fields. I also had to fix EntityReferenceItem to not assume entity IDs are integers. I guess this will fail in a couple of places I haven't noticed yet.
Comment #13
klausiOk, converting user roles to an enttiy reference field is much harder than I thought, so I split that out to a separate issue: #2044859: Convert user roles to entity_reference_field.
Comment #14
vlad.dancerGood idea!
Comment #15
jibranThis can be removed.
This can also be removed
$user->id()can be used in query.It is adding same violation so why not use
||instead ofifandelseifComment #16
klausiThanks, fixed those issues.
Comment #17
moshe weitzman commentedtypo
Do we want to put 'user' into the classname. Would help in an IDE I think?
Is the cast here needed? Can we not trust the id() method call above?
Comment #18
klausiFixed all points from #17.
Comment #19
moshe weitzman commentedThanks. RTBC.
Comment #20
alexpottIt'd be nice to profile the user_validate_name() function to see the cost of typed_data and the constraint system.
Comment #21
alexpottThis will have changed due to #2041423: Rely on 'provider' instead of 'module' for Field plugin types
Comment #22
klausiRerolled.
Not sure why this need profiling - the validation is not in the critical performance path. I doubt that profiling this will provide any useful results - of course it will be 1000% slower in relative numbers, because it now does more than just some regular expressions. In absolute numbers I predict that it would go from 0.005ms to 0.1ms.
I'm going to write a drush script for profiling.
Comment #23
klausiSo here are the benchmarks, execute the attached script with "drush php-script profiling.inc".
Before the patch:
1000 calls: 24.68ms
1 call average: 0.02468ms
After the patch:
1000 calls: 265.23ms
1 call average: 0.26523ms
So as expected the old code is 10 times faster, but one call is still well under one millisecond, so nothing to worry about.
Comment #24
moshe weitzman commentedIt is true that this isn't performance critical. It is also pathetic IMO that we are slowing down Drupal by 10x. Other examples of this slowdown *are* on the critical path.
Comment #25
klausiWe are not slowing down Drupal by 10x, we are slowing down user name validation by 10x. This is an important distinction. The overall Drupal page request takes hundreds of milliseconds, and this change takes 0.1% of that time to validate a user name. And of course not on every page request, but only when users register on the site or change their user name.
We are trading a flexible and powerful validation system here against a tiny performance penalty. We should focus our performance considerations on the problems in the critical every-request-path, and I doubt that the entity validation API ever shows up in it. Please link those example issues here, would be interested to look at them!
Patch still applies, anyone available for review or RTBC?
Comment #26
moshe weitzman commentedOK, lets let the committers evaluate that profiling. The code looks proper.
Comment #27
alexpottAssigning to catch as the committer with most performance experience.
Comment #28
catch@klausi can you confirm that this really is only on registration or when usernames are changed. Generally we don't differentiate between saving identical vs. updated values on entity updates so I'd expect it to run every time the entity is saved regardless of whether it's actually updated or not.
If we are doing these checks on every entity save, then we could likely make an overall improvement in performance despite this patch if we changed our validation logic to only happen on updated values - i.e. if a user has ten fields and only one of them is a changed value, then that's 1/10th the validation code running.
Comment #29
klausiThe ->validate() method is never called from an entity save, that are two separate things. Entity save must not validate data (well, the DB schema does a bit and throws PDOExceptions, but that does not count here).
So this does not affect entity saves at all, the validation API is only called explicitly in forms or in REST module.
Comment #30
catchRight but if a user account form is submitted, that might be to update contact preferences or something, and not username or e-mail address. Validation will run every time though.
Comment #31
klausiThat's true, but this is how we do validation: we validate all submitted form data, regardless of the state in the database. I'm not convinced we should change that for a minor performance gain.
It could be tricky if you have validation dependencies between fields, example: a workflow field can only be set to "needs review" if the body field contains some text. You fill out the body field, set the worklfow field to "needs review". Then you edit the entity again and empty the body field, but leave the workflow field at "needs review". Now the validation should trigger: "needs review" is now an invalid workflow state, although the field value was not changed. You would only run the validation on the body field (which has changed). You could argue that in such a case the validation must be done on the body field, but that does not seem right to me since the logic is in the domain of the workflow field.
You also have a problem if you have migrated some legacy data into Drupal which is not completely valid. If a required field is missing for example, then a user can edit the entity and submit an empty required field without getting validation errors, which is bad IMO. (the form API might catch this for a required field widget for us, but you can imagine other examples of invalid data)
Comment #32
fagoIt should be noted that it's perfectly possible to validate some specific fields only also - whether that's desirable or not. klausi is right in that it would miss inter-dependencies, but I thought it might be good to note that we can skip validating other stuff if we want to.
I shortly looked over the patch also - looks good to me!
Comment #33
klausiDoes not apply anymore, I'm going to reroll.
Comment #34
klausiRerolled, the change in EmailItem.php should not be necessary anymore.
Comment #35
alexpottNeeds a reroll now that #2024963: Move baseFieldDefinitions from storage to entity classes is in
Comment #36
klausiRerolled, not other changes.
Comment #37
catch1ms is fine here. klausi's right that this isn't the cause of our performance problems.
Comment #38
yched commentedThe commit contains changes in LocalActionManager.php that do not seem related ?
Comment #39
catchDoh. Reverted and re-committed.