From 26719c7168f2b5f7c84149215e662bee0ba4bb9c Mon Sep 17 00:00:00 2001 From: Harlor <harlor@web.de> Date: Thu, 20 Mar 2025 18:16:57 +0100 Subject: [PATCH] Reroll patch agianst group3 --- src/QueryAccess/EntityQueryAlter.php | 112 +++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 13 deletions(-) diff --git a/src/QueryAccess/EntityQueryAlter.php b/src/QueryAccess/EntityQueryAlter.php index 7ca0203c..ef5bc60f 100644 --- a/src/QueryAccess/EntityQueryAlter.php +++ b/src/QueryAccess/EntityQueryAlter.php @@ -2,6 +2,7 @@ namespace Drupal\group\QueryAccess; +use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Entity\EntityPublishedInterface; use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -36,6 +37,32 @@ class EntityQueryAlter extends PluginBasedQueryAlterBase { */ protected $joinAliasPlugins; + /** + * Cache service. + * + * @var \Drupal\Core\Cache\CacheBackendInterface + */ + protected CacheBackendInterface $cacheBackend; + + /** + * Attempt memoization of plugin IDs. + * + * An associative array mapping entity type IDs to arrays of plugin IDs. + * + * @var string[][] + */ + protected array $pluginIds = []; + + /** + * Attempt memoization of plugin IDs in use. + * + * An associative array mapping entity type IDs to array of plugin IDs that + * are presently in use. + * + * @var string[][] + */ + protected array $pluginIdsInUse = []; + /** * {@inheritdoc} */ @@ -43,6 +70,7 @@ class EntityQueryAlter extends PluginBasedQueryAlterBase { $instance = parent::create($container); $instance->pluginManager = $container->get('group_relation_type.manager'); $instance->database = $container->get('database'); + $instance->cacheBackend = $container->get('cache.data'); return $instance; } @@ -57,7 +85,7 @@ class EntityQueryAlter extends PluginBasedQueryAlterBase { } // Find all of the group relations that define access. - $plugin_ids = $this->pluginManager->getPluginIdsByEntityTypeAccess($entity_type_id); + $plugin_ids = $this->getPluginIds($entity_type_id); if (empty($plugin_ids)) { return; } @@ -70,18 +98,14 @@ class EntityQueryAlter extends PluginBasedQueryAlterBase { } $this->cacheableMetadata->addCacheTags($cache_tags); - // If there are no relationships using the plugins, there's no point in - // going any further. The cache tags above will invalidate our result if new - // group content is created using the plugins that define access. Retrieve - // the plugin IDs in use to optimize a loop further below. - $group_relationship_data_table = $this->entityTypeManager->getDefinition('group_relationship')->getDataTable(); - $plugin_ids_in_use = $this->database - ->select($group_relationship_data_table, 'gc') - ->fields('gc', ['plugin_id']) - ->condition('plugin_id', $plugin_ids, 'IN') - ->distinct() - ->execute() - ->fetchCol(); + // If there are no relationships using the plugins, there's no point in going + // any further. The cache tags above will invalidate our result if new group + // content is created using the plugins that define access. Retrieve the + // plugin IDs in use to optimize a loop further below. + + $group_relationship_data_table = $this->getDataTable(); + $plugin_ids_in_use = $this->getPluginIdsInUse($entity_type_id); + if (empty($plugin_ids_in_use)) { return; @@ -250,4 +274,66 @@ class EntityQueryAlter extends PluginBasedQueryAlterBase { return 'gid'; } + /** + * Get plugin IDs. + * + * @param string $entity_type_id + * The ID of the target entity type for which to examine the plugins in use. + * + * @return string[] + * The plugin IDs. + */ + protected function getPluginIds(string $entity_type_id) : array { + // Find all of the group relations that define access. + return $this->pluginIds[$entity_type_id] ??= $this->pluginManager->getPluginIdsByEntityTypeAccess($entity_type_id); + } + + /** + * Get the target data table. + * + * @return string + * The name of the target data table. + * + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + * If the `group_content` type is not defined. + */ + protected function getDataTable() : string { + return $this->entityTypeManager->getDefinition('group_relationship')->getDataTable(); + } + + /** + * Get plugin IDs in use. + * + * @param string $entity_type_id + * The ID of the target entity type for which to examine the plugins in use. + * + * @return string[] + * The plugin IDs that are in use. + */ + protected function getPluginIdsInUse(string $entity_type_id) : array { + if (!isset($this->pluginIdsInUse[$entity_type_id])) { + $cache_key = "group:group_relationship:plugins_in_use:{$entity_type_id}"; + $in_use = $this->cacheBackend->get($cache_key); + if ($in_use) { + $this->pluginIdsInUse[$entity_type_id] = $in_use->data; + } + else { + $this->pluginIdsInUse[$entity_type_id] = $this->database + ->select($this->getDataTable(), 'gc') + ->fields('gc', ['plugin_id']) + ->condition('plugin_id', $this->getPluginIds($entity_type_id), 'IN') + ->distinct() + ->execute() + ->fetchCol(); + $this->cacheBackend->set( + $cache_key, + $this->pluginIdsInUse[$entity_type_id], + tags: $this->cacheableMetadata->getCacheTags(), + ); + } + } + + return $this->pluginIdsInUse[$entity_type_id]; + } + } -- GitLab