From 39df759266a938b3f41d2373345de9fbf548a0b7 Mon Sep 17 00:00:00 2001
From: David Siegfried <david.siegfried@uni-vechta.de>
Date: Fri, 2 Sep 2022 08:27:05 +0000
Subject: [PATCH] add user course-overview to user-management, closes #1489

Closes #1489

Merge request studip/studip!928
---
 app/controllers/admin/user.php             | 83 ++++++++++++++++++++++
 app/views/admin/cronjobs/logs/index.php    |  2 +-
 app/views/admin/user/_results.php          |  8 ++-
 app/views/admin/user/show_user_courses.php | 62 ++++++++++++++++
 4 files changed, 153 insertions(+), 2 deletions(-)
 create mode 100644 app/views/admin/user/show_user_courses.php

diff --git a/app/controllers/admin/user.php b/app/controllers/admin/user.php
index 9c9491c7e86..aaa59a0a237 100644
--- a/app/controllers/admin/user.php
+++ b/app/controllers/admin/user.php
@@ -25,6 +25,7 @@ require_once 'lib/statusgruppe.inc.php';
  */
 class Admin_UserController extends AuthenticatedController
 {
+    protected $_autobind = true;
     /**
      * Common tasks for all actions.
      */
@@ -1515,6 +1516,88 @@ class Admin_UserController extends AuthenticatedController
         $this->redirect($archive_download_link);
     }
 
+    /**
+     * Course overview of a user
+     */
+    public function show_user_courses_action(User $user)
+    {
+        PageLayout::setTitle(sprintf(
+            _('Veranstaltungsübersicht von %s'),
+            $user->getFullName()
+        ));
+        $sem_courses = [];
+        $courses = Course::findByUser($this->user->id);
+        array_walk($courses,
+            function (Course $course) use (&$sem_courses) {
+                $semester_name = (string) $course->start_semester->name;
+                if (!isset($sem_courses[$semester_name])) {
+                    $sem_courses[$semester_name] = [];
+                }
+                $sem_courses[$semester_name][] = $course;
+            }
+        );
+
+        $this->sem_courses = $sem_courses;
+    }
+
+    /**
+     * Delete user from courses
+     * @throws InvalidSecurityTokenException
+     * @throws MethodNotAllowedException
+     */
+    public function delete_course_assignment_action(User $user)
+    {
+        CSRFProtection::verifyUnsafeRequest();
+
+        if (Request::get('course_id')) {
+            $courses = [Request::get('course_id')];
+        } else {
+            $courses = Request::getArray('courses');
+        }
+
+        if (empty($courses)) {
+            PageLayout::postError(_('Sie haben keine Veranstaltungen ausgewählt.'));
+        } else {
+            $courses = array_map('Seminar::GetInstance', $courses);
+            $successes = 0;
+            $fails = 0;
+
+            foreach ($courses as $course) {
+                if ($course->deleteMember($user->id)) {
+                    $successes++;
+                } else {
+                    $fails++;
+                }
+            }
+
+            if ($successes) {
+                PageLayout::postSuccess(sprintf(
+                    ngettext(
+                        '%s wurde aus %u Veranstaltung ausgetragen.',
+                        '%s wurde aus %u Veranstaltungen ausgetragen.',
+                        $successes
+                    ),
+                    htmlReady($user->getFullName()),
+                    $successes
+                ));
+            }
+
+            if ($fails) {
+                PageLayout::postError(sprintf(
+                    ngettext(
+                        '%s konnte aus %u Veranstaltung nicht ausgetragen werden.',
+                        '%s konnte aus %u Veranstaltungen nicht ausgetragen werden.',
+                        $fails
+                    ),
+                    htmlReady($user->getFullName()),
+                    $fails
+                ));
+            }
+        }
+
+        $this->redirect($this->show_user_coursesURL($user));
+    }
+
     /**
      * Init sidebar
      */
