3

In my Drupal site, only administrators create users. And users are created without an email. Users can edit themselves some of their account fields, but the email is not one of them.

But the user module adds a UserMailRequired constraint to the User entity email field. On submit, the user module's validator UserMailRequiredValidator adds a violation if the current user is not an administrator :

class UserMailRequiredValidator extends ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  public function validate($items, Constraint $constraint) {
    /** @var \Drupal\Core\Field\FieldItemListInterface $items */
    /** @var \Drupal\user\UserInterface $account */
    $account = $items->getEntity();
    $existing_value = NULL;
    if ($account->id()) {
      $account_unchanged = \Drupal::entityManager()
        ->getStorage('user')
        ->loadUnchanged($account->id());
      $existing_value = $account_unchanged->getEmail();
    }

    $required = !(!$existing_value && \Drupal::currentUser()->hasPermission('administer users'));

    if ($required && (!isset($items) || $items->isEmpty())) {
      $this->context->addViolation($constraint->message, ['@name' => $account->getFieldDefinition('mail')->getLabel()]);
    }
  }

}

So, none of my user can edit its profile. On submit, they get an error message "Email field is required". Even if the field's #required property is set to false (using hook_form_alter) and the field not displayed (#access = false) in the form render array.

How can I drop this constraint from a custom module ? (using a hook for example)

4
  • drupal.stackexchange.com/q/250302/57
    – Kevin
    Commented Jun 27, 2018 at 13:54
  • Setting fake email adresses during registration is not a good solution for me. As I said, administrators can already create accounts without an email adress. What I need is to drop the validation of this field when I submit user_form form.
    – Eria
    Commented Jun 27, 2018 at 14:03
  • Did you solve this. I just ran into it. No amount of changing #required in form alter works. I'm thinking the Plugin class has to be extended and changed. Wondering if you've already solved this @Eria
    – eahonet
    Commented Aug 9, 2019 at 15:15
  • @eahonet : unfortunately, I don't remember :/ That was one year ago, and I'm not working on this project anymore. And I don't have access to the source code. Sorry...
    – Eria
    Commented Aug 9, 2019 at 15:27

1 Answer 1

4

For those that find themselves here trying to make User Emails Optional, use hook_validation_constraint_alter. You're not extending core's, you're creating a new constraint and using it instead of core's. In my case, I replace core's with... an empty function to achieve what I want.

Something like this in .module

function optional_account_email_validation_constraint_alter(array &$definitions) {
  $definitions['UserMailRequired']['class'] = '\Drupal\my_module_name\Constraint\OverrideUserMailRequired';
}

Then a copy of the two UserMailRequiredValidator.php and UserMailRequired.php files changed to your liking.

The module administerusersbyrole has a working example of this.

I'll see if I can get around to putting my custom module onto drupal.org in the coming months.

1
  • This is the wrong hook to implement, to remove a constraint. hook_entity_base_field_info_alter() is the one that allows to remove constraints. It has the pro that allows to remove a constraint from the field of a specific entity type, which is helpful when the constraint is added to different entity types and changing the constraint for all the entity types isn't desired.
    – avpaderno
    Commented Mar 10, 2021 at 21:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.