You are here

class DataProviderPlug in RESTful 7.2

Class DataProviderPlug.

@package Drupal\restful\Plugin\resource\DataProvider

Hierarchy

Expanded class hierarchy of DataProviderPlug

File

src/Plugin/resource/DataProvider/DataProviderPlug.php, line 26
Contains \Drupal\restful\Plugin\resource\DataProvider\DataProviderPlug.

Namespace

Drupal\restful\Plugin\resource\DataProvider
View source
class DataProviderPlug extends DataProvider implements DataProviderInterface {

  /**
   * {@inheritdoc}
   */
  public function __construct(RequestInterface $request, ResourceFieldCollectionInterface $field_definitions, $account, $plugin_id, $resource_path = NULL, array $options = array(), $langcode = NULL) {
    parent::__construct($request, $field_definitions, $account, $plugin_id, $resource_path, $options, $langcode);
    if (empty($this->options['urlParams'])) {
      $this->options['urlParams'] = array(
        'filter' => TRUE,
        'sort' => TRUE,
        'fields' => TRUE,
      );
    }
  }

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

  /**
   * {@inheritdoc}
   */
  public function create($object) {
    throw new NotImplementedException('You cannot create plugins through the API.');
  }

  /**
   * {@inheritdoc}
   */
  public function view($identifier) {
    $resource_field_collection = $this
      ->initResourceFieldCollection($identifier);
    $input = $this
      ->getRequest()
      ->getParsedInput();
    $limit_fields = !empty($input['fields']) ? explode(',', $input['fields']) : array();
    foreach ($this->fieldDefinitions as $resource_field_name => $resource_field) {

      /* @var \Drupal\restful\Plugin\resource\Field\ResourceFieldInterface $resource_field */
      if ($limit_fields && !in_array($resource_field_name, $limit_fields)) {

        // Limit fields doesn't include this property.
        continue;
      }
      if (!$this
        ->methodAccess($resource_field) || !$resource_field
        ->access('view', $resource_field_collection
        ->getInterpreter())) {

        // The field does not apply to the current method or has denied
        // access.
        continue;
      }
      $resource_field_collection
        ->set($resource_field
        ->id(), $resource_field);
    }
    return $resource_field_collection;
  }

  /**
   * {@inheritdoc}
   */
  public function viewMultiple(array $identifiers) {
    $return = array();
    foreach ($identifiers as $identifier) {
      try {
        $row = $this
          ->view($identifier);
      } catch (InaccessibleRecordException $e) {
        $row = NULL;
      }
      $return[] = $row;
    }
    return array_values(array_filter($return));
  }

  /**
   * {@inheritdoc}
   */
  public function update($identifier, $object, $replace = FALSE) {

    // TODO: Document how to enable/disable resources using the API.
    $disabled_plugins = variable_get('restful_disabled_plugins', array());
    if ($object['enable']) {
      $disabled_plugins[$identifier] = FALSE;
    }
    variable_set('restful_disabled_plugins', $disabled_plugins);
  }

  /**
   * {@inheritdoc}
   */
  public function remove($identifier) {

    // TODO: Document how to enable/disable resources using the API.
    $disabled_plugins = variable_get('restful_disabled_plugins', array());
    $disabled_plugins[$identifier] = TRUE;
    variable_set('restful_disabled_plugins', $disabled_plugins);
  }

  /**
   * {@inheritdoc}
   */
  public function getIndexIds() {

    // Return all of the instance IDs.
    $plugins = restful()
      ->getResourceManager()
      ->getPlugins();
    $output = $plugins
      ->getIterator()
      ->getArrayCopy();

    // Apply filters.
    $output = $this
      ->applyFilters($output);
    $output = $this
      ->applySort($output);
    return array_keys($output);
  }

