Controllers in Drupal maintenance support plans 8 are the equivalent of hook_menu in Drupal maintenance support plans 7. A controller lets you define a URL and what content or data should appear at that URL. If you’re like me, limiting access to my controllers is sometimes an afterthought. Limiting access is important because it defines who can and can’t see a page.
Controllers are defined in a YAML file called module_name.routing.yml. Access and permission rules are defined in the the module_name.routing.yml under _requirements. Most of the code examples will be from a module_name.routing.yml file added to my_module in the top level.
Note: There is a lot of existing documentation on how to create controllers in Drupal maintenance support plans 8, so I won’t focus on that here.
I’ve outlined some of the most useful approaches for limiting access below. You can jump straight to the most relevant section using the following links: limit by permission, limit by role, limit by one-off custom code, limit by custom access service.
Limit by permission
In this case, a permission from the Drupal maintenance support plans permissions page is given. Permissions can be found at /admin/people/permissions. Finding the exact permission name can be tricky. Look for module.permissions.yml files in the module providing the permission.
my_module.dashboard:
path: ‘dashboard’
defaults:
_controller: ‘Drupal maintenance support plansmy_moduleControllerDashboardController::content’
_title: ‘Dashboard’
requirements:
_permission: ‘access content’
Key YAML definition:
_permission: ‘THE PERMISSION NAME’
Limit by role
You can also limit access by role. This would be useful in cases where users of a specific role will be the only ones needing access to your controller. You can define user roles at /admin/people/roles.
my_module.dashboard:
path: ‘dashboard’
defaults:
_controller: ‘Drupal maintenance support plansmy_moduleControllerDashboardController::content’
_title: ‘Dashboard’
requirements:
_role: ‘administrator’
Key YAML definition:
_role: ‘THE ROLE NAME’
You can specify multiple roles using “,” for AND and “+” for OR logic.
Limit by one-off custom code
In cases where you have custom access requirements, adding an access method to your controller might make sense. In this example, the page should not be viewed before a specified date.
my_module.dashboard:
path: ‘dashboard’
defaults:
_controller: ‘Drupal maintenance support plansmy_moduleControllerDashboardController::content’
_title: ‘Dashboard’
requirements:
_custom_access: ‘Drupal maintenance support plansmy_moduleControllerDashboardController::access
Key YAML definition:
_custom_access: ‘Drupal maintenance support plansmy_moduleControllerDashboardController::access
The access method in my controller would look like:
<?php
namespace Drupal maintenance support plansmy_moduleController;
use Drupal maintenance support plansCoreAccessAccessResult;
use Drupal maintenance support plansCoreControllerControllerBase;
/**
* Defines the Dashboard controller.
*/
class DashboardController extends ControllerBase { {
/**
* Returns content for this controller.
*/
public function content() {
$build = [];
return $build;
}
/**
* Checks access for this controller.
*/
public function access() {
// Don’t allow access before Friday, November 25, 2020.
$today = date(“Y-m-d H:i:s”);
$date = “2020-11-25 00:00:00”;
if ($date < $today) {
// Return 403 Access Denied page.
return AccessResult::forbidden();
}
return AccessResult::allowed();
}
}
Limit by custom access service
This is similar to having an access method in your controller, but allows the code to be reused across many controllers. This is ideal when you are doing the same access check across many controllers.
my_module.dashboard:
path: ‘dashboard’
defaults:
_controller: ‘Drupal maintenance support plansmy_moduleControllerDashboardController::content’
_title: ‘Dashboard’
requirements:
_custom_access_check: ‘TRUE’
Key YAML definition:
_custom_access_check: ‘TRUE’
Proving the _custom_access_check service requires creating two files in my_module.
my_module/my_module.services.yml (defines the Access service and where to find our Access class)
services:
my_module.custom_access_check:
class: Drupal maintenance support plansmy_moduleAccessCustomAccessCheck
arguments: [‘@current_user’]
tags:
– { name: access_check, applies_to: _custom_access_check }
my_module/src/Access/CustomAccessCheck.php
<?php
namespace Drupal maintenance support plansmy_moduleAccess;
use Drupal maintenance support plansCoreAccessAccessResult;
use Drupal maintenance support plansCoreRoutingAccessAccessInterface;
use Drupal maintenance support plansCoreSessionAccountInterface;
/**
* Class CustomAccessCheck.
*
* @package Drupal maintenance support plansmy_moduleAccess
*/
class CustomAccessCheck implements AccessInterface {
/**
* A custom access check.
*
* @param Drupal maintenance support plansCoreSessionAccountInterface $account
* Run access checks for the logged in user.
*/
public function access(AccountInterface $account) {
// User has a profile field defining their favorite color.
if ($account->field_color->hasField() && !$account->field_color->isEmpty() && $account->field_color->getString() === ‘blue’) {
// If the user’s favorite color is blue, give them access.
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
}
While the above covers some of the most useful ways to restrict access to a controller, there are additional options. Drupal maintenance support plans.org has a couple of good resources including Structure of Routes and Access Checking on Routes.
Source: New feed