Same name and namespace in other branches
  1. 8.9.x core/modules/rest/src/Plugin/ResourceBase.php \Drupal\rest\Plugin\ResourceBase
  2. 9 core/modules/rest/src/Plugin/ResourceBase.php \Drupal\rest\Plugin\ResourceBase

Common base class for resource plugins.

Note that this base class' implementation of the permissions() method generates a permission for every method for a resource. If your resource already has its own access control mechanism, you should opt out from this default permissions() method by overriding it.

Hierarchy

Expanded class hierarchy of ResourceBase

See also

\Drupal\rest\Annotation\RestResource

\Drupal\rest\Plugin\Type\ResourcePluginManager

\Drupal\rest\Plugin\ResourceInterface

Plugin API

Related topics

1 file declares its use of ResourceBase
RequestHandlerTest.php in core/modules/rest/tests/src/Kernel/RequestHandlerTest.php

File

core/modules/rest/src/Plugin/ResourceBase.php, line 27

Namespace

Drupal\rest\Plugin
View source
abstract class ResourceBase extends PluginBase implements ContainerFactoryPluginInterface, ResourceInterface {

  /**
   * The available serialization formats.
   *
   * @var array
   */
  protected $serializerFormats = [];

  /**
   * A logger instance.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * Constructs a Drupal\rest\Plugin\ResourceBase object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param array $serializer_formats
   *   The available serialization formats.
   * @param \Psr\Log\LoggerInterface $logger
   *   A logger instance.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, array $serializer_formats, LoggerInterface $logger) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->serializerFormats = $serializer_formats;
    $this->logger = $logger;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->getParameter('serializer.formats'), $container
      ->get('logger.factory')
      ->get('rest'));
  }

  /**
   * Implements ResourceInterface::permissions().
   *
   * Every plugin operation method gets its own user permission. Example:
   * "restful delete entity:node" with the title "Access DELETE on Node
   * resource".
   */
  public function permissions() {
    $permissions = [];
    $definition = $this
      ->getPluginDefinition();
    foreach ($this
      ->availableMethods() as $method) {
      $lowered_method = strtolower($method);
      $permissions["restful {$lowered_method} {$this->pluginId}"] = [
        'title' => $this
          ->t('Access @method on %label resource', [
          '@method' => $method,
          '%label' => $definition['label'],
        ]),
      ];
    }
    return $permissions;
  }

  /**
   * {@inheritdoc}
   */
  public function routes() {
    $collection = new RouteCollection();
    $definition = $this
      ->getPluginDefinition();
    $canonical_path = $definition['uri_paths']['canonical'] ?? '/' . strtr($this->pluginId, ':', '/') . '/{id}';
    $create_path = $definition['uri_paths']['create'] ?? '/' . strtr($this->pluginId, ':', '/');
    $route_name = strtr($this->pluginId, ':', '.');
    $methods = $this
      ->availableMethods();
    foreach ($methods as $method) {
      $path = $method === 'POST' ? $create_path : $canonical_path;
      $route = $this
        ->getBaseRoute($path, $method);

      // Note that '_format' and '_content_type_format' route requirements are
      // added in ResourceRoutes::getRoutesForResourceConfig().
      $collection
        ->add("{$route_name}.{$method}", $route);
    }
    return $collection;
  }

  /**
   * Provides predefined HTTP request methods.
   *
   * Plugins can override this method to provide additional custom request
   * methods.
   *
   * @return array
   *   The list of allowed HTTP request method strings.
   */
  protected function requestMethods() {
    return [
      'HEAD',
      'GET',
      'POST',
      'PUT',
      'DELETE',
      'TRACE',
      'OPTIONS',
      'CONNECT',
      'PATCH',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function availableMethods() {
    $methods = $this
      ->requestMethods();
    $available = [];
    foreach ($methods as $method) {

      // Only expose methods where the HTTP request method exists on the plugin.
      if (method_exists($this, strtolower($method))) {
        $available[] = $method;
      }
    }
    return $available;
  }

  /**
   * Gets the base route for a particular method.
   *
   * @param string $canonical_path
   *   The canonical path for the resource.
   * @param string $method
   *   The HTTP method to be used for the route.
   *
   * @return \Symfony\Component\Routing\Route
   *   The created base route.
   */
  protected function getBaseRoute($canonical_path, $method) {
    return new Route($canonical_path, [
      '_controller' => 'Drupal\\rest\\RequestHandler::handle',
    ], $this
      ->getBaseRouteRequirements($method), [], '', [], [
      $method,
    ]);
  }

  /**
   * Gets the base route requirements for a particular method.
   *
   * @param $method
   *   The HTTP method to be used for the route.
   *
   * @return array
   *   An array of requirements for parameters.
   */
  protected function getBaseRouteRequirements($method) {
    $lower_method = strtolower($method);

    // Every route MUST have requirements that result in the access manager
    // having access checks to check. If it does not, the route is made
    // inaccessible. So, we default to granting access to everyone. If a
    // permission exists, then we add that below. The access manager requires
    // that ALL access checks must grant access, so this still results in
    // correct behavior.
    $requirements = [
      '_access' => 'TRUE',
    ];

    // Only specify route requirements if the default permission exists. For any
    // more advanced route definition, resource plugins extending this base
    // class must override this method.
    $permission = "restful {$lower_method} {$this->pluginId}";
    if (isset($this
      ->permissions()[$permission])) {
      $requirements['_permission'] = $permission;
    }
    return $requirements;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property
DependencySerializationTrait::$_serviceIds protected property
DependencySerializationTrait::__sleep public function 2
DependencySerializationTrait::__wakeup public function 2
MessengerTrait::$messenger protected property The messenger. 10
MessengerTrait::messenger public function Gets the messenger. 10
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 2
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
ResourceBase::$logger protected property A logger instance.
ResourceBase::$serializerFormats protected property The available serialization formats.
ResourceBase::availableMethods public function Returns the available HTTP request methods on this plugin. Overrides ResourceInterface::availableMethods
ResourceBase::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create
ResourceBase::getBaseRoute protected function Gets the base route for a particular method.
ResourceBase::getBaseRouteRequirements protected function Gets the base route requirements for a particular method.
ResourceBase::permissions public function Implements ResourceInterface::permissions(). Overrides ResourceInterface::permissions
ResourceBase::requestMethods protected function Provides predefined HTTP request methods.
ResourceBase::routes public function Returns a collection of routes with URL path information for the resource. Overrides ResourceInterface::routes
ResourceBase::__construct public function Constructs a Drupal\rest\Plugin\ResourceBase object. Overrides PluginBase::__construct
StringTranslationTrait::$stringTranslation protected property The string translation service. 3
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 1
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.