You are here

class RestWSEntityResourceController in RESTful Web Services 7

Same name and namespace in other branches
  1. 7.2 restws.entity.inc \RestWSEntityResourceController

Controller for entity-bases resources.

Hierarchy

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');
  }

}

Members

Namesort descending Modifiers Type Description Overrides
RestWSEntityResourceController::$entityType protected property
RestWSEntityResourceController::access public function Determines access for a given operation and resource. Overrides RestWSResourceControllerInterface::access
RestWSEntityResourceController::checkPropertyAccess protected function Helper method to check access on a property.
RestWSEntityResourceController::create public function Create a new resource. Overrides RestWSResourceControllerInterface::create
RestWSEntityResourceController::delete public function Delete an existing resource. Overrides RestWSResourceControllerInterface::delete
RestWSEntityResourceController::propertyInfo public function Returns the property info for the given resource. Overrides RestWSResourceControllerInterface::propertyInfo
RestWSEntityResourceController::read public function Returns an existing resource. Overrides RestWSResourceControllerInterface::read
RestWSEntityResourceController::resource public function Returns the name of the resource. Overrides RestWSResourceControllerInterface::resource
RestWSEntityResourceController::update public function Update an existing resource. Overrides RestWSResourceControllerInterface::update
RestWSEntityResourceController::wrapper public function Returns a metadata wrapper for the resource with the given id. Overrides RestWSResourceControllerInterface::wrapper
RestWSEntityResourceController::__construct public function