You are here

abstract class RestfulDataProviderCToolsPlugins in RESTful 7

@file Contains \RestfulDataProviderCToolsPlugins

Hierarchy

Expanded class hierarchy of RestfulDataProviderCToolsPlugins

File

plugins/restful/RestfulDataProviderCToolsPlugins.php, line 8
Contains \RestfulDataProviderCToolsPlugins

View source
abstract class RestfulDataProviderCToolsPlugins extends \RestfulBase implements \RestfulDataProviderCToolsPluginsInterface {

  /**
   * The module name.
   *
   * @var string
   */
  protected $module;

  /**
   * The type of the plugin.
   *
   * @var string
   */
  protected $type;

  /**
   * The loaded plugins.
   *
   * @var array
   */
  protected $plugins = array();

  /**
   * Get the module name.
   *
   * @return string
   */
  public function getModule() {
    return $this->module;
  }

  /**
   * Get the plugin type.
   *
   * @return string
   */
  public function getType() {
    return $this->type;
  }

  /**
   * Return the plugins.
   *
   * @return array
   */
  public function getPlugins() {
    if ($this->plugins) {
      return $this->plugins;
    }
    $this->plugins = ctools_get_plugins($this
      ->getModule(), $this
      ->getType());
    return $this->plugins;
  }

  /**
   * Gets the plugins filtered and sorted by the request.
   *
   * @return array
   *   Array of plugins.
   */
  public function getPluginsSortedAndFiltered() {
    $plugins = $this
      ->getPlugins();
    $public_fields = $this
      ->getPublicFields();
    foreach ($this
      ->parseRequestForListFilter() as $filter) {
      foreach ($plugins as $plugin_name => $plugin) {

        // Initialize to TRUE for AND and FALSE for OR (neutral value).
        $match = $filter['conjunction'] == 'AND';
        for ($index = 0; $index < count($filter['value']); $index++) {
          $property = $public_fields[$filter['public_field']]['property'];
          if (empty($plugin[$property])) {

            // Property doesn't exist on the plugin, so filter it out.
            unset($plugins[$plugin_name]);
          }
          if ($filter['conjunction'] == 'OR') {
            $match = $match || $this
              ->evaluateExpression($plugin[$property], $filter['value'][$index], $filter['operator'][$index]);
            if ($match) {
              break;
            }
          }
          else {
            $match = $match && $this
              ->evaluateExpression($plugin[$property], $filter['value'][$index], $filter['operator'][$index]);
            if (!$match) {
              break;
            }
          }
        }
        if (!$match) {

          // Property doesn't match the filter.
          unset($plugins[$plugin_name]);
        }
      }
    }
    if ($this
      ->parseRequestForListSort()) {
      uasort($plugins, array(
        $this,
        'sortMultiCompare',
      ));
    }
    return $plugins;
  }

  /**
   * Overrides \RestfulBase::isValidConjuctionForFilter().
   */
  protected static function isValidConjunctionForFilter($conjunction) {
    $allowed_conjunctions = array(
      'AND',
      'OR',
    );
    if (!in_array(strtoupper($conjunction), $allowed_conjunctions)) {
      throw new \RestfulBadRequestException(format_string('Conjunction "@conjunction" is not allowed for filtering on this resource. Allowed conjunctions are: !allowed', array(
        '@conjunction' => $conjunction,
        '!allowed' => implode(', ', $allowed_conjunctions),
      )));
    }
  }

  /**
   * Evaluate a simple expression.
   *
   * @param $value1
   *   The first value.
   * @param $value2
   *   The second value.
   * @param $operator
   *   The operator.
   *
   * @return bool
   *   TRUE or FALSE based on the evaluated expression.
   *
   * @throws RestfulBadRequestException
   */
  protected function evaluateExpression($value1, $value2, $operator) {
    switch ($operator) {
      case '=':
        return $value1 == $value2;
      case '<':
        return $value1 < $value2;
      case '>':
        return $value1 > $value2;
      case '>=':
        return $value1 >= $value2;
      case '<=':
        return $value1 <= $value2;
      case '<>':
      case '!=':
        return $value1 != $value2;
      case 'IN':
        return in_array($value1, $value2);
      case 'BETWEEN':
        return $value1 >= $value2[0] && $value1 >= $value2[1];
    }
  }