diff --git a/app/views/admin/cronjobs/logs/index.php b/app/views/admin/cronjobs/logs/index.php
index 6f0511290d9..68cde605020 100644
--- a/app/views/admin/cronjobs/logs/index.php
+++ b/app/views/admin/cronjobs/logs/index.php
@@ -139,4 +139,4 @@
         </tr>
         </tfoot>
     </table>
-</form>
\ No newline at end of file
+</form>
diff --git a/app/views/admin/user/_results.php b/app/views/admin/user/_results.php
index 73b266d46df..1406c2ad811 100644
--- a/app/views/admin/user/_results.php
+++ b/app/views/admin/user/_results.php
@@ -131,7 +131,13 @@
                                 $controller->url_for('admin/user/activities/' . $user->user_id, ['from_index' => 1]),
                                 _('Datei- und Aktivitätsübersicht'),
                                 Icon::create('vcard'),
-                                ['data-dialog' => 'size=50%']
+                                ['data-dialog' => 'size=auto']
+                            );
+                            $actionMenu->addLink(
+                                $controller->show_user_coursesURL($user, ['from_index' => 1]),
+                                _('Veranstaltungsübersicht'),
+                                Icon::create('seminar'),
+                                ['data-dialog' => 'size=auto']
                             );
                             if (Config::get()->LOG_ENABLE) {
                                 $actionMenu->addLink(
diff --git a/app/views/admin/user/show_user_courses.php b/app/views/admin/user/show_user_courses.php
new file mode 100644
index 00000000000..52df5defd71
--- /dev/null
+++ b/app/views/admin/user/show_user_courses.php
@@ -0,0 +1,62 @@
+<? if (!empty($sem_courses)) : ?>
+    <form method="post" action="<?= $controller->delete_course_assignment($user) ?>" class="default collapsable"
+          data-dialog="size=auto">
+        <?= CSRFProtection::tokenTag() ?>
+        <? foreach ($sem_courses as $sem_name => $courses) : ?>
+            <fieldset>
+                <legend>
+                    <?= htmlReady($sem_name) ?>
+                </legend>
+                <table class="default ">
+                    <thead>
+                        <colgroup>
+                            <col style="width: 20px">
+                            <col>
+                            <col>
+                        </colgroup>
+                        <tr>
+                            <th>
+                                <input type="checkbox" name="all" value="1"
+                                       data-proxyfor="tbody#courses-<?= md5($sem_name) ?> td :checkbox">
+                            </th>
+                            <th><?= _('Veranstaltungsname') ?></th>
+                            <th class="actions"><?= _('Aktionen') ?></th>
+                        </tr>
+                    </thead>
+                    <tbody id="courses-<?= md5($sem_name) ?>">
+                        <? foreach ($courses as $course) : ?>
+                            <tr>
+                                <td><input type="checkbox" name="courses[]" value="<?= htmlReady($course->id) ?>"></td>
+                                <td><?= htmlReady($course->getFullname()) ?></td>
+                                <td class="actions">
+                                    <?= Icon::create('trash')->asInput([
+                                        'formaction'   => $controller->delete_course_assignment($user, ['course_id' => $course->id]),
+                                        'data-confirm' => sprintf(
+                                            _('Wollen Sie %s wirklich austragen?'),
+                                            htmlReady($user->getFullName())
+                                        ),
+                                        'data-dialog'  => 'size=auto'
+                                    ]) ?>
+                                </td>
+                            </tr>
+                        <? endforeach ?>
+                    </tbody>
+                </table>
+            </fieldset>
+        <? endforeach ?>
+        <footer data-dialog-button>
+            <?= \Studip\Button::create(
+                _('Austragen'),
+                'delete_assignments',
+                [
+                    'data-confirm' => sprintf(
+                        _('Wollen Sie %s wirklich austragen?'),
+                        htmlReady($user->getFullName())
+                    )
+                ]
+            ) ?>
+        </footer>
+    </form>
+<? else : ?>
+    <?= MessageBox::info(_('Es wurden keine Veranstaltungen gefunden.')) ?>
+<? endif ?>
-- 
GitLab