class RestWSEntityResourceController in RESTful Web Services 7
Same name and namespace in other branches
- 7.2 restws.entity.inc \RestWSEntityResourceController
Controller for entity-bases resources.
Hierarchy
- class \RestWSEntityResourceController implements RestWSResourceControllerInterface
Expanded class hierarchy of RestWSEntityResourceController
1 string reference to 'RestWSEntityResourceController'
- restws_restws_resource_info in ./
restws.module - Implements hook_restws_resource_info().
File
- ./
restws.entity.inc, line 93 - RESTful web services module integration for entities.
View source
class RestWSEntityResourceController implements RestWSResourceControllerInterface {
protected $entityType, $entityInfo;
public function __construct($name, $info) {
$this->entityType = $name;
$this->entityInfo = entity_get_info($name);
}
public function propertyInfo() {
return entity_get_property_info($this->entityType);
}
public function wrapper($id) {
return entity_metadata_wrapper($this->entityType, $id);
}
public function read($id) {
return $this
->wrapper($id)
->value();
}
public function create(array $values) {
// Make sure that bundle information is present on entities that have
// bundles.
$entity_info = entity_get_info($this->entityType);
if (isset($entity_info['bundle keys'])) {
foreach ($entity_info['bundle keys'] as $bundle_key) {
if (!array_key_exists($bundle_key, $values)) {
throw new RestWSException('Missing bundle: ' . $bundle_key, 406);
}
}
}
try {
$wrapper = entity_property_values_create_entity($this->entityType, $values);
// Get the ID and bundle property names.
$entity_keys = array_intersect_key($entity_info['entity keys'], array(
'id' => 1,
'bundle' => 1,
));
foreach (array_keys($values) as $name) {
// Don't check access on entity keys for new entities. Otherwise,
// property access checks will fail for, e.g., node type, which
// requires the 'administer nodes' permission to set.
// @see entity_metadata_node_entity_property_info().
if (!in_array($name, $entity_keys)) {
if (!$this
->checkPropertyAccess($wrapper, $name, $wrapper->{$name})) {
throw new RestWSException(t('Not authorized to set property @p', array(
'@p' => $name,
)), 403);
}
}
}
} catch (EntityMetadataWrapperException $e) {
throw new RestWSException($e
->getMessage(), 406);
}
$properties = $wrapper
->getPropertyInfo();
$diff = array_diff_key($values, $properties);
if (!empty($diff)) {
throw new RestWSException('Unknown data properties: ' . implode(' ', array_keys($diff)) . '.', 406);
}
$wrapper
->save();
return $wrapper
->getIdentifier();
}
public function update($id, array $values) {
$wrapper = $this
->wrapper($id);
$entity_info = $wrapper
->entityInfo();
// Get the ID and bundle property names.
$entity_keys = array_intersect_key($entity_info['entity keys'], array(
'id' => 1,
'bundle' => 1,
));
try {
foreach ($values as $name => $value) {
if (in_array($name, $entity_keys)) {
// We don't allow changing the entity ID or bundle.
if ($wrapper->{$name}
->value() != $value) {
throw new RestWSException('Unable to change ' . $name, 422);
}
}
else {
$wrapper->{$name}
->set($value);
if (!$this
->checkPropertyAccess($wrapper, $name, $wrapper->{$name})) {
throw new RestWSException(t('Not authorized to set property @p', array(
'@p' => $name,
)), 403);
}
}
}
} catch (EntityMetadataWrapperException $e) {
throw new RestWSException($e
->getMessage(), 406);
}
$wrapper
->save();
}
public function delete($id) {
entity_delete($this->entityType, $id);
}
public function access($op, $id) {
return entity_access($op, $this->entityType, isset($id) ? $this
->wrapper($id)
->value() : NULL);
}
public function resource() {
return $this->entityType;
}
/**
* Helper method to check access on a property.
*
* @todo Remove this once Entity API properly handles text format access.
*
* @param EntityMetadataWrapper $entity
* The parent entity.
* @param string $property_name
* The property name on the entity.
* @param EntityMetadataWrapper $property
* The property whose access is to be checked.
*
* @return bool
* TRUE if the current user has access to set the property, FALSE otherwise.
*/
protected function checkPropertyAccess($entity, $property_name, $property) {
global $user;
// Special case node author: we allow access if set to the current user.
if ($entity
->type() == 'node' && $property_name == 'author' && $property
->raw() == $GLOBALS['user']->uid) {
return TRUE;
}
elseif ($property
->type() == 'text_formatted' && $property->format
->value()) {
$format = (object) array(
'format' => $property->format
->value(),
);
if (!filter_access($format)) {
return FALSE;
}
}
return $property
->access('edit');
}
}