2

I'm working on a single-sign-on module for D8 and would like to disable the password fields on the user edit form, since passwords should be managed by the outside identity provider and not through Drupal.

Drupal adds a "current password" field to the edit page which is required if the user wants to change their email address. I can remove the field easily in a hook_form_alter, but there's a form constraint, ProtectedUserFieldConstraintValidator, that runs and fails validation if the password field is not filled out.

How can I remove this form constraint dynamically?

Things I've looked at so far:

  • In my hook_form_alter setting $form_state->getFormObject()->getEntity()->_skipProtectedUserFieldConstraint = TRUE. This is a property that this constraint checks and when TRUE will skip it, but changes to the entity here are tossed since ContentEntityForm::validateForm rebuilds the entity just before validation.
  • Looking at the BaseFieldDefinition class to see if there's a way to remove an existing constraint, but there are no API methods available to do so.

EDIT: It seems once possible approach is to extend ProfileForm, overwrite the buildEntity method to set _skipProtectedUserFieldConstraint = TRUE, and then tell core to use my forms instead. Thought a downside here is that I'm just disabling the constraint in the context of a form, but not in other contexts where the entity may be updated, like in a REST API.

2

Validation constraints are plugins with an alter hook: hook_validation_constraint_alter() (the hook name can be seen in \Drupal\Core\Validation\ConstraintManager::__construct()).

That means you can alter that plugin and replace it with your own class that doesn't do anything, or only under some conditions.

Note that constraint plugins are special, unlike everything else, they consist of two classes, the plugin class is just the definition and strings, and then here is a $classname . 'Validator' class that contains the actual logic. So you need two classes, first the constraint class, Drupal\yourmodule\Something and then an overriden version of the Validator as Drupal\yourmodule\SomethingValidator.

  • To override a validation constraint you can simply copy the classes to your custom module and edit the namespace to be correct, it will then override without you having to use hook_validation_constraint_alter(). – Duncanmoo Sep 18 '18 at 10:01
  • 1
    That's not a good idea, then you're relying on things like the module weight/order and that your module is later in the discovery and replaces the earlier definition. If you change an existing plugin, you should IMHO use the alter hook. – Berdir Sep 18 '18 at 11:16
  • A sample code of how to alter/replace the plugin within the alter hook would be helpful – wranvaud Jul 19 at 13:58
0

In this case you could alter base field definitions for User entity and set your custom constraint for password field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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