From e7bfc2e80046cdbe28122c8430d9ce9dfdafb5a1 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Mon, 6 May 2024 09:03:33 +0000
Subject: [PATCH] fixes #3977

Closes #3977

Merge request studip/studip!2945
---
 .../5.1.57_cleanup_tool_activations.php       | 23 +++++++
 lib/plugins/engine/PluginManager.class.php    | 60 +++++++++++--------
 2 files changed, 57 insertions(+), 26 deletions(-)
 create mode 100644 db/migrations/5.1.57_cleanup_tool_activations.php

diff --git a/db/migrations/5.1.57_cleanup_tool_activations.php b/db/migrations/5.1.57_cleanup_tool_activations.php
new file mode 100644
index 00000000000..6700816bc85
--- /dev/null
+++ b/db/migrations/5.1.57_cleanup_tool_activations.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * @see https://gitlab.studip.de/studip/studip/-/issues/3977
+ */
+return new class extends Migration
+{
+    public function description()
+    {
+        return 'Removes invalid tool activations (that are no longer connected '
+            . 'to a StandardPlugin';
+    }
+
+    protected function up()
+    {
+        $query = "DELETE FROM `tools_activated`
+                  WHERE `plugin_id` NOT IN (
+                      SELECT `pluginid`
+                      FROM `plugins`
+                      WHERE FIND_IN_SET(?, `plugintype`)
+                  )";
+        DBManager::get()->execute($query, [StandardPlugin::class]);
+    }
+};
diff --git a/lib/plugins/engine/PluginManager.class.php b/lib/plugins/engine/PluginManager.class.php
index be4f7661831..f08b5fa4064 100644
--- a/lib/plugins/engine/PluginManager.class.php
+++ b/lib/plugins/engine/PluginManager.class.php
@@ -427,41 +427,49 @@ class PluginManager
             $this->plugins[$id]['name'] = $name;
             $this->plugins[$id]['path'] = $path;
             $this->plugins[$id]['type'] = $type;
+        } else {
+            foreach ($this->plugins as $plugin) {
+                $common_types = array_intersect($type, $plugin['type']);
 
-            return $id;
-        }
-
-        foreach ($this->plugins as $plugin) {
-            $common_types = array_intersect($type, $plugin['type']);
-
-            if (count($common_types) > 0 && $plugin['position'] >= $position) {
-                $position = $plugin['position'] + 1;
+                if (count($common_types) > 0 && $plugin['position'] >= $position) {
+                    $position = $plugin['position'] + 1;
+                }
             }
-        }
 
-        $sql = 'INSERT INTO plugins (
+            $sql = 'INSERT INTO plugins (
                     pluginname, pluginclassname, pluginpath,
                     plugintype, navigationpos, dependentonid
                 ) VALUES (?,?,?,?,?,?)';
-        $stmt = $db->prepare($sql);
-        $stmt->execute([$name, $class, $path, join(',', $type), $position, $depends]);
-        $id = $db->lastInsertId();
-
-        $this->plugins[$id] = [
-            'id'          => $id,
-            'name'        => $name,
-            'class'       => $class,
-            'path'        => $path,
-            'type'        => $type,
-            'enabled'     => false,
-            'position'    => $position,
-            'depends'     => $depends
-        ];
+            $stmt = $db->prepare($sql);
+            $stmt->execute([$name, $class, $path, join(',', $type), $position, $depends]);
+            $id = $db->lastInsertId();
 
-        $this->readPluginInfos();
+            $this->plugins[$id] = [
+                'id'          => $id,
+                'name'        => $name,
+                'class'       => $class,
+                'path'        => $path,
+                'type'        => $type,
+                'enabled'     => false,
+                'position'    => $position,
+                'depends'     => $depends
+            ];
+
+            $this->readPluginInfos();
 
-        $db->exec("INSERT INTO roles_plugins (roleid, pluginid)
+            $db->exec("INSERT INTO roles_plugins (roleid, pluginid)
                    SELECT roleid, $id FROM roles WHERE `system` = 'y' AND rolename != 'Nobody'");
+        }
+
+        if (!in_array(StandardPlugin::class, $type)) {
+            ToolActivation::findEachBySQL(
+                function (ToolActivation $activation) use ($id) {
+                    $this->setPluginActivated($id, $activation->range_id, false);
+                },
+                'plugin_id = ?',
+                [$id]
+            );
+        }
 
         return $id;
     }
-- 
GitLab