1

Drupal's form API has a visibility state property that allows you to hide certain Form fields depending on the options selected in earlier forms.

Is there something similar for User role (e.g. a particular form field will only display if the logged in user has a certain role).

I know I can hide unwanted form fields according to role via CSS, but I would rather not print out the fields in the first place. I am creating my form inside theme-settings.php

Edit Update:

Here is my code following Rooby's answer:

function legendarysettings_form_alter(&$form, &$form_state, $form_id) {
  // To get the currently logged in user.
  global $user;
  // To target the required form.
  if  ($form_id == 'system_theme_settings') {
    // Set the role ID of the role that can edit.
    $rid = 3;
    // If user doesn't have the role in question.
    if (isset($user->roles[$rid])) {
      // Deny access to the field.
      $form['theme_settings']['admin']['#access'] = FALSE;
    }
  }

This works, except it hides the 'admin' field for role 3 (which is the admin role) but shows it to all other roles. I want the admin field to be only visible to the admin role.

6

Generally when you are hiding fields from user roles there are security implications.

The visibility state functionality you mention just hides things on the front end, which is not secure in terms of stopping users editing fields they are not actualy allowed to use.

If you want to use custom code, you can do this:

/**
 * Implements hook_form_alter().
 */
function MODULENAME_form_alter(&$form, &$form_state, $form_id) {
  // To get the currently logged in user.
  global $user;
  // To target the required form.
  if ($form_id == 'FORM_ID') {
    // Set the role ID of the role that can edit.
    $rid = ROLE_ID_FOR ROLE USER NEEDS TO EDIT;
    // If user doesn't have the role in question.
    if (isset($user->roles[$rid])) {
      // Deny access to the field.
      $form['FIELD_NAME']['#access'] = FALSE;
    }
  }
}

This is a basic example and you might have to change it to deal with multiple roles having access or something.

This is ok for custom forms or if you only need to control access to a couple of fields but if you want more control or don't want custom code, etc, the best option is the field permissions module.

With that module you can go to the field edit form and select to use custom permissions, after which you can select which roles can access the field.

EDIT
To answer the edit in the question, your code

// If user doesn't have the role in question.
if (isset($user->roles[$rid])) {

Is doing the opposite of what the comment says it is doing. To do what the comment says you would want to do this:

// If user doesn't have the role in question.
if (!isset($user->roles[$rid])) {
|improve this answer|||||
  • I am sure you mean = FALSE; not == FALSE; plus, if the OP is creating the actual form, all that would be needed to do is not create the actual $form['field'] in the first place if the user didn't have the required role. – Jimajamma Jan 19 '14 at 18:18
  • @rooby. Thanks! How do I get the name of a field in theme settings? I have used print_r which has produced this array. I want to hide all the admin fields (which are on line numbers 164 to 190). How can I get the names of these elements. I have tried using ['theme_settings']['admin']['#access'] & ['admin']['#access'], but it doesn't work. Thanks for any help you can offer! – big_smile Jan 21 '14 at 20:34
  • It's pretty hard to read that output but I would think it would be $form['theme_settings']['admin']['#access'] = FALSE; If you post your full form alter code in the original post it might be useful. – rooby Jan 21 '14 at 22:22
  • @rooby I have updated my question. – big_smile Mar 1 '14 at 12:03
0

Else you can just list out all the roles who can access the field as an array in the same form beginning and just check if the logged in user has any one of the roles you declared in that array.

For example.

$roles_accepted = array(2,3,4,5);

now get the roles of the user from $user variable. so you have two variables. 1.$roles_accepted 2.$user_roles

And now, using in_array() you can compare the roles and display the field to those who have the role you specified.

|improve this answer|||||
  • With the array approach this simplest comparison method would be if (array_intersect($roles_accepted, $user_roles)) – rooby Jan 21 '14 at 22:25

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.