Example #1
0
 /**
  * Provides all routes for a given REST resource config.
  *
  * This method determines where a resource is reachable, what path
  * replacements are used, the required HTTP method for the operation etc.
  *
  * @param \Drupal\rest\RestResourceConfigInterface $rest_resource_config
  *   The rest resource config.
  *
  * @return \Symfony\Component\Routing\RouteCollection
  *   The route collection.
  */
 protected function getRoutesForResourceConfig(RestResourceConfigInterface $rest_resource_config)
 {
     $plugin = $rest_resource_config->getResourcePlugin();
     $collection = new RouteCollection();
     foreach ($plugin->routes() as $name => $route) {
         /** @var \Symfony\Component\Routing\Route $route */
         // @todo: Are multiple methods possible here?
         $methods = $route->getMethods();
         // Only expose routes where the method is enabled in the configuration.
         if ($methods && ($method = $methods[0]) && ($supported_formats = $rest_resource_config->getFormats($method))) {
             $route->setRequirement('_csrf_request_header_token', 'TRUE');
             // Check that authentication providers are defined.
             if (empty($rest_resource_config->getAuthenticationProviders($method))) {
                 $this->logger->error('At least one authentication provider must be defined for resource @id', array(':id' => $rest_resource_config->id()));
                 continue;
             }
             // Check that formats are defined.
             if (empty($rest_resource_config->getFormats($method))) {
                 $this->logger->error('At least one format must be defined for resource @id', array(':id' => $rest_resource_config->id()));
                 continue;
             }
             // If the route has a format requirement, then verify that the
             // resource has it.
             $format_requirement = $route->getRequirement('_format');
             if ($format_requirement && !in_array($format_requirement, $rest_resource_config->getFormats($method))) {
                 continue;
             }
             // The configuration seems legit at this point, so we set the
             // authentication provider and add the route.
             $route->setOption('_auth', $rest_resource_config->getAuthenticationProviders($method));
             $route->setDefault('_rest_resource_config', $rest_resource_config->id());
             $collection->add("rest.{$name}", $route);
         }
     }
     return $collection;
 }
 /**
  * Informs the entity that entities it depends on will be deleted.
  *
  * @param \Drupal\rest\RestResourceConfigInterface $rest_config
  *   The rest configuration.
  * @param array $dependencies
  *   An array of dependencies that will be deleted keyed by dependency type.
  *   Dependency types are, for example, entity, module and theme.
  *
  * @return bool
  *   TRUE if the entity has been changed as a result, FALSE if not.
  */
 protected function onDependencyRemovalForResourceGranularity(RestResourceConfigInterface $rest_config, array $dependencies)
 {
     $changed = FALSE;
     // Only module-related dependencies can be fixed. All other types of
     // dependencies cannot, because they were not generated based on supported
     // authentication providers or formats.
     if (isset($dependencies['module'])) {
         // Try to fix dependencies.
         $removed_auth = array_keys(array_intersect($this->authProviders, $dependencies['module']));
         $removed_formats = array_keys(array_intersect($this->formatProviders, $dependencies['module']));
         $configuration_before = $configuration = $rest_config->get('configuration');
         if (!empty($removed_auth) || !empty($removed_formats)) {
             // All methods support the same formats and authentication providers, so
             // get those for whichever the first listed method is.
             $first_method = $rest_config->getMethods()[0];
             // Try to fix dependency problems by removing affected
             // authentication providers and formats.
             foreach ($removed_formats as $format) {
                 if (in_array($format, $rest_config->getFormats($first_method), TRUE)) {
                     $configuration['formats'] = array_diff($configuration['formats'], $removed_formats);
                 }
             }
             foreach ($removed_auth as $auth) {
                 if (in_array($auth, $rest_config->getAuthenticationProviders($first_method), TRUE)) {
                     $configuration['authentication'] = array_diff($configuration['authentication'], $removed_auth);
                 }
             }
             if (empty($configuration['authentication'])) {
                 // Remove the key if there are no more authentication providers
                 // supported.
                 unset($configuration['authentication']);
             }
             if (empty($configuration['formats'])) {
                 // Remove the key if there are no more formats supported.
                 unset($configuration['formats']);
             }
             if (empty($configuration['authentication']) || empty($configuration['formats'])) {
                 // If there no longer are any supported authentication providers or
                 // formats, this REST resource can no longer function, and so we
                 // cannot fix this config entity to keep it working.
                 $configuration = [];
             }
         }
         if ($configuration_before != $configuration && !empty($configuration)) {
             $rest_config->set('configuration', $configuration);
             // Only mark the dependencies problems as fixed if there is any
             // configuration left.
             $changed = TRUE;
         }
     }
     // If the dependency problems are not marked as fixed at this point they
     // should be related to the resource plugin and the config entity should
     // be deleted.
     return $changed;
 }