abstract class RestfulDataProviderEFQ in RESTful 7
@file Contains \RestfulDataProviderEFQ
Hierarchy
- class \RestfulPluginBase implements RestfulPluginInterface
- class \RestfulBase implements RestfulInterface
- class \RestfulDataProviderEFQ implements RestfulDataProviderEFQInterface, RestfulDataProviderInterface
- class \RestfulBase implements RestfulInterface
Expanded class hierarchy of RestfulDataProviderEFQ
File
- plugins/
restful/ RestfulDataProviderEFQ.php, line 8 - Contains \RestfulDataProviderEFQ
View source
abstract class RestfulDataProviderEFQ extends \RestfulBase implements \RestfulDataProviderEFQInterface, \RestfulDataProviderInterface {
/**
* The entity type.
*
* @var string
*/
protected $entityType;
/**
* The bundle.
*
* @var string
*/
protected $bundle;
/**
* The bundle.
*
* @var string
*/
protected $EFQClass = '\\EntityFieldQuery';
/**
* Getter for $bundle.
*
* @return string
*/
public function getBundle() {
return $this->bundle;
}
/**
* Getter for $entityType.
*
* @return string
*/
public function getEntityType() {
return $this->entityType;
}
/**
* Get the entity info for the current entity the endpoint handling.
*
* @param null $type
* The entity type. Optional.
* @return array
* The entity info.
*/
public function getEntityInfo($type = NULL) {
return entity_get_info($type ? $type : $this
->getEntityType());
}
/**
* Constructs a RestfulDataProviderEFQ 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.
*
* @throws RestfulServerConfigurationException
*/
public function __construct(array $plugin, \RestfulAuthenticationManager $auth_manager = NULL, \DrupalCacheInterface $cache_controller = NULL, $language = NULL) {
parent::__construct($plugin, $auth_manager, $cache_controller, $language);
$this->entityType = $plugin['entity_type'];
$this->bundle = $plugin['bundle'];
// Allow providing an alternative to \EntityFieldQuery.
$data_provider_options = $this
->getPluginKey('data_provider_options');
if (!empty($data_provider_options['efq_class'])) {
if (!is_subclass_of($data_provider_options['efq_class'], '\\EntityFieldQuery')) {
throw new \RestfulServerConfigurationException(format_string('The provided class @class does not extend from \\EntityFieldQuery.', array(
'@class' => $data_provider_options['efq_class'],
)));
}
$this->EFQClass = $data_provider_options['efq_class'];
}
}
/**
* Defines default sort fields if none are provided via the request URL.
*
* @return array
* Array keyed by the public field name, and the order ('ASC' or 'DESC') as value.
*/
public function defaultSortInfo() {
return array(
'id' => 'ASC',
);
}
/**
* {@inheritdoc}
*/
public function getQueryForList() {
$entity_type = $this
->getEntityType();
$query = $this
->getEntityFieldQuery();
if ($path = $this
->getPath()) {
$ids = explode(',', $path);
if (!empty($ids)) {
$query
->entityCondition('entity_id', $ids, 'IN');
}
}
$this
->queryForListSort($query);
$this
->queryForListFilter($query);
$this
->queryForListPagination($query);
$this
->addExtraInfoToQuery($query);
return $query;
}
/**
* Sort the query for list.
*
* @param \EntityFieldQuery $query
* The query object.
*
* @throws \RestfulBadRequestException
*
* @see \RestfulEntityBase::getQueryForList
*/
protected function queryForListSort(\EntityFieldQuery $query) {
$public_fields = $this
->getPublicFields();
// Get the sorting options from the request object.
$sorts = $this
->parseRequestForListSort();
$sorts = $sorts ? $sorts : $this
->defaultSortInfo();
foreach ($sorts as $public_field_name => $direction) {
// Determine if sorting is by field or property.
if (!($property_name = $public_fields[$public_field_name]['property'])) {
throw new \RestfulBadRequestException('The current sort selection does not map to any entity property or Field API field.');
}
if (field_info_field($property_name)) {
$query
->fieldOrderBy($public_fields[$public_field_name]['property'], $public_fields[$public_field_name]['column'], $direction);
}
else {
$column = $this
->getColumnFromProperty($property_name);
$query
->propertyOrderBy($column, $direction);
}
}
}
/**
* Filter the query for list.
*
* @param \EntityFieldQuery $query
* The query object.
*
* @throws \RestfulBadRequestException
*
* @see \RestfulEntityBase::getQueryForList
*/
protected function queryForListFilter(\EntityFieldQuery $query) {
$public_fields = $this
->getPublicFields();
foreach ($this
->parseRequestForListFilter() as $filter) {
// Determine if filtering is by field or property.
if (!($property_name = $public_fields[$filter['public_field']]['property'])) {
throw new \RestfulBadRequestException('The current filter selection does not map to any entity property or Field API field.');
}
if (field_info_field($property_name)) {
if (in_array(strtoupper($filter['operator'][0]), array(
'IN',
'NOT IN',
'BETWEEN',
))) {
if (is_array($filter['value']) && empty($filter['value'])) {
if (strtoupper($filter['operator'][0]) == 'NOT IN') {
// Skip filtering by an empty value when operator is 'NOT IN',
// since it throws an SQL error.
continue;
}
// Since Drupal doesn't know how to handle an empty array within a
// condition we add the `NULL` as an element to the array.
$filter['value'] = array(
NULL,
);
}
$query
->fieldCondition($public_fields[$filter['public_field']]['property'], $public_fields[$filter['public_field']]['column'], $filter['value'], $filter['operator'][0]);
continue;
}
for ($index = 0; $index < count($filter['value']); $index++) {
$query
->fieldCondition($public_fields[$filter['public_field']]['property'], $public_fields[$filter['public_field']]['column'], $filter['value'][$index], $filter['operator'][$index]);
}
}
else {
$column = $this
->getColumnFromProperty($property_name);
if (in_array(strtoupper($filter['operator'][0]), array(
'IN',
'NOT IN',
'BETWEEN',
))) {
if (is_array($filter['value']) && empty($filter['value'])) {
if (strtoupper($filter['operator'][0]) == 'NOT IN') {
// Skip filtering by an empty value when operator is 'NOT IN',
// since it throws an SQL error.
continue;
}
// Since Drupal doesn't know how to handle an empty array within a
// condition we add the `NULL` as an element to the array.
$filter['value'] = array(
NULL,
);
}
$query
->propertyCondition($column, $filter['value'], $filter['operator'][0]);
continue;
}
for ($index = 0; $index < count($filter['value']); $index++) {
$query
->propertyCondition($column, $filter['value'][$index], $filter['operator'][$index]);
}
}
}
}
/**
* Get the DB column name from a property.
*
* The "property" defined in the public field is actually the property
* of the entity metadata wrapper. Sometimes that property can be a
* different name than the column in the DB. For example, for nodes the
* "uid" property is mapped in entity metadata wrapper as "author", so
* we make sure to get the real column name.
*
* @param string $property_name
* The property name.
*
* @return string
* The column name.
*/
protected function getColumnFromProperty($property_name) {
$property_info = entity_get_property_info($this
->getEntityType());
return $property_info['properties'][$property_name]['schema field'];
}
/**
* Overrides \RestfulBase::isValidOperatorsForFilter().
*/
protected static function isValidOperatorsForFilter(array $operators) {
$allowed_operators = array(
'=',
'>',
'<',
'>=',
'<=',
'<>',
'!=',
'BETWEEN',
'CONTAINS',
'IN',
'LIKE',
'NOT IN',
'STARTS_WITH',
);
foreach ($operators as $operator) {
if (!in_array($operator, $allowed_operators)) {
throw new \RestfulBadRequestException(format_string('Operator "@operator" is not allowed for filtering on this resource. Allowed operators are: !allowed', array(
'@operator' => $operator,
'!allowed' => implode(', ', $allowed_operators),
)));
}
}
}
/**
* Overrides \RestfulBase::isValidConjuctionForFilter().
*/
protected static function isValidConjunctionForFilter($conjunction) {
$allowed_conjunctions = array(
'AND',
);
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),
)));
}
}
/**
* Set correct page (i.e. range) for the query for list.
*
* Determine the page that should be seen. Page 1, is actually offset 0 in the
* query range.
*
* @param \EntityFieldQuery $query
* The query object.
*
* @throws \RestfulBadRequestException
*
* @see \RestfulEntityBase::getQueryForList
*/
protected function queryForListPagination(\EntityFieldQuery $query) {
list($offset, $range) = $this
->parseRequestForListPagination();
$query
->range($offset, $range);
}
/**
* {@inheritdoc}
*/
public function getQueryCount() {
$query = $this
->getEntityFieldQuery();
if ($path = $this
->getPath()) {
$ids = explode(',', $path);
$query
->entityCondition('entity_id', $ids, 'IN');
}
$this
->queryForListFilter($query);
$this
->addExtraInfoToQuery($query);
$query
->addTag('restful_count');
return $query
->count();
}
/**
* {@inheritdoc}
*/
public function getTotalCount() {
return intval($this
->getQueryCount()
->execute());
}
/**
* Adds query tags and metadata to the EntityFieldQuery.
*
* @param \EntityFieldQuery $query
* The query to enhance.
*/
protected function addExtraInfoToQuery($query) {
parent::addExtraInfoToQuery($query);
$entity_type = $this
->getEntityType();
// The only time you need to add the access tags to a EFQ is when you don't
// have fieldConditions.
if (empty($query->fieldConditions)) {
// Add a generic entity access tag to the query.
$query
->addTag($entity_type . '_access');
}
$query
->addMetaData('restful_handler', $this);
}
/**
* {@inheritdoc}
*/
public function index() {
// Defer the actual implementation to \RestfulEntityBase.
return $this
->getList();
}
/**
* {@inheritdoc}
*/
public function viewMultiple(array $ids) {
// Defer the actual implementation to \RestfulEntityBase.
return $this
->viewEntities(implode(',', $ids));
}
/**
* {@inheritdoc}
*/
public function view($id) {
// Defer the actual implementation to \RestfulEntityBase.
return $this
->viewEntity($id);
}
/**
* {@inheritdoc}
*/
public function update($id, $full_replace = FALSE) {
// Defer the actual implementation to \RestfulEntityBase.
return $this
->updateEntity($id, $full_replace);
}
/**
* {@inheritdoc}
*/
public function create() {
// Defer the actual implementation to \RestfulEntityBase.
return $this
->createEntity();
}
/**
* {@inheritdoc}
*/
public function remove($id) {
// Defer the actual implementation to \RestfulEntityBase.
$this
->deleteEntity($id);
}
/**
* Get a list of entities.
*
* @return array
* Array of entities, as passed to RestfulEntityBase::viewEntity().
*
* @throws RestfulBadRequestException
*/
public abstract function getList();
/**
* View an entity.
*
* @param $id
* The ID to load the entity.
*
* @return array
* Array with the public fields populated.
*
* @throws Exception
*/
public abstract function viewEntity($id);
/**
* Get a list of entities based on a list of IDs.
*
* @param string $ids_string
* Coma separated list of ids.
*
* @return array
* Array of entities, as passed to RestfulEntityBase::viewEntity().
*
* @throws RestfulBadRequestException
*/
public abstract function viewEntities($ids_string);
/**
* Create a new entity.
*
* @return array
* Array with the output of the new entity, passed to
* RestfulEntityInterface::viewEntity().
*
* @throws RestfulForbiddenException
*/
public abstract function createEntity();
/**
* Update an entity.
*
* @param $id
* The ID to load the entity.
* @param bool $null_missing_fields
* Determine if properties that are missing form the request array should
* be treated as NULL, or should be skipped. Defaults to FALSE, which will
* skip missing the fields to NULL.
*
* @return array
* Array with the output of the new entity, passed to
* RestfulEntityInterface::viewEntity().
*/
protected abstract function updateEntity($id, $null_missing_fields = FALSE);
/**
* Delete an entity using DELETE.
*
* No result is returned, just the HTTP header is set to 204.
*
* @param $id
* The ID to load the entity.
*/
public abstract function deleteEntity($id);
/**
* Initialize an EntityFieldQuery (or extending class).
*
* @return \EntityFieldQuery
* The initialized query with the basics filled in.
*/
protected function getEntityFieldQuery() {
$query = $this
->EFQObject();
$entity_type = $this
->getEntityType();
$query
->entityCondition('entity_type', $entity_type);
$entity_info = $this
->getEntityInfo();
if ($this
->getBundle() && $entity_info['entity keys']['bundle']) {
$query
->entityCondition('bundle', $this
->getBundle());
}
return $query;
}
/**
* Gets a EFQ object.
*
* @return \EntityFieldQuery
* The object that inherits from \EntityFieldQuery.
*/
protected function EFQObject() {
$efq_class = $this->EFQClass;
return new $efq_class();
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
RestfulBase:: |
protected | property | Authentication manager. | |
RestfulBase:: |
protected | property | Cache controller object. | |
RestfulBase:: |
protected | property | Nested array that provides information about what method to call for each route pattern. | |
RestfulBase:: |
protected | property | Array keyed by the header property, and the value. | |
RestfulBase:: |
protected | property | Determines the language of the items that should be returned. | |
RestfulBase:: |
protected | property | The HTTP method used for the request. | |
RestfulBase:: |
protected | property | The path of the request. | |
RestfulBase:: |
protected | property | The public fields that are exposed to the API. | 1 |
RestfulBase:: |
protected | property | Determines the number of items that should be returned when viewing lists. | |
RestfulBase:: |
protected | property | Rate limit manager. | |
RestfulBase:: |
protected | property | The request array. | |
RestfulBase:: |
public | property | Static cache controller. | |
RestfulBase:: |
protected | property | Holds additional information about the generated values. This information is available to the formatters. | |
RestfulBase:: |
public | function |
Determine if user can access the handler. Overrides RestfulInterface:: |
4 |
RestfulBase:: |
protected | function | Checks access based on the referer header and the allow_origin setting. | |
RestfulBase:: |
protected static | function | Get the cache id parameters based on the keys. | |
RestfulBase:: |
protected | function | Add default values to the public fields array. | 2 |
RestfulBase:: |
public | function |
Add the a value to a multi-value HTTP header. Overrides RestfulInterface:: |
|
RestfulBase:: |
public | function | Invalidates cache for a certain entity. | |
RestfulBase:: |
public static | function | Helper function to remove the application generated request data. | |
RestfulBase:: |
protected | function | Clear an entry from the rendered cache. | |
RestfulBase:: |
public | function | Clear all caches corresponding to the current resource. | |
RestfulBase:: |
public static | function | Returns the default controllers for the entity. | 1 |
RestfulBase:: |
public | function | Call resource using the DELETE http method. | |
RestfulBase:: |
public static | function | Execute a user callback. | |
RestfulBase:: |
public | function | Call the output format on the given data. | |
RestfulBase:: |
protected | function | Get the formatter handler for the current restful formatter. | |
RestfulBase:: |
public | function | Returns the names of the available formatter plugins. | |
RestfulBase:: |
protected | function | Generate a cache identifier for the request and the current context. | |
RestfulBase:: |
public | function | Call resource using the GET http method. | |
RestfulBase:: |
public | function | Proxy method to get the account from the authenticationManager. | |
RestfulBase:: |
public | function | Getter for $authenticationManager. | |
RestfulBase:: |
public | function | Getter for $cacheController. | |
RestfulBase:: |
public | function | Return the controller from a given path. | |
RestfulBase:: |
public | function | Get the defined controllers | |
RestfulBase:: |
public | function |
Return array keyed by the header property, and the value. Overrides RestfulInterface:: |
|
RestfulBase:: |
public | function | Get the language code. | |
RestfulBase:: |
public static | function | Get the non translated menu item. | |
RestfulBase:: |
public | function | Get the HTTP method used for the request. | |
RestfulBase:: |
public static | function | Get the resource name and version from the page arguments in the router. | |
RestfulBase:: |
public | function | Return the path of the request. | |
RestfulBase:: |
public | function |
Return the properties that should be public after processing. Overrides RestfulInterface:: |
|
RestfulBase:: |
public | function | Get the pager range. | |
RestfulBase:: |
public | function | Getter for rateLimitManager. | |
RestfulBase:: |
protected | function | Get an entry from the rendered cache. | |
RestfulBase:: |
public | function | Get the request array. | |
RestfulBase:: |
protected | function | Gets a request array with the data that should be piped to sub requests. | |
RestfulBase:: |
public static | function | Return the last version for a given resource. | |
RestfulBase:: |
public | function | Return the resource name. | |
RestfulBase:: |
public | function | Helper method; Get the URL of the resource and query strings. | |
RestfulBase:: |
public | function | Get value metadata. | |
RestfulBase:: |
public | function | Return array keyed with the major and minor version of the resource. | |
RestfulBase:: |
public static | function | Gets the major and minor version for the current request. | |
RestfulBase:: |
public | function | Call resource using the GET http method. | |
RestfulBase:: |
final public static | function | Helper method to determine if an array is numeric. | |
RestfulBase:: |
public | function | Helper method to know if the current request is for a list. | |
RestfulBase:: |
public static | function | Determines if the HTTP method represents a read operation. | |
RestfulBase:: |
public static | function | Determines if the HTTP method is one of the known methods. | |
RestfulBase:: |
public static | function | Determines if the HTTP method represents a write operation. | |
RestfulBase:: |
protected | function | Get the default cache object based on the plugin configuration. | |
RestfulBase:: |
protected static | function | Helper method with the code to run for non implemented CRUD operations. | |
RestfulBase:: |
public | function | Call resource using the OPTIONS http method. | |
RestfulBase:: |
protected | function | Overrides the range parameter with the URL value if any. | |
RestfulBase:: |
protected | function | Filter the query for list. | |
RestfulBase:: |
protected | function | Parses the request object to get the pagination options. | |
RestfulBase:: |
protected | function | Parses the request to get the sorting options. | |
RestfulBase:: |
public static | function | Parses the version string. | |
RestfulBase:: |
public | function | Call resource using the PATCH http method. | |
RestfulBase:: |
public | function | Call resource using the POST http method. | |
RestfulBase:: |
public | function |
Entry point to process a request. Overrides RestfulInterface:: |
|
RestfulBase:: |
protected | function | Process plugin options by validation keys exists, and set default values. | |
RestfulBase:: |
public | function | Call resource using the PUT http method. | |
RestfulBase:: |
public | function | Proxy method to set the account from the authenticationManager. | |
RestfulBase:: |
public | function | Setter for $authenticationManager. | |
RestfulBase:: |
public | function |
Set the HTTP headers. Overrides RestfulInterface:: |
|
RestfulBase:: |
public | function | Sets the language code. | |
RestfulBase:: |
public | function | Set the HTTP method used for the request. | |
RestfulBase:: |
public | function | Set the path of the request. | |
RestfulBase:: |
public | function | Set the public fields. | |
RestfulBase:: |
public | function | Set the pager range. | |
RestfulBase:: |
public | function | Setter for rateLimitManager. | |
RestfulBase:: |
protected | function | Store an entry in the rendered cache. | |
RestfulBase:: |
public | function | Set the request array. | |
RestfulBase:: |
public | function | Gets a resource URL based on the current version. | |
RestfulDataProviderEFQ:: |
protected | property | The bundle. | |
RestfulDataProviderEFQ:: |
protected | property | The bundle. | |
RestfulDataProviderEFQ:: |
protected | property | The entity type. | |
RestfulDataProviderEFQ:: |
protected | function |
Adds query tags and metadata to the EntityFieldQuery. Overrides RestfulBase:: |
|
RestfulDataProviderEFQ:: |
public | function |
Create an item from the request object. Overrides RestfulBase:: |
|
RestfulDataProviderEFQ:: |
abstract public | function | Create a new entity. | 1 |
RestfulDataProviderEFQ:: |
public | function | Defines default sort fields if none are provided via the request URL. | 1 |
RestfulDataProviderEFQ:: |
abstract public | function | Delete an entity using DELETE. | 1 |
RestfulDataProviderEFQ:: |
protected | function | Gets a EFQ object. | |
RestfulDataProviderEFQ:: |
public | function | Getter for $bundle. | |
RestfulDataProviderEFQ:: |
protected | function | Get the DB column name from a property. | |
RestfulDataProviderEFQ:: |
protected | function | Initialize an EntityFieldQuery (or extending class). | |
RestfulDataProviderEFQ:: |
public | function | Get the entity info for the current entity the endpoint handling. | 1 |
RestfulDataProviderEFQ:: |
public | function | Getter for $entityType. | |
RestfulDataProviderEFQ:: |
abstract public | function | Get a list of entities. | 1 |
RestfulDataProviderEFQ:: |
public | function |
Prepare a query for RestfulEntityBase::getTotalCount(). Overrides RestfulDataProviderEFQInterface:: |
1 |
RestfulDataProviderEFQ:: |
public | function |
Prepare a query for RestfulEntityBase::getList(). Overrides RestfulDataProviderEFQInterface:: |
4 |
RestfulDataProviderEFQ:: |
public | function |
Get the total count of entities that match certain request. Overrides RestfulDataProviderEFQInterface:: |
|
RestfulDataProviderEFQ:: |
public | function |
Get a list of entities. Overrides RestfulBase:: |
|
RestfulDataProviderEFQ:: |
protected static | function |
Overrides \RestfulBase::isValidConjuctionForFilter(). Overrides RestfulBase:: |
|
RestfulDataProviderEFQ:: |
protected static | function |
Overrides \RestfulBase::isValidOperatorsForFilter(). Overrides RestfulBase:: |
|
RestfulDataProviderEFQ:: |
protected | function | Filter the query for list. | |
RestfulDataProviderEFQ:: |
protected | function | Set correct page (i.e. range) for the query for list. | |
RestfulDataProviderEFQ:: |
protected | function | Sort the query for list. | |
RestfulDataProviderEFQ:: |
public | function |
Remove the item from the data source. Overrides RestfulBase:: |
|
RestfulDataProviderEFQ:: |
public | function |
Update an item based on the request object. Overrides RestfulBase:: |
|
RestfulDataProviderEFQ:: |
abstract protected | function | Update an entity. | 1 |
RestfulDataProviderEFQ:: |
public | function |
View an item from the data source. Overrides RestfulBase:: |
|
RestfulDataProviderEFQ:: |
abstract public | function | Get a list of entities based on a list of IDs. | 1 |
RestfulDataProviderEFQ:: |
abstract public | function | View an entity. | 1 |
RestfulDataProviderEFQ:: |
public | function |
View a collection of items. Overrides RestfulBase:: |
|
RestfulDataProviderEFQ:: |
public | function |
Constructs a RestfulDataProviderEFQ object. Overrides RestfulBase:: |
2 |
RestfulInterface:: |
constant | Return this value from public field access callbacks to allow access. | ||
RestfulInterface:: |
constant | Return this value from public field access callbacks to deny access. | ||
RestfulInterface:: |
constant | Return this value from public field access callbacks to not affect access. | ||
RestfulInterface:: |
constant | |||
RestfulInterface:: |
constant | |||
RestfulInterface:: |
constant | HTTP methods. | ||
RestfulInterface:: |
constant | |||
RestfulInterface:: |
constant | |||
RestfulInterface:: |
constant | |||
RestfulInterface:: |
constant | |||
RestfulInterface:: |
public | function | Return the properties that should be public. | 7 |
RestfulInterface:: |
constant | |||
RestfulInterface:: |
constant | Token value for token generation functions. | ||
RestfulInterface:: |
constant | |||
RestfulPluginBase:: |
protected | property | The plugin definition array. | |
RestfulPluginBase:: |
public | function |
Gets information about the restful plugin. Overrides RestfulPluginInterface:: |
|
RestfulPluginBase:: |
public | function |
Gets information about the restful plugin key. Overrides RestfulPluginInterface:: |
|
RestfulPluginBase:: |
public | function |
Sets information about the restful plugin. Overrides RestfulPluginInterface:: |
|
RestfulPluginBase:: |
public | function |
Gets information about the restful plugin key. Overrides RestfulPluginInterface:: |