From abe91c4fcae6f1a7ba3d40ec4dd38dde04662145 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Noack?= <noack@data-quest.de>
Date: Fri, 29 Sep 2023 10:45:00 +0000
Subject: [PATCH] Resolve #3248 "Bearbeiten der Zugangsberechtigungen dauert
 sehr lange / Performance Anmeldesets mit vielen Bedingungen schlecht"

Closes #3248

Merge request studip/studip!2206
---
 .../admission/UserFilterField.class.php       | 26 ++++++++++++-----
 .../SemesterOfStudyCondition.class.php        | 29 ++++++++++---------
 .../userfilter/SubjectConditionAny.class.php  |  3 --
 3 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/lib/classes/admission/UserFilterField.class.php b/lib/classes/admission/UserFilterField.class.php
index ab6db5799ce..9081e9015bd 100644
--- a/lib/classes/admission/UserFilterField.class.php
+++ b/lib/classes/admission/UserFilterField.class.php
@@ -59,6 +59,9 @@ class UserFilterField
 
     public static $isParameterized = false;
 
+    protected static $cached_valid_values;
+    protected static $available_filter_fields;
+
     /**
      * Database tables and fields to get valid values and concrete user values
      * from.
@@ -92,12 +95,17 @@ class UserFilterField
             '!=' => _('ist nicht')
         ];
         if ($this->valuesDbNameField) {
-            // Get all available values from database.
-            $stmt = DBManager::get()->query(
-                "SELECT DISTINCT `".$this->valuesDbIdField."`, `".$this->valuesDbNameField."` ".
-                "FROM `".$this->valuesDbTable."` ORDER BY `".$this->valuesDbNameField."` ASC");
-            while ($current = $stmt->fetch(PDO::FETCH_ASSOC)) {
-                $this->validValues[$current[$this->valuesDbIdField]] = $current[$this->valuesDbNameField];
+            if (isset(self::$cached_valid_values[static::class])) {
+                $this->validValues = self::$cached_valid_values[static::class];
+            } else {
+                // Get all available values from database.
+                $stmt = DBManager::get()->query(
+                        "SELECT DISTINCT `" . $this->valuesDbIdField . "`, `" . $this->valuesDbNameField . "` " .
+                        "FROM `" . $this->valuesDbTable . "` ORDER BY `" . $this->valuesDbNameField . "` ASC");
+                while ($current = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                    $this->validValues[$current[$this->valuesDbIdField]] = $current[$this->valuesDbNameField];
+                }
+                self::$cached_valid_values[static::class] = $this->validValues;
             }
         }
         if ($fieldId) {
@@ -186,6 +194,7 @@ class UserFilterField
      */
     public static function getAvailableFilterFields()
     {
+        if (self::$available_filter_fields === null) {
         $fields = [];
         // Load all PHP class files found in the condition field folder.
         foreach (glob(realpath(dirname(__FILE__).'/userfilter').'/*.class.php') as $file) {
@@ -204,9 +213,12 @@ class UserFilterField
             }
         }
         asort($fields);
-        return $fields;
+            self::$available_filter_fields = $fields;
+        }
+        return self::$available_filter_fields;
     }
 
+
     /**
      * Which compare operator is set?
      *
diff --git a/lib/classes/admission/userfilter/SemesterOfStudyCondition.class.php b/lib/classes/admission/userfilter/SemesterOfStudyCondition.class.php
index c7347561731..2c1233a05a5 100644
--- a/lib/classes/admission/userfilter/SemesterOfStudyCondition.class.php
+++ b/lib/classes/admission/userfilter/SemesterOfStudyCondition.class.php
@@ -18,7 +18,6 @@ class SemesterOfStudyCondition extends UserFilterField
     // --- ATTRIBUTES ---
     public $valuesDbTable = 'user_studiengang';
     public $valuesDbIdField = 'semester';
-    public $valuesDbNameField = 'semester';
     public $userDataDbTable = 'user_studiengang';
     public $userDataDbField = 'semester';
 
@@ -49,19 +48,23 @@ class SemesterOfStudyCondition extends UserFilterField
             '=' => _('ist'),
             '!=' => _('ist nicht')
         ];
-        // Initialize to some value in case there are no semester numbers.
-        $maxsem = 15;
-        // Calculate the maximal available semester.
-        $query = "SELECT MAX(`{$this->valuesDbIdField}`) AS maxsem
-                  FROM `{$this->valuesDbTable}`";
-        $stmt = DBManager::get()->query($query);
-        if ($current = $stmt->fetch(PDO::FETCH_ASSOC)) {
-            if ($current['maxsem']) {
-                $maxsem = $current['maxsem'];
+        if (isset(self::$cached_valid_values[static::class])) {
+            $this->validValues = self::$cached_valid_values[static::class];
+        } else {
+            // Initialize to some value in case there are no semester numbers.
+            $maxsem = 15;
+            // Calculate the maximal available semester.
+                $stmt = DBManager::get()->query("SELECT MAX(" . $this->valuesDbIdField . ") AS maxsem " .
+                    "FROM `" . $this->valuesDbTable . "`");
+            if ($current = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                if ($current['maxsem']) {
+                    $maxsem = $current['maxsem'];
+                }
             }
-        }
-        for ($i = 1; $i <= $maxsem; $i++) {
-            $this->validValues[$i] = $i;
+            for ($i = 1; $i <= $maxsem; $i++) {
+                $this->validValues[$i] = $i;
+            }
+            self::$cached_valid_values[static::class] = $this->validValues;
         }
     }
 
diff --git a/lib/classes/admission/userfilter/SubjectConditionAny.class.php b/lib/classes/admission/userfilter/SubjectConditionAny.class.php
index 4b3caba0629..107c86ce29e 100644
--- a/lib/classes/admission/userfilter/SubjectConditionAny.class.php
+++ b/lib/classes/admission/userfilter/SubjectConditionAny.class.php
@@ -19,9 +19,6 @@ require_once realpath(__DIR__ . '/..') . '/UserFilterField.class.php';
 class SubjectConditionAny extends UserFilterField
 {
     // --- ATTRIBUTES ---
-    public $valuesDbTable = 'fach';
-    public $valuesDbIdField = 'fach_id';
-    public $valuesDbNameField = 'name';
     public $userDataDbTable = 'user_studiengang';
     public $userDataDbField = 'fach_id';
 
-- 
GitLab