diff options
| author | Jan-Hendrik Willms <tleilax+studip@gmail.com> | 2021-11-11 14:45:40 +0000 |
|---|---|---|
| committer | Jan-Hendrik Willms <tleilax+studip@gmail.com> | 2021-11-11 14:45:40 +0000 |
| commit | 55966778f070aca0dfe9f405db1a7bfa098a13f6 (patch) | |
| tree | ca92156a67377660cebeb8cc9cfd7d7171a8fc4e /lib/admissionrules | |
| parent | 9dcac1b5473709f6f5d2843fa4120ff2050e8074 (diff) | |
TIC #9569
Diffstat (limited to 'lib/admissionrules')
| -rwxr-xr-x[-rw-r--r--] | lib/admissionrules/coursememberadmission/CourseMemberAdmission.class.php | 144 | ||||
| -rwxr-xr-x[-rw-r--r--] | lib/admissionrules/coursememberadmission/templates/configure.php | 130 | ||||
| -rwxr-xr-x[-rw-r--r--] | lib/admissionrules/coursememberadmission/templates/info.php | 44 |
3 files changed, 220 insertions, 98 deletions
diff --git a/lib/admissionrules/coursememberadmission/CourseMemberAdmission.class.php b/lib/admissionrules/coursememberadmission/CourseMemberAdmission.class.php index db7a137..74892fd 100644..100755 --- a/lib/admissionrules/coursememberadmission/CourseMemberAdmission.class.php +++ b/lib/admissionrules/coursememberadmission/CourseMemberAdmission.class.php @@ -17,14 +17,15 @@ class CourseMemberAdmission extends AdmissionRule { + const MODE_MUST_BE_IN_COURSES = 0; + const MODE_MAY_NOT_BE_IN_COURSES = 1; // --- ATTRIBUTES --- /** * End of course admission. */ - public $mandatory_course_id = ''; + public $courses_to_add = '[]'; public $modus = ''; - public $default_message1 = ''; // --- OPERATIONS --- @@ -33,11 +34,10 @@ class CourseMemberAdmission extends AdmissionRule * * @param String ruleId */ - public function __construct($ruleId='', $courseSetId = '') + public function __construct($ruleId = '', $courseSetId = '') { parent::__construct($ruleId, $courseSetId); - $this->default_message = _('Sie sind nicht in der Veranstaltung "%s" eingetragen.'); - $this->default_message1 = _('Sie dürfen nicht in der Veranstaltung "%s" eingetragen sein.'); + if ($ruleId) { $this->load(); } else { @@ -48,26 +48,31 @@ class CourseMemberAdmission extends AdmissionRule /** * Deletes the admission rule and all associated data. */ - public function delete() { + public function delete() + { parent::delete(); + // Delete rule data. - $stmt = DBManager::get()->prepare("DELETE FROM `coursememberadmissions` - WHERE `rule_id`=?"); - $stmt->execute([$this->id]); + DBManager::get()->execute( + "DELETE FROM `coursememberadmissions` WHERE `rule_id` = ?", + [$this->id] + ); } /** * Gets some text that describes what this AdmissionRule (or respective * subclass) does. */ - public static function getDescription() { + public static function getDescription() + { return _("Anmelderegeln dieses Typs legen eine Veranstaltung fest, in der die Nutzer bereits eingetragen sein müssen, oder in der sie nicht eingetragen sein dürfen, um sich zu Veranstaltungen des Anmeldesets anmelden zu können."); } /** * Return this rule's name. */ - public static function getName() { + public static function getName() + { return _("Veranstaltungsbezogene Anmeldung"); } @@ -76,24 +81,24 @@ class CourseMemberAdmission extends AdmissionRule * * @return String */ - public function getTemplate() { + public function getTemplate() + { // Open generic admission rule template. $tpl = $GLOBALS['template_factory']->open('admission/rules/configure'); $tpl->set_attribute('rule', $this); - $factory = new Flexi_TemplateFactory(dirname(__FILE__).'/templates/'); - // Now open specific template for this rule and insert base template. - - $tpl2 = $factory->open('configure'); - $tpl2->set_attribute('rule', $this); - $tpl2->set_attribute('mandatory_course', Course::find($this->mandatory_course_id)); - $tpl2->set_attribute('tpl', $tpl->render()); - return $tpl2->render(); + + return $this->getTemplateFactory()->render('configure', [ + 'rule' => $this, + 'tpl' => $tpl->render(), + 'courses' => $this->getDecodedCourses(), + ]); } /** * Helper function for loading rule definition from database. */ - public function load() { + public function load() + { // Load data. $stmt = DBManager::get()->prepare("SELECT * FROM `coursememberadmissions` WHERE `rule_id`=? LIMIT 1"); @@ -102,8 +107,8 @@ class CourseMemberAdmission extends AdmissionRule $this->message = $current['message']; $this->startTime = $current['start_time']; $this->endTime = $current['end_time']; - $this->mandatory_course_id = $current['course_id']; - $this->modus = $current['modus']; + $this->courses_to_add = $current['courses']; + $this->modus = (int) $current['modus']; } } @@ -114,15 +119,27 @@ class CourseMemberAdmission extends AdmissionRule * @param String courseId * @return Array */ - public function ruleApplies($userId, $courseId) { + public function ruleApplies($userId, $courseId) + { $errors = []; if ($this->checkTimeFrame()) { - $user = User::find($userId); - $is_member = $user->course_memberships->findOneBy('seminar_id', $this->mandatory_course_id); - if ((!$this->modus && !$is_member) || ($this->modus && $is_member)) { - $errors[] = $this->getMessage(Course::find($this->mandatory_course_id)); + $courses = $this->getDecodedCourses(); + foreach ($courses as $course) { + $is_member = CourseMember::exists([$course->id, $userId]); + + if (($this->modus == self::MODE_MUST_BE_IN_COURSES && !$is_member) + || ($this->modus == self::MODE_MAY_NOT_BE_IN_COURSES && $is_member) + ) { + $errors[] = $this->getMessage($course); + } + } + + // mode: "Mitgliedschaft ist in mindestens einer dieser Veranstaltungen notwendig" + if ($this->modus == self::MODE_MUST_BE_IN_COURSES && count($errors) < count($courses)) { + $errors = []; } } + return $errors; } @@ -134,24 +151,27 @@ class CourseMemberAdmission extends AdmissionRule * @param Array $data * @return AdmissionRule This object. */ - public function setAllData($data) { + public function setAllData($data) + { parent::setAllData($data); - $this->mandatory_course_id = $data['mandatory_course_id'] ?: $data['mandatory_course_id_old']; - $this->modus = $data['modus']; + + $this->modus = (int) $data['modus']; + $this->courses_to_add = json_encode(array_keys($data['courses_to_add'])); return $this; - } + } /** * Store rule definition to database. */ - public function store() { + public function store() + { // Store data. $stmt = DBManager::get()->prepare("INSERT INTO `coursememberadmissions` - (`rule_id`, `message`, `course_id`, `modus`, `start_time`, + (`rule_id`, `message`, `courses`, `modus`, `start_time`, `end_time`, `mkdate`, `chdate`) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE `start_time`=VALUES(`start_time`), - `end_time`=VALUES(`end_time`),message=VALUES(message),course_id=VALUES(course_id),modus=VALUES(modus), `chdate`=VALUES(`chdate`)"); - $stmt->execute([$this->id, $this->message,$this->mandatory_course_id, (int)$this->modus, (int)$this->startTime, + `end_time`=VALUES(`end_time`),message=VALUES(message),courses=VALUES(courses),modus=VALUES(modus), `chdate`=VALUES(`chdate`)"); + $stmt->execute([$this->id, $this->message, $this->courses_to_add, (int)$this->modus, (int)$this->startTime, (int)$this->endTime, time(), time()]); } @@ -162,10 +182,11 @@ class CourseMemberAdmission extends AdmissionRule */ public function toString() { - $factory = new Flexi_TemplateFactory(dirname(__FILE__).'/templates/'); - $tpl = $factory->open('info'); - $tpl->set_attribute('rule', $this); - return $tpl->render(); + return $this->getTemplateFactory()->render('info', [ + 'courses' => $this->getDecodedCourses(), + 'rule' => $this, + 'modus' => $this->modus, + ]); } /** @@ -178,7 +199,7 @@ class CourseMemberAdmission extends AdmissionRule public function validate($data) { $errors = parent::validate($data); - if (!($data['mandatory_course_id'] || $data['mandatory_course_id_old'])) { + if (!$data['courses_to_add']) { $errors[] = _('Bitte wählen Sie eine Veranstaltung aus.'); } return $errors; @@ -187,6 +208,7 @@ class CourseMemberAdmission extends AdmissionRule public function getMessage($course = null) { $message = parent::getMessage(); + if ($course) { return sprintf($message, $course->getFullname('number-name')); } else { @@ -194,4 +216,44 @@ class CourseMemberAdmission extends AdmissionRule } } + private function getDecodedCourses() + { + $decoded_courses = json_decode($this->courses_to_add, true); + if (!$decoded_courses) { + return []; + } + return Course::findMany($decoded_courses); + } + + public function getValidityPeriod(): string + { + if ($this->getStartTime() && $this->getEndTime()) { + return sprintf( + _('Diese Regel gilt von %s bis %s.'), + strftime('%d.%m.%Y %H:%M', $this->getStartTime()), + strftime('%d.%m.%Y %H:%M', $this->getEndTime()) + ); + } + + if ($this->getStartTime() && !$this->getEndTime()) { + return sprintf( + _('Diese Regel gilt ab %s.'), + strftime('%d.%m.%Y %H:%M', $this->getStartTime()) + ); + } + + if (!$this->getStartTime() && $this->getEndTime()) { + return sprintf( + _('Diese Regel gilt bis %s.'), + strftime('%d.%m.%Y %H:%M', $this->getEndTime()) + ); + } + + return ''; + } + + private function getTemplateFactory(): Flexi_TemplateFactory + { + return new Flexi_TemplateFactory(__DIR__ . '/templates/'); + } } diff --git a/lib/admissionrules/coursememberadmission/templates/configure.php b/lib/admissionrules/coursememberadmission/templates/configure.php index 5434f5c..88560d8 100644..100755 --- a/lib/admissionrules/coursememberadmission/templates/configure.php +++ b/lib/admissionrules/coursememberadmission/templates/configure.php @@ -1,35 +1,36 @@ -<h3><?= $rule->getName() ?></h3> +<h3><?= htmlReady($rule->getName()) ?></h3> + <?= $tpl ?> + <input type="hidden" name="search_sem_qs_choose" value="title_lecturer_number"> -<? if ($mandatory_course) : ?> - <input type="hidden" name="mandatory_course_id_old" value="<?=$mandatory_course->id?>"> +<? foreach ($courses as $course) : ?> + <input type="hidden" name="mandatory_course_id_old[]" value="<?= htmlReady($course->id) ?>"> + <label class="caption"> <?= _('Mitgliedschaft in folgender Veranstaltung überprüfen') ?>: </label> <p> - <?=htmlReady($mandatory_course->getFullName('number-name-semester'));?> - <a href="<?=URLHelper::getScriptLink('dispatch.php/course/details/index/' . $mandatory_course->id) ?>" data-dialog> - <?= Icon::create( - 'info-circle', - Icon::ROLE_INACTIVE, - ['title' =>_('Veranstaltungsdetails aufrufen')] - )?> + <?=htmlReady($course->getFullName('number-name-semester'));?> + <a href="<?=URLHelper::getLink('dispatch.php/course/details/index/' . $course->id) ?>" data-dialog> + <?= Icon::create('info-circle')->asImg([ + 'title' =>_('Veranstaltungsdetails aufrufen') + ]) ?> </a> </p> -<? endif ?> +<? endforeach ?> <label class="caption"> <?= _('Modus') ?>: </label> <div> - <label> - <input type="radio" name="modus" value="0" <?=(!$rule->modus ? 'checked' : '')?>> - <?=_("Mitgliedschaft ist notwendig")?> + <label> + <input type="radio" name="modus" value="0" <? if ($rule->modus == CourseMemberAdmission::MODE_MUST_BE_IN_COURSES) echo 'checked'; ?>> + <?=_("Mitgliedschaft ist in mindestens einer dieser Veranstaltungen notwendig")?> </label> <label> - <input type="radio" name="modus" value="1" <?=($rule->modus ? 'checked' : '')?>> - <?=_("Mitgliedschaft ist verboten")?> + <input type="radio" name="modus" value="1" <? if ($rule->modus == CourseMemberAdmission::MODE_MAY_NOT_BE_IN_COURSES) echo 'checked'; ?>> + <?=_("Mitgliedschaft ist in keiner dieser Veranstaltungen erlaubt")?> </label> </div> @@ -39,27 +40,84 @@ <div style="display:inline-block"> -<?= -QuickSearch::get("mandatory_course_id", new SeminarSearch('number-name-lecturer')) - ->render(); -?> -<?= Semester::getSemesterSelector( - ['name' => 'search_sem_sem'], - Semester::getIndexById($_SESSION['_default_sem'], false, !$GLOBALS['perm']->have_perm('admin')), - 'key', - false -)?> - + <?= + QuickSearch::get("mandatory_course_id", new SeminarSearch('number-name-lecturer')) + ->fireJSFunctionOnSelect('addcourse') + ->render(); + ?> + <?= Semester::getSemesterSelector( + ['name' => 'search_sem_sem'], + Semester::getIndexById($_SESSION['_default_sem'], false, !$GLOBALS['perm']->have_perm('admin')), + 'key', + false + )?> + <br><br> + <ul> + <? foreach ($courses as $course) : ?> + <li> + <input type="hidden" id="<?= htmlReady($course->id) ?>" + name="courses_to_add[<?= htmlReady($course->id) ?>]" + value="<?= htmlReady($course->name) ?>"> + <span><?= htmlReady($course->name) ?></span> + <a href="#" onclick="return removecourse('<?= htmlReady($course->id) ?>')"> + <?= Icon::create('trash') ?> + </a> + </li> + <? endforeach ?> + </ul> </div> -<br><br> <script> - $('#ruleform input[name="modus"]').on('change', - function () { - var message = [ - "<?=jsReady($rule->default_message, 'script-double')?>", - "<?=jsReady($rule->default_message1, 'script-double')?>" - ]; - $('#ruleform textarea').text(message[this.value]); - }); + $('#ruleform input[name="modus"]').on('change', function () { + const message = <?= json_encode([ + _('Sie sind nicht in der Veranstaltung "%s" eingetragen.'), + _('Sie dürfen nicht in der Veranstaltung "%s" eingetragen sein.'), + ]) ?>; + console.log(this, this.value); + $('#ruleform textarea').text(message[this.value]); + }).filter(':checked').change(); + + function addcourse(id, title) { + + if ($('input[name="courses_to_add[' + id + ']"]').length === 0) { + var wrapper = $('<li>'); + var input = $('<input>') + .attr('id', id) + .attr('type', 'hidden') + .attr('name', 'courses_to_add['+ id + ']') + .attr('value', title); + wrapper.append(input); + + var trash = $('<input>') + .attr('type', 'image') + .attr('src', STUDIP.ASSETS_URL + 'images/icons/blue/trash.svg') + .attr('name', 'remove_[' + id + ']') + .attr('value', '1') + .attr('onclick', "return removecourse('" + id + "')"); + + var icon = $('<a>') + .attr('onclick', "return removecourse('" + id + "')") + .attr('href', '#'); + var img = $('<img>') + .attr('src', STUDIP.ASSETS_URL + 'images/icons/blue/trash.svg') + .attr('width', '16px') + .attr('height', '16px'); + icon.append(img); + + var nametext = $('<span>') + .html(title) + .text(); + wrapper.append(nametext); + wrapper.append(icon); + + $('input[name=mandatory_course_id_parameter]').parent().find('ul').append(wrapper); + } + + } + + function removecourse(id) { + $('input#' + id).parent().remove(); + return false; + } + </script> diff --git a/lib/admissionrules/coursememberadmission/templates/info.php b/lib/admissionrules/coursememberadmission/templates/info.php index 532c591..5e35643 100644..100755 --- a/lib/admissionrules/coursememberadmission/templates/info.php +++ b/lib/admissionrules/coursememberadmission/templates/info.php @@ -1,21 +1,23 @@ -<?php -if ($rule->getStartTime() && $rule->getEndTime()) { - echo sprintf(_('Diese Regel gilt von %s bis %s.'), strftime('%d.%m.%Y %H:%M', - $rule->getStartTime()), strftime('%d.%m.%Y %H:%M', $rule->getEndTime())).'<br/>'; -} else if ($rule->getStartTime() && !$rule->getEndTime()) { - echo sprintf(_('Diese Regel gilt ab %s.'), strftime('%d.%m.%Y %H:%M', $rule->getStartTime())).'<br/>'; -} else if (!$rule->getStartTime() && $rule->getEndTime()) { - echo sprintf(_('Diese Regel gilt bis %s.'), strftime('%d.%m.%Y %H:%M', $rule->getEndTime())).'<br/>'; -} -$course = Course::find($rule->mandatory_course_id); -if ($course) { -echo sprintf(!$rule->modus ? - _('Die Anmeldung ist nur Teilnehmenden der Veranstaltung: <b>%s</b> %s erlaubt.') : - _('Die Anmeldung ist für Teilnehmende der Veranstaltung: <b>%s</b> %s verboten.'), - $course->getFullname('number-name-semester'), '<a href="'.URLHelper::getScriptLink('dispatch.php/course/details/index/' . $course->id).'" data-dialog>'. - Icon::create( - 'info-circle', - Icon::ROLE_INACTIVE, - ['title' =>_('Veranstaltungsdetails aufrufen')] - ).'</a>'); -} +<? if ($rule->getValidityPeriod()): ?> + <?= $rule->getValidityPeriod() ?><br> +<? endif; ?> + +<? if ($modus == CourseMemberAdmission::MODE_MAY_NOT_BE_IN_COURSES): ?> + <?= _('Die Anmeldung ist für Teilnehmende einer der folgenden Veranstaltungen nicht erlaubt:') ?> +<? elseif ($modus == CourseMemberAdmission::MODE_MUST_BE_IN_COURSES): ?> + <?= _('Die Anmeldung ist nur für Teilnehmende mindestens einer der folgenden Veranstaltungen erlaubt:') ?> +<? endif; ?> +<br> + +<ul> +<? foreach ($courses as $course): ?> + <li> + <strong><?= htmlReady($course->getFullname('number-name-semester')) ?></strong> + <a href="<?= URLHelper::getLink('dispatch.php/course/details/index/' . $course->id) ?>" data-dialog> + <?= Icon::create('info-circle')->asImg([ + 'title' => _('Veranstaltungsdetails aufrufen') + ]) ?> + </a> + </li> +<? endforeach; ?> +</ul> |
