Chris@0: moduleHandler = $module_handler; Chris@0: $this->stringTranslation = $string_translation; Chris@0: $this->controllerResolver = $controller_resolver; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the YAML discovery. Chris@0: * Chris@0: * @return \Drupal\Core\Discovery\YamlDiscovery Chris@0: * The YAML discovery. Chris@0: */ Chris@0: protected function getYamlDiscovery() { Chris@0: if (!isset($this->yamlDiscovery)) { Chris@0: $this->yamlDiscovery = new YamlDiscovery('permissions', $this->moduleHandler->getModuleDirectories()); Chris@0: } Chris@0: return $this->yamlDiscovery; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getPermissions() { Chris@0: $all_permissions = $this->buildPermissionsYaml(); Chris@0: Chris@0: return $this->sortPermissions($all_permissions); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function moduleProvidesPermissions($module_name) { Chris@0: // @TODO Static cache this information, see Chris@0: // https://www.drupal.org/node/2339487 Chris@0: $permissions = $this->getPermissions(); Chris@0: Chris@0: foreach ($permissions as $permission) { Chris@0: if ($permission['provider'] == $module_name) { Chris@0: return TRUE; Chris@0: } Chris@0: } Chris@0: return FALSE; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Builds all permissions provided by .permissions.yml files. Chris@0: * Chris@0: * @return array[] Chris@0: * Each return permission is an array with the following keys: Chris@0: * - title: The title of the permission. Chris@0: * - description: The description of the permission, defaults to NULL. Chris@0: * - provider: The provider of the permission. Chris@0: */ Chris@0: protected function buildPermissionsYaml() { Chris@0: $all_permissions = []; Chris@0: $all_callback_permissions = []; Chris@0: Chris@0: foreach ($this->getYamlDiscovery()->findAll() as $provider => $permissions) { Chris@0: // The top-level 'permissions_callback' is a list of methods in controller Chris@0: // syntax, see \Drupal\Core\Controller\ControllerResolver. These methods Chris@0: // should return an array of permissions in the same structure. Chris@0: if (isset($permissions['permission_callbacks'])) { Chris@0: foreach ($permissions['permission_callbacks'] as $permission_callback) { Chris@0: $callback = $this->controllerResolver->getControllerFromDefinition($permission_callback); Chris@0: if ($callback_permissions = call_user_func($callback)) { Chris@0: // Add any callback permissions to the array of permissions. Any Chris@0: // defaults can then get processed below. Chris@0: foreach ($callback_permissions as $name => $callback_permission) { Chris@0: if (!is_array($callback_permission)) { Chris@0: $callback_permission = [ Chris@0: 'title' => $callback_permission, Chris@0: ]; Chris@0: } Chris@0: Chris@0: $callback_permission += [ Chris@0: 'description' => NULL, Chris@0: 'provider' => $provider, Chris@0: ]; Chris@0: Chris@0: $all_callback_permissions[$name] = $callback_permission; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: unset($permissions['permission_callbacks']); Chris@0: } Chris@0: Chris@0: foreach ($permissions as &$permission) { Chris@0: if (!is_array($permission)) { Chris@0: $permission = [ Chris@0: 'title' => $permission, Chris@0: ]; Chris@0: } Chris@0: $permission['title'] = $this->t($permission['title']); Chris@0: $permission['description'] = isset($permission['description']) ? $this->t($permission['description']) : NULL; Chris@0: $permission['provider'] = !empty($permission['provider']) ? $permission['provider'] : $provider; Chris@0: } Chris@0: Chris@0: $all_permissions += $permissions; Chris@0: } Chris@0: Chris@0: return $all_permissions + $all_callback_permissions; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sorts the given permissions by provider name and title. Chris@0: * Chris@0: * @param array $all_permissions Chris@0: * The permissions to be sorted. Chris@0: * Chris@0: * @return array[] Chris@0: * Each return permission is an array with the following keys: Chris@0: * - title: The title of the permission. Chris@0: * - description: The description of the permission, defaults to NULL. Chris@0: * - provider: The provider of the permission. Chris@0: */ Chris@0: protected function sortPermissions(array $all_permissions = []) { Chris@0: // Get a list of all the modules providing permissions and sort by Chris@0: // display name. Chris@0: $modules = $this->getModuleNames(); Chris@0: Chris@0: uasort($all_permissions, function (array $permission_a, array $permission_b) use ($modules) { Chris@0: if ($modules[$permission_a['provider']] == $modules[$permission_b['provider']]) { Chris@0: return $permission_a['title'] > $permission_b['title']; Chris@0: } Chris@0: else { Chris@0: return $modules[$permission_a['provider']] > $modules[$permission_b['provider']]; Chris@0: } Chris@0: }); Chris@0: return $all_permissions; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns all module names. Chris@0: * Chris@0: * @return string[] Chris@0: * Returns the human readable names of all modules keyed by machine name. Chris@0: */ Chris@0: protected function getModuleNames() { Chris@0: $modules = []; Chris@0: foreach (array_keys($this->moduleHandler->getModuleList()) as $module) { Chris@0: $modules[$module] = $this->moduleHandler->getName($module); Chris@0: } Chris@0: asort($modules); Chris@0: return $modules; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Wraps system_rebuild_module_data() Chris@0: * Chris@0: * @return \Drupal\Core\Extension\Extension[] Chris@0: */ Chris@0: protected function systemRebuildModuleData() { Chris@0: return system_rebuild_module_data(); Chris@0: } Chris@0: Chris@0: }