Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
88.89% |
8 / 9 |
CRAP | |
97.92% |
47 / 48 |
| PermissionHandler | |
0.00% |
0 / 1 |
|
88.89% |
8 / 9 |
24 | |
97.92% |
47 / 48 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| getYamlDiscovery | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
| getPermissions | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| moduleProvidesPermissions | |
100.00% |
1 / 1 |
3 | |
100.00% |
5 / 5 |
|||
| buildPermissionsYaml | |
100.00% |
1 / 1 |
10 | |
100.00% |
22 / 22 |
|||
| sortPermissions | |
100.00% |
1 / 1 |
2 | |
100.00% |
1 / 1 |
|||
| anonymous function | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
| getModuleNames | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
| systemRebuildModuleData | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\user\PermissionHandler. | |
| */ | |
| namespace Drupal\user; | |
| use Drupal\Component\Discovery\YamlDiscovery; | |
| use Drupal\Core\Controller\ControllerResolverInterface; | |
| use Drupal\Core\Extension\ModuleHandlerInterface; | |
| use Drupal\Core\StringTranslation\StringTranslationTrait; | |
| use Drupal\Core\StringTranslation\TranslationInterface; | |
| /** | |
| * Provides the available permissions based on yml files. | |
| * | |
| * To define permissions you can use a $module.permissions.yml file. This file | |
| * defines machine names, human-readable names, restrict access (if required for | |
| * security warning), and optionally descriptions for each permission type. The | |
| * machine names are the canonical way to refer to permissions for access | |
| * checking. | |
| * | |
| * If your module needs to define dynamic permissions you can use the | |
| * permission_callbacks key to declare a callable that will return an array of | |
| * permissions, keyed by machine name. Each item in the array can contain the | |
| * same keys as an entry in $module.permissions.yml. | |
| * | |
| * Here is an example from the core filter module (comments have been added): | |
| * @code | |
| * # The key is the permission machine name, and is required. | |
| * administer filters: | |
| * # (required) Human readable name of the permission used in the UI. | |
| * title: 'Administer text formats and filters' | |
| * # (optional) Additional description fo the permission used in the UI. | |
| * description: 'Define how text is handled by combining filters into text formats.' | |
| * # (optional) Boolean, when set to true a warning about site security will | |
| * # be displayed on the Permissions page. Defaults to false. | |
| * restrict access: false | |
| * | |
| * # An array of callables used to generate dynamic permissions. | |
| * permission_callbacks: | |
| * # Each item in the array should return an associative array with one or | |
| * # more permissions following the same keys as the permission defined above. | |
| * - Drupal\filter\FilterPermissions::permissions | |
| * @endcode | |
| * | |
| * @see filter.permissions.yml | |
| * @see \Drupal\filter\FilterPermissions | |
| * @see user_api | |
| */ | |
| class PermissionHandler implements PermissionHandlerInterface { | |
| use StringTranslationTrait; | |
| /** | |
| * The module handler. | |
| * | |
| * @var \Drupal\Core\Extension\ModuleHandlerInterface | |
| */ | |
| protected $moduleHandler; | |
| /** | |
| * The YAML discovery class to find all .permissions.yml files. | |
| * | |
| * @var \Drupal\Component\Discovery\YamlDiscovery | |
| */ | |
| protected $yamlDiscovery; | |
| /** | |
| * The controller resolver. | |
| * | |
| * @var \Drupal\Core\Controller\ControllerResolverInterface | |
| */ | |
| protected $controllerResolver; | |
| /** | |
| * Constructs a new PermissionHandler. | |
| * | |
| * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler | |
| * The module handler. | |
| * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation | |
| * The string translation. | |
| * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver | |
| * The controller resolver. | |
| */ | |
| public function __construct(ModuleHandlerInterface $module_handler, TranslationInterface $string_translation, ControllerResolverInterface $controller_resolver) { | |
| // @todo It would be nice if you could pull all module directories from the | |
| // container. | |
| $this->moduleHandler = $module_handler; | |
| $this->stringTranslation = $string_translation; | |
| $this->controllerResolver = $controller_resolver; | |
| } | |
| /** | |
| * Gets the YAML discovery. | |
| * | |
| * @return \Drupal\Component\Discovery\YamlDiscovery | |
| * The YAML discovery. | |
| */ | |
| protected function getYamlDiscovery() { | |
| if (!isset($this->yamlDiscovery)) { | |
| $this->yamlDiscovery = new YamlDiscovery('permissions', $this->moduleHandler->getModuleDirectories()); | |
| } | |
| return $this->yamlDiscovery; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getPermissions() { | |
| $all_permissions = $this->buildPermissionsYaml(); | |
| return $this->sortPermissions($all_permissions); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function moduleProvidesPermissions($module_name) { | |
| // @TODO Static cache this information, see | |
| // https://www.drupal.org/node/2339487 | |
| $permissions = $this->getPermissions(); | |
| foreach ($permissions as $permission) { | |
| if ($permission['provider'] == $module_name) { | |
| return TRUE; | |
| } | |
| } | |
| return FALSE; | |
| } | |
| /** | |
| * Builds all permissions provided by .permissions.yml files. | |
| * | |
| * @return array[] | |
| * Each return permission is an array with the following keys: | |
| * - title: The title of the permission. | |
| * - description: The description of the permission, defaults to NULL. | |
| * - provider: The provider of the permission. | |
| */ | |
| protected function buildPermissionsYaml() { | |
| $all_permissions = array(); | |
| $all_callback_permissions = array(); | |
| foreach ($this->getYamlDiscovery()->findAll() as $provider => $permissions) { | |
| // The top-level 'permissions_callback' is a list of methods in controller | |
| // syntax, see \Drupal\Core\Controller\ControllerResolver. These methods | |
| // should return an array of permissions in the same structure. | |
| if (isset($permissions['permission_callbacks'])) { | |
| foreach ($permissions['permission_callbacks'] as $permission_callback) { | |
| $callback = $this->controllerResolver->getControllerFromDefinition($permission_callback); | |
| if ($callback_permissions = call_user_func($callback)) { | |
| // Add any callback permissions to the array of permissions. Any | |
| // defaults can then get processed below. | |
| foreach ($callback_permissions as $name => $callback_permission) { | |
| if (!is_array($callback_permission)) { | |
| $callback_permission = array( | |
| 'title' => $callback_permission, | |
| ); | |
| } | |
| $callback_permission += array( | |
| 'description' => NULL, | |
| ); | |
| $callback_permission['provider'] = $provider; | |
| $all_callback_permissions[$name] = $callback_permission; | |
| } | |
| } | |
| } | |
| unset($permissions['permission_callbacks']); | |
| } | |
| foreach ($permissions as &$permission) { | |
| if (!is_array($permission)) { | |
| $permission = array( | |
| 'title' => $permission, | |
| ); | |
| } | |
| $permission['title'] = $this->t($permission['title']); | |
| $permission['description'] = isset($permission['description']) ? $this->t($permission['description']) : NULL; | |
| $permission['provider'] = $provider; | |
| } | |
| $all_permissions += $permissions; | |
| } | |
| return $all_permissions + $all_callback_permissions; | |
| } | |
| /** | |
| * Sorts the given permissions by provider name and title. | |
| * | |
| * @param array $all_permissions | |
| * The permissions to be sorted. | |
| * | |
| * @return array[] | |
| * Each return permission is an array with the following keys: | |
| * - title: The title of the permission. | |
| * - description: The description of the permission, defaults to NULL. | |
| * - provider: The provider of the permission. | |
| */ | |
| protected function sortPermissions(array $all_permissions = array()) { | |
| // Get a list of all the modules providing permissions and sort by | |
| // display name. | |
| $modules = $this->getModuleNames(); | |
| uasort($all_permissions, function (array $permission_a, array $permission_b) use ($modules) { | |
| if ($modules[$permission_a['provider']] == $modules[$permission_b['provider']]) { | |
| return $permission_a['title'] > $permission_b['title']; | |
| } | |
| else { | |
| return $modules[$permission_a['provider']] > $modules[$permission_b['provider']]; | |
| } | |
| }); | |
| return $all_permissions; | |
| } | |
| /** | |
| * Returns all module names. | |
| * | |
| * @return string[] | |
| * Returns the human readable names of all modules keyed by machine name. | |
| */ | |
| protected function getModuleNames() { | |
| $modules = array(); | |
| foreach (array_keys($this->moduleHandler->getModuleList()) as $module) { | |
| $modules[$module] = $this->moduleHandler->getName($module); | |
| } | |
| asort($modules); | |
| return $modules; | |
| } | |
| /** | |
| * Wraps system_rebuild_module_data() | |
| * | |
| * @return \Drupal\Core\Extension\Extension[] | |
| */ | |
| protected function systemRebuildModuleData() { | |
| return system_rebuild_module_data(); | |
| } | |
| } |