Problem/Motivation
Version 2 of the EmailValidator is out.
https://github.com/egulias/EmailValidator/releases
Version 2 has pluggable lexers fulfilling interface EmailLexer, which would unblock some contrib #2749873-5: "email.validator" core service cannot be easily replaced.
Proposed resolution
Upgrade it.
Remaining tasks
User interface changes
None
API changes
This will not break any usages in contrib. Existing injections of the service will still work because it extends from the same class.
If the service is overridden - which feels a little unlikely - then the service will now have to implement EmailValidatorInterface. Before there was no interface so this is a big improvement for swapping out this service.
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#46 | interdiff--2755401-2--33-46.txt | 2.28 KB | gg4 |
#46 | 2755401-2-46.patch | 12.79 KB | gg4 |
#33 | 2755401-2-33.patch | 13.78 KB | alexpott |
#33 | 29-33-interdiff.txt | 3.2 KB | alexpott |
#29 | drupal_2755401_29.patch | 11.75 KB | Xano |
Comments
Comment #2
cilefen CreditAttribution: cilefen commentedComment #3
cilefen CreditAttribution: cilefen commentedComment #5
cilefen CreditAttribution: cilefen commentedSymfony has only just added support for this https://github.com/symfony/symfony/commit/25d39aa81988762461bd5274c23e99...
Comment #6
cilefen CreditAttribution: cilefen commentedCross-posting with #2749873: "email.validator" core service cannot be easily replaced:
Comment #7
cilefen CreditAttribution: cilefen commentedThis is postponed on #2749873: "email.validator" core service cannot be easily replaced. We need BC on this.
Comment #8
dawehnerMaybe here a really naive question: Do we have to move to version 2.x of the library? Is there a fundamental reason to do so, beside receiving bug fixes?
Comment #9
cilefen CreditAttribution: cilefen commentedIt is not naive. Version 2 has pluggable lexers fulfilling interface EmailLexer, which would unblock some contrib #2749873-5: "email.validator" core service cannot be easily replaced.
Comment #10
dawehner@cilefen
That is a strong point, let's add this to the issue summary.
Comment #11
cilefen CreditAttribution: cilefen commentedComment #14
naveenvalechaComment #15
naveenvalechaComment #16
cilefen CreditAttribution: cilefen commentedI went over the relevant sections of the BC policy. Form classes, constructors for service objects, plugins, and controllers are all considered @internal. However, the constructors changed because the email.validator service actually changed its type. This was mentioned in #2749873-13: "email.validator" core service cannot be easily replaced (I am thinking of closing that issue in favor of this issue). Along the way:
The param type should be fully namespaced.
This is missing the "@" in {@inheritdoc}.
Comment #17
naveenvalechaAccommodated #16 to move this forward. Is it RTBC or N/W?
//Naveen
Comment #18
cilefen CreditAttribution: cilefen commentedIt needs work in terms of finding a way to preserve the datatype of the email.validator service.
Comment #19
dawehnerI'm wondering whether you could do something with autoloading stuff inside composer.json
Comment #21
alexpottWe don't need the hook_update because this will go in a new version and the container is cached with a version key.
Here's a version where typehints of both \Drupal\Component\Utility\EmailValidatorInterface and \Egulias\EmailValidator\EmailValidator will both work. So existing code in contrib or custom will continue to work but we'll also get to typehint on the new EmailValidatorInterface.
I think we need a CR to tell people to update any typehints to use the new interface.
Comment #22
dawehnerHere is a question: Should we introduce a new validation service, and mark the old one as deprecated? This way we could inform people that they need to change stuff (Like changing typehints)
Comment #23
heddnJust marked #2930358: Update to Swift Mailer 6.x as postponed on this issue. Swiftmailer cannot upgrade to 6.x because of this dependency conflict.
Comment #26
joelpittetComment #27
gg4 CreditAttribution: gg4 commentedBumping priority as there doesn't seem to be a good workaround for this contrib blocker.
Comment #28
alexpottHmmm these don't match. Need to document the $email_validation param.
re #22 that gets us into the fun of service versions - unless we can think of a better name than
email.validator.v2
- I guess we could take the opportunity to deprecate and namespace the service name ie.core.email.validator
. But I'm not sure that's a great solution.Comment #29
XanoThis patch is a re-roll, upgrades egulias/email-validator from 2.1.2 to 2.1.5, addresses the feedback from #28, and renames the
EmailValidator::isvalid()
$mail
parameter to$email
for consistency with the implemented interface.Comment #30
XanoI published a change record.
Comment #31
alexpott@Xano thanks for the change record.
Reading it makes me ponder if we're doing this right. I think the question is on what level should the validators be set. Is it the code level or the application level? I think for the email.validator service it probably should be on the application level - ie. via the container. So I'm not sure that email.validator should have a method that allows you to change the validators. If you want to do that in code just create an Egulias\EmailValidator\EmailValidator object and away you go.
So I'm thinking that the service itself should not really allow the validator to be passed in. It feels odd to do that. If you want to customise the email validation for the entire application you should replace the service. What I'm thinking is that we should throw an error if isValid() is called with the validator argument. And in Drupal 9 we should decouple
Drupal\Component\Utility\EmailValidator
fromEgulias\EmailValidator\EmailValidator
. In D8 it is useful that they are coupled because anything typehinting onEgulias\EmailValidator\EmailValidator
will still work but in D9 everything you typehint to the interface and the interface should reflect the concerns of the service i.e. not passing in a validator.Comment #32
alexpottThe current patch is not documenting $email_validation on the interface. I agree with this. It shouldn't be part of the service interface.
Comment #33
alexpottHere's a patch that enforces the fact that we ignore custom validation on our service.
Comment #34
alexpottI've swapped around the change record to detail what we really want people to do. Which is to update any typehints from
\Egulias\EmailValidator\EmailValidator
to\Drupal\Component\Utility\EmailValidatorInterface
. The fact that we're also upping the version is an implementation detail.Comment #35
cilefen CreditAttribution: cilefen commentedI attached #2749873: "email.validator" core service cannot be easily replaced to the CR.
Comment #39
alexpottCrediting all the people who worked on #2749873: "email.validator" core service cannot be easily replaced since these issues have turned out to be duplicates.
Comment #40
XanoI just stumbled upon #2965887: Require egulias/email-validator >= 1.2.14 and was wondering if we want to credit that person too when we close that issue after this one has been fixed.
Comment #41
alexpott@Xano I think we close but not credit on this issue. That's because the other did the same as this to make the service swappable but that issue just bumps a dependency in core/composer.json.
Comment #42
gg4 CreditAttribution: gg4 commented#33 still applies and LGTM.
Comment #44
alexpottComment #45
gg4 CreditAttribution: gg4 commentedAnything blocking landing #33 at this point?
Comment #46
gg4 CreditAttribution: gg4 commentedSpoke too soon. Re-roll of #33.
Comment #47
effulgentsia CreditAttribution: effulgentsia at Acquia commentedDo we want to add the same kind of check for the third argument ($strict) that 1.x supported as well? Maybe emit a deprecation warning for that instead of a bad method call exception?
Comment #48
alexpott@effulgentsia I'm not sure that that is worth it. Here's why. The old signature is
public function isValid($email, $checkDNS = false, $strict = false);
so if you've called it like so->isValid('blha', FALSE, TRUE)
you're going to get a hard error due to the second argument not being an instance of\Egulias\EmailValidator\Validation\EmailValidation
.This makes this issue interesting because it makes it impossible to provide a new
email.validator
service that satisfies the two BC concerns... ie. still implements\Egulias\EmailValidator\EmailValidatorInterface
and accepts either format ofisValid()
.Comment #49
alexpottI think the current solution is the best one because
\Egulias\EmailValidator\EmailValidatorInterface
or extends from\Egulias\EmailValidator\EmailValidator
still worksisValid()
the break is going to be hard and the error message will point to exactly what's wrong.However we could argue that we should only be making this change in Drupal 9.
Comment #50
gg4 CreditAttribution: gg4 commentedHuge plus one on this going back to RTBC from me.
Comment #51
catchhmm I think at least the information in #49 should be in the change record - however that limitation doesn't make this issue a problem for a minor IMO.
Comment #52
alexpottI've added the following caveat to the change record.
Comment #53
catchCommitted 9e7b020 and pushed to 8.7.x. Thanks!
Comment #55
gg4 CreditAttribution: gg4 commentedWould a backport of to 8.6.x ever be considered for this issue? From what I can gather, it is pretty much impossible to implement a similar core patch in a local project that uses a composer to include Drupal with
drupal/core
.Comment #57
timcosgrove CreditAttribution: timcosgrove at Pinterest commentedEchoing Bonus here: is it possible to backport this? Not asking for someone else to do the work necessarily, but I would love the opinion of someone who understands the subsystems here better, to know if a backport is even possible or reasonable.
Comment #58
heddnI think bumping a major version dependency can be done in a minor release. But not within a hotfix in 8.6.x. Gotta keep our BC promises.
Comment #59
timcosgrove CreditAttribution: timcosgrove at Pinterest commentedThat's fair. 8.7 is not that far off. Thanks!
Comment #60
cilefen CreditAttribution: cilefen commentedTechnically, according to policy, only patch- and minor-level library updates are allowed in minor releases.
Comment #61
jibranPublished the change record.
Comment #62
mxr576Just tried to check the Drupal 8.7 compatibility of the module that I maintain and all classes where I injected the email validator service is broken :face_with_rolling_eyes:
The reason is quite obvious before Drupal 8.7 there was no `Drupal\Component\Utility\EmailValidatorInterface` interface, I could only use the interface provided by the vendor package. Isn't it some kind of BC break?
https://github.com/drupal/core/blob/8.6.x/core.services.yml#L1691-L1692
vs.
https://github.com/drupal/core/blob/8.7.x/core.services.yml#L1692-L1693
https://github.com/drupal/core/tree/8.6.x/lib/Drupal/Component/Utility
vs.
https://github.com/drupal/core/tree/8.7.x/lib/Drupal/Component/Utility
As I can see I can only support both 8.6. and 8.7 at the same time if I implement an adapter or a proxy class that I'll use in type-hints and which will translate between email-validator >=1.2 and >=2.0.
Comment #63
wcweb CreditAttribution: wcweb commentedApologies if this is OT. Not sure where I should post this to follow the issue, but upgrading to Drupal 8.7.1 breaks webform, which gives HTTP ERROR 500, upon submission:
PHP Fatal error: Declaration of Drupal\Component\Utility\EmailValidator::isValid($email, ?Egulias\EmailValidator\Validation\EmailValidation $email_validation = NULL) must be compatible with Egulias\EmailValidator\EmailValidator::isValid($email, $checkDNS = false, $strict = false) in /var/www/iweek/site/core/lib/Drupal/Component/Utility/EmailValidator.php on line 12
Where might be the correct place to follow this or submit an issue? As it seems to be a core issue.
Any advice gratefully appreciated.
Comment #64
cilefen CreditAttribution: cilefen commentedI would open new issues then relate them from this issue to get attention.
Comment #65
themetman CreditAttribution: themetman commentedI am also having this problem upgrading to 8.7.1 when trying to see the admin/config/system/site-information page and also when trying to update the Basic Site Email.
How can I add this to the issue? I have not found it reported yet.
Comment #66
mxr576I guess you forgot to update the email validator package. You should see this output for this command:
If you see 1.x.x as a version you should update the email validator package to 2.x.
Comment #67
themetman CreditAttribution: themetman commentedThanks for the swift response.
I seem to have the latest version
egulias/email-validator 2.1.7 A library for validating emails against several RFCs
Comment #68
joachim CreditAttribution: joachim as a volunteer commented> This will not break any usages in contrib. Existing injections of the service will still work because it extends from the same class.
It does, if contrib injections of the service typehint on Egulias\EmailValidator\EmailValidatorInterface, which is gone in version 2.0 of the package.
Comment #69
mxr576#68 +1
Comment #70
eiriksmAnother way it breaks contrib is that if you contrib wanted to use the old service like so:
Currently this is not the function signature of the same service and its method. Also, it is not possible to check dns (second parameter) in the new core service. So if I had a module that would check dns on registration, for example, it would all of a sudden not work even one tiny bit after I upgraded to 8.7.
The wording in the change record is therefore not completely true :)
One can easily get around this by using the EmailValidator class directly, but it is for sure a BC break in my opinion.
Can we add this documentation to the change record somehow? Or somewhere else? Should be documented at least? What can I do to help others that needs these other parameters?