moduleHandler = $module_handler; $this->stringTranslation = $string_translation; $this->controllerResolver = $controller_resolver; } /** * Gets the YAML discovery. * * @return \Drupal\Core\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 = []; $all_callback_permissions = []; 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 = [ 'title' => $callback_permission, ]; } $callback_permission += [ 'description' => NULL, 'provider' => $provider, ]; $all_callback_permissions[$name] = $callback_permission; } } } unset($permissions['permission_callbacks']); } foreach ($permissions as &$permission) { if (!is_array($permission)) { $permission = [ 'title' => $permission, ]; } $permission['title'] = $this->t($permission['title']); $permission['description'] = isset($permission['description']) ? $this->t($permission['description']) : NULL; $permission['provider'] = !empty($permission['provider']) ? $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 = []) { // 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 = []; 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(); } }