MenuPerRoleLinkTreeManipulator.php in Menu Per Role 8
File
src/MenuPerRoleLinkTreeManipulator.php
View source
<?php
declare (strict_types=1);
namespace Drupal\menu_per_role;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Menu\DefaultMenuLinkTreeManipulators;
use Drupal\Core\Menu\MenuLinkInterface;
use Drupal\Core\Routing\AdminContext;
use Drupal\menu_link_content\Plugin\Menu\MenuLinkContent;
class MenuPerRoleLinkTreeManipulator extends DefaultMenuLinkTreeManipulators {
protected $adminContext;
protected $config;
protected $adminRoles;
public function setAdminContext(AdminContext $adminContext) : void {
$this->adminContext = $adminContext;
}
public function setConfigFactory(ConfigFactoryInterface $config) : void {
$this->config = $config;
}
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) {
$function = function () {
return $this
->getEntity();
};
$function = \Closure::bind($function, $instance, get_class($instance));
$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');
if ($show_role && count(array_intersect($show_role, $this->account
->getRoles())) == 0) {
$result = $result
->andIf(AccessResult::forbidden()
->addCacheContexts([
'user.roles',
]));
}
if ($hidden_role && count(array_intersect($hidden_role, $this->account
->getRoles())) > 0) {
$result = $result
->andIf(AccessResult::forbidden()
->addCacheContexts([
'user.roles',
]));
}
}
}
return $result;
}
protected function bypassAccessCheck() : bool {
$bypass_access_check = FALSE;
$menu_per_role_settings = $this->config
->get('menu_per_role.settings');
$admin_bypass_access_front = $menu_per_role_settings
->get('admin_bypass_access_front');
$admin_bypass_access_admin = $menu_per_role_settings
->get('admin_bypass_access_admin');
$context_is_admin = $this->adminContext
->isAdminRoute();
$user_is_admin = $this
->isUserAdmin();
if ($user_is_admin) {
if ($context_is_admin && $admin_bypass_access_admin || !$context_is_admin && $admin_bypass_access_front) {
$bypass_access_check = TRUE;
}
}
else {
if ($context_is_admin && $this->account
->hasPermission('bypass menu_per_role access admin') || !$context_is_admin && $this->account
->hasPermission('bypass menu_per_role access front')) {
$bypass_access_check = TRUE;
}
}
return $bypass_access_check;
}
protected function isUserAdmin() : bool {
if ($this->account
->id() == 1) {
return TRUE;
}
if (!$this->adminRoles) {
$role_storage = $this->entityTypeManager
->getStorage('user_role');
$admin_roles = $role_storage
->getQuery()
->condition('is_admin', TRUE)
->execute();
$this->adminRoles = $admin_roles;
}
$account_roles = $this->account
->getRoles(TRUE);
foreach ($account_roles as $account_role) {
if (in_array($account_role, $this->adminRoles)) {
return TRUE;
}
}
return FALSE;
}
}