  /**
   * Removes plugins from the list based on the request options.
   *
   * @param \Drupal\restful\Plugin\resource\ResourceInterface[] $plugins
   *   The array of resource plugins keyed by instance ID.
   *
   * @return \Drupal\restful\Plugin\resource\ResourceInterface[]
   *   The same array minus the filtered plugins.
   */
  protected function applyFilters(array $plugins) {
    $resource_manager = restful()
      ->getResourceManager();
    $filters = $this
      ->parseRequestForListFilter();

    // If the 'all' option is not present, then add a filters to retrieve only
    // the last resource.
    $input = $this
      ->getRequest()
      ->getParsedInput();
    $all = !empty($input['all']);

    // Apply the filter to the list of plugins.
    foreach ($plugins as $instance_id => $plugin) {
      if (!$all) {

        // Remove the plugin if it's not the latest version.
        $version = $plugin
          ->getVersion();
        list($last_major, $last_minor) = $resource_manager
          ->getResourceLastVersion($plugin
          ->getResourceMachineName());
        if ($version['major'] != $last_major || $version['minor'] != $last_minor) {

          // We don't add the major and minor versions to filters because we
          // cannot depend on the presence of the versions as public fields.
          unset($plugins[$instance_id]);
          continue;
        }
      }

      // If the discovery is turned off for the resource, unset it.
      $definition = $plugin
        ->getPluginDefinition();
      if (!$definition['discoverable']) {
        unset($plugins[$instance_id]);
        continue;
      }

      // A filter on a result needs the ResourceFieldCollection representing the
      // result to return.
      $interpreter = new DataInterpreterPlug($this
        ->getAccount(), new PluginWrapper($plugin));
      $this->fieldDefinitions
        ->setInterpreter($interpreter);
      foreach ($filters as $filter) {
        if (!$this->fieldDefinitions
          ->evalFilter($filter)) {
          unset($plugins[$instance_id]);
        }
      }
    }
    $this->fieldDefinitions
      ->setInterpreter(NULL);
    return $plugins;
  }

  /**
   * Sorts plugins on the list based on the request options.
   *
   * @param \Drupal\restful\Plugin\resource\ResourceInterface[] $plugins
   *   The array of resource plugins keyed by instance ID.
   *
   * @return \Drupal\restful\Plugin\resource\ResourceInterface[]
   *   The sorted array.
   */
  protected function applySort(array $plugins) {
    if ($sorts = $this
      ->parseRequestForListSort()) {
      uasort($plugins, function ($plugin1, $plugin2) use ($sorts) {
        $interpreter1 = new DataInterpreterPlug($this
          ->getAccount(), new PluginWrapper($plugin1));
        $interpreter2 = new DataInterpreterPlug($this
          ->getAccount(), new PluginWrapper($plugin2));
        foreach ($sorts as $key => $order) {
          $property = $this->fieldDefinitions
            ->get($key)
            ->getProperty();
          $value1 = $interpreter1
            ->getWrapper()
            ->get($property);
          $value2 = $interpreter2
            ->getWrapper()
            ->get($property);
          if ($value1 == $value2) {
            continue;
          }
          return ($order == 'DESC' ? -1 : 1) * strcmp($value1, $value2);
        }
        return 0;
      });
    }
    return $plugins;
  }

