groupmenu-8.x-1.0-beta2/src/GroupMenuService.php
src/GroupMenuService.php
<?php
namespace Drupal\groupmenu;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\group\GroupMembershipLoader;
use Drupal\system\MenuInterface;
/**
* Checks access for displaying menu pages.
*/
class GroupMenuService implements GroupMenuServiceInterface {
/**
* Static cache of groupmenu.settings.
*
* @var array
*/
protected $groupmenuConfig;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The current user's account object.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* The group membership loader.
*
* @var \Drupal\group\GroupMembershipLoader
*/
protected $membershipLoader;
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* An array containing the menu access results.
*
* @var array
*/
protected $menuAccess = [];
/**
* An array containing the menus for a user.
*
* @var array
*/
protected $userMenus = [];
/**
* An array containing the menus for a user and group.
*
* @var array
*/
protected $userGroupMenus = [];
/**
* Static cache of all group menu objects keyed by group ID.
*
* @var \Drupal\system\MenuInterface[][]
*/
protected $groupMenus = [];
/**
* Constructs a GroupTypeController.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
* @param \Drupal\group\GroupMembershipLoader $membership_loader
* The group membership loader.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The factory for configuration objects.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, AccountInterface $current_user, GroupMembershipLoader $membership_loader, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $configFactory) {
$this->entityTypeManager = $entity_type_manager;
$this->currentUser = $current_user;
$this->membershipLoader = $membership_loader;
$this->moduleHandler = $module_handler;
$this->configFactory = $configFactory;
}
/**
* {@inheritdoc}
*/
public function getConfig() {
if (!$this->groupmenuConfig) {
$this->groupmenuConfig = $this->configFactory->get('groupmenu.settings');
}
return $this->groupmenuConfig;
}
/**
* {@inheritdoc}
*/
public function setConfig(string $key, string $value) {
$this->configFactory->getEditable('groupmenu.settings')->set($key, $value)->save();
}
/**
* {@inheritdoc}
*/
public function menuAccess($op, MenuInterface $menu, AccountInterface $account = NULL) {
if (!isset($account)) {
$account = $this->currentUser;
}
$account_id = $account->id();
$menu_id = $menu->id();
$plugin_id = 'group_menu:menu';
if (isset($this->menuAccess[$op][$account_id][$menu_id])) {
return $this->menuAccess[$op][$account_id][$menu_id];
}
if ($account->hasPermission('administer menu')) {
return $this->menuAccess[$op][$account_id][$menu_id] = AccessResult::allowed();
}
$group_relationship = $this->entityTypeManager->getStorage('group_relationship');
$group_relationships = $group_relationship->loadByEntity($menu);
// If the menu does not belong to any group, we have nothing to say.
if (empty($group_relationships)) {
return $this->menuAccess[$op][$account_id][$menu_id] = AccessResult::neutral();
}
// Load menus' groups based on group relationships.
/** @var \Drupal\group\Entity\GroupInterface[] $groups */
$groups = [];
foreach ($group_relationships as $group_relationship) {
/** @var \Drupal\group\Entity\GroupRelationshipInterface $group_relationship */
$group = $group_relationship->getGroup();
$groups[$group->id()] = $group;
}
foreach ($groups as $group) {
if (!$group->getMember($account)) {
return $this->menuAccess[$op][$account_id][$menu_id] = AccessResult::neutral();
}
// From this point on you need group to allow you to perform the requested
// operation. If you are not granted access for a group, you should be
// denied access instead.
if ($group->hasPermission("$op $plugin_id entity", $account) ||
$group->hasPermission("$op any $plugin_id entity", $account)
) {
return $this->menuAccess[$op][$account_id][$menu_id] = AccessResult::allowed();
}
}
return $this->menuAccess[$op][$account_id][$menu_id] = AccessResult::neutral();
}
/**
* {@inheritdoc}
*/
public function loadUserGroupMenus($op, AccountInterface $account = NULL) {
if (!isset($account)) {
$account = $this->currentUser;
}
$account_id = $account->id();
if (isset($this->userMenus[$op][$account_id])) {
return $this->userMenus[$op][$account_id];
}
$group_memberships = $this->membershipLoader->loadByUser($account);
$this->userMenus[$op][$account_id] = [];
foreach ($group_memberships as $group_membership) {
$gid = $group_membership->getGroupRelationship()->getGroupId();
$this->userMenus[$op][$account_id] += $this->loadUserGroupMenusByGroup($op, $gid, $account);
}
return $this->userMenus[$op][$account_id];
}
/**
* {@inheritdoc}
*/
public function loadUserGroupMenusByGroup($op, $group_id, AccountInterface $account = NULL) {
if (!isset($account)) {
$account = $this->currentUser;
}
$account_id = $account->id();
if (isset($this->userGroupMenus[$op][$account_id][$group_id])) {
return $this->userGroupMenus[$op][$account_id][$group_id];
}
$group_menus = $this->getGroupMenus();
$group_menu_for_group = (!empty($group_menus[$group_id])) ? $group_menus[$group_id] : [];
return $this->userGroupMenus[$op][$account_id][$group_id] = $group_menu_for_group;
}
/**
* {@inheritdoc}
*/
public function getGroupMenus() {
if (!$this->groupMenus) {
$plugin_id = 'group_menu:menu';
$menus = $this->entityTypeManager->getStorage('menu')
->loadMultiple();
// Get all group menu group relationships.
$group_relationships = $this->entityTypeManager->getStorage('group_relationship')
->loadByPluginId($plugin_id);
foreach ($group_relationships as $group_relationship) {
/** @var \Drupal\group\Entity\GroupRelationshipInterface $group_relationship */
// If neither the group id or menu id is available, skip this record.
if (!isset($group_relationship->gid->target_id) || !isset($group_relationship->entity_id->target_id)) {
continue;
}
// Group id.
$gid = $group_relationship->getGroupId();
// Returns string id of menu.
$menu_id = $group_relationship->getEntityId();
$this->groupMenus[$gid][$menu_id] = $menus[$menu_id];
}
}
return $this->groupMenus;
}
}
