From 462a4673c3d2402d643f2dc5bedaf6a6230ec8b1 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Mon, 21 Feb 2022 10:44:18 +0000
Subject: [PATCH] optimize cache and notification handling for RolePersistence,
 fixes #644

---
 lib/plugins/db/RolePersistence.class.php | 35 ++++++++++++------------
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/lib/plugins/db/RolePersistence.class.php b/lib/plugins/db/RolePersistence.class.php
index 4ffb2c8bfae..88abce32b5d 100644
--- a/lib/plugins/db/RolePersistence.class.php
+++ b/lib/plugins/db/RolePersistence.class.php
@@ -63,10 +63,6 @@ class RolePersistence
      */
     public static function saveRole($role)
     {
-        // sweep roles cache, see #getAllRoles
-        self::expireRolesCache();
-
-        // role is not in database
         $query = "INSERT INTO `roles` (`roleid`, `rolename`, `system`)
                   VALUES (?, ?, 'n')
                   ON DUPLICATE KEY UPDATE `rolename` = VALUES(`rolename`)";
@@ -82,6 +78,9 @@ class RolePersistence
             $event = 'RoleDidUpdate';
         }
 
+        // sweep roles cache, see #getAllRoles
+        self::expireRolesCache();
+
         NotificationCenter::postNotification(
             $event,
             $role->getRoleid(),
@@ -101,18 +100,11 @@ class RolePersistence
         $id = $role->getRoleid();
         $name = $role->getRolename();
 
-        // sweep roles cache
-        self::expireRolesCache();
-
         $query = "SELECT `pluginid` FROM `roles_plugins` WHERE `roleid` = ?";
         $statement = DBManager::get()->prepare($query);
         $statement->execute([$id]);
         $statement->setFetchMode(PDO::FETCH_COLUMN, 0);
 
-        foreach ($statement as $plugin_id) {
-            unset(self::getPluginRolesCache()[$plugin_id]);
-        }
-
         DBManager::get()->execute(
             "DELETE `roles`, `roles_user`, `roles_plugins`, `roles_studipperms`
              FROM `roles`
@@ -123,6 +115,13 @@ class RolePersistence
             [$id]
         );
 
+        // sweep roles cache
+        self::expireRolesCache();
+
+        foreach ($statement as $plugin_id) {
+            unset(self::getPluginRolesCache()[$plugin_id]);
+        }
+
         NotificationCenter::postNotification('RoleDidDelete', $id, $name);
     }
 
@@ -322,8 +321,6 @@ class RolePersistence
     {
         $plugin_id = (int) $plugin_id;
 
-        unset(self::getPluginRolesCache()[$plugin_id]);
-
         $query = "REPLACE INTO `roles_plugins` (`roleid`, `pluginid`)
                   VALUES (:role_id, :plugin_id)";
         $statement = DBManager::get()->prepare($query);
@@ -332,13 +329,16 @@ class RolePersistence
         foreach ($role_ids as $role_id) {
             $statement->bindValue(':role_id', $role_id);
             $statement->execute();
+        }
+
+        unset(self::getPluginRolesCache()[$plugin_id]);
 
+        foreach ($role_ids as $role_id) {
             NotificationCenter::postNotification(
                 'PluginRoleAssignmentDidCreate',
                 $role_id,
                 $plugin_id
             );
-
         }
     }
 
@@ -352,8 +352,6 @@ class RolePersistence
     {
         $plugin_id = (int) $plugin_id;
 
-        unset(self::getPluginRolesCache()[$plugin_id]);
-
         $query = "DELETE FROM `roles_plugins`
                   WHERE `pluginid` = :plugin_id
                     AND `roleid` = :role_id";
@@ -363,13 +361,16 @@ class RolePersistence
         foreach ($role_ids as $role_id) {
             $statement->bindValue(':role_id', $role_id);
             $statement->execute();
+        }
 
+        unset(self::getPluginRolesCache()[$plugin_id]);
+
+        foreach ($role_ids as $role_id) {
             NotificationCenter::postNotification(
                 'PluginRoleAssignmentDidDelete',
                 $role_id,
                 $plugin_id
             );
-
         }
     }
 
-- 
GitLab