From 6e15a2bc5a99f579cd12f7069051c2ad87a5e402 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Tue, 2 May 2023 11:25:49 +0000
Subject: [PATCH] add user lookup filter for roles and use that for auto
 inserting, fixes #2029

Closes #2029

Merge request studip/studip!1323
---
 app/controllers/admin/autoinsert.php     |  4 +-
 lib/classes/AutoInsert.class.php         |  9 +++--
 lib/classes/UserLookup.class.php         | 47 +++++++++++++++++++++++-
 lib/plugins/db/RolePersistence.class.php |  1 +
 4 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/app/controllers/admin/autoinsert.php b/app/controllers/admin/autoinsert.php
index fd3b7e0ff56..70464e17d58 100644
--- a/app/controllers/admin/autoinsert.php
+++ b/app/controllers/admin/autoinsert.php
@@ -157,7 +157,6 @@ class Admin_AutoinsertController extends AuthenticatedController
                 PageLayout::postError(_('Keine Filterkriterien gewählt'));
             } else {
                 $seminar = Seminar::GetInstance(Request::option('sem_id'));
-                $group = select_group($seminar->getSemesterStartTime());
 
                 $userlookup = new UserLookup();
                 foreach ($filters as $type => $values) {
@@ -231,7 +230,8 @@ class Admin_AutoinsertController extends AuthenticatedController
             'fachsemester' => _('Studienfachsemester'),
             'institut'     => _('Einrichtung'),
             'status'       => _('Statusgruppe'),
-            'domain'       => _('Domäne')
+            'domain'       => _('Domäne'),
+            'role'         => _('Rolle'),
         ];
 
         $links = new ActionsWidget();
diff --git a/lib/classes/AutoInsert.class.php b/lib/classes/AutoInsert.class.php
index 6eb00974faa..417e6ffa518 100644
--- a/lib/classes/AutoInsert.class.php
+++ b/lib/classes/AutoInsert.class.php
@@ -89,7 +89,7 @@ class AutoInsert
     /**
      * Trägt den Benutzer in den Eingestellten veranstaltungen automatisch ein.
      * @param string $user_id
-     * @param bool $status Wenn Status nicht angegeben wird, wird der Status des Users aus user_id genommen
+     * @param string|bool $status Wenn Status nicht angegeben wird, wird der Status des Users aus user_id genommen
      * @return array 'added' Namen der Seminare in die der User eingetragen wurde
      *                     array 'removed' Namen der Seminare aus denen der User ausgetragen wurde
      */
@@ -112,7 +112,6 @@ class AutoInsert
 
             $key = $domain . '.' . $status;
             if (is_array($this->settings[$key])) {
-                $id = key($this->settings[$key]);
                 foreach ($this->settings[$key] as $id => $value) {
                     $settings[$id] = $value;
                 }
@@ -241,13 +240,15 @@ class AutoInsert
      * Removes a seminar from the autoinsertion process.
      * @param string $seminar_id Id of the seminar
      */
-    public static function deleteSeminar($seminar_id)
+    public static function deleteSeminar($seminar_id): bool
     {
         $query     = "DELETE FROM auto_insert_sem WHERE seminar_id = ?";
         $statement = DBManager::get()->prepare($query);
-        $statement->execute([$seminar_id]);
+        $result = $statement->execute([$seminar_id]);
 
         unset(self::getSeminarCache()[$seminar_id]);
+
+        return $result > 0;
     }
 
     /**
diff --git a/lib/classes/UserLookup.class.php b/lib/classes/UserLookup.class.php
index 61732ae36a8..ddf9276bc0a 100644
--- a/lib/classes/UserLookup.class.php
+++ b/lib/classes/UserLookup.class.php
@@ -67,8 +67,12 @@ class UserLookup
             'values' => 'UserLookup::statusValues',
         ],
         'domain' => [
-            'filter'    =>'UserLookup::domainFilter',
-            'values'    =>'UserLookup::domainValues'
+            'filter' => 'UserLookup::domainFilter',
+            'values' => 'UserLookup::domainValues',
+        ],
+        'role' => [
+            'filter' => 'UserLookup::roleFilter',
+            'values' => 'UserLookup::roleValues',
         ],
     ];
 
@@ -457,4 +461,43 @@ class UserLookup
 
         return $domains;
     }
+
+    /**
+     * Return all users with a matching assigned role given in $needles
+     *
+     * @param  array $needles List of domain ids to filter against
+     * @return array List of user ids matching the given filter
+     */
+    protected static function roleFilter($needles): array
+    {
+        if (!$needles) {
+            return [];
+        }
+
+        $user_ids = [];
+        foreach ($needles as $role_id) {
+            $users = RolePersistence::getUsersWithRoleById($role_id, false);
+            foreach ($users as $user) {
+                $user_ids[$user->id] = $user->id;
+            }
+        }
+
+        return array_values($user_ids);
+    }
+
+    /**
+     * Return all valid roles
+     *
+     * @return array Associative array of domain id and name
+     */
+    protected static function roleValues(): array
+    {
+        $roles = [];
+        $roles['keine'] = _('Ohne Rollenzuweisung');
+        foreach (RolePersistence::getAllRoles() as $role) {
+            $roles[$role->getRoleid()] = $role->getRolename();
+        }
+
+        return $roles;
+    }
 }
diff --git a/lib/plugins/db/RolePersistence.class.php b/lib/plugins/db/RolePersistence.class.php
index 85f47a2a17b..d2b03471f80 100644
--- a/lib/plugins/db/RolePersistence.class.php
+++ b/lib/plugins/db/RolePersistence.class.php
@@ -22,6 +22,7 @@ class RolePersistence
     /**
      * Returns all available roles.
      *
+     * @param bool $grouped Return the roles grouped by system type or other
      * @return Role[]|array{system: Role[], other: Role[]}
      */
     public static function getAllRoles(bool $grouped = false): array
-- 
GitLab