Mercurial > hg > isophonics-drupal-site
comparison core/modules/user/src/PermissionHandler.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\user; | |
4 | |
5 use Drupal\Core\Discovery\YamlDiscovery; | |
6 use Drupal\Core\Controller\ControllerResolverInterface; | |
7 use Drupal\Core\Extension\ModuleHandlerInterface; | |
8 use Drupal\Core\StringTranslation\StringTranslationTrait; | |
9 use Drupal\Core\StringTranslation\TranslationInterface; | |
10 | |
11 /** | |
12 * Provides the available permissions based on yml files. | |
13 * | |
14 * To define permissions you can use a $module.permissions.yml file. This file | |
15 * defines machine names, human-readable names, restrict access (if required for | |
16 * security warning), and optionally descriptions for each permission type. The | |
17 * machine names are the canonical way to refer to permissions for access | |
18 * checking. | |
19 * | |
20 * If your module needs to define dynamic permissions you can use the | |
21 * permission_callbacks key to declare a callable that will return an array of | |
22 * permissions, keyed by machine name. Each item in the array can contain the | |
23 * same keys as an entry in $module.permissions.yml. | |
24 * | |
25 * Here is an example from the core filter module (comments have been added): | |
26 * @code | |
27 * # The key is the permission machine name, and is required. | |
28 * administer filters: | |
29 * # (required) Human readable name of the permission used in the UI. | |
30 * title: 'Administer text formats and filters' | |
31 * # (optional) Additional description fo the permission used in the UI. | |
32 * description: 'Define how text is handled by combining filters into text formats.' | |
33 * # (optional) Boolean, when set to true a warning about site security will | |
34 * # be displayed on the Permissions page. Defaults to false. | |
35 * restrict access: false | |
36 * | |
37 * # An array of callables used to generate dynamic permissions. | |
38 * permission_callbacks: | |
39 * # Each item in the array should return an associative array with one or | |
40 * # more permissions following the same keys as the permission defined above. | |
41 * - Drupal\filter\FilterPermissions::permissions | |
42 * @endcode | |
43 * | |
44 * @see filter.permissions.yml | |
45 * @see \Drupal\filter\FilterPermissions | |
46 * @see user_api | |
47 */ | |
48 class PermissionHandler implements PermissionHandlerInterface { | |
49 | |
50 use StringTranslationTrait; | |
51 | |
52 /** | |
53 * The module handler. | |
54 * | |
55 * @var \Drupal\Core\Extension\ModuleHandlerInterface | |
56 */ | |
57 protected $moduleHandler; | |
58 | |
59 /** | |
60 * The YAML discovery class to find all .permissions.yml files. | |
61 * | |
62 * @var \Drupal\Core\Discovery\YamlDiscovery | |
63 */ | |
64 protected $yamlDiscovery; | |
65 | |
66 /** | |
67 * The controller resolver. | |
68 * | |
69 * @var \Drupal\Core\Controller\ControllerResolverInterface | |
70 */ | |
71 protected $controllerResolver; | |
72 | |
73 /** | |
74 * Constructs a new PermissionHandler. | |
75 * | |
76 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler | |
77 * The module handler. | |
78 * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation | |
79 * The string translation. | |
80 * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver | |
81 * The controller resolver. | |
82 */ | |
83 public function __construct(ModuleHandlerInterface $module_handler, TranslationInterface $string_translation, ControllerResolverInterface $controller_resolver) { | |
84 // @todo It would be nice if you could pull all module directories from the | |
85 // container. | |
86 $this->moduleHandler = $module_handler; | |
87 $this->stringTranslation = $string_translation; | |
88 $this->controllerResolver = $controller_resolver; | |
89 } | |
90 | |
91 /** | |
92 * Gets the YAML discovery. | |
93 * | |
94 * @return \Drupal\Core\Discovery\YamlDiscovery | |
95 * The YAML discovery. | |
96 */ | |
97 protected function getYamlDiscovery() { | |
98 if (!isset($this->yamlDiscovery)) { | |
99 $this->yamlDiscovery = new YamlDiscovery('permissions', $this->moduleHandler->getModuleDirectories()); | |
100 } | |
101 return $this->yamlDiscovery; | |
102 } | |
103 | |
104 /** | |
105 * {@inheritdoc} | |
106 */ | |
107 public function getPermissions() { | |
108 $all_permissions = $this->buildPermissionsYaml(); | |
109 | |
110 return $this->sortPermissions($all_permissions); | |
111 } | |
112 | |
113 /** | |
114 * {@inheritdoc} | |
115 */ | |
116 public function moduleProvidesPermissions($module_name) { | |
117 // @TODO Static cache this information, see | |
118 // https://www.drupal.org/node/2339487 | |
119 $permissions = $this->getPermissions(); | |
120 | |
121 foreach ($permissions as $permission) { | |
122 if ($permission['provider'] == $module_name) { | |
123 return TRUE; | |
124 } | |
125 } | |
126 return FALSE; | |
127 } | |
128 | |
129 /** | |
130 * Builds all permissions provided by .permissions.yml files. | |
131 * | |
132 * @return array[] | |
133 * Each return permission is an array with the following keys: | |
134 * - title: The title of the permission. | |
135 * - description: The description of the permission, defaults to NULL. | |
136 * - provider: The provider of the permission. | |
137 */ | |
138 protected function buildPermissionsYaml() { | |
139 $all_permissions = []; | |
140 $all_callback_permissions = []; | |
141 | |
142 foreach ($this->getYamlDiscovery()->findAll() as $provider => $permissions) { | |
143 // The top-level 'permissions_callback' is a list of methods in controller | |
144 // syntax, see \Drupal\Core\Controller\ControllerResolver. These methods | |
145 // should return an array of permissions in the same structure. | |
146 if (isset($permissions['permission_callbacks'])) { | |
147 foreach ($permissions['permission_callbacks'] as $permission_callback) { | |
148 $callback = $this->controllerResolver->getControllerFromDefinition($permission_callback); | |
149 if ($callback_permissions = call_user_func($callback)) { | |
150 // Add any callback permissions to the array of permissions. Any | |
151 // defaults can then get processed below. | |
152 foreach ($callback_permissions as $name => $callback_permission) { | |
153 if (!is_array($callback_permission)) { | |
154 $callback_permission = [ | |
155 'title' => $callback_permission, | |
156 ]; | |
157 } | |
158 | |
159 $callback_permission += [ | |
160 'description' => NULL, | |
161 'provider' => $provider, | |
162 ]; | |
163 | |
164 $all_callback_permissions[$name] = $callback_permission; | |
165 } | |
166 } | |
167 } | |
168 | |
169 unset($permissions['permission_callbacks']); | |
170 } | |
171 | |
172 foreach ($permissions as &$permission) { | |
173 if (!is_array($permission)) { | |
174 $permission = [ | |
175 'title' => $permission, | |
176 ]; | |
177 } | |
178 $permission['title'] = $this->t($permission['title']); | |
179 $permission['description'] = isset($permission['description']) ? $this->t($permission['description']) : NULL; | |
180 $permission['provider'] = !empty($permission['provider']) ? $permission['provider'] : $provider; | |
181 } | |
182 | |
183 $all_permissions += $permissions; | |
184 } | |
185 | |
186 return $all_permissions + $all_callback_permissions; | |
187 } | |
188 | |
189 /** | |
190 * Sorts the given permissions by provider name and title. | |
191 * | |
192 * @param array $all_permissions | |
193 * The permissions to be sorted. | |
194 * | |
195 * @return array[] | |
196 * Each return permission is an array with the following keys: | |
197 * - title: The title of the permission. | |
198 * - description: The description of the permission, defaults to NULL. | |
199 * - provider: The provider of the permission. | |
200 */ | |
201 protected function sortPermissions(array $all_permissions = []) { | |
202 // Get a list of all the modules providing permissions and sort by | |
203 // display name. | |
204 $modules = $this->getModuleNames(); | |
205 | |
206 uasort($all_permissions, function (array $permission_a, array $permission_b) use ($modules) { | |
207 if ($modules[$permission_a['provider']] == $modules[$permission_b['provider']]) { | |
208 return $permission_a['title'] > $permission_b['title']; | |
209 } | |
210 else { | |
211 return $modules[$permission_a['provider']] > $modules[$permission_b['provider']]; | |
212 } | |
213 }); | |
214 return $all_permissions; | |
215 } | |
216 | |
217 /** | |
218 * Returns all module names. | |
219 * | |
220 * @return string[] | |
221 * Returns the human readable names of all modules keyed by machine name. | |
222 */ | |
223 protected function getModuleNames() { | |
224 $modules = []; | |
225 foreach (array_keys($this->moduleHandler->getModuleList()) as $module) { | |
226 $modules[$module] = $this->moduleHandler->getName($module); | |
227 } | |
228 asort($modules); | |
229 return $modules; | |
230 } | |
231 | |
232 /** | |
233 * Wraps system_rebuild_module_data() | |
234 * | |
235 * @return \Drupal\Core\Extension\Extension[] | |
236 */ | |
237 protected function systemRebuildModuleData() { | |
238 return system_rebuild_module_data(); | |
239 } | |
240 | |
241 } |