3

Use case: I have added a required field for users. When user 1 (or an administrator) adds a user, the field should not be required.

Code that doesn't work (in Drupal 8):

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_register_form') {
    if (\Drupal::currentUser()->id() == 1) {
      $form['field_fieldname']['#required'] = FALSE; // No effect
      $form['field_fieldname']['widget']['#required'] = FALSE; 
    }
  }
}

Changing the widget "works", but the validation fails. The solution for Drupal 7 doesn't seem to be usable anymore.

$form['field_fieldname'][<lang>][0]['value']['#required'] = FALSE;
  • Not sure try $form['account']['field_fieldname'][<lang>][0]['value']['#required'] = FALSE; – DRUPWAY Feb 6 '17 at 14:04
1

It can be tricky to bybass D8 entity validation scheme in this way. Why don't you just set this field settings as "not required" and then set

$form['field_fieldname']['widget'][0]['#required'] = TRUE

when

\Drupal::currentUser()->id() != 1
  • 1
    Basically the right approach, make it not required by default and then change it to required conditionally. Keep in mind that this will only protect the form, you should also implement a validation constraint to validate this on the API level, in case you ever need this validation to work for REST or other API oriented things. Also, I'd recommend to not hardcode uid 1, instead work with permissions, for example \Drupal::currentUser()->hasPermission('administer users') in such a case. – Berdir Feb 6 '17 at 17:07
  • Nikko: I prefer that the website/UI shows the default behavior (required) and that custom code handles the exceptions, but this is definitely a work-around. (Is the extra nesting, "[0]", a typo?) Berdir: The code was written for user 1 - and nobody else. – hansfn Feb 6 '17 at 20:49
  • hansfn: did you find a way to do this, without inverting the behavior? So that for most users the field is required, except for the defined user? Nikko: you state "It can be tricky to bybass D8 entity validation scheme in this way" - do we know if Drupal 8 has a documented, correct way to do this? Currently I am setting $form['field_name']['#access'] = FALSE; in my hook_form_alter. This works, because core's EntityConstraintViolationList class respects '#access' in its filterByFieldAccess method. It's not user-friendly though, because the field disappears from the form completely for the user. – mcaleaa Jun 12 '18 at 8:12

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.