diff options
| author | David Siegfried <david.siegfried@uni-vechta.de> | 2025-06-26 08:25:12 +0000 |
|---|---|---|
| committer | David Siegfried <david.siegfried@uni-vechta.de> | 2025-06-26 08:25:12 +0000 |
| commit | 3b244eacbfd8a3c3e4a87f17e8e0e659b608045c (patch) | |
| tree | a57e00ace249c8587d348db68d7600bea5102f0c | |
| parent | 964ff48d51a2af44548be2cca51e79b98bc51906 (diff) | |
add users directly to accepted-list , fixes #4060
Closes #4060
Merge request studip/studip!3984
| -rw-r--r-- | app/controllers/course/members.php | 107 | ||||
| -rw-r--r-- | app/views/course/members/autor_list.php | 3 | ||||
| -rw-r--r-- | lib/models/AdmissionApplication.php | 68 |
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; |