  /**
   * Sort plugins by multiple criteria.
   *
   * @param $value1
   *   The first value.
   * @param $value2
   *   The second value.
   *
   * @return int
   *   The values expected by uasort() function.
   *
   * @link http://stackoverflow.com/a/13673568/750039
   */
  protected function sortMultiCompare($value1, $value2) {
    $sorts = $this
      ->parseRequestForListSort();
    foreach ($sorts as $key => $order) {
      if ($value1[$key] == $value2[$key]) {
        continue;
      }
      return ($order == 'DESC' ? -1 : 1) * strcmp($value1[$key], $value2[$key]);
    }
    return 0;
  }

  /**
   * Constructs a RestfulDataProviderCToolsPlugins object.
   *
   * @param array $plugin
   *   Plugin definition.
   * @param RestfulAuthenticationManager $auth_manager
   *   (optional) Injected authentication manager.
   * @param DrupalCacheInterface $cache_controller
   *   (optional) Injected cache backend.
   * @param string $language
   *   (optional) The language to return items in.
   */
  public function __construct(array $plugin, \RestfulAuthenticationManager $auth_manager = NULL, \DrupalCacheInterface $cache_controller = NULL, $language = NULL) {
    parent::__construct($plugin, $auth_manager, $cache_controller, $language);

    // Validate keys exist in the plugin's "data provider options".
    $required_keys = array(
      'module',
      'type',
    );
    $options = $this
      ->processDataProviderOptions($required_keys);
    $this->module = $options['module'];
    $this->type = $options['type'];
    ctools_include('plugins');
  }

  /**
   * {@inheritdoc}
   */
  public function getTotalCount() {
    return count($this
      ->getPluginsSortedAndFiltered());
  }
  public function index() {
    $return = array();
    foreach (array_keys($this
      ->getPluginsSortedAndFiltered()) as $plugin_name) {
      $return[] = $this
        ->view($plugin_name);
    }
    return $return;
  }

