Change record status: 
Project: 
Introduced in branch: 
8.7.x
Description: 

In future if the email.validator service is injected into a class then the service should be typehinted to \Drupal\Component\Utility\EmailValidatorInterface. For example:

  /**
   * Constructs a new ContactFormEditForm.
   *
   * @param \Drupal\Component\Utility\EmailValidatorInterface $email_validator
   *   The email validator.
   * @param \Drupal\Core\Path\PathValidatorInterface $path_validator
   *   The path validator service.
   */
  public function __construct(EmailValidatorInterface $email_validator, PathValidatorInterface $path_validator) {
    $this->emailValidator = $email_validator;
    $this->pathValidator = $path_validator;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('email.validator'),
      $container->get('path.validator')
    );
  }

Basic email validation is unchanged:

$email_validator = \Drupal::service('email.validator');
assert($email_validator instanceof \Egulias\EmailValidator\EmailValidator);
$email_validator->isValid('info@example.com');

In order to change core's email validation you can swap out the existing email.validator with a service that implements \Drupal\Component\Utility\EmailValidatorInterface. See https://www.drupal.org/docs/8/api/services-and-dependency-injection/alte... for more. To stay compatible with existing Drupal 8 code, it is recommended that the new class extends from \Egulias\EmailValidator\EmailValidator.

If you have overridden the email.validator service there is a small chance that the overridden service will not implement EmailValidatorInterface::isValid() correctly. In such cases, PHP will error immediately and the solution is to fix your overridden implementation to comply with the interface.

Impacts: 
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done

Comments

mxr576’s picture

If you type-hinted \Egulias\EmailValidator\EmailValidator or \Egulias\EmailValidator\EmailValidatorInterface in your code where you injected the email.validator service then your code is broken under Drupal >= 8.7.0 because the updated email.validator service does not extend/implements these.

drakythe’s picture

My team and I recently discovered that Core allows users to sign up with an email that does not contain a TLD. I understand the RFC allows for this possiblity, but there is zero reason for our client sites to follow this pattern. Digging in I discovered we're using this library and found the EmailValidator.php file https://git.drupalcode.org/project/drupal/blob/8.8.x/core/lib/Drupal/Com... purposely disabled the second parameter that we might use to specify the DNS Validator and not the RFC Validator, both of which are provided by the Egulias/EmailValidator library. It makes sense to me that this should be configurable per site.

What is the reasoning behind disabling the ability to specify the validator?

dmezquia’s picture

Hi @drakythe, what is the state of this? your team could find a solution to validate the domains, maybe some patch?

brad.bulger’s picture

It looks like the reasoning is laid out in #2755401: Upgrade EmailValidator to 2.x. I am not sure I follow the argument, but I gather that they're saying if you want to make those kinds of changes, you should write your own service?