abstract class RestWSBaseFormat in RESTful Web Services 7.2
Same name and namespace in other branches
- 7 restws.formats.inc \RestWSBaseFormat
A base for all simple formats that are just serializing/unserializing an array of property values.
Hierarchy
- class \RestWSBaseFormat implements RestWSFormatInterface
Expanded class hierarchy of RestWSBaseFormat
File
- ./
restws.formats.inc, line 97 - RESTful web services module formats.
View source
abstract class RestWSBaseFormat implements RestWSFormatInterface {
protected $formatName;
protected $formatInfo;
public function __construct($name, $info) {
$this->formatName = $name;
$this->formatInfo = $info;
}
/**
* Gets the representation of a resource.
*/
public function viewResource($resourceController, $id) {
$values = $this
->getData($resourceController
->wrapper($id));
$function = __FUNCTION__;
drupal_alter('restws_response', $values, $function, $this->formatName, $resourceController);
return $this
->serialize($values);
}
/**
* Creates a new resource.
*/
public function createResource($resourceController, $data) {
$values = $this
->unserialize($resourceController
->propertyInfo(), $data);
$id = $resourceController
->create($values);
$ref = $this
->getResourceReference($resourceController
->resource(), $id);
$function = __FUNCTION__;
drupal_alter('restws_response', $ref, $function, $this->formatName, $resourceController);
return $this
->serialize($ref);
}
/**
* Updates a resource.
*/
public function updateResource($resourceController, $id, $data) {
$values = $this
->unserialize($resourceController
->propertyInfo(), $data);
$resourceController
->update($id, $values);
// Return an empty representation by default.
$value = array();
$function = __FUNCTION__;
drupal_alter('restws_response', $value, $function, $this->formatName, $resourceController);
return $this
->serialize($value);
}
/**
* Deletes a resource.
*/
public function deleteResource($resourceController, $id) {
$resourceController
->delete($id);
// Return an empty representation by default.
$value = array();
$function = __FUNCTION__;
drupal_alter('restws_response', $value, $function, $this->formatName, $resourceController);
return $this
->serialize($value);
}
/**
* Implements RestWSFormatInterface::queryResource().
*/
public function queryResource($resourceController, $payload) {
// Get the parameter from the URL.
$parameters = drupal_get_query_parameters();
$rest_controls = restws_meta_controls();
$properties = $resourceController
->propertyInfo();
$split_parameters = $this
->splitParameters($properties, $parameters);
$values = $this
->generateQueryURIs($resourceController, $parameters, $split_parameters['filters']);
$full = isset($split_parameters['meta_controls'][$rest_controls['full']]) ? $split_parameters['meta_controls'][$rest_controls['full']] : 1;
$result = $resourceController
->query($split_parameters['filters'], $split_parameters['meta_controls']);
$values['list'] = array();
if ($full === '0') {
foreach ($result as $id) {
$values['list'][] = $this
->getResourceReference($resourceController
->resource(), $id);
}
}
else {
foreach ($result as $id) {
$values['list'][] = $this
->getData($resourceController
->wrapper($id));
}
}
$function = __FUNCTION__;
drupal_alter('restws_response', $values, $function, $this->formatName, $resourceController);
return $this
->serialize($values);
}
public function mimeType() {
return $this->formatInfo['mime type'];
}
public function getName() {
return $this->formatName;
}
/**
* Gets a simple PHP array using URI references for some wrapped data.
*
* This is the counter-part of self::getPropertyValues().
*/
public function getData($wrapper) {
$data = array();
$filtered = restws_property_access_filter($wrapper);
foreach ($filtered as $name => $property) {
try {
if ($property instanceof EntityDrupalWrapper) {
// For referenced entities only return the URI.
if ($id = $property
->getIdentifier()) {
$data[$name] = $this
->getResourceReference($property
->type(), $id);
}
}
elseif ($property instanceof EntityValueWrapper) {
$data[$name] = $property
->value();
}
elseif ($property instanceof EntityListWrapper || $property instanceof EntityStructureWrapper) {
$data[$name] = $this
->getData($property);
}
} catch (EntityMetadataWrapperException $e) {
// A property causes problems - ignore that.
}
}
return $data;
}
public function getResourceReference($resource, $id) {
$return = array(
'uri' => restws_resource_uri($resource, $id),
'id' => $id,
'resource' => $resource,
);
if (module_exists('uuid') && ($info = entity_get_info($resource))) {
// Check whether the entity type integrates with UUID module.
if ($info['base table'] && in_array('uuid', $info['schema_fields_sql']['base table'])) {
$ids = entity_get_uuid_by_id($resource, array(
$id,
));
if ($id = reset($ids)) {
$return['uuid'] = $id;
}
}
}
return $return;
}
/**
* Transforms simple-array data values to valid entity property values.
*
* This is the counter-part of $this->getData(), thus it converts resource
* references to the required value(s).
*
* @param array $values
* The array representation of the data values.
* @param $property_info
* The property info array of the entity type for which we are transforming
* the values.
*/
protected function getPropertyValues(array &$values, $property_info) {
foreach ($values as $name => &$property_value) {
if (isset($property_info[$name]) && ($info = $property_info[$name])) {
// Check if there is a resource array and if the property has a type.
if (is_array($property_value) && isset($info['type'])) {
// Check if the field is a list or a single value field.
if (entity_property_list_extract_type($info['type'])) {
// Check if the list values consist of structure wrappers.
if (array_key_exists('property info', $info)) {
foreach ($property_value as &$list_values) {
$this
->getPropertyValues($list_values, $info['property info']);
}
}
else {
$list_type = entity_property_list_extract_type($info['type']);
foreach ($property_value as &$list_value) {
$list_value = $this
->getResourceReferenceValue($list_type, $list_value);
}
}
}
else {
// Check if the property is a structure wrapper.
if (array_key_exists('property info', $info)) {
$this
->getPropertyValues($property_value, $info['property info']);
}
else {
$property_value = $this
->getResourceReferenceValue($info['type'], $property_value);
}
}
}
}
}
}
/**
* Gets the resource reference value.
*
* @param $type
* The data type of the reference property.
* @param array $reference
* The input data specifying the resource reference in one supported way.
*
* @return mixed
* The value to be set for the reference. Usually this is an entity or
* resource id, but for generic entity references it's an
* EntityDrupalWrapper.
*
* @see RestWSBaseFormat::getResourceReference()
*/
protected function getResourceReferenceValue($type, array $reference) {
if (isset($reference['id']) && $type != 'entity') {
return $reference['id'];
}
elseif ($type == 'entity' && isset($reference['id']) && isset($reference['resource'])) {
if (!entity_get_info($reference['resource'])) {
throw new RestWSException('Invalid resource for entity reference given.', 406);
}
return entity_metadata_wrapper($reference['resource'], $reference['id']);
}
elseif (isset($reference['uri'])) {
// @todo: Implement setting references by URI by parsing resource/id from
// the URI.
}
elseif (isset($reference['uuid']) && module_exists('uuid') && $type != 'entity') {
$ids = entity_get_id_by_uuid($type, array(
$reference['uuid'],
));
if (!$ids) {
throw new RestWSException('Invalid UUID for resource reference given.', 406);
}
return reset($ids);
}
throw new RestWSException('Invalid value for resource reference given.', 406);
}
/**
* Splits a query parameter into two sub arrays containing the filters and
* meta controls.
*
* @param array $properties
* An array containing the properties of the resource.
*
* @param array $parameters
* An array which contains filters and meta controls.
*
* @return array
* An array containing two sub arrays, one for filters and one for meta
* controls with corresponding keys.
*
* @throws RestWSException
* If a filter isn't valid, the function will throw a RestWSException with
* the 412 HTTP status code.
*/
protected function splitParameters($properties, array $parameters) {
$meta_controls = array();
$rest_controls = restws_meta_controls();
foreach ($parameters as $control_name => $property) {
if (isset($rest_controls[$control_name])) {
$meta_controls[$control_name] = $property;
unset($parameters[$control_name]);
}
}
$filters = array();
foreach ($parameters as $parameter => $value) {
// Check if the property is prefixed.
if (substr($parameter, 0, 9) == 'property_') {
$parameter = substr($parameter, 9, strlen($parameter) - 9);
}
// If the parameter doesn't exist, we can not filter for and need to
// notify the client about it.
if (!isset($properties[$parameter])) {
throw new RestWSException('Not a valid filter: ' . $parameter, 412);
}
$filters[$parameter] = $value;
}
return array(
'meta_controls' => $meta_controls,
'filters' => $filters,
);
}
/**
* Generates all navigation links for querying.
*
* @param RestWSResourceControllerInterface $resourceController
* The controller used to query the resource.
*
* @param array $parameters
* The HTTP GET parameters for the query.
*
* @param array $filters
* The filters for the query.
*
* @return array
* An array containing all navigation links.
*
* @throws RestWSException
* If the page is out of range the function will throw a new RestWSException
* with HTTP status code 404.
*/
protected function generateQueryURIs(RestWSResourceControllerInterface $resourceController, array $parameters, array $filters) {
$rest_controls = restws_meta_controls();
$count = $resourceController
->count($filters);
$limit = isset($parameters[$rest_controls['limit']]) ? $parameters[$rest_controls['limit']] : NULL;
$limit = $resourceController
->limit($limit);
$page = isset($parameters[$rest_controls['page']]) ? $parameters[$rest_controls['page']] : 0;
$last = floor($count / $limit);
if ($page > $last || $page < 0) {
throw new RestWSException('Page doesn\'t exist.', 404);
}
$uris = array();
$options = array(
'query' => &$parameters,
);
$uris['self'] = restws_resource_uri($resourceController
->resource(), NULL, $options);
$parameters['page'] = 0;
$uris['first'] = restws_resource_uri($resourceController
->resource(), NULL, $options);
$parameters['page'] = $last;
$uris['last'] = restws_resource_uri($resourceController
->resource(), NULL, $options);
if ($page != 0) {
$parameters['page'] = $page - 1;
$uris['prev'] = restws_resource_uri($resourceController
->resource(), NULL, $options);
}
if ($page != $last) {
$parameters['page'] = $page + 1;
$uris['next'] = restws_resource_uri($resourceController
->resource(), NULL, $options);
}
return $uris;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
RestWSBaseFormat:: |
protected | property | ||
RestWSBaseFormat:: |
protected | property | ||
RestWSBaseFormat:: |
public | function |
Creates a new resource. Overrides RestWSFormatInterface:: |
2 |
RestWSBaseFormat:: |
public | function |
Deletes a resource. Overrides RestWSFormatInterface:: |
|
RestWSBaseFormat:: |
protected | function | Generates all navigation links for querying. | |
RestWSBaseFormat:: |
public | function | Gets a simple PHP array using URI references for some wrapped data. | |
RestWSBaseFormat:: |
public | function |
Returns the short name of this format. Overrides RestWSFormatInterface:: |
|
RestWSBaseFormat:: |
protected | function | Transforms simple-array data values to valid entity property values. | |
RestWSBaseFormat:: |
public | function | ||
RestWSBaseFormat:: |
protected | function | Gets the resource reference value. | |
RestWSBaseFormat:: |
public | function |
Returns the mime type of this format, e.g. 'application/json' or
'application/xml'. Overrides RestWSFormatInterface:: |
|
RestWSBaseFormat:: |
public | function |
Implements RestWSFormatInterface::queryResource(). Overrides RestWSFormatInterface:: |
2 |
RestWSBaseFormat:: |
protected | function | Splits a query parameter into two sub arrays containing the filters and meta controls. | |
RestWSBaseFormat:: |
public | function |
Updates a resource. Overrides RestWSFormatInterface:: |
1 |
RestWSBaseFormat:: |
public | function |
Gets the representation of a resource. Overrides RestWSFormatInterface:: |
2 |
RestWSBaseFormat:: |
public | function | 1 |