class ResourceRoutes in Drupal 8
Same name and namespace in other branches
- 9 core/modules/rest/src/Routing/ResourceRoutes.php \Drupal\rest\Routing\ResourceRoutes
Subscriber for REST-style routes.
Hierarchy
- class \Drupal\rest\Routing\ResourceRoutes implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
Expanded class hierarchy of ResourceRoutes
1 string reference to 'ResourceRoutes'
- rest.services.yml in core/
modules/ rest/ rest.services.yml - core/modules/rest/rest.services.yml
1 service uses ResourceRoutes
- rest.resource_routes in core/
modules/ rest/ rest.services.yml - Drupal\rest\Routing\ResourceRoutes
File
- core/
modules/ rest/ src/ Routing/ ResourceRoutes.php, line 17
Namespace
Drupal\rest\RoutingView source
class ResourceRoutes implements EventSubscriberInterface {
/**
* The plugin manager for REST plugins.
*
* @var \Drupal\rest\Plugin\Type\ResourcePluginManager
*/
protected $manager;
/**
* The REST resource config storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $resourceConfigStorage;
/**
* A logger instance.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* Constructs a RouteSubscriber object.
*
* @param \Drupal\rest\Plugin\Type\ResourcePluginManager $manager
* The resource plugin manager.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
*/
public function __construct(ResourcePluginManager $manager, EntityTypeManagerInterface $entity_type_manager, LoggerInterface $logger) {
$this->manager = $manager;
$this->resourceConfigStorage = $entity_type_manager
->getStorage('rest_resource_config');
$this->logger = $logger;
}
/**
* Alters existing routes for a specific collection.
*
* @param \Drupal\Core\Routing\RouteBuildEvent $event
* The route build event.
*
* @return array
*/
public function onDynamicRouteEvent(RouteBuildEvent $event) {
// Iterate over all enabled REST resource config entities.
/** @var \Drupal\rest\RestResourceConfigInterface[] $resource_configs */
$resource_configs = $this->resourceConfigStorage
->loadMultiple();
foreach ($resource_configs as $resource_config) {
if ($resource_config
->status()) {
$resource_routes = $this
->getRoutesForResourceConfig($resource_config);
$event
->getRouteCollection()
->addCollection($resource_routes);
}
}
}
/**
* 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
// - that have an explicit method and allow >=1 format for that method
// - that exist for BC
// @see \Drupal\rest\RouteProcessor\RestResourceGetRouteProcessorBC
if ($methods && ($method = $methods[0]) && ($supported_formats = $rest_resource_config
->getFormats($method)) || $route
->hasOption('bc_route')) {
$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', [
'@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', [
'@id' => $rest_resource_config
->id(),
]);
continue;
}
// Remove BC routes for unsupported formats.
if ($route
->getOption('bc_route') === TRUE) {
$format_requirement = $route
->getRequirement('_format');
if ($format_requirement && !in_array($format_requirement, $rest_resource_config
->getFormats($method))) {
continue;
}
}
// The configuration has been validated, so we update the route to:
// - set the allowed response body content types/formats for methods
// that may send response bodies (unless hardcoded by the plugin)
// - set the allowed request body content types/formats for methods that
// allow request bodies to be sent (unless hardcoded by the plugin)
// - set the allowed authentication providers
if (in_array($method, [
'GET',
'HEAD',
'POST',
'PUT',
'PATCH',
], TRUE) && !$route
->hasRequirement('_format')) {
$route
->addRequirements([
'_format' => implode('|', $rest_resource_config
->getFormats($method)),
]);
}
if (in_array($method, [
'POST',
'PATCH',
'PUT',
], TRUE) && !$route
->hasRequirement('_content_type_format')) {
$route
->addRequirements([
'_content_type_format' => implode('|', $rest_resource_config
->getFormats($method)),
]);
}
$route
->setOption('_auth', $rest_resource_config
->getAuthenticationProviders($method));
$route
->setDefault('_rest_resource_config', $rest_resource_config
->id());
$parameters = $route
->getOption('parameters') ?: [];
$route
->setOption('parameters', $parameters + [
'_rest_resource_config' => [
'type' => 'entity:' . $rest_resource_config
->getEntityTypeId(),
],
]);
$collection
->add("rest.{$name}", $route);
}
}
return $collection;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[RoutingEvents::DYNAMIC] = 'onDynamicRouteEvent';
return $events;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ResourceRoutes:: |
protected | property | A logger instance. | |
ResourceRoutes:: |
protected | property | The plugin manager for REST plugins. | |
ResourceRoutes:: |
protected | property | The REST resource config storage. | |
ResourceRoutes:: |
protected | function | Provides all routes for a given REST resource config. | |
ResourceRoutes:: |
public static | function | Returns an array of event names this subscriber wants to listen to. | |
ResourceRoutes:: |
public | function | Alters existing routes for a specific collection. | |
ResourceRoutes:: |
public | function | Constructs a RouteSubscriber object. |