function EntityAccessControlHandler::fieldAccess

Same name and namespace in other branches
  1. 11.x core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php \Drupal\Core\Entity\EntityAccessControlHandler::fieldAccess()

File

core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php, line 314

Class

EntityAccessControlHandler
Defines a default implementation for entity access control handler.

Namespace

Drupal\Core\Entity

Code

public function fieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account = NULL, FieldItemListInterface $items = NULL, $return_as_object = FALSE) {
  $account = $this->prepareUser($account);
  // Get the default access restriction that lives within this field.
  $default = $items ? $items->defaultAccess($operation, $account) : AccessResult::allowed();
  // Explicitly disallow changing the entity ID and entity UUID.
  $entity = $items ? $items->getEntity() : NULL;
  if ($operation === 'edit' && $entity) {
    if ($field_definition->getName() === $this->entityType
      ->getKey('id')) {
      // String IDs can be set when creating the entity.
      if (!($entity->isNew() && $field_definition->getType() === 'string')) {
        return $return_as_object ? AccessResult::forbidden('The entity ID cannot be changed.')->addCacheableDependency($entity) : FALSE;
      }
    }
    elseif ($field_definition->getName() === $this->entityType
      ->getKey('uuid')) {
      // UUIDs can be set when creating an entity.
      if (!$entity->isNew()) {
        return $return_as_object ? AccessResult::forbidden('The entity UUID cannot be changed.')->addCacheableDependency($entity) : FALSE;
      }
    }
  }
  // Get the default access restriction as specified by the access control
  // handler.
  $entity_default = $this->checkFieldAccess($operation, $field_definition, $account, $items);
  // Combine default access, denying access wins.
  $default = $default->andIf($entity_default);
  // Invoke hook and collect grants/denies for field access from other
  // modules.
  $grants = [];
  $this->moduleHandler()
    ->invokeAllWith('entity_field_access', function (callable $hook, string $module) use ($operation, $field_definition, $account, $items, &$grants) {
    $grants[] = [
      $module => $hook($operation, $field_definition, $account, $items),
    ];
  });
  // Our default access flag is masked under the ':default' key.
  $grants = array_merge([
    ':default' => $default,
  ], ...$grants);
  // Also allow modules to alter the returned grants/denies.
  $context = [
    'operation' => $operation,
    'field_definition' => $field_definition,
    'items' => $items,
    'account' => $account,
  ];
  $this->moduleHandler()
    ->alter('entity_field_access', $grants, $context);
  $result = $this->processAccessHookResults($grants);
  return $return_as_object ? $result : $result->isAllowed();
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.