From 9ba053ad773f4ed015ab565b3c5129d8e7f80c89 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Mon, 13 Nov 2023 14:17:58 +0000
Subject: [PATCH] fixes #3435

Closes #3435

Merge request studip/studip!2343
---
 app/controllers/consultation/admin.php        |  2 +
 app/views/consultation/admin/create.php       |  7 ++
 app/views/consultation/admin/edit.php         |  8 +++
 ..._mailing_option_to_consultation_blocks.php | 29 ++++++++
 lib/classes/ConsultationMailer.php            | 66 ++++++++++---------
 lib/models/ConsultationBlock.php              |  1 +
 6 files changed, 81 insertions(+), 32 deletions(-)
 create mode 100644 db/migrations/5.5.7_add_tutor_mailing_option_to_consultation_blocks.php

diff --git a/app/controllers/consultation/admin.php b/app/controllers/consultation/admin.php
index b335e360401..e5a709fa314 100644
--- a/app/controllers/consultation/admin.php
+++ b/app/controllers/consultation/admin.php
@@ -205,6 +205,7 @@ class Consultation_AdminController extends ConsultationController
                 $block->calendar_events   = Request::bool('calender-events', false);
                 $block->show_participants = Request::bool('show-participants', false);
                 $block->require_reason    = Request::option('require-reason');
+                $block->mail_to_tutors    = Request::bool('mail-to-tutors', false);
                 $block->confirmation_text = trim(Request::get('confirmation-text')) ?: null;
                 $block->note              = Request::get('note');
                 $block->size              = Request::int('size', 1);
@@ -395,6 +396,7 @@ class Consultation_AdminController extends ConsultationController
         $this->block->calendar_events = Request::bool('calender-events', false);
         $this->block->show_participants = Request::bool('show-participants', false);
         $this->block->require_reason = Request::option('require-reason');
+        $this->block->mail_to_tutors = Request::bool('mail-to-tutors', false);
         $this->block->confirmation_text = trim(Request::get('confirmation-text'));
         $this->block->lock_time = Request::int('lock_time');
 
