Mercurial > hg > isophonics-drupal-site
comparison core/modules/rest/src/Entity/ConfigDependencies.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\rest\Entity; | |
4 | |
5 use Drupal\Core\DependencyInjection\ContainerInjectionInterface; | |
6 use Drupal\rest\RestResourceConfigInterface; | |
7 use Symfony\Component\DependencyInjection\ContainerInterface; | |
8 | |
9 /** | |
10 * Calculates rest resource config dependencies. | |
11 * | |
12 * @internal | |
13 */ | |
14 class ConfigDependencies implements ContainerInjectionInterface { | |
15 | |
16 /** | |
17 * The serialization format providers, keyed by format. | |
18 * | |
19 * @var string[] | |
20 */ | |
21 protected $formatProviders; | |
22 | |
23 /** | |
24 * The authentication providers, keyed by ID. | |
25 * | |
26 * @var string[] | |
27 */ | |
28 protected $authProviders; | |
29 | |
30 /** | |
31 * Creates a new ConfigDependencies instance. | |
32 * | |
33 * @param string[] $format_providers | |
34 * The serialization format providers, keyed by format. | |
35 * @param string[] $auth_providers | |
36 * The authentication providers, keyed by ID. | |
37 */ | |
38 public function __construct(array $format_providers, array $auth_providers) { | |
39 $this->formatProviders = $format_providers; | |
40 $this->authProviders = $auth_providers; | |
41 } | |
42 | |
43 /** | |
44 * {@inheritdoc} | |
45 */ | |
46 public static function create(ContainerInterface $container) { | |
47 return new static( | |
48 $container->getParameter('serializer.format_providers'), | |
49 $container->getParameter('authentication_providers') | |
50 ); | |
51 } | |
52 | |
53 /** | |
54 * Calculates dependencies of a specific rest resource configuration. | |
55 * | |
56 * This function returns dependencies in a non-sorted, non-unique manner. It | |
57 * is therefore the caller's responsibility to sort and remove duplicates | |
58 * from the result prior to saving it with the configuration or otherwise | |
59 * using it in a way that requires that. For example, | |
60 * \Drupal\rest\Entity\RestResourceConfig::calculateDependencies() does this | |
61 * via its \Drupal\Core\Entity\DependencyTrait::addDependency() method. | |
62 * | |
63 * @param \Drupal\rest\RestResourceConfigInterface $rest_config | |
64 * The rest configuration. | |
65 * | |
66 * @return string[][] | |
67 * Dependencies keyed by dependency type. | |
68 * | |
69 * @see \Drupal\rest\Entity\RestResourceConfig::calculateDependencies() | |
70 */ | |
71 public function calculateDependencies(RestResourceConfigInterface $rest_config) { | |
72 $granularity = $rest_config->get('granularity'); | |
73 | |
74 // Dependency calculation is the same for either granularity, the most | |
75 // notable difference is that for the 'resource' granularity, the same | |
76 // authentication providers and formats are supported for every method. | |
77 switch ($granularity) { | |
78 case RestResourceConfigInterface::METHOD_GRANULARITY: | |
79 $methods = $rest_config->getMethods(); | |
80 break; | |
81 case RestResourceConfigInterface::RESOURCE_GRANULARITY: | |
82 $methods = array_slice($rest_config->getMethods(), 0, 1); | |
83 break; | |
84 default: | |
85 throw new \InvalidArgumentException('Invalid granularity specified.'); | |
86 } | |
87 | |
88 // The dependency lists for authentication providers and formats | |
89 // generated on container build. | |
90 $dependencies = []; | |
91 foreach ($methods as $request_method) { | |
92 // Add dependencies based on the supported authentication providers. | |
93 foreach ($rest_config->getAuthenticationProviders($request_method) as $auth) { | |
94 if (isset($this->authProviders[$auth])) { | |
95 $module_name = $this->authProviders[$auth]; | |
96 $dependencies['module'][] = $module_name; | |
97 } | |
98 } | |
99 // Add dependencies based on the supported authentication formats. | |
100 foreach ($rest_config->getFormats($request_method) as $format) { | |
101 if (isset($this->formatProviders[$format])) { | |
102 $module_name = $this->formatProviders[$format]; | |
103 $dependencies['module'][] = $module_name; | |
104 } | |
105 } | |
106 } | |
107 | |
108 return $dependencies; | |
109 } | |
110 | |
111 /** | |
112 * Informs the entity that entities it depends on will be deleted. | |
113 * | |
114 * @param \Drupal\rest\RestResourceConfigInterface $rest_config | |
115 * The rest configuration. | |
116 * @param array $dependencies | |
117 * An array of dependencies that will be deleted keyed by dependency type. | |
118 * Dependency types are, for example, entity, module and theme. | |
119 * | |
120 * @return bool | |
121 * TRUE if the entity has been changed as a result, FALSE if not. | |
122 * | |
123 * @see \Drupal\Core\Config\Entity\ConfigEntityInterface::onDependencyRemoval() | |
124 */ | |
125 public function onDependencyRemoval(RestResourceConfigInterface $rest_config, array $dependencies) { | |
126 $granularity = $rest_config->get('granularity'); | |
127 switch ($granularity) { | |
128 case RestResourceConfigInterface::METHOD_GRANULARITY: | |
129 return $this->onDependencyRemovalForMethodGranularity($rest_config, $dependencies); | |
130 case RestResourceConfigInterface::RESOURCE_GRANULARITY: | |
131 return $this->onDependencyRemovalForResourceGranularity($rest_config, $dependencies); | |
132 default: | |
133 throw new \InvalidArgumentException('Invalid granularity specified.'); | |
134 } | |
135 } | |
136 | |
137 /** | |
138 * Informs the entity that entities it depends on will be deleted. | |
139 * | |
140 * @param \Drupal\rest\RestResourceConfigInterface $rest_config | |
141 * The rest configuration. | |
142 * @param array $dependencies | |
143 * An array of dependencies that will be deleted keyed by dependency type. | |
144 * Dependency types are, for example, entity, module and theme. | |
145 * | |
146 * @return bool | |
147 * TRUE if the entity has been changed as a result, FALSE if not. | |
148 */ | |
149 protected function onDependencyRemovalForMethodGranularity(RestResourceConfigInterface $rest_config, array $dependencies) { | |
150 $changed = FALSE; | |
151 // Only module-related dependencies can be fixed. All other types of | |
152 // dependencies cannot, because they were not generated based on supported | |
153 // authentication providers or formats. | |
154 if (isset($dependencies['module'])) { | |
155 // Try to fix dependencies. | |
156 $removed_auth = array_keys(array_intersect($this->authProviders, $dependencies['module'])); | |
157 $removed_formats = array_keys(array_intersect($this->formatProviders, $dependencies['module'])); | |
158 $configuration_before = $configuration = $rest_config->get('configuration'); | |
159 if (!empty($removed_auth) || !empty($removed_formats)) { | |
160 // Try to fix dependency problems by removing affected | |
161 // authentication providers and formats. | |
162 foreach (array_keys($rest_config->get('configuration')) as $request_method) { | |
163 foreach ($removed_formats as $format) { | |
164 if (in_array($format, $rest_config->getFormats($request_method), TRUE)) { | |
165 $configuration[$request_method]['supported_formats'] = array_diff($configuration[$request_method]['supported_formats'], $removed_formats); | |
166 } | |
167 } | |
168 foreach ($removed_auth as $auth) { | |
169 if (in_array($auth, $rest_config->getAuthenticationProviders($request_method), TRUE)) { | |
170 $configuration[$request_method]['supported_auth'] = array_diff($configuration[$request_method]['supported_auth'], $removed_auth); | |
171 } | |
172 } | |
173 if (empty($configuration[$request_method]['supported_auth'])) { | |
174 // Remove the key if there are no more authentication providers | |
175 // supported by this request method. | |
176 unset($configuration[$request_method]['supported_auth']); | |
177 } | |
178 if (empty($configuration[$request_method]['supported_formats'])) { | |
179 // Remove the key if there are no more formats supported by this | |
180 // request method. | |
181 unset($configuration[$request_method]['supported_formats']); | |
182 } | |
183 if (empty($configuration[$request_method])) { | |
184 // Remove the request method altogether if it no longer has any | |
185 // supported authentication providers or formats. | |
186 unset($configuration[$request_method]); | |
187 } | |
188 } | |
189 } | |
190 if ($configuration_before != $configuration && !empty($configuration)) { | |
191 $rest_config->set('configuration', $configuration); | |
192 // Only mark the dependencies problems as fixed if there is any | |
193 // configuration left. | |
194 $changed = TRUE; | |
195 } | |
196 } | |
197 // If the dependency problems are not marked as fixed at this point they | |
198 // should be related to the resource plugin and the config entity should | |
199 // be deleted. | |
200 return $changed; | |
201 } | |
202 | |
203 /** | |
204 * Informs the entity that entities it depends on will be deleted. | |
205 * | |
206 * @param \Drupal\rest\RestResourceConfigInterface $rest_config | |
207 * The rest configuration. | |
208 * @param array $dependencies | |
209 * An array of dependencies that will be deleted keyed by dependency type. | |
210 * Dependency types are, for example, entity, module and theme. | |
211 * | |
212 * @return bool | |
213 * TRUE if the entity has been changed as a result, FALSE if not. | |
214 */ | |
215 protected function onDependencyRemovalForResourceGranularity(RestResourceConfigInterface $rest_config, array $dependencies) { | |
216 $changed = FALSE; | |
217 // Only module-related dependencies can be fixed. All other types of | |
218 // dependencies cannot, because they were not generated based on supported | |
219 // authentication providers or formats. | |
220 if (isset($dependencies['module'])) { | |
221 // Try to fix dependencies. | |
222 $removed_auth = array_keys(array_intersect($this->authProviders, $dependencies['module'])); | |
223 $removed_formats = array_keys(array_intersect($this->formatProviders, $dependencies['module'])); | |
224 $configuration_before = $configuration = $rest_config->get('configuration'); | |
225 if (!empty($removed_auth) || !empty($removed_formats)) { | |
226 // All methods support the same formats and authentication providers, so | |
227 // get those for whichever the first listed method is. | |
228 $first_method = $rest_config->getMethods()[0]; | |
229 | |
230 // Try to fix dependency problems by removing affected | |
231 // authentication providers and formats. | |
232 foreach ($removed_formats as $format) { | |
233 if (in_array($format, $rest_config->getFormats($first_method), TRUE)) { | |
234 $configuration['formats'] = array_diff($configuration['formats'], $removed_formats); | |
235 } | |
236 } | |
237 foreach ($removed_auth as $auth) { | |
238 if (in_array($auth, $rest_config->getAuthenticationProviders($first_method), TRUE)) { | |
239 $configuration['authentication'] = array_diff($configuration['authentication'], $removed_auth); | |
240 } | |
241 } | |
242 if (empty($configuration['authentication'])) { | |
243 // Remove the key if there are no more authentication providers | |
244 // supported. | |
245 unset($configuration['authentication']); | |
246 } | |
247 if (empty($configuration['formats'])) { | |
248 // Remove the key if there are no more formats supported. | |
249 unset($configuration['formats']); | |
250 } | |
251 if (empty($configuration['authentication']) || empty($configuration['formats'])) { | |
252 // If there no longer are any supported authentication providers or | |
253 // formats, this REST resource can no longer function, and so we | |
254 // cannot fix this config entity to keep it working. | |
255 $configuration = []; | |
256 } | |
257 } | |
258 if ($configuration_before != $configuration && !empty($configuration)) { | |
259 $rest_config->set('configuration', $configuration); | |
260 // Only mark the dependencies problems as fixed if there is any | |
261 // configuration left. | |
262 $changed = TRUE; | |
263 } | |
264 } | |
265 // If the dependency problems are not marked as fixed at this point they | |
266 // should be related to the resource plugin and the config entity should | |
267 // be deleted. | |
268 return $changed; | |
269 } | |
270 | |
271 } |