aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Siegfried <david.siegfried@uni-vechta.de>2025-06-26 08:25:12 +0000
committerDavid Siegfried <david.siegfried@uni-vechta.de>2025-06-26 08:25:12 +0000
commit3b244eacbfd8a3c3e4a87f17e8e0e659b608045c (patch)
treea57e00ace249c8587d348db68d7600bea5102f0c
parent964ff48d51a2af44548be2cca51e79b98bc51906 (diff)
add users directly to accepted-list , fixes #4060
Closes #4060 Merge request studip/studip!3984
-rw-r--r--app/controllers/course/members.php107
-rw-r--r--app/views/course/members/autor_list.php3
-rw-r--r--lib/models/AdmissionApplication.php68
3 files changed, 166 insertions, 12 deletions
diff --git a/app/controllers/course/members.php b/app/controllers/course/members.php
index fa9dd55..5c070c9 100644
--- a/app/controllers/course/members.php
+++ b/app/controllers/course/members.php
@@ -426,6 +426,18 @@ class Course_MembersController extends AuthenticatedController
$this->redirect('course/members/index');
}
+ public function execute_multipersonsearch_accepted_action(): void
+ {
+ if (!$this->is_tutor) {
+ throw new AccessDeniedException();
+ }
+
+ $mp = MultiPersonSearch::load('add_accepted' . $this->course_id);
+ $this->addAccepted($mp->getAddedUsers(), Course::find($this->course_id));
+
+ $this->redirect('course/members/index');
+ }
+
/**
* Add tutors to a seminar.
* @throws AccessDeniedException
@@ -880,6 +892,9 @@ class Course_MembersController extends AuthenticatedController
case 'remove':
$target = 'course/members/cancel_subscription/collection/autor';
break;
+ case 'to_accepted_list':
+ $target = 'course/members/to_accepted_list';
+ break;
case 'to_course':
$this->redirect('course/members/select_course');
return;
@@ -1285,6 +1300,20 @@ class Course_MembersController extends AuthenticatedController
$this->redirect('course/members/index');
}
+ public function to_accepted_list_action(): void
+ {
+ if (!$this->is_tutor) {
+ throw new AccessDeniedException();
+ }
+
+ if (!empty($this->flash['users'])) {
+ $user_ids = array_keys(array_filter($this->flash['users']));
+
+ $this->addAccepted($user_ids, Course::find($this->course_id));
+ }
+
+ $this->redirect('course/members/index');
+ }
/**
* Moves selected users to waitlist, either at the top or at the end.
* @param $which_end 'first' or 'last': append to top or to end of waitlist?
@@ -1679,6 +1708,14 @@ class Course_MembersController extends AuthenticatedController
Icon::create('add')
));
+ $ignore = array_merge(
+ $filtered_members['dozent']->pluck('user_id'),
+ $filtered_members['tutor']->pluck('user_id'),
+ $filtered_members['autor']->pluck('user_id'),
+ $filtered_members['user']->pluck('user_id'),
+ $filtered_members['awaiting']->pluck('user_id')
+ );
+
// add "add person to waitlist" to sidebar
if (
$course->isAdmissionEnabled()
@@ -1686,13 +1723,7 @@ class Course_MembersController extends AuthenticatedController
&& !$course->admission_disable_waitlist
&& (!$course->getFreeSeats() || $course->admission_disable_waitlist_move)
) {
- $ignore = array_merge(
- $filtered_members['dozent']->pluck('user_id'),
- $filtered_members['tutor']->pluck('user_id'),
- $filtered_members['autor']->pluck('user_id'),
- $filtered_members['user']->pluck('user_id'),
- $filtered_members['awaiting']->pluck('user_id')
- );
+
$mp = MultiPersonSearch::get("add_waitlist{$this->course_id}")
->setLinkText(_('Person(en) auf Warteliste eintragen'))
->setDefaultSelectedUser($ignore)
@@ -1706,6 +1737,21 @@ class Course_MembersController extends AuthenticatedController
$element = LinkElement::fromHTML($mp, Icon::create('add'));
$widget->addElement($element);
}
+
+ if ($course->admission_prelim) {
+ $mp = MultiPersonSearch::get("add_accepted{$course->id}")
+ ->setLinkText(_('Vorläufig akzeptierte Teilnehmende eintragen'))
+ ->setDefaultSelectedUser($ignore)
+ ->setLinkIconPath('')
+ ->setTitle(_('Vorläufig akzeptierte Teilnehmende eintragen'))
+ ->setExecuteURL($this->execute_multipersonsearch_acceptedURL())
+ ->setSearchObject($searchType)
+ ->addQuickfilter(_('Mitglieder der Einrichtung'), $membersOfInstitute)
+ ->setNavigationItem('/course/members/view')
+ ->render();
+ $element = LinkElement::fromHTML($mp, Icon::create('add'));
+ $widget->addElement($element);
+ }
$widget->addLink(
_('Teilnehmendenliste importieren'),
$this->import_autorlistURL(),
@@ -2088,6 +2134,53 @@ class Course_MembersController extends AuthenticatedController
}
/**
+ * Adds the given users to the accepted list of the current course
+ */
+ private function addAccepted(array $user_ids, Course $course): void
+ {
+ $added = [];
+ $failed = [];
+
+ User::findEachMany(
+ function (User $user) use ($course, &$added, &$failed): void {
+ if (AdmissionApplication::addAcceptedMember($user, $course)) {
+ $added[] = $user->getFullName();
+ } else {
+ $failed[] = $user->getFullName();
+ }
+ },
+ $user_ids
+ );
+
+ if (count($added) > 0) {
+ PageLayout::postSuccess(
+ sprintf(
+ ngettext(
+ 'Es wurde %u neue Person auf die vorläufig akzeptierten Liste hinzugefügt.',
+ 'Es wurden %u neue Personen auf die vorläufig akzeptierten Liste eingetragen.',
+ count($added)
+ ),
+ count($added)
+ ),
+ $added
+ );
+ }
+ if (count($failed) > 0) {
+ PageLayout::postError(
+ sprintf(
+ ngettext(
+ '%u Person konnte nicht auf die vorläufig akzeptierten Liste eingetragen werden.',
+ '%u neue Personen konnten nicht auf die vorläufig akzeptierten Liste eingetragen werden.',
+ count($failed)
+ ),
+ count($failed),
+ ),
+ $failed
+ );
+ }
+ }
+
+ /**
* Adds the given users to the target course.
* @param array $users users to add
* @param string $target_course_id which course to add users to
diff --git a/app/views/course/members/autor_list.php b/app/views/course/members/autor_list.php
index 24bebcc..adbf8ad 100644
--- a/app/views/course/members/autor_list.php
+++ b/app/views/course/members/autor_list.php
@@ -206,6 +206,9 @@
<option value="to_course">
<?= _('In andere Veranstaltung verschieben/kopieren') ?>
</option>
+ <option value="to_accepted_list">
+ <?= _('Auf die vorläufige Liste verschieben') ?>
+ </option>
<? endif ?>
<option value="message"><?=_('Nachricht senden')?></option>
</select>
diff --git a/lib/models/AdmissionApplication.php b/lib/models/AdmissionApplication.php
index 6ecc17f..3da80ca 100644
--- a/lib/models/AdmissionApplication.php
+++ b/lib/models/AdmissionApplication.php
@@ -176,17 +176,75 @@ class AdmissionApplication extends SimpleORMap implements PrivacyObject
}
/**
+ * Adds the given user to the accepted list of the current course and sends a
+ * corresponding message.
+ */
+ public static function addAcceptedMember(User $user, Course $course): bool
+ {
+ $position = (int) DBManager::get()->fetchColumn(
+ "SELECT MAX(`position`) AS maxpos FROM `admission_seminar_user` WHERE `seminar_id`=?",
+ [$course->id]
+ );
+
+ $data = [
+ 'seminar_id' => $course->id,
+ 'user_id' => $user->id,
+ 'position' => $position + 1,
+ 'status' => 'accepted'
+ ];
+
+ $member_ship = AdmissionApplication::findOneBySQL(
+ "`user_id` = ? AND `status` = 'awaiting'",
+ [$user->id]
+ );
+
+ if (!$member_ship) {
+ $member_ship = AdmissionApplication::build($data);
+ $updated = false;
+ } else {
+ $member_ship->setData($data);
+ $updated = true;
+ }
+
+ if ($member_ship->store()) {
+ $course_member = CourseMember::find([$course->id, $user->id]);
+
+ if ($course_member) {
+ $course_member->delete();
+ }
+ $message_title = sprintf(_('Teilnahme an der Veranstaltung %s'), $course->getFullName());
+
+ if ($updated) {
+ $message_body = sprintf(
+ _('Sie wurden in die Veranstaltung **%s** auf einen vorläufigen Platz hochgestuft. Die endgültige Zulassung zu der Veranstaltung ist noch von weiteren Bedingungen abhängig, die Sie bitte der Veranstaltungsbeschreibung entnehmen.'),
+ $course->getFullName()
+ );
+ } else {
+ $message_body = sprintf(
+ _('Sie wurden in die Veranstaltung **%s** auf einen vorläufigen Platz eingetragen. Die endgültige Zulassung zu der Veranstaltung ist noch von weiteren Bedingungen abhängig, die Sie bitte der Veranstaltungsbeschreibung entnehmen.'),
+ $course->getFullName()
+ );
+ }
+ StudipLog::log('SEM_USER_ADD', $course->id, $user->id, 'accepted', 'Vorläufig akzeptiert');
+
+ messaging::sendSystemMessage($user->id, $message_title, $message_body);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
* @param string $seminar_id
- * @param string $send_message
+ * @param bool $send_message
* @return void
- * @throws NotificationVetoException
+ * @throws \Studip\Exception
*/
public static function addMembers(string $seminar_id, bool $send_message = true): void
{
$messaging = new messaging;
-
- //Daten holen / Abfrage ob ueberhaupt begrenzt
- $course = Course::find($seminar_id, true);
+ $course = Course::find($seminar_id, true);
if ($course->isAdmissionEnabled()) {
$sem_preliminary = $course->admission_prelim == 1;