You are here

public function MediaLibraryFieldWidgetOpener::checkAccess in Drupal 8

Same name and namespace in other branches
  1. 9 core/modules/media_library/src/MediaLibraryFieldWidgetOpener.php \Drupal\media_library\MediaLibraryFieldWidgetOpener::checkAccess()
  2. 10 core/modules/media_library/src/MediaLibraryFieldWidgetOpener.php \Drupal\media_library\MediaLibraryFieldWidgetOpener::checkAccess()

Checks media library access.

Parameters

\Drupal\media_library\MediaLibraryState $state: The media library.

\Drupal\Core\Session\AccountInterface $account: The user for which to check access.

Return value

\Drupal\Core\Access\AccessResultInterface The access result.

Overrides MediaLibraryOpenerInterface::checkAccess

See also

https://www.drupal.org/project/drupal/issues/3038254

File

core/modules/media_library/src/MediaLibraryFieldWidgetOpener.php, line 41

Class

MediaLibraryFieldWidgetOpener
The media library opener for field widgets.

Namespace

Drupal\media_library

Code

public function checkAccess(MediaLibraryState $state, AccountInterface $account) {
  $parameters = $state
    ->getOpenerParameters() + [
    'entity_id' => NULL,
  ];
  $process_result = function ($result) {
    if ($result instanceof RefinableCacheableDependencyInterface) {
      $result
        ->addCacheContexts([
        'url.query_args',
      ]);
    }
    return $result;
  };

  // Forbid access if any of the required parameters are missing.
  foreach ([
    'entity_type_id',
    'bundle',
    'field_name',
  ] as $key) {
    if (empty($parameters[$key])) {
      return $process_result(AccessResult::forbidden("{$key} parameter is missing."));
    }
  }
  $entity_type_id = $parameters['entity_type_id'];
  $bundle = $parameters['bundle'];
  $field_name = $parameters['field_name'];

  // Since we defer to a field to determine access, ensure we are dealing with
  // a fieldable entity type.
  $entity_type = $this->entityTypeManager
    ->getDefinition($entity_type_id);
  if (!$entity_type
    ->entityClassImplements(FieldableEntityInterface::class)) {
    throw new \LogicException("The media library can only be opened by fieldable entities.");
  }
  $storage = $this->entityTypeManager
    ->getStorage($entity_type_id);
  $access_handler = $this->entityTypeManager
    ->getAccessControlHandler($entity_type_id);
  if (!empty($parameters['revision_id'])) {
    $entity = $storage
      ->loadRevision($parameters['revision_id']);
    $entity_access = $access_handler
      ->access($entity, 'update', $account, TRUE);
  }
  elseif ($parameters['entity_id']) {
    $entity = $storage
      ->load($parameters['entity_id']);
    $entity_access = $access_handler
      ->access($entity, 'update', $account, TRUE);
  }
  else {
    $entity_access = $access_handler
      ->createAccess($bundle, $account, [], TRUE);
  }

  // If entity-level access is denied, there's no point in continuing.
  if (!$entity_access
    ->isAllowed()) {
    return $process_result($entity_access);
  }

  // If the entity has not been loaded, create it in memory now.
  if (!isset($entity)) {
    $values = [];
    if ($bundle_key = $entity_type
      ->getKey('bundle')) {
      $values[$bundle_key] = $bundle;
    }

    /** @var \Drupal\Core\Entity\FieldableEntityInterface $entity */
    $entity = $storage
      ->create($values);
  }
  $items = $entity
    ->get($field_name);
  $field_definition = $items
    ->getFieldDefinition();
  if ($field_definition
    ->getType() !== 'entity_reference') {
    throw new \LogicException('Expected the media library to be opened by an entity reference field.');
  }
  if ($field_definition
    ->getFieldStorageDefinition()
    ->getSetting('target_type') !== 'media') {
    throw new \LogicException('Expected the media library to be opened by an entity reference field that target media items.');
  }
  $field_access = $access_handler
    ->fieldAccess('edit', $field_definition, $account, $items, TRUE);
  return $process_result($entity_access
    ->andIf($field_access));
}