0

I want to provide a field in a node to lists a subset of available roles. These roles could be used to decide how the node would be displayed to users with the roles selected here.

Is there a way to create an entity reference field of entity type user role? If yes, how can I restrict the field to display only certain roles? The usual way is to create a view with entity reference display and add conditions in the view to restrict the options. Is it possible to create a view of type user role?

1

Two parts to check here.

  1. Is it possible to reference user role (a config entity)
  2. Is there a way to restrict the available roles in the field level.

reg #1, yes! the out-of-box Drupal core allows creating an entity reference field with the target entity as a user role.

Entity reference field of target user roles

For #2, there is no easy way as the only way to restrict the available option(in core) is via views, but unfortunately, we can create views of the content entities. However, we can add a reference handler with config (as below) to restrict the available roles.

<?php

namespace Drupal\mymodule\Plugin\EntityReferenceSelection;

use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provide configuration to select specific roles to reference.
 *
 * @EntityReferenceSelection(
 *   id = "default:user_role",
 *   label = @Translation("Role selection"),
 *   entity_types = {"user_role"},
 *   group = "default",
 *   weight = 1
 * )
 */
class RoleSelection extends DefaultSelection {

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);
    $configuration = $this->getConfiguration();
    $entity_type_id = $configuration['target_type'];
    $storage = $this->entityTypeManager->getStorage($entity_type_id);

    $options = array_map(function ($entity) {
      /** @var \Drupal\Core\Entity\EntityInterface $entity */
      return $entity->label();
    }, $storage->loadMultiple());

    $form['target_roles'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('Allowed roles'),
      '#options' => $options,
      '#default_value' => isset($configuration['target_roles']) ? (array) $configuration['target_roles'] : [],
      '#multiple' => TRUE,
    ];
    return $form;
  }
    /**
   * {@inheritDoc}
   */
  protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
    $configuration = $this->getConfiguration();
    $target_type = $configuration['target_type'] ?: [];
    $entity_type = $this->entityTypeManager->getDefinition($target_type);
    $query = parent::buildEntityQuery($match, $match_operator);

    // Add condition, if set of roles selected.
    if (isset( $configuration['target_roles'])) {
      $query->condition($entity_type->getKey('id'), $configuration['target_roles'], 'IN');
    }
    return $query;
  }

}

Here is the field settings page: role field settings

and here is the final output:

restricted roles listed in the main entity

| improve this answer | |

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.