19

In Drupal 7, what is the best way to prevent any non-administrative user from changing a custom user profile field?

Use case: I've created a user field called "Customer ID" that I do not want the user (any of my actual customers) to change. The field exists for my own reference and for programmatic usage in other modules. I don't mind the user seeing Customer ID, but they should not be able to edit it.

Should I override the page template for the user profile page? If so, how is the template changed to make a field read-only or invisible?

Thank you very much for your help!

Chris

4 Answers 4

17

I think Field Permissions is what you are looking for. Here is a quote about it (from the module's project page):

... allows site administrators to set field-level permissions to edit, view and create fields on any entity.

Features:

  • Enable field permissions on any entity, not just nodes.
  • Role-based field permissions allowing different viewing patterned based on what access the user has.
  • Author-level permissions allow viewing and editing of fields based on who the entity owner is.
  • Permissions for each field are not enabled by default. Instead, administrators can enable these permissions explicitly for the fields where this feature is needed.
  • Field permissions overview
4
  • Thanks, notme! I've installed the Field Permissions module (alpha version is latest, which makes me a little nervous, but whatever), and it does hide the field from the user when the user views his profile. After experimenting with all of the module's settings, there doesn't seem to be a way to make the field visible but read-only. Not an absolute requirement, but would be nice to have.
    – ctlarsen
    May 14, 2011 at 18:00
  • Setting a field to be visible means that a textfield is shown as plain text. If you want to keep the textfield and set it as read-only, I guess you have to use a hook_form_alter on your form.
    – pasine
    May 14, 2011 at 21:46
  • Thanks again, notme. I'll take the hook_form_alter route and see where that takes me. It sounds like it's the best way to go.
    – ctlarsen
    May 15, 2011 at 12:23
  • The module Field Permissions works fine with Drupal 8 but you could hide only custom fields i think (i needed to hyde also user name) Oct 4, 2017 at 13:58
6

To hide the field from the user profile form you can set the #access property of a field to FALSE using hook_form_FORMID_alter.

The following snippet hides the field field_organisation from the user profile form for non-admins:

function YOURCUSTOMMODULE_form_user_profile_form_alter(&$form, &$form_state, $form_id) {
  $current_user = user_uid_optional_load();
  if($current_user->uid != 1) {
    $form['field_organisation']['#access'] = FALSE;
  }
}

See also this similar question on drupalanswers

You can also hide the field from the user profile page (not the form) using template_preprocess_user_profile

The following snippet hides the field field_organisation from the user page for non-admins:

function YOURCUSTOMMODULE_preprocess_user_profile(&$vars) {
  $current_user = user_uid_optional_load();
  if($current_user->uid != 1) {
    unset($vars['user_profile']['field_organisation']);
  }
}
1

Seems to be there is a module called http://drupal.org/project/user_readonly "The module allows an administrator to prevent modification of user account/profile fields. The administrator can select which fields will be disallowed, or which fields will be allowed."

0

hook_form_alter will work for Drupal 8/9 as well, we can hide other custom fields in User profile using #access attribute of form elements:

use Drupal\Core\Form\FormStateInterface;

hook_form_alter(&$form, FormStateInterface $form_state, $form_id) {
{
    // Disable form fields based on User Roles
    if ($form_id == 'user_form') { 
      $roles = \Drupal::currentUser()->getRoles();
      if (!in_array('administrator', $roles)){
        // Do something if user has no role administrator;
        $form['account']['roles']['#access'] = FALSE;
        $form['field_organizations_reference']['#access'] = FALSE;
      }
      if (in_array('administrator', $roles)){
         // Do something if user has role administrator;
         $form['account']['roles']['#access'] = TRUE;
         $form['field_organizations_reference']['#access'] = TRUE;
      }
      // Do other stuff for your other roles 
    }
}

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.