Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
As of #2278353: Update to Symfony 2.5, the core email validation class will be using egulias/EmailValidator #2313669: Bring in egulias/EmailValidator for RFC compliant email address validation. valid_email_address() should use it too. Deprecate valid_email_address().
Proposed resolution
Modify valid_email_address() to use the egulias/EmailValidator. Mark valid_email_address() as deprecated to be removed in 8.x (or 9.x?).
Remaining tasks
Provide fall back to existing functionality for php 5.2
User interface changes
API changes
Creates the email.validator service and \Drupal::emailIsValid().
Beta phase evaluation
Issue category | Task because this is stability-enhancing code. |
---|---|
Issue priority | Major because it increases stability of Drupal. |
Disruption | Not disruptive for core/contributed and custom modules/themes because it maintains the commonly-used valid_email_address(). It will just work consistently now. |
Comment | File | Size | Author |
---|---|---|---|
#76 | valid_email_address-2343043-76.patch | 1.06 KB | RAWDESK |
#75 | valid_email_address-2343043-75.patch | 1.16 KB | RAWDESK |
#74 | valid_email_address-2343043-74.patch | 96.87 KB | sanduhrs |
#72 | valid_email_address-2343043-72.patch | 94.98 KB | sanduhrs |
#45 | valid_email_address-2343043-45.patch | 162.26 KB | cilefen |
Comments
Comment #1
cilefen CreditAttribution: cilefen commentedComment #2
rbayliss CreditAttribution: rbayliss commentedNo constructor argument is needed, I think.
Comment #3
cilefen CreditAttribution: cilefen commented@rbayliss You are right. I had been working on another issue and the Symfony class that uses this library has a constructor argument.
Comment #4
droplet CreditAttribution: droplet commentedNoted that it isn't pass Chrome's client-side validation. (didn't test other browsers yet)
https://github.com/egulias/EmailValidator/blob/master/tests/egulias/Test...
Comment #5
andypostreturn new EmailValidator()->isValid($mail);
Comment #6
cilefen CreditAttribution: cilefen commented@andypost: Are you sure that is possible in PHP 5.4? I think so...
Comment #7
hussainwebI am thinking this should be a service. That would allow someone to specify a different validation class. What do you think?
Comment #8
cilefen CreditAttribution: cilefen commentedComment #9
cilefen CreditAttribution: cilefen commented@hussainweb That is an interesting idea. You'll want to also patch #2278353: Update to Symfony 2.5.
Comment #10
cilefen CreditAttribution: cilefen commented@hussainweb But you can see that on #2278353: Update to Symfony 2.5 there is a Drupal-side class used to configure the validator.
Comment #11
hussainweb@cilefen: If my understanding of this page is correct, I guess we can just remove the constraint we have added #2278353-89: Update to Symfony 2.5. I think we will just have to make sure we pass in
strict
astrue
and it will use our new email validator class. Is this correct?Comment #12
cilefen CreditAttribution: cilefen commented@hussainweb Yes, strict must be true.
Comment #13
cilefen CreditAttribution: cilefen commentedI would consider as a follow-up to deprecate valid_email_address().
Comment #14
cilefen CreditAttribution: cilefen commentedComment #15
cilefen CreditAttribution: cilefen commentedI suggest this issue is a beta priority (see https://www.drupal.org/contribute/core/beta-changes) because it standardizes a library integration and reduces fragility. Without this, valid_email_address and the email validator class do different things, which could lead to unexpected results.
Comment #16
pwolanin CreditAttribution: pwolanin commentedWhy do we need an instance instead of a static method?
If it's a service I guess the motivation is so that people can swap the implementation?
Comment #17
cilefen CreditAttribution: cilefen commented@pwolanin EmailValidator->isValid isn't a static. Is there a way to work around having an instance?
Comment #18
cilefen CreditAttribution: cilefen commentedComment #19
cilefen CreditAttribution: cilefen commented@pwolanin The EmailValidator is not a Drupal class. The idea behind having it as a service is for the same reason we front-end other non-Drupal classes as services—which I think is to make it easier to find and to consider it an integral part of Drupal. If we want this method to be a static we will have to front-end it with a Drupal-side class.
Comment #20
cilefen CreditAttribution: cilefen commented@pwolanin: is this what you mean?
Comment #21
cilefen CreditAttribution: cilefen commentedI bumped this to major because core currently has two different email validators that work differently: EmailValidator and valid_email_address().
Comment #22
pwolanin CreditAttribution: pwolanin commentedSo, can we deprecate the function?
Are the other methods in the class generally used? If not maybe the static wrapper could be like
As a direct replacement for the function
Comment #23
cilefen CreditAttribution: cilefen commentedComment #24
cilefen CreditAttribution: cilefen commentedComment #25
cilefen CreditAttribution: cilefen commentedAdded @deprecated.
Comment #26
cilefen CreditAttribution: cilefen commentedComment #27
cilefen CreditAttribution: cilefen commentedRemoved the static function and fixed the deprecation line versions.
Comment #28
dawehnerAre we sure we really want to add a method onto the drupal static class? This is something we should avoid here, because validating a mail is not a often used operation if you ask me.
Comment #29
cilefen CreditAttribution: cilefen commentedThis is without the \Drupal method.
Comment #30
cilefen CreditAttribution: cilefen commentedRemoved a double newline.
Comment #31
cilefen CreditAttribution: cilefen commentedReroll.
Comment #32
cilefen CreditAttribution: cilefen commentedComment #33
dawehnerI think it totally makes sense to use the same email validation mechanism everywhere.
Comment #34
mpdonadioPatch looks good, and gave it a quick test drive on a system form where valid_email_address() is used.
Comment #35
alexpottYep having two different results from validating email address is confusing. Committed 2cdd0e2 and pushed to 8.0.x. Thanks!
Thank you for adding the beta evaluation to the issue summary.
Comment #37
catchCrossposted:
Are there any e-mail addresses that would have been allowed by filter_var() that won't be allowed by this library?
This could have implications for the migration path if so. Don't see it discussed in any of the previous issues.
Comment #38
cilefen CreditAttribution: cilefen commentedThe issue that changed the validator when adding users was #2313669: Bring in egulias/EmailValidator for RFC compliant email address validation. I wonder if anyone has tried, or could try on a large list of valid D7 account addresses.
Comment #40
cilefen CreditAttribution: cilefen commentedHere is the Drupal 7 back-port.
Comment #41
cilefen CreditAttribution: cilefen commentedComment #43
cilefen CreditAttribution: cilefen commentedI fixed the whitespace errors in the vendor libraries.
Comment #45
cilefen CreditAttribution: cilefen commentedThe OpenID test was using 'mail@invalid#' as a test of an invalid email address. Evidently, the new email validator would allow it, which could be an issue on its own. For now, I switched it to 'foo', which is used in user.test.
Comment #47
David_Rothstein CreditAttribution: David_Rothstein as a volunteer commentedI think we'd have to have a fallback for sites on PHP 5.2.
So is there really no hope of this getting fixed/improved in PHP itself?
Comment #48
cilefen CreditAttribution: cilefen commentedSomething like https://bugs.php.net/bug.php?id=69140
Comment #49
AnybodyI agree with #47 that PHP 5.2.5 has to be supported because of the Drupal System requirements.
Somehow we should find a good or at least better solution ASAP because of issues like #1427516: valid_email_address() rejects valid email addresses and can't wait for things to happen in issues sleeping like https://bugs.php.net/bug.php?id=69140.
I think the currently only valuable solution would be to use a custom regex for php versions below 5.3.2 and the solution from the patch in #45 for higher versions. What's your oppinon?
This blog post shows the problems: http://markonphp.com/properly-validate-email-address-php/
Comment #50
TR CreditAttribution: TR commentedThere's no change record for this?
Comment #51
David_Rothstein CreditAttribution: David_Rothstein as a volunteer commentedWe need a fallback for PHP 5.2, but that doesn't necessarily mean we need to hold up this issue on a fix for PHP 5.2.
In other words, one possible fallback would be to just keep calling filter_var() for older PHP versions, and only load up this library and use it if the PHP version is new enough.
Comment #52
AnybodyGreat! +1 for #51
Comment #53
frobI just ran into this issue for a test suite for valid email addresses from a api vendor.
All of that to say +1 for #51. Fall back to existing functionality if the php version is too old.
Comment #54
frobUpdated remaining tasks in issue summary and marking as needs work.
Comment #55
frobAfter testing this with wikipedia's like of strange valid email addresses, only two didn't work.
"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com
"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a"@example.org
Would this be considered and up stream issue?
Comment #56
cilefen CreditAttribution: cilefen commentedRe: #55: yes
Comment #57
frobGood, so all that is left to do is put in the 5.2 fallback.
Comment #62
davemckain CreditAttribution: davemckain commented#50: We are working on filling in the missing Change Record for this as part of #2873881: [meta] Add Change Record to @deprecated for common.inc at DrupalCon Vienna. The draft CR can be found at [#2912661]. We are all newbies to this so please be gentle :-)
Comment #63
Mile23Published the CR for the 8.x branch. https://www.drupal.org/node/2912661
Comment #64
xjmIf this needs backport to D7, it should be Patch (to be ported) until the D7 maintainers create a separate D7 issue for it, and then it can be marked back to Fixed against the 8.x branch it was committed to.
Comment #65
xjmFor #49 / #51 about the 5.2 fallback I think we also could create a separate followup and link it here, but it's a D7-only issue since D8 requires 5.5.9.
Comment #66
frobHaven't we been working on the D7 backport since #40?
Comment #67
David_Rothstein CreditAttribution: David_Rothstein as a volunteer commentedYes, the backport has been in progress here for a couple years (the issue is currently filed against D7), but a separate issue could be created also and then this one closed.
I do recall that this patch was relatively close to being ready though.
Comment #68
David_Rothstein CreditAttribution: David_Rothstein as a volunteer commentedThat said, I am really not sure about including a composer.json in Drupal 7 core - won't that cause problems for people who are already using Composer to manage their sites?
This is mostly just a one-off library, so would it be possible to include the library manually (like we normally would) without having to mess with Composer?
Comment #69
cilefen CreditAttribution: cilefen as a volunteer commentedGood point.
Comment #70
frob+1 #68
Comment #71
RAWDESK CreditAttribution: RAWDESK commentedIn attendance of the official D7 backport release, I just wanted to share my efforts in an alternative solution using xautoload using the Libraries API to autoload the necessary classes from Egulias' email validator, currently at version 2.1.7.
Still struggling with the expected availability of the necessary classes though, and reported here in xautoload doc support
https://www.drupal.org/node/1976234#comment-13021989
Tried to follow the class instantiation approach as applied in patch #45, but without success either :
Comment #72
sanduhrsAttached is a patch that adds the needed libraries from doctrine and egulias to the mics folder.
It loads the classes when valid_email_address() is invoked.
It uses EmailValidator() when php >= 5.5 and falls back filter_var() otherwise.
Please review.
Comment #74
sanduhrsChanged the invalid mail test of openid as explained in #45
Comment #75
RAWDESK CreditAttribution: RAWDESK commentedHi sanduhrs,
Thanks for providing this working patch.
So from the valid_email_address() point of view my test passed.
There's one side effect I noticed during 1 of my tests where after successful registration of numéros@mailinator.com user, a subsequent registration of numeros@mailinator.com was refused by core user module.
Inside user_account_form_validate() function, the entered email address is also validated against existing users.
For the above case numeros@mailinator.com is seen as an existing user because of the unCOLLATEd query on utf8_general_ci collated mail column.
After applying my attached patch on user module, the validation passed without an error message but for some unclear reason the registration does not complete successful (user_register_submit handler not triggered).
Small side remark with your patch #74:
I tried to replace your class includes with a recursive iterator, but the order in which this happens seems to be relevant for this EmailValidator plugin.
Here's my suggestion for improvement, in case the plugin should receive new php files in the future :
I'll take some time next week to further investigate my new issue.
Regards,
Comment #76
RAWDESK CreditAttribution: RAWDESK commentedFixed patch.
Comment #77
sanduhrsThe issue in #76 is out of scope of this patch IMHO.
The same behavior can be observed in D8/D9.
So the patch in #74 stands, but should be updated with the latest version of egulias/EmailValidator:3.1.2
Comment #78
poker10 CreditAttribution: poker10 at ActivIT s.r.o. commentedSome test are failing on PHP 7.4 and higher with patch #74. The new library needs to be checked/updated.
See: https://www.drupal.org/pift-ci-job/2363706 and others.
And I also agree that the change in patch #76 is not relevant to this issue (not mention that this change is not working correctly in DBs other than MySQL/MariaDB).
Comment #79
poker10 CreditAttribution: poker10 at ActivIT s.r.o. commentedMaybe the new proposed hook in #2966195: valid_email_address() should be easily overridable will better suit the current D7 status and we would not need to include 3rd party library into D7 core?
I think it would be better to close this as Fixed in D8 and for D7 use the flexible approach proposed by the mentioned issue, where sites can potentially add whatever library they want and D7 core does not need to maintain it. What do you think?
Comment #80
cilefen CreditAttribution: cilefen as a volunteer commentedWe should definitely close this and let contrib take it on after the hook goes in.
Comment #81
cilefen CreditAttribution: cilefen as a volunteer commented#2966195: valid_email_address() should be easily overridable is in.