Upgraded drupal core with security updates
[yaffs-website] / web / core / modules / rest / src / Entity / RestResourceConfig.php
1 <?php
2
3 namespace Drupal\rest\Entity;
4
5 use Drupal\Core\Config\Entity\ConfigEntityBase;
6 use Drupal\Core\Entity\EntityStorageInterface;
7 use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection;
8 use Drupal\rest\RestResourceConfigInterface;
9
10 /**
11  * Defines a RestResourceConfig configuration entity class.
12  *
13  * @ConfigEntityType(
14  *   id = "rest_resource_config",
15  *   label = @Translation("REST resource configuration"),
16  *   config_prefix = "resource",
17  *   admin_permission = "administer rest resources",
18  *   label_callback = "getLabelFromPlugin",
19  *   entity_keys = {
20  *     "id" = "id"
21  *   },
22  *   config_export = {
23  *     "id",
24  *     "plugin_id",
25  *     "granularity",
26  *     "configuration"
27  *   }
28  * )
29  */
30 class RestResourceConfig extends ConfigEntityBase implements RestResourceConfigInterface {
31
32   /**
33    * The REST resource config id.
34    *
35    * @var string
36    */
37   protected $id;
38
39   /**
40    * The REST resource plugin id.
41    *
42    * @var string
43    */
44   protected $plugin_id;
45
46   /**
47    * The REST resource configuration granularity.
48    *
49    * Currently either:
50    * - \Drupal\rest\RestResourceConfigInterface::METHOD_GRANULARITY
51    * - \Drupal\rest\RestResourceConfigInterface::RESOURCE_GRANULARITY
52    *
53    * @var string
54    */
55   protected $granularity;
56
57   /**
58    * The REST resource configuration.
59    *
60    * @var array
61    */
62   protected $configuration;
63
64   /**
65    * The rest resource plugin manager.
66    *
67    * @var \Drupal\Component\Plugin\PluginManagerInterface
68    */
69   protected $pluginManager;
70
71   /**
72    * {@inheritdoc}
73    */
74   public function __construct(array $values, $entity_type) {
75     parent::__construct($values, $entity_type);
76     // The config entity id looks like the plugin id but uses __ instead of :
77     // because : is not valid for config entities.
78     if (!isset($this->plugin_id) && isset($this->id)) {
79       // Generate plugin_id on first entity creation.
80       $this->plugin_id = str_replace('.', ':', $this->id);
81     }
82   }
83
84   /**
85    * The label callback for this configuration entity.
86    *
87    * @return string The label.
88    */
89   protected function getLabelFromPlugin() {
90     $plugin_definition = $this->getResourcePluginManager()
91       ->getDefinition(['id' => $this->plugin_id]);
92     return $plugin_definition['label'];
93   }
94
95   /**
96    * Returns the resource plugin manager.
97    *
98    * @return \Drupal\Component\Plugin\PluginManagerInterface
99    */
100   protected function getResourcePluginManager() {
101     if (!isset($this->pluginManager)) {
102       $this->pluginManager = \Drupal::service('plugin.manager.rest');
103     }
104     return $this->pluginManager;
105   }
106
107   /**
108    * {@inheritdoc}
109    */
110   public function getResourcePlugin() {
111     return $this->getPluginCollections()['resource']->get($this->plugin_id);
112   }
113
114   /**
115    * {@inheritdoc}
116    */
117   public function getMethods() {
118     switch ($this->granularity) {
119       case RestResourceConfigInterface::METHOD_GRANULARITY:
120         return $this->getMethodsForMethodGranularity();
121       case RestResourceConfigInterface::RESOURCE_GRANULARITY:
122         return $this->configuration['methods'];
123       default:
124         throw new \InvalidArgumentException('Invalid granularity specified.');
125     }
126   }
127
128   /**
129    * Retrieves a list of supported HTTP methods for this resource.
130    *
131    * @return string[]
132    *   A list of supported HTTP methods.
133    */
134   protected function getMethodsForMethodGranularity() {
135     $methods = array_keys($this->configuration);
136     return array_map([$this, 'normalizeRestMethod'], $methods);
137   }
138
139   /**
140    * {@inheritdoc}
141    */
142   public function getAuthenticationProviders($method) {
143     switch ($this->granularity) {
144       case RestResourceConfigInterface::METHOD_GRANULARITY:
145         return $this->getAuthenticationProvidersForMethodGranularity($method);
146       case RestResourceConfigInterface::RESOURCE_GRANULARITY:
147         return $this->configuration['authentication'];
148       default:
149         throw new \InvalidArgumentException('Invalid granularity specified.');
150     }
151   }
152
153   /**
154    * Retrieves a list of supported authentication providers.
155    *
156    * @param string $method
157    *   The request method e.g GET or POST.
158    *
159    * @return string[]
160    *   A list of supported authentication provider IDs.
161    */
162   public function getAuthenticationProvidersForMethodGranularity($method) {
163     $method = $this->normalizeRestMethod($method);
164     if (in_array($method, $this->getMethods()) && isset($this->configuration[$method]['supported_auth'])) {
165       return $this->configuration[$method]['supported_auth'];
166     }
167     return [];
168   }
169
170   /**
171    * {@inheritdoc}
172    */
173   public function getFormats($method) {
174     switch ($this->granularity) {
175       case RestResourceConfigInterface::METHOD_GRANULARITY:
176         return $this->getFormatsForMethodGranularity($method);
177       case RestResourceConfigInterface::RESOURCE_GRANULARITY:
178         return $this->configuration['formats'];
179       default:
180         throw new \InvalidArgumentException('Invalid granularity specified.');
181     }
182   }
183
184   /**
185    * Retrieves a list of supported response formats.
186    *
187    * @param string $method
188    *   The request method e.g GET or POST.
189    *
190    * @return string[]
191    *   A list of supported format IDs.
192    */
193   protected function getFormatsForMethodGranularity($method) {
194     $method = $this->normalizeRestMethod($method);
195     if (in_array($method, $this->getMethods()) && isset($this->configuration[$method]['supported_formats'])) {
196       return $this->configuration[$method]['supported_formats'];
197     }
198     return [];
199   }
200
201   /**
202    * {@inheritdoc}
203    */
204   public function getPluginCollections() {
205     return [
206       'resource' => new DefaultSingleLazyPluginCollection($this->getResourcePluginManager(), $this->plugin_id, [])
207     ];
208   }
209
210   /**
211    * (@inheritdoc)
212    */
213   public function calculateDependencies() {
214     parent::calculateDependencies();
215
216     foreach ($this->getRestResourceDependencies()->calculateDependencies($this) as $type => $dependencies) {
217       foreach ($dependencies as $dependency) {
218         $this->addDependency($type, $dependency);
219       }
220     }
221     return $this;
222   }
223
224   /**
225    * {@inheritdoc}
226    */
227   public function onDependencyRemoval(array $dependencies) {
228     $parent = parent::onDependencyRemoval($dependencies);
229
230     // If the dependency problems are not marked as fixed at this point they
231     // should be related to the resource plugin and the config entity should
232     // be deleted.
233     $changed = $this->getRestResourceDependencies()->onDependencyRemoval($this, $dependencies);
234     return $parent || $changed;
235   }
236
237   /**
238    * Returns the REST resource dependencies.
239    *
240    * @return \Drupal\rest\Entity\ConfigDependencies
241    */
242   protected function getRestResourceDependencies() {
243     return \Drupal::service('class_resolver')->getInstanceFromDefinition(ConfigDependencies::class);
244   }
245
246   /**
247    * Normalizes the method.
248    *
249    * @param string $method
250    *   The request method.
251    *
252    * @return string
253    *   The normalized request method.
254    */
255   protected function normalizeRestMethod($method) {
256     return strtoupper($method);
257   }
258
259   /**
260    * {@inheritdoc}
261    */
262   public function postSave(EntityStorageInterface $storage, $update = TRUE) {
263     parent::postSave($storage, $update);
264
265     \Drupal::service('router.builder')->setRebuildNeeded();
266   }
267
268   /**
269    * {@inheritdoc}
270    */
271   public static function postDelete(EntityStorageInterface $storage, array $entities) {
272     parent::postDelete($storage, $entities);
273
274     \Drupal::service('router.builder')->setRebuildNeeded();
275   }
276
277 }