1<?php
2
3namespace Drupal\user\Entity;
4
5use Drupal\Core\Config\Entity\ConfigEntityBase;
6use Drupal\Core\Entity\EntityStorageInterface;
7use Drupal\user\RoleInterface;
8
9/**
10 * Defines the user role entity class.
11 *
12 * @ConfigEntityType(
13 *   id = "user_role",
14 *   label = @Translation("Role"),
15 *   label_collection = @Translation("Roles"),
16 *   label_singular = @Translation("role"),
17 *   label_plural = @Translation("roles"),
18 *   label_count = @PluralTranslation(
19 *     singular = "@count role",
20 *     plural = "@count roles",
21 *   ),
22 *   handlers = {
23 *     "storage" = "Drupal\user\RoleStorage",
24 *     "access" = "Drupal\user\RoleAccessControlHandler",
25 *     "list_builder" = "Drupal\user\RoleListBuilder",
26 *     "form" = {
27 *       "default" = "Drupal\user\RoleForm",
28 *       "delete" = "Drupal\Core\Entity\EntityDeleteForm"
29 *     }
30 *   },
31 *   admin_permission = "administer permissions",
32 *   config_prefix = "role",
33 *   static_cache = TRUE,
34 *   entity_keys = {
35 *     "id" = "id",
36 *     "weight" = "weight",
37 *     "label" = "label"
38 *   },
39 *   links = {
40 *     "delete-form" = "/admin/people/roles/manage/{user_role}/delete",
41 *     "edit-form" = "/admin/people/roles/manage/{user_role}",
42 *     "edit-permissions-form" = "/admin/people/permissions/{user_role}",
43 *     "collection" = "/admin/people/roles",
44 *   },
45 *   config_export = {
46 *     "id",
47 *     "label",
48 *     "weight",
49 *     "is_admin",
50 *     "permissions",
51 *   }
52 * )
53 */
54class Role extends ConfigEntityBase implements RoleInterface {
55
56  /**
57   * The machine name of this role.
58   *
59   * @var string
60   */
61  protected $id;
62
63  /**
64   * The human-readable label of this role.
65   *
66   * @var string
67   */
68  protected $label;
69
70  /**
71   * The weight of this role in administrative listings.
72   *
73   * @var int
74   */
75  protected $weight;
76
77  /**
78   * The permissions belonging to this role.
79   *
80   * @var array
81   */
82  protected $permissions = [];
83
84  /**
85   * An indicator whether the role has all permissions.
86   *
87   * @var bool
88   */
89  protected $is_admin;
90
91  /**
92   * {@inheritdoc}
93   */
94  public function getPermissions() {
95    if ($this->isAdmin()) {
96      return [];
97    }
98    return $this->permissions;
99  }
100
101  /**
102   * {@inheritdoc}
103   */
104  public function getWeight() {
105    return $this->get('weight');
106  }
107
108  /**
109   * {@inheritdoc}
110   */
111  public function setWeight($weight) {
112    $this->set('weight', $weight);
113    return $this;
114  }
115
116  /**
117   * {@inheritdoc}
118   */
119  public function hasPermission($permission) {
120    if ($this->isAdmin()) {
121      return TRUE;
122    }
123    return in_array($permission, $this->permissions);
124  }
125
126  /**
127   * {@inheritdoc}
128   */
129  public function grantPermission($permission) {
130    if ($this->isAdmin()) {
131      return $this;
132    }
133    if (!$this->hasPermission($permission)) {
134      $this->permissions[] = $permission;
135    }
136    return $this;
137  }
138
139  /**
140   * {@inheritdoc}
141   */
142  public function revokePermission($permission) {
143    if ($this->isAdmin()) {
144      return $this;
145    }
146    $this->permissions = array_diff($this->permissions, [$permission]);
147    return $this;
148  }
149
150  /**
151   * {@inheritdoc}
152   */
153  public function isAdmin() {
154    return (bool) $this->is_admin;
155  }
156
157  /**
158   * {@inheritdoc}
159   */
160  public function setIsAdmin($is_admin) {
161    $this->is_admin = $is_admin;
162    return $this;
163  }
164
165  /**
166   * {@inheritdoc}
167   */
168  public static function postLoad(EntityStorageInterface $storage, array &$entities) {
169    parent::postLoad($storage, $entities);
170    // Sort the queried roles by their weight.
171    // See \Drupal\Core\Config\Entity\ConfigEntityBase::sort().
172    uasort($entities, 'static::sort');
173  }
174
175  /**
176   * {@inheritdoc}
177   */
178  public function preSave(EntityStorageInterface $storage) {
179    parent::preSave($storage);
180
181    if (!isset($this->weight) && ($roles = $storage->loadMultiple())) {
182      // Set a role weight to make this new role last.
183      $max = array_reduce($roles, function ($max, $role) {
184        return $max > $role->weight ? $max : $role->weight;
185      });
186      $this->weight = $max + 1;
187    }
188
189    if (!$this->isSyncing()) {
190      // Permissions are always ordered alphabetically to avoid conflicts in the
191      // exported configuration.
192      sort($this->permissions);
193    }
194  }
195
196}
197