  /**
   * {@inheritdoc}
   */
  protected function initDataInterpreter($identifier) {
    $resource_manager = restful()
      ->getResourceManager();
    try {
      $plugin = $resource_manager
        ->getPlugin($identifier);
    } catch (UnauthorizedException $e) {
      return NULL;
    } catch (PluginNotFoundException $e) {
      throw new NotFoundException('Invalid URL path.');
    }

    // If the plugin is not discoverable throw an access denied exception.
    $definition = $plugin
      ->getPluginDefinition();
    if (empty($definition['discoverable'])) {
      throw new InaccessibleRecordException(sprintf('The plugin %s is not discoverable.', $plugin
        ->getResourceName()));
    }
    return new DataInterpreterPlug($this
      ->getAccount(), new PluginWrapper($plugin));
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheFragments($identifier) {

    // If we are trying to get the context for multiple ids, join them.
    if (is_array($identifier)) {
      $identifier = implode(',', $identifier);
    }
    $fragments = new ArrayCollection(array(
      'resource' => $identifier,
    ));
    $options = $this
      ->getOptions();
    switch ($options['renderCache']['granularity']) {
      case DRUPAL_CACHE_PER_USER:
        if ($uid = $this
          ->getAccount()->uid) {
          $fragments
            ->set('user_id', (int) $uid);
        }
        break;
      case DRUPAL_CACHE_PER_ROLE:
        $fragments
          ->set('user_role', implode(',', $this
          ->getAccount()->roles));
        break;
    }
    return $fragments;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DataProvider::$account protected property The account authenticated from the request for entity access checks.
DataProvider::$fieldDefinitions protected property The field definitions.
DataProvider::$langcode protected property Determines the language of the items that should be returned.
DataProvider::$metadata protected property Array of metadata. Use this as a mean to pass info to the render layer.
DataProvider::$options protected property User defined options.
DataProvider::$pluginId protected property Resource identifier.
DataProvider::$range protected property Determines the number of items that should be returned when viewing lists.
DataProvider::$request protected property The request
DataProvider::$resourcePath protected property The resource path.
DataProvider::addExtraInfoToQuery protected function Adds query tags and metadata to the EntityFieldQuery. 2
DataProvider::addOptions public function Adds the options in the provided array to the data provider options. Overrides DataProviderInterface::addOptions
DataProvider::canonicalPath public function Generates the canonical path for a given path. Overrides DataProviderInterface::canonicalPath 1
DataProvider::discover public function Return the discovery information for the given entity. Overrides DataProviderInterface::discover
DataProvider::getAccount public function Gets the authenticated account. Overrides DataProviderInterface::getAccount
DataProvider::getLangCode public function Get the language code. Overrides DataProviderInterface::getLangCode
DataProvider::getLanguage protected static function Gets the global language.
DataProvider::getMetadata public function Returns the metadata collection. Overrides DataProviderInterface::getMetadata
DataProvider::getOptions public function Gets the data provider options. Overrides DataProviderInterface::getOptions
DataProvider::getRange public function Gets the range. Overrides DataProviderInterface::getRange
DataProvider::getRequest public function Gets the request. Overrides DataProviderInterface::getRequest
DataProvider::getResourcePath public function Get the resource path. Overrides DataProviderInterface::getResourcePath
DataProvider::index public function List operation. Overrides CrudInterface::index 2
DataProvider::initResourceFieldCollection protected function Initialize the empty resource field collection to bundle the output.
DataProvider::isNestedField public static function Checks if the passed in string is a dot-nested field. Overrides DataProviderInterface::isNestedField
DataProvider::isValidConjunctionForFilter protected static function Check if a conjunction is valid for filtering. 1
DataProvider::isValidOperatorsForFilter protected static function Check if an operator is valid for filtering. 1
DataProvider::methodAccess public function Checks if the provided field can be used with the current method. Overrides DataProviderInterface::methodAccess
DataProvider::parseRequestForListFilter protected function Filter the query for list.
DataProvider::parseRequestForListPagination protected function Parses the request object to get the pagination options.
DataProvider::parseRequestForListSort protected function Parses the request to get the sorting options.
DataProvider::processFilterInput public static function Processes the input for a filter and adds the appropriate defaults. Overrides DataProviderInterface::processFilterInput
DataProvider::setAccount public function Sets the authenticated account. Overrides DataProviderInterface::setAccount
DataProvider::setHttpHeader protected function Sets an HTTP header.
DataProvider::setLangCode public function Sets the language code. Overrides DataProviderInterface::setLangCode
DataProvider::setOptions public function Sets the options. Overrides DataProviderInterface::setOptions
DataProvider::setRange public function Sets the range. Overrides DataProviderInterface::setRange
DataProvider::setRequest public function Sets the request. Overrides DataProviderInterface::setRequest
DataProvider::setResourcePath public function Set the resource path. Overrides DataProviderInterface::setResourcePath
DataProviderPlug::applyFilters protected function Removes plugins from the list based on the request options.
DataProviderPlug::applySort protected function Sorts plugins on the list based on the request options.
DataProviderPlug::count public function Counts the total results for the index call. Overrides CrudInterface::count
DataProviderPlug::create public function Create operation. Overrides CrudInterface::create
DataProviderPlug::getCacheFragments public function Gets the entity context. Overrides DataProvider::getCacheFragments
DataProviderPlug::getIndexIds public function Returns the ID to render for the current index GET request. Overrides DataProviderInterface::getIndexIds
DataProviderPlug::initDataInterpreter protected function Get the data interpreter. Overrides DataProvider::initDataInterpreter
DataProviderPlug::remove public function Delete operation. Overrides CrudInterface::remove
DataProviderPlug::update public function Update operation. Overrides CrudInterface::update
DataProviderPlug::view public function Read operation. Overrides CrudInterface::view
DataProviderPlug::viewMultiple public function Read operation. Overrides CrudInterface::viewMultiple
DataProviderPlug::__construct public function Constructor. Overrides DataProvider::__construct