You are here

protected static function TemporaryQueryGuard::getAccessConditionForKnownSubsets in JSON:API 8

Same name and namespace in other branches
  1. 8.2 src/Access/TemporaryQueryGuard.php \Drupal\jsonapi\Access\TemporaryQueryGuard::getAccessConditionForKnownSubsets()

Gets an access condition for the allowed JSONAPI_FILTER_AMONG_* subsets.

If access is allowed for the JSONAPI_FILTER_AMONG_ALL subset, then no conditions are returned. Otherwise, if access is allowed for JSONAPI_FILTER_AMONG_PUBLISHED, JSONAPI_FILTER_AMONG_ENABLED, or JSONAPI_FILTER_AMONG_OWN, then a condition group is returned for the union of allowed subsets. If no subsets are allowed, then static::alwaysFalse() is returned.

Parameters

\Drupal\Core\Entity\EntityTypeInterface $entity_type: The entity type for which to check filter access.

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

\Drupal\Core\Cache\CacheableMetadata $cacheability: Collects cacheability for the query.

Return value

\Drupal\jsonapi\Query\EntityConditionGroup|null An EntityConditionGroup or NULL if no conditions need to be applied to secure an entity query.

1 call to TemporaryQueryGuard::getAccessConditionForKnownSubsets()
TemporaryQueryGuard::getAccessCondition in src/Access/TemporaryQueryGuard.php
Gets an EntityConditionGroup that filters out inaccessible entities.

File

src/Access/TemporaryQueryGuard.php, line 350

Class

TemporaryQueryGuard
Adds sufficient access control to collection queries.

Namespace

Drupal\jsonapi\Access

Code

protected static function getAccessConditionForKnownSubsets(EntityTypeInterface $entity_type, AccountInterface $account, CacheableMetadata $cacheability) {

  // Get the combined access results for each JSONAPI_FILTER_AMONG_* subset.
  $access_results = static::getAccessResultsFromEntityFilterHook($entity_type, $account);

  // No conditions are needed if access is allowed for all entities.
  $cacheability
    ->addCacheableDependency($access_results[JSONAPI_FILTER_AMONG_ALL]);
  if ($access_results[JSONAPI_FILTER_AMONG_ALL]
    ->isAllowed()) {
    return NULL;
  }

  // If filtering is not allowed across all entities, but is allowed for
  // certain subsets, then add conditions that reflect those subsets. These
  // will be grouped in an OR to reflect that access may be granted to
  // more than one subset. If no conditions are added below, then
  // static::alwaysFalse() is returned.
  $conditions = [];

  // The "published" subset.
  $published_field_name = $entity_type
    ->getKey('published');
  if ($published_field_name) {
    $access_result = $access_results[JSONAPI_FILTER_AMONG_PUBLISHED];
    $cacheability
      ->addCacheableDependency($access_result);
    if ($access_result
      ->isAllowed()) {
      $conditions[] = new EntityCondition($published_field_name, 1);
      $cacheability
        ->addCacheTags($entity_type
        ->getListCacheTags());
    }
  }

  // @todo Remove when Drupal 8.5 support is dropped (terms are publishable in >=8.6).
  if (floatval(\Drupal::VERSION) < 8.6 && $entity_type
    ->id() === 'taxonomy_term') {
    $access_result = $access_results[JSONAPI_FILTER_AMONG_PUBLISHED];
    $cacheability
      ->addCacheableDependency($access_result);
    if ($access_result
      ->isAllowed()) {
      $conditions[] = new EntityCondition('tid', 0, '>');
      $cacheability
        ->addCacheTags($entity_type
        ->getListCacheTags());
    }
  }

  // The "enabled" subset.
  // @todo Remove ternary when the 'status' key is added to the User entity type.
  $status_field_name = $entity_type
    ->id() === 'user' ? 'status' : $entity_type
    ->getKey('status');
  if ($status_field_name) {
    $access_result = $access_results[JSONAPI_FILTER_AMONG_ENABLED];
    $cacheability
      ->addCacheableDependency($access_result);
    if ($access_result
      ->isAllowed()) {
      $conditions[] = new EntityCondition($status_field_name, 1);
      $cacheability
        ->addCacheTags($entity_type
        ->getListCacheTags());
    }
  }

  // The "owner" subset.
  // @todo Remove ternary when the 'uid' key is added to the User entity type.
  $owner_field_name = $entity_type
    ->id() === 'user' ? 'uid' : $entity_type
    ->getKey('owner');

  // @todo Remove when Drupal 8.5 and 8.6 support is dropped.
  if (floatval(\Drupal::VERSION) < 8.699999999999999) {
    $owner_field_name = $entity_type
      ->id() === 'user' ? $owner_field_name : $entity_type
      ->getKey('uid');
  }
  if ($owner_field_name) {
    $access_result = $access_results[JSONAPI_FILTER_AMONG_OWN];
    $cacheability
      ->addCacheableDependency($access_result);
    if ($access_result
      ->isAllowed()) {
      $cacheability
        ->addCacheContexts([
        'user',
      ]);
      if ($account
        ->isAuthenticated()) {
        $conditions[] = new EntityCondition($owner_field_name, $account
          ->id());
        $cacheability
          ->addCacheTags($entity_type
          ->getListCacheTags());
      }
    }
  }

  // If no conditions were added above, then access wasn't granted to any
  // subset, so return alwaysFalse().
  if (empty($conditions)) {
    return static::alwaysFalse($entity_type);
  }

  // If more than one condition was added above, then access was granted to
  // more than one subset, so combine them with an OR.
  if (count($conditions) > 1) {
    return new EntityConditionGroup('OR', $conditions);
  }

  // Otherwise return the single condition.
  return $conditions[0];
}