View source
<?php
declare (strict_types=1);
namespace Drupal\og;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\RouteBuilderInterface;
use Drupal\og\Event\GroupCreationEvent;
use Drupal\og\Event\GroupCreationEventInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class GroupTypeManager implements GroupTypeManagerInterface {
const GROUP_RELATION_MAP_CACHE_KEY = 'og.group_manager.group_relation_map';
const SETTINGS_CONFIG_KEY = 'og.settings';
const GROUPS_CONFIG_KEY = 'groups';
protected $configFactory;
protected $entityTypeBundleInfo;
protected $eventDispatcher;
protected $cache;
protected $permissionManager;
protected $groupMap;
protected $groupRelationMap = [];
protected $moduleHandler;
protected $ogRoleManager;
protected $routeBuilder;
protected $groupAudienceHelper;
protected $entityTypeManager;
public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, EventDispatcherInterface $event_dispatcher, CacheBackendInterface $cache, PermissionManagerInterface $permission_manager, OgRoleManagerInterface $og_role_manager, RouteBuilderInterface $route_builder, OgGroupAudienceHelperInterface $group_audience_helper) {
$this->configFactory = $config_factory;
$this->entityTypeManager = $entity_type_manager;
$this->entityTypeBundleInfo = $entity_type_bundle_info;
$this->eventDispatcher = $event_dispatcher;
$this->cache = $cache;
$this->permissionManager = $permission_manager;
$this->ogRoleManager = $og_role_manager;
$this->routeBuilder = $route_builder;
$this->groupAudienceHelper = $group_audience_helper;
}
public function isGroup($entity_type_id, $bundle) {
$group_map = $this
->getGroupMap();
return isset($group_map[$entity_type_id]) && in_array($bundle, $group_map[$entity_type_id]);
}
public function isGroupContent($entity_type_id, $bundle) {
return $this->groupAudienceHelper
->hasGroupAudienceField($entity_type_id, $bundle);
}
public function getGroupBundleIdsByEntityType($entity_type_id) {
$group_map = $this
->getGroupMap();
return isset($group_map[$entity_type_id]) ? $group_map[$entity_type_id] : [];
}
public function getAllGroupContentBundleIds() {
$bundles = [];
foreach ($this
->getGroupRelationMap() as $group_bundle_ids) {
foreach ($group_bundle_ids as $group_content_entity_type_ids) {
foreach ($group_content_entity_type_ids as $group_content_entity_type_id => $group_content_bundle_ids) {
$bundles[$group_content_entity_type_id] = array_merge(isset($bundles[$group_content_entity_type_id]) ? $bundles[$group_content_entity_type_id] : [], $group_content_bundle_ids);
}
}
}
return $bundles;
}
public function getAllGroupContentBundlesByEntityType($entity_type_id) {
$bundles = $this
->getAllGroupContentBundleIds();
if (!isset($bundles[$entity_type_id])) {
throw new \InvalidArgumentException("The '{$entity_type_id}' entity type has no group content bundles.");
}
return $bundles[$entity_type_id];
}
public function getGroupBundleIdsByGroupContentBundle($group_content_entity_type_id, $group_content_bundle_id) {
$bundles = [];
foreach ($this->groupAudienceHelper
->getAllGroupAudienceFields($group_content_entity_type_id, $group_content_bundle_id) as $field) {
$group_entity_type_id = $field
->getSetting('target_type');
$handler_settings = $field
->getSetting('handler_settings');
$group_bundle_ids = !empty($handler_settings['target_bundles']) ? $handler_settings['target_bundles'] : [];
if (empty($group_bundle_ids)) {
$group_bundle_ids = $this
->getGroupMap()[$group_entity_type_id];
}
foreach ($group_bundle_ids as $group_bundle_id) {
$bundles[$group_entity_type_id][$group_bundle_id] = $group_bundle_id;
}
}
return $bundles;
}
public function getGroupContentBundleIdsByGroupBundle($group_entity_type_id, $group_bundle_id) {
$group_relation_map = $this
->getGroupRelationMap();
return isset($group_relation_map[$group_entity_type_id][$group_bundle_id]) ? $group_relation_map[$group_entity_type_id][$group_bundle_id] : [];
}
public function addGroup($entity_type_id, $bundle_id) {
if ($this
->isGroup($entity_type_id, $bundle_id)) {
throw new \InvalidArgumentException("The '{$entity_type_id}' of type '{$bundle_id}' is already a group.");
}
$editable = $this->configFactory
->getEditable('og.settings');
$groups = $editable
->get('groups');
$groups[$entity_type_id][] = $bundle_id;
$groups[$entity_type_id] = array_unique($groups[$entity_type_id]);
$editable
->set('groups', $groups);
$editable
->save();
$event = new GroupCreationEvent($entity_type_id, $bundle_id);
$this->eventDispatcher
->dispatch(GroupCreationEventInterface::EVENT_NAME, $event);
$this->ogRoleManager
->createPerBundleRoles($entity_type_id, $bundle_id);
$this
->refreshGroupMap();
$this->routeBuilder
->setRebuildNeeded();
}
public function removeGroup($entity_type_id, $bundle_id) {
$editable = $this->configFactory
->getEditable('og.settings');
$groups = $editable
->get('groups');
if (isset($groups[$entity_type_id])) {
$search_key = array_search($bundle_id, $groups[$entity_type_id]);
if ($search_key !== FALSE) {
unset($groups[$entity_type_id][$search_key]);
}
$groups = array_filter($groups);
$editable
->set('groups', $groups);
$editable
->save();
$this
->resetGroupMap();
$this->routeBuilder
->setRebuildNeeded();
}
}
public function reset() {
$this
->resetGroupMap();
$this
->resetGroupRelationMap();
}
public function resetGroupMap() {
$this->groupMap = [];
}
public function resetGroupRelationMap() {
$this->groupRelationMap = [];
$this->cache
->delete(self::GROUP_RELATION_MAP_CACHE_KEY);
}
public function getGroupMap() {
if (empty($this->groupMap)) {
$this
->refreshGroupMap();
}
return $this->groupMap;
}
protected function getGroupRelationMap() {
if (empty($this->groupRelationMap)) {
$this
->populateGroupRelationMap();
}
return $this->groupRelationMap;
}
protected function refreshGroupMap() {
$group_map = $this->configFactory
->get(static::SETTINGS_CONFIG_KEY)
->get(static::GROUPS_CONFIG_KEY);
$this->groupMap = !empty($group_map) ? $group_map : [];
}
protected function populateGroupRelationMap() : void {
if ($cached_map = $this
->getCachedGroupRelationMap()) {
$this->groupRelationMap = $cached_map;
return;
}
$this->groupRelationMap = [];
$user_bundles = $this->entityTypeManager
->getDefinition('user')
->getKey('bundle') ?: [
'user',
];
foreach ($this->entityTypeBundleInfo
->getAllBundleInfo() as $group_content_entity_type_id => $bundles) {
foreach ($bundles as $group_content_bundle_id => $bundle_info) {
if (in_array($group_content_bundle_id, $user_bundles)) {
continue;
}
foreach ($this
->getGroupBundleIdsByGroupContentBundle($group_content_entity_type_id, $group_content_bundle_id) as $group_entity_type_id => $group_bundle_ids) {
foreach ($group_bundle_ids as $group_bundle_id) {
$this->groupRelationMap[$group_entity_type_id][$group_bundle_id][$group_content_entity_type_id][$group_content_bundle_id] = $group_content_bundle_id;
}
}
}
}
$this->cache
->set(self::GROUP_RELATION_MAP_CACHE_KEY, $this->groupRelationMap);
}
protected function getCachedGroupRelationMap() : ?array {
return $this->cache
->get(self::GROUP_RELATION_MAP_CACHE_KEY)->data ?? NULL;
}
}