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