You are here

class CacheDecoratedResource in RESTful 7.2

Hierarchy

Expanded class hierarchy of CacheDecoratedResource

6 files declare their use of CacheDecoratedResource
CacheFragmentController.php in src/RenderCache/Entity/CacheFragmentController.php
Contains \Drupal\restful\RenderCache\Entity\CacheFragmentController.
DataProvider.php in src/Plugin/resource/DataProvider/DataProvider.php
Contains \Drupal\restful\Plugin\resource\DataProvider\DataProvider.
DataProviderDbQuery.php in src/Plugin/resource/DataProvider/DataProviderDbQuery.php
Contains \Drupal\restful\Plugin\resource\DataProvider\DataProviderDbQuery.
DataProviderEntity.php in src/Plugin/resource/DataProvider/DataProviderEntity.php
Contains \Drupal\restful\Plugin\resource\DataProvider\DataProviderEntity.
restful.entity.inc in ./restful.entity.inc
Contains entity related code.

... See full list

File

src/Plugin/resource/Decorators/CacheDecoratedResource.php, line 18
Contains \Drupal\restful\Plugin\resource\Decorators\CacheDecoratedResource

Namespace

Drupal\restful\Plugin\resource\Decorators
View source
class CacheDecoratedResource extends ResourceDecoratorBase implements CacheDecoratedResourceInterface {

  /**
   * Separator string for cache fragment key value pairs.
   */
  const CACHE_PAIR_SEPARATOR = '#';

  /**
   * Cache controller object.
   *
   * @var \DrupalCacheInterface
   */
  protected $cacheController;

  /**
   * The data provider.
   *
   * @var DataProviderInterface
   */
  protected $dataProvider;