diff --git a/app/views/consultation/admin/create.php b/app/views/consultation/admin/create.php
index ff0b4831d4c..627afeacc86 100644
--- a/app/views/consultation/admin/create.php
+++ b/app/views/consultation/admin/create.php
@@ -198,6 +198,13 @@ $intervals = [
             <?= _('Die freien Termine auch im Kalender markieren') ?>
         </label>
 
+    <? if ($range instanceof Course): ?>
+        <label>
+            <input type="checkbox" name="mail-to-tutors" value="1" checked>
+            <?= _('Tutor/innen beim Versand allgemeiner Nachrichten berücksichtigen?') ?>
+        </label>
+    <? endif; ?>
+
         <label>
             <input type="checkbox" name="show-participants" value="1"
                     <? if (Request::bool('show-participants')) echo 'checked'; ?>>
diff --git a/app/views/consultation/admin/edit.php b/app/views/consultation/admin/edit.php
index 2017c321e8c..f0b1a4f4055 100644
--- a/app/views/consultation/admin/edit.php
+++ b/app/views/consultation/admin/edit.php
@@ -57,6 +57,14 @@
             <?= _('Die freien Termine auch im Kalender markieren') ?>
         </label>
 
+    <? if ($block->range_type === 'course'): ?>
+        <label>
+            <input type="checkbox" name="mail-to-tutors" value="1"
+                <? if ($block->mail_to_tutors) echo 'checked'; ?>>
+            <?= _('Tutor/innen beim Versand allgemeiner Nachrichten berücksichtigen?') ?>
+        </label>
+    <? endif; ?>
+
         <label>
             <input type="checkbox" name="show-participants" value="1"
                 <? if ($block->show_participants) echo 'checked'; ?>>
diff --git a/db/migrations/5.5.7_add_tutor_mailing_option_to_consultation_blocks.php b/db/migrations/5.5.7_add_tutor_mailing_option_to_consultation_blocks.php
new file mode 100644
index 00000000000..3a2de1eb890
--- /dev/null
+++ b/db/migrations/5.5.7_add_tutor_mailing_option_to_consultation_blocks.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @author Jan-Hendrik Willms <tleilax+studip@gmail.com>
+ * @license GPL2 or any later version
+ * @see https://gitlab.studip.de/studip/studip/-/issues/3435
+ */
+final class AddTutorMailingOptionToConsultationBlocks extends Migration
+{
+    public function description()
+    {
+        return 'Adds the flag "mail_to_tutors" to table "consultation_blocks"';
+    }
+
+    protected function up()
+    {
+        $query = "ALTER TABLE `consultation_blocks`
+                  ADD COLUMN `mail_to_tutors` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1 AFTER `require_reason`";
+        DBManager::get()->exec($query);
+    }
+
+    protected function down()
+    {
+        $query = "ALTER TABLE `consultation_blocks`
+                  DROP COLUMN `mail_to_tutors`";
+        DBManager::get()->exec($query);
+    }
+
+}
diff --git a/lib/classes/ConsultationMailer.php b/lib/classes/ConsultationMailer.php
index 45ef0b48fc0..cf5af537fd9 100644
--- a/lib/classes/ConsultationMailer.php
+++ b/lib/classes/ConsultationMailer.php
@@ -5,30 +5,14 @@
  */
 class ConsultationMailer
 {
-    private static $messaging = null;
-
-    /**
-     * Returns a messaging object.
-     *
-     * @return messaging object
-     */
-    private static function getMessaging()
-    {
-        if (self::$messaging === null) {
-            self::$messaging = new messaging();
-        }
-        return self::$messaging;
-    }
-
     /**
      * Sends a consultation information message.
      *
-     * @param User|null         $sender  Sender
-     * @param User             $user    Recipient
-     * @param ConsultationSlot $slot    Slot in question
-     * @param string           $subject Subject of the message
-     * @param string           $reason  Reason for a booking or cancelation
-     * @param User             $sender  Sender of the message
+     * @param User|null           $sender  Sender
+     * @param User                $user    Recipient
+     * @param ConsultationBooking $booking    Booking in question
+     * @param string              $subject Subject of the message
+     * @param string|null         $reason  Reason for a booking or cancelation
      */
     public static function sendMessage(?User $sender, User $user, ConsultationBooking $booking, string $subject, ?string $reason = '')
     {
@@ -63,11 +47,7 @@ class ConsultationMailer
      */
     public static function sendBookingMessageToResponsibilities(?User $sender, ConsultationBooking $booking)
     {
-        foreach ($booking->slot->block->responsible_persons as $user) {
-            if ($user->id === $GLOBALS['user']->id) {
-                continue;
-            }
-
+        foreach (self::getResponsiblePersonsOfBlock($booking->slot->block) as $user) {
             self::sendMessage(
                 $sender,
                 $user,
@@ -97,7 +77,7 @@ class ConsultationMailer
      * Send an information message about a changed reason to a user of the
      * booked slot.
      *
-     * @param User                 $sender   The sender of the message
+     * @param User|null           $sender   The sender of the message
      * @param ConsultationBooking $booking  The booking
      * @param User                $receiver The receiver of the message
      */
@@ -120,11 +100,7 @@ class ConsultationMailer
      */
     public static function sendCancelMessageToResponsibilities(?User $sender, ConsultationBooking $booking, string $reason = '')
     {
-        foreach ($booking->slot->block->responsible_persons as $user) {
-            if ($user->id === $GLOBALS['user']->id) {
-                continue;
-            }
-
+        foreach (self::getResponsiblePersonsOfBlock($booking->slot->block) as $user) {
             self::sendMessage(
                 $sender,
                 $user,
@@ -150,4 +126,30 @@ class ConsultationMailer
             sprintf(_('Termin bei %s abgesagt'), $booking->slot->block->range_display), trim($reason)
         );
     }
+
+    /**
+     * @return Generator<User>
+     */
+    private static function getResponsiblePersonsOfBlock(ConsultationBlock $block): Generator
+    {
+        foreach ($block->responsible_persons as $user) {
+            /** @var User $user */
+
+            // No mail to self
+            if ($user->id === User::findCurrent()->id) {
+                continue;
+            }
+
+            // No mails to tutors
+            if (
+                $block->range_type === 'course'
+                && !$block->mail_to_tutors
+                && !$GLOBALS['perm']->have_studip_perm('dozent', $block->range_id, $user->id)
+            ) {
+                continue;
+            }
+
+            yield $user;
+        }
+    }
 }
diff --git a/lib/models/ConsultationBlock.php b/lib/models/ConsultationBlock.php
index ea792d8af66..a4d1579fb3b 100644
--- a/lib/models/ConsultationBlock.php
+++ b/lib/models/ConsultationBlock.php
@@ -20,6 +20,7 @@
  * @property int $calendar_events database column
  * @property int $show_participants database column
  * @property string $require_reason database column
+ * @property bool $mail_to_tutors database column
  * @property string|null $confirmation_text database column
  * @property string $note database column
  * @property int $size database column
-- 
GitLab