NodeAccessGrantsCacheContext.php 2.33 KB
Newer Older
1 2 3 4 5 6 7 8 9
<?php

/**
 * @file
 * Contains \Drupal\Core\Cache\NodeAccessGrantsCacheContext.
 */

namespace Drupal\node\Cache;

10 11
use Drupal\Core\Cache\Context\CalculatedCacheContextInterface;
use Drupal\Core\Cache\Context\UserCacheContext;
12 13 14 15 16 17 18

/**
 * Defines the node access view cache context service.
 *
 * This allows for node access grants-sensitive caching when listing nodes.
 *
 * @see node_query_node_access_alter()
19
 * @ingroup node_access
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
 */
class NodeAccessGrantsCacheContext extends UserCacheContext implements CalculatedCacheContextInterface {

  /**
   * {@inheritdoc}
   */
  public static function getLabel() {
    return t("Content access view grants");
  }

  /**
   * {@inheritdoc}
   */
  public function getContext($operation = NULL) {
    // If the current user either can bypass node access then we don't need to
    // determine the exact node grants for the current user.
    if ($this->user->hasPermission('bypass node access')) {
      return 'all';
    }

    // When no specific operation is specified, check the grants for all three
    // possible operations.
    if ($operation === NULL) {
      $result = [];
      foreach (['view', 'update', 'delete'] as $op) {
        $result[] = $this->checkNodeGrants($op);
      }
      return implode('-', $result);
    }
    else {
      return $this->checkNodeGrants($operation);
    }
  }

  /**
   * Checks the node grants for the given operation.
   *
   * @param string $operation
   *   The operation to check the node grants for.
   *
   * @return string
   *   The string representation of the cache context.
   */
  protected function checkNodeGrants($operation) {
    // When checking the grants for the 'view' operation and the current user
    // has a global view grant (i.e. a view grant for node ID 0) — note that
    // this is automatically the case if no node access modules exist (no
    // hook_node_grants() implementations) then we don't need to determine the
    // exact node view grants for the current user.
    if ($operation === 'view' && node_access_view_all_nodes($this->user)) {
      return 'view.all';
    }

    $grants = node_access_grants($operation, $this->user);
    $grants_context_parts = [];
    foreach ($grants as $realm => $gids) {
      $grants_context_parts[] = $realm . ':' . implode(',', $gids);
    }
    return $operation . '.' . implode(';', $grants_context_parts);
  }

}