From 118d31c8878b5918fddd913069e57077c4aa46f2 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Tue, 30 Apr 2024 12:09:43 +0000
Subject: [PATCH] cleanup blubber and delete correctly, fixes #4097

Closes #4097

Merge request studip/studip!2943
---
 db/migrations/5.1.56_cleanup_blubber.php | 46 ++++++++++++++++++++++++
 lib/classes/UserManagement.class.php     | 12 -------
 lib/models/User.class.php                | 17 +++++++++
 3 files changed, 63 insertions(+), 12 deletions(-)
 create mode 100644 db/migrations/5.1.56_cleanup_blubber.php

diff --git a/db/migrations/5.1.56_cleanup_blubber.php b/db/migrations/5.1.56_cleanup_blubber.php
new file mode 100644
index 00000000000..86348bcb0ba
--- /dev/null
+++ b/db/migrations/5.1.56_cleanup_blubber.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * @see https://gitlab.studip.de/studip/studip/-/issues/4097
+ */
+return new class extends Migration
+{
+    public function description()
+    {
+        return 'Removes orhpaned blubber entries';
+    }
+
+    protected function up()
+    {
+        $query = "DELETE bt, ouv
+                  FROM `blubber_threads` AS bt
+                  LEFT JOIN `object_user_visits` AS ouv
+                    ON (bt.`thread_id` = ouv.`object_id`)
+                  WHERE bt.`external_contact` = 0
+                    AND bt.`user_id` NOT IN (
+                        SELECT `user_id` FROM `auth_user_md5`
+                    )";
+        DBManager::get()->exec($query);
+
+        $query = "DELETE FROM `blubber_comments`
+                  WHERE (
+                      `external_contact` = 0
+                      AND `user_id` NOT IN (
+                          SELECT `user_id` FROM `auth_user_md5`
+                      )
+                    ) OR `thread_id` NOT IN (
+                      SELECT `thread_id` FROM `blubber_threads`
+                    )";
+        DBManager::get()->exec($query);
+
+        $query = "DELETE FROM `blubber_mentions`
+                  WHERE (
+                      `external_contact` = 0
+                      AND `user_id` NOT IN (
+                          SELECT `user_id` FROM `auth_user_md5`
+                      )
+                    ) OR `thread_id` NOT IN (
+                    SELECT `thread_id` FROM `blubber_threads`
+                  )";
+        DBManager::get()->exec($query);
+    }
+};
diff --git a/lib/classes/UserManagement.class.php b/lib/classes/UserManagement.class.php
index c831b855a4a..e3d9aa38be2 100644
--- a/lib/classes/UserManagement.class.php
+++ b/lib/classes/UserManagement.class.php
@@ -1122,18 +1122,6 @@ class UserManagement
         // delete the datafields
         $localEntries = DataFieldEntry::removeAll($user_id);
 
-        // delete all blubber entrys
-        $query = "DELETE blubber_threads, blubber_mentions, blubber_comments
-                  FROM blubber_threads
-                  LEFT JOIN blubber_mentions USING (user_id)
-                  LEFT JOIN blubber_comments USING (user_id)
-                  WHERE user_id = ?";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$user_id]);
-        if ($count = $statement->rowCount()) {
-            $msg .= 'info§' . sprintf(_('%s Blubber gelöscht.'), $count) . '§';
-        }
-
         // delete user from waiting lists
         $query = "SELECT seminar_id FROM admission_seminar_user WHERE user_id = ?";
         $statement = DBManager::get()->prepare($query);
diff --git a/lib/models/User.class.php b/lib/models/User.class.php
index 056b48aea9b..ab92bade912 100644
--- a/lib/models/User.class.php
+++ b/lib/models/User.class.php
@@ -52,6 +52,9 @@
  * @property SimpleORMapCollection|Kategorie[] $profile_categories has_many Kategorie
  * @property SimpleORMapCollection|MvvContact[] $mvv_assignments has_many MvvContact
  * @property SimpleORMapCollection|CourseMemberNotification[] $course_notifications has_many CourseMemberNotification
+ * @property SimpleORMapCollection|BlubberThread[] $blubber_threads has_many BlubberThread
+ * @property SimpleORMapCollection|BlubberComment[] $blubber_comments has_many BlubberComment
+ * @property SimpleORMapCollection|BlubberMention[] $blubber_mentions has_many BlubberMention
  * @property UserInfo $info has_one UserInfo
  * @property UserOnline $online has_one UserOnline
  * @property Courseware\Unit $courseware_units has_one Courseware\Unit
@@ -206,6 +209,20 @@ class User extends AuthUserMd5 implements Range, PrivacyObject, Studip\Calendar\
             'assoc_foreign_key' => 'author_id'
         ];
 
+        // Blubber relations
+        $config['has_many']['blubber_threads'] = [
+            'class_name' => BlubberThread::class,
+            'on_delete'  => 'delete',
+        ];
+        $config['has_many']['blubber_comments'] = [
+            'class_name' => BlubberComment::class,
+            'on_delete'  => 'delete',
+        ];
+        $config['has_many']['blubber_mentions'] = [
+            'class_name' => BlubberMention::class,
+            'on_delete'  => 'delete',
+        ];
+
         $config['additional_fields']['config']['get'] = function ($user) {
             return UserConfig::get($user->id);
         };
-- 
GitLab