groupmenu-8.x-1.0-beta2/src/GroupMenuConfigOverrides.php
src/GroupMenuConfigOverrides.php
<?php
namespace Drupal\groupmenu;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\group\Entity\GroupRelationshipType;
/**
* Group menu configuration overrides.
*/
class GroupMenuConfigOverrides implements ConfigFactoryOverrideInterface {
/**
* The configuration storage.
*
* Do not access this directly. Should be accessed through self::getConfig()
* so that the cache of configurations is used.
*
* @var \Drupal\Core\Config\StorageInterface
*/
protected $baseStorage;
/**
* The current user's account object.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* The cache backend.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
/**
* Statically cache configurations keyed by configuration name.
*
* @var array
*/
protected $configurations;
/**
* Statically cache group types keyed by node type.
*
* @var array
*/
protected $groupTypes;
/**
* Statically cache the current users group menu IDs keyed by group type.
*
* @var array
*/
protected $userGroupMenuIds;
/**
* Statically cache overrides per node type.
*
* @var array[]
*/
protected $overrides;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs the GroupMenuConfigOverrides object.
*
* @param \Drupal\Core\Config\StorageInterface $storage
* The configuration storage engine.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache backend.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(StorageInterface $storage, AccountInterface $current_user, CacheBackendInterface $cache, EntityTypeManagerInterface $entity_type_manager) {
$this->baseStorage = $storage;
$this->currentUser = $current_user;
$this->cache = $cache;
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public function loadOverrides($names) {
$overrides = [];
$node_type_names = array_filter($names, function ($name) {
return strpos($name, 'node.type') === 0;
});
if (!empty($node_type_names)) {
foreach ($node_type_names as $node_type_name) {
if (isset($this->overrides[$node_type_name])) {
$overrides[$node_type_name] = $this->overrides[$node_type_name];
}
else {
$current_config = $this->getConfig($node_type_name);
// We first get a list of all group types where the node type plugin
// has enabled the setting to show group menus. With those group
// types we can get all the group menu content types to look for
// actual group menu content. Once we have the group menu content, we
// can check their groups to see if the user has permissions to edit
// the menus.
$group_types = $this->getEnabledGroupMenuTypesByNodeType($current_config['type']);
if ($group_types && $menus = $this->getUserGroupMenuIdsByGroupTypes($group_types)) {
$overrides[$node_type_name] = [
'third_party_settings' => [
'menu_ui' => [
'available_menus' => array_merge($current_config['third_party_settings']['menu_ui']['available_menus'], $menus),
],
],
];
// Add result to static cache.
$this->overrides[$node_type_name] = $overrides[$node_type_name];
}
}
}
}
return $overrides;
}
/**
* Get all group types where the group menus are enabled for a node type.
*
* @param string $node_type
* A node type.
*
* @return array
* An array of group types with the ID as key and value.
*/
protected function getEnabledGroupMenuTypesByNodeType($node_type) {
if (isset($this->groupTypes[$node_type])) {
return $this->groupTypes[$node_type];
}
$cid = 'groupmenu:group_menu_types:' . $node_type;
$persistent_cache = $this->cache->get($cid);
if ($persistent_cache && $persistent_cache->valid) {
$this->groupTypes[$node_type] = $persistent_cache->data;
return $this->groupTypes[$node_type];
}
$plugin_id = 'group_node:' . $node_type;
$group_relationship_types = GroupRelationshipType::loadByPluginId($plugin_id);
// Get the list of group types to find menus for.
$this->groupTypes[$node_type] = [];
/** @var \Drupal\group\entity\GroupRelationshipTypeInterface $group_relationship_type */
foreach ($group_relationship_types as $group_relationship_type) {
if (!empty($group_relationship_type->getPlugin()->getConfiguration()['node_form_group_menu'])) {
$this->groupTypes[$node_type][$group_relationship_type->getGroupType()->id()] = $group_relationship_type->getGroupType()->id();
}
}
$this->cache->set($cid, $this->groupTypes[$node_type]);
return $this->groupTypes[$node_type];
}
/**
* Get a users group menu IDs for a list of group types.
*
* @param array $group_types
* An array of group types with the ID as key.
*
* @return array
* An array of menu IDs.
*/
protected function getUserGroupMenuIdsByGroupTypes(array $group_types) {
$group_types_cid = md5(implode('-', $group_types));
if (isset($this->userGroupMenuIds[$this->currentUser->id()][$group_types_cid])) {
return $this->userGroupMenuIds[$this->currentUser->id()][$group_types_cid];
}
$cid = 'groupmenu:user_group_menu_ids:' . $this->currentUser->id() . ':' . $group_types_cid;
$persistent_cache = $this->cache->get($cid);
if ($persistent_cache && $persistent_cache->valid) {
$this->userGroupMenuIds[$this->currentUser->id()][$group_types_cid] = $persistent_cache->data;
return $this->userGroupMenuIds[$this->currentUser->id()][$group_types_cid];
}
$plugin_id = 'group_menu:menu';
$group_relationship_types = $this->entityTypeManager->getStorage('group_relationship_type')
->loadByProperties([
'plugin_id' => $plugin_id,
'group_type' => array_keys($group_types),
]);
if (empty($group_relationship_types)) {
return [];
}
$group_relationships = $this->entityTypeManager->getStorage('group_relationship')
->loadByProperties([
'type' => array_keys($group_relationship_types),
]);
// Check access and add menus to config.
$this->userGroupMenuIds[$this->currentUser->id()][$group_types_cid] = [];
foreach ($group_relationships as $group_relationship) {
/** @var \Drupal\group\Entity\GroupRelationshipInterface $group_relationship */
if ($group_relationship && $group_relationship->getGroup()->hasPermission("update $plugin_id entity", $this->currentUser) && $entity = $group_relationship->getEntity()) {
$this->userGroupMenuIds[$this->currentUser->id()][$group_types_cid][] = $entity->id();
}
}
$this->cache->set($cid, $this->userGroupMenuIds[$this->currentUser->id()][$group_types_cid]);
return $this->userGroupMenuIds[$this->currentUser->id()][$group_types_cid];
}
/**
* {@inheritdoc}
*/
protected function getConfig($config_name) {
if (!isset($this->configurations[$config_name])) {
$this->configurations[$config_name] = $this->baseStorage->read($config_name);
}
return $this->configurations[$config_name];
}
/**
* {@inheritdoc}
*/
public function getCacheSuffix() {
return 'GroupMenuConfigOverrides';
}
/**
* {@inheritdoc}
*/
public function getCacheableMetadata($name) {
return new CacheableMetadata();
}
/**
* {@inheritdoc}
*/
public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) {
return NULL;
}
}