  /**
   * {@inheritdoc}
   *
   * @todo: We should generalize this, as it's repeated often.
   */
  public function view($id) {
    $cache_id = array(
      'md' => $this
        ->getModule(),
      'tp' => $this
        ->getType(),
      'id' => $id,
    );
    $cached_data = $this
      ->getRenderedCache($cache_id);
    if (!empty($cached_data->data)) {
      return $cached_data->data;
    }
    if (!($plugin = ctools_get_plugins($this
      ->getModule(), $this
      ->getType(), $id))) {

      // Since the discovery resource sits under 'api/' it will pick up all
      // invalid paths like 'api/invalid'. If it is not a valid plugin then
      // return a 404.
      throw new \RestfulNotFoundException('Invalid URL path.');
    }

    // Loop over all the defined public fields.
    foreach ($this
      ->getPublicFields() as $public_field_name => $info) {
      $value = NULL;
      if ($info['create_or_update_passthrough']) {

        // The public field is a dummy one, meant only for passing data upon
        // create or update.
        continue;
      }

      // If there is a callback defined execute it instead of a direct mapping.
      if ($info['callback']) {
        $value = static::executeCallback($info['callback'], array(
          $plugin,
        ));
      }
      elseif ($info['property']) {
        $value = $plugin[$info['property']];
      }

      // Execute the process callbacks.
      if ($value && $info['process_callbacks']) {
        foreach ($info['process_callbacks'] as $process_callback) {
          $value = static::executeCallback($process_callback, array(
            $value,
          ));
        }
      }
      $output[$public_field_name] = $value;
    }
    $this
      ->setRenderedCache($output, $cache_id);
    return $output;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
RestfulBase::$authenticationManager protected property Authentication manager.
RestfulBase::$cacheController protected property Cache controller object.
RestfulBase::$controllers protected property Nested array that provides information about what method to call for each route pattern.
RestfulBase::$httpHeaders protected property Array keyed by the header property, and the value.
RestfulBase::$langcode protected property Determines the language of the items that should be returned.
RestfulBase::$method protected property The HTTP method used for the request.
RestfulBase::$path protected property The path of the request.
RestfulBase::$publicFields protected property The public fields that are exposed to the API. 1
RestfulBase::$range protected property Determines the number of items that should be returned when viewing lists.
RestfulBase::$rateLimitManager protected property Rate limit manager.
RestfulBase::$request protected property The request array.
RestfulBase::$staticCache public property Static cache controller.
RestfulBase::$valueMetadata protected property Holds additional information about the generated values. This information is available to the formatters.
RestfulBase::access public function Determine if user can access the handler. Overrides RestfulInterface::access 4
RestfulBase::accessByAllowOrigin protected function Checks access based on the referer header and the allow_origin setting.
RestfulBase::addCidParams protected static function Get the cache id parameters based on the keys.
RestfulBase::addDefaultValuesToPublicFields protected function Add default values to the public fields array. 2
RestfulBase::addExtraInfoToQuery protected function Adds query tags and metadata to the EntityFieldQuery. 2
RestfulBase::addHttpHeaders public function Add the a value to a multi-value HTTP header. Overrides RestfulInterface::addHttpHeaders
RestfulBase::cacheInvalidate public function Invalidates cache for a certain entity.
RestfulBase::cleanRequest public static function Helper function to remove the application generated request data.
RestfulBase::clearRenderedCache protected function Clear an entry from the rendered cache.
RestfulBase::clearResourceRenderedCache public function Clear all caches corresponding to the current resource.
RestfulBase::controllersInfo public static function Returns the default controllers for the entity. 1
RestfulBase::create public function 3
RestfulBase::delete public function Call resource using the DELETE http method.
RestfulBase::executeCallback public static function Execute a user callback.
RestfulBase::format public function Call the output format on the given data.
RestfulBase::formatter protected function Get the formatter handler for the current restful formatter.
RestfulBase::formatterNames public function Returns the names of the available formatter plugins.
RestfulBase::generateCacheId protected function Generate a cache identifier for the request and the current context.
RestfulBase::get public function Call resource using the GET http method.
RestfulBase::getAccount public function Proxy method to get the account from the authenticationManager.
RestfulBase::getAuthenticationManager public function Getter for $authenticationManager.
RestfulBase::getCacheController public function Getter for $cacheController.
RestfulBase::getControllerFromPath public function Return the controller from a given path.
RestfulBase::getControllers public function Get the defined controllers
RestfulBase::getHttpHeaders public function Return array keyed by the header property, and the value. Overrides RestfulInterface::getHttpHeaders
RestfulBase::getLangCode public function Get the language code.
RestfulBase::getMenuItem public static function Get the non translated menu item.
RestfulBase::getMethod public function Get the HTTP method used for the request.
RestfulBase::getPageArguments public static function Get the resource name and version from the page arguments in the router.
RestfulBase::getPath public function Return the path of the request.
RestfulBase::getPublicFields public function Return the properties that should be public after processing. Overrides RestfulInterface::getPublicFields
RestfulBase::getRange public function Get the pager range.
RestfulBase::getRateLimitManager public function Getter for rateLimitManager.
RestfulBase::getRenderedCache protected function Get an entry from the rendered cache.
RestfulBase::getRequest public function Get the request array.
RestfulBase::getRequestForSubRequest protected function Gets a request array with the data that should be piped to sub requests.
RestfulBase::getResourceLastVersion public static function Return the last version for a given resource.
RestfulBase::getResourceName public function Return the resource name.
RestfulBase::getUrl public function Helper method; Get the URL of the resource and query strings.
RestfulBase::getValueMetadata public function Get value metadata.
RestfulBase::getVersion public function Return array keyed with the major and minor version of the resource.
RestfulBase::getVersionFromRequest public static function Gets the major and minor version for the current request.
RestfulBase::head public function Call resource using the GET http method.
RestfulBase::isArrayNumeric final public static function Helper method to determine if an array is numeric.
RestfulBase::isListRequest public function Helper method to know if the current request is for a list.
RestfulBase::isReadMethod public static function Determines if the HTTP method represents a read operation.
RestfulBase::isValidMethod public static function Determines if the HTTP method is one of the known methods.
RestfulBase::isValidOperatorsForFilter protected static function Check if an operator is valid for filtering. 1
RestfulBase::isWriteMethod public static function Determines if the HTTP method represents a write operation.
RestfulBase::newCacheObject protected function Get the default cache object based on the plugin configuration.
RestfulBase::notImplementedCrudOperation protected static function Helper method with the code to run for non implemented CRUD operations.
RestfulBase::options public function Call resource using the OPTIONS http method.
RestfulBase::overrideRange protected function Overrides the range parameter with the URL value if any.
RestfulBase::parseRequestForListFilter protected function Filter the query for list.
RestfulBase::parseRequestForListPagination protected function Parses the request object to get the pagination options.
RestfulBase::parseRequestForListSort protected function Parses the request to get the sorting options.
RestfulBase::parseVersionString public static function Parses the version string.
RestfulBase::patch public function Call resource using the PATCH http method.
RestfulBase::post public function Call resource using the POST http method.
RestfulBase::process public function Entry point to process a request. Overrides RestfulInterface::process
RestfulBase::processDataProviderOptions protected function Process plugin options by validation keys exists, and set default values.
RestfulBase::put public function Call resource using the PUT http method.
RestfulBase::remove public function 3
RestfulBase::setAccount public function Proxy method to set the account from the authenticationManager.
RestfulBase::setAuthenticationManager public function Setter for $authenticationManager.
RestfulBase::setHttpHeaders public function Set the HTTP headers. Overrides RestfulInterface::setHttpHeaders
RestfulBase::setLangCode public function Sets the language code.
RestfulBase::setMethod public function Set the HTTP method used for the request.
RestfulBase::setPath public function Set the path of the request.
RestfulBase::setPublicFields public function Set the public fields.
RestfulBase::setRange public function Set the pager range.
RestfulBase::setRateLimitManager public function Setter for rateLimitManager.
RestfulBase::setRenderedCache protected function Store an entry in the rendered cache.
RestfulBase::setRequest public function Set the request array.
RestfulBase::update public function 3
RestfulBase::versionedUrl public function Gets a resource URL based on the current version.
RestfulBase::viewMultiple public function 2
RestfulDataProviderCToolsPlugins::$module protected property The module name.
RestfulDataProviderCToolsPlugins::$plugins protected property The loaded plugins.
RestfulDataProviderCToolsPlugins::$type protected property The type of the plugin.
RestfulDataProviderCToolsPlugins::evaluateExpression protected function Evaluate a simple expression.
RestfulDataProviderCToolsPlugins::getModule public function Get the module name.
RestfulDataProviderCToolsPlugins::getPlugins public function Return the plugins. 1
RestfulDataProviderCToolsPlugins::getPluginsSortedAndFiltered public function Gets the plugins filtered and sorted by the request.
RestfulDataProviderCToolsPlugins::getTotalCount public function Get the total count of entities that match certain request. Overrides RestfulDataProviderCToolsPluginsInterface::getTotalCount
RestfulDataProviderCToolsPlugins::getType public function Get the plugin type.
RestfulDataProviderCToolsPlugins::index public function Get a list of entities. Overrides RestfulBase::index
RestfulDataProviderCToolsPlugins::isValidConjunctionForFilter protected static function Overrides \RestfulBase::isValidConjuctionForFilter(). Overrides RestfulBase::isValidConjunctionForFilter
RestfulDataProviderCToolsPlugins::sortMultiCompare protected function Sort plugins by multiple criteria.
RestfulDataProviderCToolsPlugins::view public function @todo: We should generalize this, as it's repeated often. Overrides RestfulBase::view
RestfulDataProviderCToolsPlugins::__construct public function Constructs a RestfulDataProviderCToolsPlugins object. Overrides RestfulBase::__construct
RestfulInterface::ACCESS_ALLOW constant Return this value from public field access callbacks to allow access.
RestfulInterface::ACCESS_DENY constant Return this value from public field access callbacks to deny access.
RestfulInterface::ACCESS_IGNORE constant Return this value from public field access callbacks to not affect access.
RestfulInterface::CONNECT constant
RestfulInterface::DELETE constant
RestfulInterface::GET constant HTTP methods.
RestfulInterface::HEAD constant
RestfulInterface::OPTIONS constant
RestfulInterface::PATCH constant
RestfulInterface::POST constant
RestfulInterface::publicFieldsInfo public function Return the properties that should be public. 7
RestfulInterface::PUT constant
RestfulInterface::TOKEN_VALUE constant Token value for token generation functions.
RestfulInterface::TRACE constant
RestfulPluginBase::$plugin protected property The plugin definition array.
RestfulPluginBase::getPlugin public function Gets information about the restful plugin. Overrides RestfulPluginInterface::getPlugin
RestfulPluginBase::getPluginKey public function Gets information about the restful plugin key. Overrides RestfulPluginInterface::getPluginKey
RestfulPluginBase::setPlugin public function Sets information about the restful plugin. Overrides RestfulPluginInterface::setPlugin
RestfulPluginBase::setPluginKey public function Gets information about the restful plugin key. Overrides RestfulPluginInterface::setPluginKey