You are here

public function DefaultMenuLinkTreeManipulators::checkNodeAccess in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Menu/DefaultMenuLinkTreeManipulators.php \Drupal\Core\Menu\DefaultMenuLinkTreeManipulators::checkNodeAccess()

Performs access checking for nodes in an optimized way.

This manipulator should be added before the generic ::checkAccess() one, because it provides a performance optimization for ::checkAccess().

Parameters

\Drupal\Core\Menu\MenuLinkTreeElement[] $tree: The menu link tree to manipulate.

Return value

\Drupal\Core\Menu\MenuLinkTreeElement[] The manipulated menu link tree.

File

core/lib/Drupal/Core/Menu/DefaultMenuLinkTreeManipulators.php, line 132

Class

DefaultMenuLinkTreeManipulators
Provides a couple of menu link tree manipulators.

Namespace

Drupal\Core\Menu

Code

public function checkNodeAccess(array $tree) {
  $node_links = [];
  $this
    ->collectNodeLinks($tree, $node_links);
  if ($node_links) {
    $nids = array_keys($node_links);
    $query = $this->entityTypeManager
      ->getStorage('node')
      ->getQuery();
    $query
      ->accessCheck(TRUE);
    $query
      ->condition('nid', $nids, 'IN');

    // Allows admins to view all nodes, by both disabling node_access
    // query rewrite as well as not checking for the node status. The
    // 'view own unpublished nodes' permission is ignored to not require cache
    // entries per user.
    $access_result = AccessResult::allowed()
      ->cachePerPermissions();
    if ($this->account
      ->hasPermission('bypass node access')) {
      $query
        ->accessCheck(FALSE);
    }
    else {
      $access_result
        ->addCacheContexts([
        'user.node_grants:view',
      ]);
      $query
        ->condition('status', NodeInterface::PUBLISHED);
    }
    $nids = $query
      ->execute();
    foreach ($nids as $nid) {
      foreach ($node_links[$nid] as $key => $link) {
        $node_links[$nid][$key]->access = $access_result;
      }
    }
  }
  return $tree;
}