You are here

protected function MenuPerRoleLinkTreeManipulator::menuLinkCheckAccess in Menu Per Role 8

Checks access for one menu link instance.

Parameters

\Drupal\Core\Menu\MenuLinkInterface $instance: The menu link instance.

Return value

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

Overrides DefaultMenuLinkTreeManipulators::menuLinkCheckAccess

File

src/MenuPerRoleLinkTreeManipulator.php, line 63

Class

MenuPerRoleLinkTreeManipulator
Menu Per Role link tree manipulator service.

Namespace

Drupal\menu_per_role

Code

protected function menuLinkCheckAccess(MenuLinkInterface $instance) {
  $result = parent::menuLinkCheckAccess($instance);
  $cache_contexts = [
    'user.is_super_user',
    'route.is_admin',
  ];
  if ($this
    ->bypassAccessCheck()) {
    $result
      ->andIf(AccessResult::neutral()
      ->addCacheContexts($cache_contexts));
    return $result;
  }
  if ($instance instanceof MenuLinkContent) {

    // Sadly ::getEntity() is protected at the moment.
    $function = function () {

      // @phpstan-ignore-next-line
      return $this
        ->getEntity();
    };
    $function = \Closure::bind($function, $instance, get_class($instance));

    /** @var \Drupal\menu_link_content\Entity\MenuLinkContent $entity */
    $entity = $function();
    if (isset($entity->menu_per_role__show_role)) {
      $show_role = $entity->menu_per_role__show_role
        ->getValue();
      $show_role = array_column($show_role, 'target_id');
      $hidden_role = $entity->menu_per_role__hide_role
        ->getValue();
      $hidden_role = array_column($hidden_role, 'target_id');

      // Check whether this role has visibility access (must be present).
      if ($show_role && count(array_intersect($show_role, $this->account
        ->getRoles())) == 0) {
        $result = $result
          ->andIf(AccessResult::forbidden()
          ->addCacheContexts([
          'user.roles',
        ]));
      }

      // Check whether this role has visibility access (must not be present).
      if ($hidden_role && count(array_intersect($hidden_role, $this->account
        ->getRoles())) > 0) {
        $result = $result
          ->andIf(AccessResult::forbidden()
          ->addCacheContexts([
          'user.roles',
        ]));
      }
    }
  }
  return $result;
}