  /**
   * Constructs a Drupal\Component\Plugin\PluginBase object.
   *
   * @param ResourceInterface $subject
   *   The decorated object.
   * @param \DrupalCacheInterface $cache_controller
   *   Injected cache manager.
   */
  public function __construct(ResourceInterface $subject, \DrupalCacheInterface $cache_controller = NULL) {

    // TODO: Implement the ResourceManager factory to use the CacheDecoratedResource.
    $this->subject = $subject;
    $this->cacheController = $cache_controller ? $cache_controller : $this
      ->newCacheObject();
    $cache_info = $this
      ->defaultCacheInfo();
    $this->pluginDefinition['renderCache'] = $cache_info;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheController() {
    return $this->cacheController;
  }

  /**
   * Get the default cache object based on the plugin configuration.
   *
   * By default, this returns an instance of the DrupalDatabaseCache class.
   * Classes implementing DrupalCacheInterface can register themselves both as a
   * default implementation and for specific bins.
   *
   * @return \DrupalCacheInterface
   *   The cache object associated with the specified bin.
   *
   * @see \DrupalCacheInterface
   * @see _cache_get_object()
   */
  protected function newCacheObject() {

    // We do not use drupal_static() here because we do not want to change the
    // storage of a cache bin mid-request.
    static $cache_object;
    if (isset($cache_object)) {

      // Return cached object.
      return $cache_object;
    }
    $cache_info = $this
      ->defaultCacheInfo();
    $class_name = empty($cache_info['class']) ? NULL : $cache_info['class'];

    // If there is no class name in the plugin definition, try to get it from
    // the variables.
    if (empty($class_name)) {
      $class_name = variable_get('cache_class_' . $cache_info['bin']);
    }

    // If it is still empty, then default to drupal's default cache class.
    if (empty($class_name)) {
      $class_name = variable_get('cache_default_class', 'DrupalDatabaseCache');
    }
    $cache_object = new $class_name($cache_info['bin']);
    return $cache_object;
  }

  /**
   * {@inheritdoc}
   */
  public function dataProviderFactory() {
    if ($this->dataProvider && $this->dataProvider instanceof CacheDecoratedDataProvider) {
      return $this->dataProvider;
    }

    // Get the data provider from the subject of the decorator.
    $decorated_provider = $this->subject
      ->dataProviderFactory();
    $this->dataProvider = new CacheDecoratedDataProvider($decorated_provider, $this
      ->getCacheController());
    $plugin_definition = $this
      ->getPluginDefinition();
    $this->dataProvider
      ->addOptions(array(
      'renderCache' => $this
        ->defaultCacheInfo(),
      'resource' => array(
        'version' => array(
          'major' => $plugin_definition['majorVersion'],
          'minor' => $plugin_definition['minorVersion'],
        ),
        'name' => $plugin_definition['resource'],
      ),
    ));
    return $this->dataProvider;
  }

  /**
   * {@inheritdoc}
   */
  public function getPath() {
    return $this->subject
      ->getPath();
  }

  /**
   * {@inheritdoc}
   */
  public function setPath($path) {
    $this->subject
      ->setPath($path);
  }

  /**
   * {@inheritdoc}
   */
  public function getFieldDefinitions() {
    return $this->subject
      ->getFieldDefinitions();
  }

  /**
   * {@inheritdoc}
   */
  public function getDataProvider() {
    if (isset($this->dataProvider)) {
      return $this->dataProvider;
    }
    $this->dataProvider = $this
      ->dataProviderFactory();
    return $this->dataProvider;
  }

  /**
   * {@inheritdoc}
   */
  public function setDataProvider(DataProviderInterface $data_provider = NULL) {
    $this->dataProvider = $data_provider;
  }

  /**
   * {@inheritdoc}
   */
  public function process() {
    $path = $this
      ->getPath();
    return ResourceManager::executeCallback($this
      ->getControllerFromPath($path), array(
      $path,
    ));
  }

  /**
   * {@inheritdoc}
   */
  public function view($path) {

    // TODO: This is duplicating the code from Resource::view
    $ids = explode(static::IDS_SEPARATOR, $path);

    // REST requires a canonical URL for every resource.
    $canonical_path = $this
      ->getDataProvider()
      ->canonicalPath($path);
    $this
      ->getRequest()
      ->getHeaders()
      ->add(HttpHeader::create('Link', $this
      ->versionedUrl($canonical_path, array(), FALSE) . '; rel="canonical"'));

    // If there is only one ID then use 'view'. Else, use 'viewMultiple'. The
    // difference between the two is that 'view' allows access denied
    // exceptions.
    if (count($ids) == 1) {
      return array(
        $this
          ->getDataProvider()
          ->view($ids[0]),
      );
    }
    else {
      return $this
        ->getDataProvider()
        ->viewMultiple($ids);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function index($path) {

    // TODO: This is duplicating the code from Resource::index
    return $this
      ->getDataProvider()
      ->index();
  }

  /**
   * {@inheritdoc}
   */
  public function update($path) {
    $this
      ->invalidateResourceCache($path);

    // Update according to the decorated.
    return $this->subject
      ->update($path);
  }

  /**
   * {@inheritdoc}
   */
  public function replace($path) {
    $this
      ->invalidateResourceCache($path);

    // Update according to the decorated.
    return $this->subject
      ->replace($path);
  }

  /**
   * {@inheritdoc}
   */
  public function remove($path) {
    $this
      ->invalidateResourceCache($path);
    $this->subject
      ->remove($path);
  }

  /**
   * Gets the default cache info.
   *
   * @return array
   *   The cache info.
   */
  protected function defaultCacheInfo() {
    $plugin_definition = $this
      ->getPluginDefinition();
    $cache_info = empty($plugin_definition['renderCache']) ? array() : $plugin_definition['renderCache'];
    $cache_info += array(
      'render' => variable_get('restful_render_cache', FALSE),
      'class' => NULL,
      'bin' => RenderCache::CACHE_BIN,
      'expire' => CACHE_PERMANENT,
      'simpleInvalidate' => TRUE,
      'granularity' => DRUPAL_CACHE_PER_USER,
    );
    return $cache_info;
  }

  /**
   * {@inheritdoc}
   */
  public function getResourceMachineName() {
    return $this->subject
      ->getResourceMachineName();
  }

  /**
   * {@inheritdoc}
   *
   * This is a decorated resource, get proxy the call until you reach the
   * annotated resource.
   */
  public function getPluginDefinition() {
    return $this->subject
      ->getPluginDefinition();
  }

  /**
   * {@inheritdoc}
   */
  public function enable() {
    $this->subject
      ->enable();
  }

  /**
   * {@inheritdoc}
   */
  public function disable() {
    $this->subject
      ->disable();
  }

  /**
   * {@inheritdoc}
   */
  public function isEnabled() {
    return $this->subject
      ->isEnabled();
  }

  /**
   * {@inheritdoc}
   */
  public function hasSimpleInvalidation() {
    $data_provider = $this
      ->getDataProvider();
    $options = $data_provider
      ->getOptions();
    $cache_info = $options['renderCache'];
    return !empty($cache_info['simpleInvalidate']);
  }

  /**
   * Invalidates the resource cache for the given resource on the provided id.
   *
   * @param string $id
   *   The id.
   */
  protected function invalidateResourceCache($id) {

    // Invalidate the render cache for this resource.
    $query = new \EntityFieldQuery();
    $canonical_id = $this
      ->getDataProvider()
      ->canonicalPath($id);
    $query
      ->entityCondition('entity_type', 'cache_fragment')
      ->propertyCondition('type', 'resource')
      ->propertyCondition('value', $this::serializeKeyValue($this
      ->getResourceName(), $canonical_id));
    foreach (CacheFragmentController::lookUpHashes($query) as $hash) {
      $this
        ->getCacheController()
        ->clear($hash);
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function serializeKeyValue($key, $value) {
    return sprintf('%s%s%s', $key, static::CACHE_PAIR_SEPARATOR, $value);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CacheDecoratedResource::$cacheController protected property Cache controller object.
CacheDecoratedResource::$dataProvider protected property The data provider.
CacheDecoratedResource::CACHE_PAIR_SEPARATOR constant Separator string for cache fragment key value pairs.
CacheDecoratedResource::dataProviderFactory public function Data provider factory. Overrides ResourceDecoratorBase::dataProviderFactory
CacheDecoratedResource::defaultCacheInfo protected function Gets the default cache info.
CacheDecoratedResource::disable public function Disable the resource. Overrides ResourceDecoratorBase::disable
CacheDecoratedResource::enable public function Enable the resource. Overrides ResourceDecoratorBase::enable
CacheDecoratedResource::getCacheController public function Getter for $cacheController. Overrides CacheDecoratedResourceInterface::getCacheController
CacheDecoratedResource::getDataProvider public function Gets the data provider. Overrides ResourceDecoratorBase::getDataProvider
CacheDecoratedResource::getFieldDefinitions public function Gets the field definitions. Overrides ResourceDecoratorBase::getFieldDefinitions
CacheDecoratedResource::getPath public function Gets the path of the resource. Overrides ResourceDecoratorBase::getPath
CacheDecoratedResource::getPluginDefinition public function This is a decorated resource, get proxy the call until you reach the annotated resource. Overrides ResourceDecoratorBase::getPluginDefinition
CacheDecoratedResource::getResourceMachineName public function Gets the resource machine name. Overrides ResourceDecoratorBase::getResourceMachineName
CacheDecoratedResource::hasSimpleInvalidation public function Checks if simple invalidation is enabled for this resource. Overrides CacheDecoratedResourceInterface::hasSimpleInvalidation
CacheDecoratedResource::index public function Basic implementation for listing. Overrides ResourceDecoratorBase::index
CacheDecoratedResource::invalidateResourceCache protected function Invalidates the resource cache for the given resource on the provided id.
CacheDecoratedResource::isEnabled public function Checks if the resource is enabled. Overrides ResourceDecoratorBase::isEnabled
CacheDecoratedResource::newCacheObject protected function Get the default cache object based on the plugin configuration.
CacheDecoratedResource::process public function Controller function that passes the data along and executes right action. Overrides ResourceDecoratorBase::process
CacheDecoratedResource::remove public function Basic implementation for update. Overrides ResourceDecoratorBase::remove
CacheDecoratedResource::replace public function Basic implementation for update. Overrides ResourceDecoratorBase::replace
CacheDecoratedResource::serializeKeyValue public static function Generates a serialized key value pair. Overrides CacheDecoratedResourceInterface::serializeKeyValue
CacheDecoratedResource::setDataProvider public function Sets the data provider. Overrides ResourceDecoratorBase::setDataProvider
CacheDecoratedResource::setPath public function Sets the path of the resource. Overrides ResourceDecoratorBase::setPath
CacheDecoratedResource::update public function Basic implementation for update. Overrides ResourceDecoratorBase::update
CacheDecoratedResource::view public function Basic implementation for view. Overrides ResourceDecoratorBase::view
CacheDecoratedResource::__construct public function Constructs a Drupal\Component\Plugin\PluginBase object.
ResourceDecoratorBase::$subject protected property The decorated resource.
ResourceDecoratorBase::access public function Determine if user can access the handler. Overrides ResourceInterface::access
ResourceDecoratorBase::calculateDependencies public function
ResourceDecoratorBase::controllersInfo public function Gets the controllers. Overrides ResourceInterface::controllersInfo
ResourceDecoratorBase::create public function Basic implementation for create. Overrides ResourceInterface::create
ResourceDecoratorBase::defaultConfiguration public function
ResourceDecoratorBase::discover public function Discovery controller callback. Overrides ResourceInterface::discover
ResourceDecoratorBase::doDelete public function Shorthand method to perform a quick DELETE request. Overrides ResourceInterface::doDelete
ResourceDecoratorBase::doGet public function Shorthand method to perform a quick GET request. Overrides ResourceInterface::doGet
ResourceDecoratorBase::doPatch public function Shorthand method to perform a quick PATCH request. Overrides ResourceInterface::doPatch
ResourceDecoratorBase::doPost public function Shorthand method to perform a quick POST request. Overrides ResourceInterface::doPost
ResourceDecoratorBase::doPut public function Shorthand method to perform a quick PUT request. Overrides ResourceInterface::doPut
ResourceDecoratorBase::doWrite private function
ResourceDecoratorBase::getAccount public function Get the user from for request. Overrides ResourceInterface::getAccount
ResourceDecoratorBase::getConfiguration public function
ResourceDecoratorBase::getControllerFromPath public function Return the controller for a given path. Overrides ResourceInterface::getControllerFromPath
ResourceDecoratorBase::getControllers public function Gets the controllers for this resource. Overrides ResourceInterface::getControllers
ResourceDecoratorBase::getDecoratedResource public function Gets the decorated resource. Overrides ResourceDecoratorInterface::getDecoratedResource
ResourceDecoratorBase::getPluginId public function
ResourceDecoratorBase::getPrimaryResource public function Gets the primary resource, the one that is not a decorator. Overrides ResourceDecoratorInterface::getPrimaryResource
ResourceDecoratorBase::getRequest public function Get the request object. Overrides ResourceInterface::getRequest
ResourceDecoratorBase::getResourceName public function Gets the resource name. Overrides ResourceInterface::getResourceName
ResourceDecoratorBase::getUrl public function Helper method; Get the URL of the resource and query strings. Overrides ResourceInterface::getUrl
ResourceDecoratorBase::getVersion public function Return array keyed with the major and minor version of the resource. Overrides ResourceInterface::getVersion
ResourceDecoratorBase::isInstanceOf public function Checks if the decorated object is an instance of something. Overrides ExplorableDecoratorInterface::isInstanceOf
ResourceDecoratorBase::setAccount public function Overrides ResourceInterface::setAccount 1
ResourceDecoratorBase::setConfiguration public function
ResourceDecoratorBase::setFieldDefinitions public function Sets the field definitions. Overrides ResourceInterface::setFieldDefinitions
ResourceDecoratorBase::setPluginDefinition public function This is a decorated resource, set proxy the request until you reach the annotated resource. Overrides ResourceInterface::setPluginDefinition
ResourceDecoratorBase::setRequest public function Sets the request object. Overrides ResourceInterface::setRequest
ResourceDecoratorBase::switchUserBack public function Switches the user back from the original user for the session. Overrides ResourceInterface::switchUserBack
ResourceDecoratorBase::versionedUrl public function Gets a resource URL based on the current version. Overrides ResourceInterface::versionedUrl
ResourceDecoratorBase::__call public function If any method not declared, then defer it to the decorated field.
ResourceInterface::IDS_SEPARATOR constant The string that separates multiple ids.