You are here

function paragraphs_paragraphs_item_access in Paragraphs 7

Implements hook_paragraphs_item_access().

File

./paragraphs.module, line 223
Paragraphs hooks and common functions.

Code

function paragraphs_paragraphs_item_access(ParagraphsItemEntity $entity, $op, $account) {
  $permissions =& drupal_static(__FUNCTION__, array());
  $parent_permissions =& drupal_static(__FUNCTION__ . '_parents', array());
  if (!in_array($op, array(
    'view',
    'update',
    'delete',
    'create',
  ), TRUE)) {

    // If there was no bundle to check against, or the $op was not one of the
    // supported ones, we return access denied.
    return PARAGRAPHS_ITEM_ACCESS_IGNORE;
  }
  $check_parent_op = $op;

  // Update/Delete/Create access requires update access on the parent.
  if (in_array($op, array(
    'update',
    'delete',
    'create',
  ), TRUE)) {
    $check_parent_op = 'update';
  }

  // When we have no entity, create a generic cid.
  if (empty($entity)) {
    $cid = 'all_entities:' . $op;
  }
  elseif ($op == 'create' || isset($entity->is_new) && $entity->is_new) {
    $cid = $entity->bundle;
  }
  else {
    $cid = $entity->item_id . '_' . $entity->revision_id;
  }

  // Check if we cached permission check.
  if (isset($permissions[$account->uid][$cid][$op])) {
    return $permissions[$account->uid][$cid][$op];
  }
  if (empty($entity)) {

    // Ignore access when we don't have a host entity.
    $permissions[$account->uid][$cid][$op] = PARAGRAPHS_ITEM_ACCESS_IGNORE;
  }
  elseif ($host_entity = $entity
    ->hostEntity()) {
    $host_entity_info = entity_get_info($entity
      ->hostEntityType());
    $host_id_key = $host_entity_info['entity keys']['id'];
    $parent_cid = $entity
      ->hostEntityType() . '_' . implode('_', entity_extract_ids($entity
      ->hostEntityType(), $host_entity));

    // Check if we have an ID key set. If not then the parent entity is new and
    // we check for create access.
    if (!isset($host_entity->{$host_id_key}) || empty($host_entity->{$host_id_key})) {
      $check_parent_op = 'create';
      $host_entity->is_new = TRUE;
    }
    if (isset($parent_permissions[$account->uid][$parent_cid][$check_parent_op])) {
      return $parent_permissions[$account->uid][$parent_cid][$check_parent_op];
    }

    // We need to use node_access over node's entity_access permission check
    // because entity_access will fallback to checking revision permissions when
    // trying to update paragraph items in a node revision.
    if ($entity
      ->hostEntityType() == 'node') {

      // We assume that any node without a nid is being created and check
      // permissions against the node bundle.
      if (!isset($host_entity->nid) && node_access($check_parent_op, $entity
        ->hostEntityBundle())) {
        $permissions[$account->uid][$cid][$op] = PARAGRAPHS_ITEM_ACCESS_ALLOW;
      }
      elseif (isset($host_entity->nid) && node_access($check_parent_op, $host_entity)) {
        $permissions[$account->uid][$cid][$op] = PARAGRAPHS_ITEM_ACCESS_ALLOW;
      }
      else {
        $permissions[$account->uid][$cid][$op] = PARAGRAPHS_ITEM_ACCESS_DENY;
      }
    }
    else {
      if (entity_access($check_parent_op, $entity
        ->hostEntityType(), $host_entity)) {
        $permissions[$account->uid][$cid][$op] = PARAGRAPHS_ITEM_ACCESS_ALLOW;
        $parent_permissions[$account->uid][$parent_cid][$check_parent_op] = PARAGRAPHS_ITEM_ACCESS_ALLOW;
      }
      else {

        // Deny access as parent entity access failed.
        $permissions[$account->uid][$cid][$op] = PARAGRAPHS_ITEM_ACCESS_DENY;
        $parent_permissions[$account->uid][$parent_cid][$check_parent_op] = PARAGRAPHS_ITEM_ACCESS_DENY;
      }
    }
  }
  else {

    // Ignore access when we don't have a host entity.
    $permissions[$account->uid][$cid][$op] = PARAGRAPHS_ITEM_ACCESS_IGNORE;
  }
  return $permissions[$account->uid][$cid][$op];
}