Permissions
A permission allows one action: "view content", "administer the blog". A module declares permissions, and the administrator gives them to roles in the panel. Code checks not the user's role but whether the permission is present — so one module works on sites with any set of roles.
Where permissions are declared
In the file blog.permissions.yml in the root of the module folder. Create it by hand:
# web/modules/custom/blog/blog.permissions.yml
administer blog:
title: 'Administer the blog'The key is the machine name of the permission, a plain string with spaces. title is the name the administrator sees.
Granting a permission
After drush cr open People → Permissions, the address /admin/people/permissions. The Blog group now has the row "Administer the blog" with a checkbox for each role. Tick the role you need and save. By default the Administrator role gets every permission automatically.
Checking in a route
Replace the general permission in the settings route with your own:
# web/modules/custom/blog/blog.routing.yml
blog.settings:
path: '/admin/config/content/blog'
defaults:
_form: '\Drupal\blog\Form\SettingsForm'
_title: 'Blog settings'
requirements:
_permission: 'administer blog'Now only roles with the administer blog permission can open the settings page. Others see "Access denied", and the link to the page disappears from their menu.
Several permissions are listed on one line: a comma means all are needed, a plus means any one is enough.
# web/modules/custom/blog/blog.routing.yml
requirements:
_permission: 'administer blog+administer site configuration'Description and warning
# web/modules/custom/blog/blog.permissions.yml
administer blog:
title: 'Administer the blog'
description: 'Change the list title and the number of articles per page.'
restrict access: true
view blog subscribers:
title: 'View the list of subscribers'description is shown under the title. restrict access: true adds a warning that the permission should be given only to trusted roles.
Checking in code
Sometimes you need to close not the whole page but a part of it. In a controller the current user is returned by the currentUser() method:
// web/modules/custom/blog/src/Controller/BlogController.php
public function list(): array
{
$build['intro'] = ['#markup' => $this->config('blog.settings')->get('list_title')];
if ($this->currentUser()->hasPermission('view blog subscribers')) {
$build['admin'] = ['#markup' => '<p>Subscribers: 12</p>'];
}
return $build;
}The line about subscribers is seen only by those who have the permission. In hooks the user is taken through \Drupal::currentUser().
| Method | What it returns |
|---|---|
hasPermission('…') | Whether the permission is present |
isAuthenticated() | Whether the user is logged in |
isAnonymous() | Whether it is an anonymous visitor |
id() | The user number, 0 for an anonymous visitor |
getDisplayName() | The display name |
Access to a node
The right to a particular node depends on the author, the published status and access modules, so the entity itself is asked:
// web/modules/custom/blog/src/Controller/BlogController.php
if ($node->access('update')) {
// show the Edit link
}The operations are view, update, delete. Without a second argument the check is made for the current user.
Common mistake
Checking a role — in_array('editor', $user->getRoles()) — is a bad habit: roles differ from site to site, they are renamed and added. Declare a permission and check hasPermission(), and let the site administrator decide who gets it. And keep in mind: the user with number 1 passes any permission check, so test access under an ordinary account.