aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/Seminar.class.php
diff options
context:
space:
mode:
authorPhilipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de>2024-09-24 10:53:31 +0200
committerPhilipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de>2024-09-24 10:53:31 +0200
commit4459dd7917f4d1c34f40bb68f0e991e9c3d53e4c (patch)
tree5c07151ae61276d334e88f6309c30d439a85c12e /lib/classes/Seminar.class.php
parentda0022e5c1abbf9825ae76debaabdff7e8623bb4 (diff)
parent97a188592c679890a25c37ab78463add76a52ff7 (diff)
Merge branch 'main' into issue-3911issue-3911
Diffstat (limited to 'lib/classes/Seminar.class.php')
-rw-r--r--lib/classes/Seminar.class.php2439
1 files changed, 0 insertions, 2439 deletions
diff --git a/lib/classes/Seminar.class.php b/lib/classes/Seminar.class.php
deleted file mode 100644
index 054c337..0000000
--- a/lib/classes/Seminar.class.php
+++ /dev/null
@@ -1,2439 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter003: TEST
-# Lifter007: TODO
-# Lifter010: TODO
-/**
- * Seminar.class.php - This class represents a Seminar in Stud.IP
- *
- * This class provides functions for seminar-members, seminar-dates, and seminar-modules
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * @author Till Glöggler <tgloeggl@uni-osnabrueck.de>
- * @author Stefan Suchi <suchi@data-quest>
- * @author Suchi & Berg GmbH <info@data-quest.de>
- * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
- * @category Stud.IP
- */
-
-require_once 'lib/dates.inc.php';
-
-class Seminar
-{
- var $issues = null; // Array of Issue
- var $irregularSingleDates = null; // Array of SingleDates
- var $messages = []; // occured errors, infos, and warnings
- var $semester = null;
- var $filterStart = 0;
- var $filterEnd = 0;
- var $hasDatesOutOfDuration = -1;
- var $message_stack = [];
-
- var $user_number = 0;//?
- var $commands; //?
- var $BookedRoomsStatTemp; //???
-
- var $request_id;//TODO
- var $requestData;
- var $room_request;
-
- private $_metadate = null; // MetaDate
-
- private $alias = [
- 'seminar_number' => 'VeranstaltungsNummer',
- 'subtitle' => 'Untertitel',
- 'description' => 'Beschreibung',
- 'location' => 'Ort',
- 'misc' => 'Sonstiges',
- 'read_level' => 'Lesezugriff',
- 'write_level' => 'Schreibzugriff',
- 'semester_start_time' => 'start_time',
- 'semester_duration_time' => 'duration_time',
- 'form' => 'art',
- 'participants' => 'teilnehmer',
- 'requirements' => 'vorrausetzungen',
- 'orga' => 'lernorga',
- ];
-
- private $course = null;
-
- private $course_set = null;
-
- private static $seminar_object_pool;
-
- public static function GetInstance($id = false, $refresh_cache = false)
- {
- if ($id) {
- if ($refresh_cache) {
- self::$seminar_object_pool[$id] = null;
- }
- if (!empty(self::$seminar_object_pool[$id]) && is_object(self::$seminar_object_pool[$id]) && self::$seminar_object_pool[$id]->getId() == $id) {
- return self::$seminar_object_pool[$id];
- } else {
- self::$seminar_object_pool[$id] = new Seminar($id);
- return self::$seminar_object_pool[$id];
- }
- } else {
- return new Seminar(false);
- }
- }
-
- public static function setInstance(Seminar $seminar)
- {
- return self::$seminar_object_pool[$seminar->id] = $seminar;
- }
-
- /**
- * Constructor
- *
- * Pass nothing to create a seminar, or the seminar_id from an existing seminar to change or delete
- * @access public
- * @param string $seminar_id the seminar to be retrieved
- */
- public function __construct($course_or_id = FALSE)
- {
- $course = Course::toObject($course_or_id);
- if ($course) {
- $this->course = $course;
- } elseif ($course_or_id === false) {
- $this->course = new Course();
- $this->course->setId($this->course->getNewId());
- } else { //hmhmhm
- throw new Exception(sprintf(_('Fehler: Konnte das Seminar mit der ID %s nicht finden!'), $course_or_id));
- }
- }
-
- public function __get($field)
- {
- if ($field == 'is_new') {
- return $this->course->isNew();
- }
- if ($field == 'metadate') {
- if ($this->_metadate === null) {
- $this->_metadate = new MetaDate($this->id);
- $this->_metadate->setSeminarStartTime($this->start_time);
- $this->_metadate->setSeminarDurationTime($this->duration_time);
- }
- return $this->_metadate;
- }
- if(isset($this->alias[$field])) {
- $field = $this->alias[$field];
- }
- return $this->course->$field;
- }
-
- public function __set($field, $value)
- {
- if(isset($this->alias[$field])) {
- $field = $this->alias[$field];
- }
- if ($field == 'metadate') {
- return $this->_metadate = $value;
- }
- return $this->course->$field = $value;
- }
-
- public function __isset($field)
- {
- if ($field == 'metadate') {
- return is_object($this->_metadate);
- }
- if(isset($this->alias[$field])) {
- $field = $this->alias[$field];
- }
- return isset($this->course->$field);
- }
-
- public function __call($method, $params)
- {
- return call_user_func_array([$this->course, $method], $params);
- }
-
- public static function GetSemIdByDateId($date_id)
- {
- $stmt = DBManager::get()->prepare("SELECT range_id FROM termine WHERE termin_id = ? LIMIT 1");
- $stmt->execute([$date_id]);
- return $stmt->fetchColumn();
- }
-
- /**
- *
- * creates an new id for this object
- * @access private
- * @return string the unique id
- */
- public function createId()
- {
- return $this->course->getNewId();
- }
-
- public function getMembers($status = 'dozent')
- {
- $ret = [];
- foreach($this->course->getMembersWithStatus($status) as $m) {
- $ret[$m->user_id]['user_id'] = $m->user_id;
- $ret[$m->user_id]['username'] = $m->username;
- $ret[$m->user_id]['Vorname'] = $m->vorname;
- $ret[$m->user_id]['Nachname'] = $m->nachname;
- $ret[$m->user_id]['Email'] = $m->email;
- $ret[$m->user_id]['position'] = $m->position;
- $ret[$m->user_id]['label'] = $m->label;
- $ret[$m->user_id]['status'] = $m->status;
- $ret[$m->user_id]['mkdate'] = $m->mkdate;
- $ret[$m->user_id]['fullname'] = $m->getUserFullname();
- }
- return $ret;
- }
-
- public function getAdmissionMembers($status = 'awaiting')
- {
- $ret = [];
- foreach($this->course->admission_applicants->findBy('status', $status)->orderBy('position nachname') as $m) {
- $ret[$m->user_id]['user_id'] = $m->user_id;
- $ret[$m->user_id]['username'] = $m->username;
- $ret[$m->user_id]['Vorname'] = $m->vorname;
- $ret[$m->user_id]['Nachname'] = $m->nachname;
- $ret[$m->user_id]['Email'] = $m->email;
- $ret[$m->user_id]['position'] = $m->position;
- $ret[$m->user_id]['status'] = $m->status;
- $ret[$m->user_id]['mkdate'] = $m->mkdate;
- $ret[$m->user_id]['fullname'] = $m->getUserFullname();
- }
- return $ret;
- }
-
- public function getId()
- {
- return $this->id;
- }
-
- public function getName()
- {
- return $this->name;
- }
-
- /**
- * return the field VeranstaltungsNummer for the seminar
- *
- * @return string the seminar-number for the current seminar
- */
- public function getNumber()
- {
- return $this->seminar_number;
- }
-
- public function isVisible()
- {
- return $this->visible;
- }
-
- public function getInstitutId()
- {
- return $this->institut_id;
- }
-
- public function getSemesterStartTime()
- {
- return $this->semester_start_time;
- }
-
- public function getSemesterDurationTime()
- {
- return $this->semester_duration_time;
- }
-
- public function getNextDate($return_mode = 'string')
- {
- $next_date = '';
- if ($return_mode == 'int') {
- echo __class__.'::'.__function__.', line '.__line__.', return_mode "int" ist not supported by this function!';die;
- }
-
- if (!$termine = SeminarDB::getNextDate($this->id))
- return false;
-
- foreach ($termine['termin'] as $singledate_id) {
- $next_date .= DateFormatter::formatDateAndRoom($singledate_id, $return_mode) . '<br>';
- }
-
- if (!empty($termine['ex_termin'])) {
- foreach ($termine['ex_termin'] as $ex_termin_id) {
- $ex_termin = new SingleDate($ex_termin_id);
- $template = $GLOBALS['template_factory']->open('dates/missing_date.php');
- $template->formatted_date = DateFormatter::formatDateAndRoom($ex_termin_id, $return_mode);
- $template->ex_termin = $ex_termin;
- $missing_date = $template->render();
-
- if (!empty($termine['termin'])) {
- $termin = new SingleDate($termine['termin'][0]);
- if ($ex_termin->getStartTime() <= $termin->getStartTime()) {
- return $next_date . $missing_date;
- } else {
- return $next_date;
- }
- } else {
- return $missing_date;
- }
- }
- } else {
- return $next_date;
- }
-
- return false;
- }
-
- public function getFirstDate($return_mode = 'string') {
- if (!$dates = SeminarDB::getFirstDate($this->id)) {
- return false;
- }
-
- return DateFormatter::formatDateWithAllRooms(['termin' => $dates], $return_mode);
- }
-
- /**
- * This function returns an associative array of the dates owned by this seminar
- *
- * @returns mixed a multidimensional array of seminar-dates
- */
- public function getUndecoratedData($filter = false)
- {
-
- // Caching
- $cache = StudipCacheFactory::getCache();
- $cache_key = 'course/undecorated_data/'. $this->id;
-
- if ($filter) {
- $sub_key = ($_SESSION['_language'] ?? 'none') .'/'. $this->filterStart .'-'. $this->filterEnd;
- } else {
- $sub_key = ($_SESSION['_language'] ?? 'none') .'/unfiltered';
- }
-
- $data = unserialize($cache->read($cache_key));
-
- // build cache from scratch
- if (empty($data) || empty($data[$sub_key])) {
- $cycles = $this->metadate->getCycleData();
- $dates = $this->getSingleDates($filter, $filter);
- $rooms = [];
-
- foreach (array_keys($cycles) as $id) {
- if ($this->filterStart && $this->filterEnd
- && !$this->metadate->hasDates($id, $this->filterStart, $this->filterEnd))
- {
- unset($cycles[$id]);
- continue;
- }
-
- $cycles[$id]['first_date'] = CycleDataDB::getFirstDate($id);
- $cycles[$id]['last_date'] = CycleDataDB::getLastDate($id);
- if (!empty($cycles[$id]['assigned_rooms'])) {
- foreach ($cycles[$id]['assigned_rooms'] as $room_id => $count) {
- if (!isset($rooms[$room_id])) {
- $rooms[$room_id] = 0;
- }
- $rooms[$room_id] += $count;
- }
- }
- }
-
- // besser wieder mit direktem Query statt Objekten
- if (is_array($cycles) && count($cycles) === 0) {
- $cycles = false;
- }
-
- $ret['regular']['turnus_data'] = $cycles;
-
- // the irregular single-dates
- foreach ($dates as $val) {
- $zw = [
- 'metadate_id' => $val->getMetaDateID(),
- 'termin_id' => $val->getTerminID(),
- 'date_typ' => $val->getDateType(),
- 'start_time' => $val->getStartTime(),
- 'end_time' => $val->getEndTime(),
- 'mkdate' => $val->getMkDate(),
- 'chdate' => $val->getMkDate(),
- 'ex_termin' => $val->isExTermin(),
- 'orig_ex' => $val->isExTermin(),
- 'range_id' => $val->getRangeID(),
- 'author_id' => $val->getAuthorID(),
- 'resource_id' => $val->getResourceID(),
- 'raum' => $val->getFreeRoomText(),
- 'typ' => $val->getDateType(),
- 'tostring' => $val->toString()
- ];
-
- if ($val->getResourceID()) {
- if (!isset($rooms[$val->getResourceID()])) {
- $rooms[$val->getResourceID()] = 0;
- }
- $rooms[$val->getResourceID()]++;
- }
-
- $ret['irregular'][$val->getTerminID()] = $zw;
- }
-
- $ret['rooms'] = $rooms;
- $ret['ort'] = $this->location;
-
- $data[$sub_key] = $ret;
-
- // write data to cache
- $cache->write($cache_key, serialize($data), 600);
- }
-
- return $data[$sub_key];
- }
-
- public function getFormattedTurnus($short = FALSE)
- {
- // activate this with StEP 00077
- /* $cache = Cache::instance();
- * $cache_key = "formatted_turnus".$this->id;
- * if (! $return_string = $cache->read($cache_key))
- * {
- */
- return $this->getDatesExport(['short' => $short, 'shrink' => true]);
-
- // activate this with StEP 00077
- // $cache->write($cache_key, $return_string, 60*60);
- // }
- }
-
- public function getFormattedTurnusDates($short = FALSE)
- {
- if ($cycles = $this->metadate->getCycles()) {
- $return_string = [];
- foreach ($cycles as $id => $c) {
- $return_string[$id] = $c->toString($short);
- //hmm tja...
- if ($c->description){
- $return_string[$id] .= ' ('. htmlReady($c->description) .')';
- }
- }
- return $return_string;
- } else
- return FALSE;
- }
-
- public function getMetaDateCount()
- {
- return sizeof($this->metadate->cycles);
- }
-
- public function getMetaDateValue($key, $value_name)
- {
- return $this->metadate->cycles[$key]->$value_name;
- }
-
- public function setMetaDateValue($key, $value_name, $value)
- {
- $this->metadate->cycles[$key]->$value_name = $value;
- }
-
- /**
- * restore the data
- *
- * the complete data of the object will be loaded from the db
- * @access public
- * @throws Exception if there is no such course
- * @return boolean always true
- */
- public function restore()
- {
- if ($this->course->id) {
- $this->course->restore();
- }
- $this->irregularSingleDates = null;
- $this->issues = null;
- $this->_metadate = null;
- $this->course_set = null;
-
- return TRUE;
- }
-
- /**
- * returns an array of variables from the seminar-object, excluding variables
- * containing objects or arrays
- *
- * @return array
- */
- public function getSettings() {
- $settings = $this->course->toRawArray();
- unset($settings['config']);
- return $settings;
- }
-
- public function store($trigger_chdate = true)
- {
- // activate this with StEP 00077
- // $cache = Cache::instance();
- // $cache->expire("formatted_turnus".$this->id);
-
- //check for security consistency
- if ($this->write_level < $this->read_level) // hier wusste ein Lehrender nicht, was er tat
- $this->write_level = $this->read_level;
-
- if ($this->irregularSingleDates) {
- foreach ($this->irregularSingleDates as $val) {
- $val->store();
- }
- }
-
- if ($this->issues) {
- foreach ($this->issues as $val) {
- $val->store();
- }
- }
-
- $metadate_changed = isset($this->metadate) ? $this->metadate->store() : 0;
- $course_changed = $this->course->store();
- if ($metadate_changed && $trigger_chdate) {
- return $this->course->triggerChdate();
- } else {
- return $course_changed ?: false;
- }
- }
-
- public function setStartSemester($start)
- {
- global $perm;
-
- if ($perm->have_perm('tutor') && $start != $this->semester_start_time) {
- // logging >>>>>>
- StudipLog::log("SEM_SET_STARTSEMESTER", $this->getId(), $start);
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- // logging <<<<<<
- $this->semester_start_time = $start;
- $this->metadate->setSeminarStartTime($start);
- $this->createMessage(_("Das Startsemester wurde geändert."));
- $this->createInfo(_("Beachten Sie, dass Termine, die nicht mit den Einstellungen der regelmäßigen Zeit übereinstimmen (z.B. auf Grund einer Verschiebung der regelmäßigen Zeit), teilweise gelöscht sein könnten!"));
- return TRUE;
- }
- return FALSE;
- }
-
- public function removeAndUpdateSingleDates()
- {
- SeminarCycleDate::removeOutRangedSingleDates(
- $this->semester_start_time,
- $this->getEndSemesterVorlesEnde(),
- $this->id
- );
-
- foreach ($this->metadate->cycles as $key => $val) {
- $this->metadate->cycles[$key]->readSingleDates();
- $this->metadate->createSingleDates($key);
- $this->metadate->cycles[$key]->termine = NULL;
- }
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- }
-
- public function getStartSemester()
- {
- return $this->semester_start_time;
- }
-
- /*
- * setEndSemester
- * @param end integer 0 (one Semester), -1 (eternal), or timestamp of last happening semester
- * @returns TRUE on success, FALSE on failure
- */
- public function setEndSemester($end)
- {
- global $perm;
-
- $previousEndSemester = $this->getEndSemester(); // save the end-semester before it is changed, so we can choose lateron in which semesters we need to be rebuilt the SingleDates
-
- if ($end != $this->getEndSemester()) { // only change Duration if it differs from the current one
-
- if ($end == 0) { // the seminar takes place just in the selected start-semester
- $this->semester_duration_time = 0;
- $this->metadate->setSeminarDurationTime(0);
- // logging >>>>>>
- StudipLog::log("SEM_SET_ENDSEMESTER", $this->getId(), $end, 'Laufzeit: 1 Semester');
- // logging <<<<<<
- } else if ($end == -1) { // the seminar takes place in every semester above and including the start-semester
- // logging >>>>>>
- StudipLog::log("SEM_SET_ENDSEMESTER", $this->getId(), $end, 'Laufzeit: unbegrenzt');
- // logging <<<<<<
- $this->semester_duration_time = -1;
- $this->metadate->setSeminarDurationTime(-1);
- SeminarCycleDate::removeOutRangedSingleDates(
- $this->semester_start_time,
- $this->getEndSemesterVorlesEnde(),
- $this->id
- );
- } else { // the seminar takes place between the selected start~ and end-semester
- // logging >>>>>>
- StudipLog::log("SEM_SET_ENDSEMESTER", $this->getId(), $end);
- // logging <<<<<<
- $this->semester_duration_time = $end - $this->semester_start_time; // the duration is stored, not the real end-point
- $this->metadate->setSeminarDurationTime($this->semester_duration_time);
- }
-
- $this->createMessage(_("Die Dauer wurde geändert."));
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
-
- /*
- * If the duration has been changed, we have to create new SingleDates
- * if the new duration is longer than the previous one
- */
- if ( ($previousEndSemester != -1) && ( ($previousEndSemester < $this->getEndSemester()) || (($previousEndSemester == 0) && ($this->getEndSemester() == -1) ) )) {
- // if the previous duration was unlimited, the only option choosable is
- // a shorter duration then 'ever', so there cannot be any new SingleDates
-
- // special case: if the previous selection was 'one semester' and the new one is 'eternal',
- // than we have to find out the end of the only semester, the start-semester
- if ($previousEndSemester == 0) {
- $startAfterTimeStamp = $this->course->start_semester->ende;
- } else {
- $startAfterTimeStamp = $previousEndSemester;
- }
-
- foreach ($this->metadate->cycles as $key => $val) {
- $this->metadate->createSingleDates(['metadate_id' => $key, 'startAfterTimeStamp' => $startAfterTimeStamp]);
- $this->metadate->cycles[$key]->termine = NULL; // emtpy the SingleDates for each cycle, so that SingleDates, which were not in the current view, are not loaded and therefore should not be visible
- }
- }
- }
-
- return TRUE;
- }
-
- /*
- * getEndSemester
- * @returns 0 (one Semester), -1 (eternal), or TimeStamp of last Semester for this Seminar
- */
- public function getEndSemester()
- {
- if ($this->semester_duration_time == 0) return 0; // seminar takes place only in the start-semester
- if ($this->semester_duration_time == -1) return -1; // seminar takes place eternally
- return $this->semester_start_time + $this->semester_duration_time; // seminar takes place between start~ and end-semester
- }
-
- public function getEndSemesterVorlesEnde()
- {
- if ($this->semester_duration_time == -1) {
- $semesters = Semester::getAll();
- $very_last_semester = array_pop($semesters);
- return $very_last_semester->vorles_ende;
- }
- return $this->course->end_semester->vorles_ende;
- }
-
- /**
- * return the name of the seminars start-semester
- *
- * @return string the name of the start-semester or false if there is no start-semester
- */
- public function getStartSemesterName()
- {
- return $this->course->start_semester->name;
- }
-
- /**
- * return an array of singledate-objects for the submitted cycle identified by metadate_id
- *
- * @param string $metadate_id the id identifying the cycle
- *
- * @return mixed an array of singledate-objects
- */
- public function readSingleDatesForCycle($metadate_id)
- {
- return $this->metadate->readSingleDates($metadate_id, $this->filterStart, $this->filterEnd);
- }
-
- public function readSingleDates($force = FALSE, $filter = FALSE)
- {
- if (!$force) {
- if (is_array($this->irregularSingleDates)) {
- return TRUE;
- }
- }
- $this->irregularSingleDates = [];
-
- if ($filter) {
- $data = SeminarDB::getSingleDates($this->id, $this->filterStart, $this->filterEnd);
- } else {
- $data = SeminarDB::getSingleDates($this->id);
- }
-
- foreach ($data as $val) {
- unset($termin);
- $termin = new SingleDate();
- $termin->fillValuesFromArray($val);
- $this->irregularSingleDates[$val['termin_id']] =& $termin;
- }
- }
-
- public function &getSingleDate($singleDateID, $cycle_id = '')
- {
- if ($cycle_id == '') {
- $this->readSingleDates();
- return $this->irregularSingleDates[$singleDateID];
- } else {
- $dates = $this->metadate->getSingleDates($cycle_id, $this->filterStart, $this->filterEnd);
- $data =& $dates;
- return $data[$singleDateID];
- }
- }
-
- public function &getSingleDates($filter = false, $force = false, $include_deleted_dates = false)
- {
- $this->readSingleDates($force, $filter);
- if (!$include_deleted_dates) {
- return $this->irregularSingleDates;
- } else {
- $deleted_dates = [];
- foreach (SeminarDB::getDeletedSingleDates($this->getId(), $this->filterStart, $this->filterEnd) as $val) {
- $termin = new SingleDate();
- $termin->fillValuesFromArray($val);
- $deleted_dates[$val['termin_id']] = $termin;
- }
- $dates = array_merge($this->irregularSingleDates, $deleted_dates);
- uasort($dates, function($a,$b) {
- if ($a->getStartTime() == $b->getStartTime()) return 0;
- return $a->getStartTime() < $b->getStartTime() ? -1 : 1;}
- );
- return $dates;
- }
- }
-
- public function getCycles()
- {
- return $this->metadate->getCycles();
- }
-
- public function &getSingleDatesForCycle($metadate_id)
- {
- if (!$this->metadate->cycles[$metadate_id]->termine) {
- $this->metadate->readSingleDates($metadate_id, $this->filterStart, $this->filterEnd);
- if (!$this->metadate->cycles[$metadate_id]->termine) {
- $this->readSingleDates();
- $this->metadate->createSingleDates($metadate_id, $this->irregularSingleDates);
- $this->metadate->readSingleDates($metadate_id, $this->filterStart, $this->filterEnd);
- }
- //$this->metadate->readSingleDates($metadate_id, $this->filterStart, $this->filterEnd);
- }
- $dates = $this->metadate->getSingleDates($metadate_id, $this->filterStart, $this->filterEnd);
- return $dates;
- }
-
- public function readIssues($force = false)
- {
- if (!is_array($this->issues) || $force) {
- $this->issues = [];
- $data = SeminarDB::getIssues($this->id);
-
- foreach ($data as $val) {
- unset($issue);
- $issue = new Issue();
- $issue->fillValuesFromArray($val);
- $this->issues[$val['issue_id']] =& $issue;
- }
- }
- }
-
- public function addSingleDate(&$singledate)
- {
- // logging >>>>>>
- StudipLog::log("SEM_ADD_SINGLEDATE", $this->getId(), $singledate->toString(), 'SingleDateID: '.$singledate->getTerminID());
- // logging <<<<<<
-
- $cache = StudipCacheFactory::getCache();
- $cache->expire('course/undecorated_data/'. $this->getId());
-
- $this->readSingleDates();
- $this->irregularSingleDates[$singledate->getSingleDateID()] =& $singledate;
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- return TRUE;
- }
-
- public function addIssue(&$issue)
- {
- $this->readIssues();
- if ($issue instanceof Issue) {
- $max = -1;
- if (is_array($this->issues)) foreach ($this->issues as $val) {
- if ($val->getPriority() > $max) {
- $max = $val->getPriority();
- }
- }
- $max++;
- $issue->setPriority($max);
- $this->issues[$issue->getIssueID()] =& $issue;
- return TRUE;
- } else {
- return FALSE;
- }
- }
-
- public function deleteSingleDate($date_id, $cycle_id = '')
- {
- $this->readSingleDates();
- // logging >>>>>>
- StudipLog::log("SEM_DELETE_SINGLEDATE",$date_id, $this->getId(), 'Cycle_id: '.$cycle_id);
- // logging <<<<<<
- if ($cycle_id == '') {
- $this->irregularSingleDates[$date_id]->delete(true);
- unset ($this->irregularSingleDates[$date_id]);
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- return TRUE;
- } else {
- $this->metadate->deleteSingleDate($cycle_id, $date_id, $this->filterStart, $this->filterEnd);
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- return TRUE;
- }
- }
-
- public function cancelSingleDate($date_id, $cycle_id = '')
- {
- if ($cycle_id) {
- return $this->deleteSingleDate($date_id, $cycle_id);
- }
- $this->readSingleDates();
- // logging >>>>>>
- StudipLog::log("SEM_DELETE_SINGLEDATE",$date_id, $this->getId(), 'appointment cancelled');
- // logging <<<<<<
- $this->irregularSingleDates[$date_id]->setExTermin(true);
- $this->irregularSingleDates[$date_id]->store();
- unset ($this->irregularSingleDates[$date_id]);
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- return TRUE;
- }
-
- public function unDeleteSingleDate($date_id, $cycle_id = '')
- {
- // logging >>>>>>
- StudipLog::log("SEM_UNDELETE_SINGLEDATE",$date_id, $this->getId(), 'Cycle_id: '.$cycle_id);
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- // logging <<<<<<
- if ($cycle_id == '') {
- $termin = new SingleDate($date_id);
- if (!$termin->isExTermin()) {
- return false;
- }
- $termin->setExTermin(false);
- $termin->store();
- return true;
- } else {
- return $this->metadate->unDeleteSingleDate($cycle_id, $date_id, $this->filterStart, $this->filterEnd);
- }
- }
-
- /**
- * return all stacked messages as a multidimensional array
- *
- * The array has the following structure:
- * array( 'type' => ..., 'message' ... )
- * where type is one of error, info and success
- *
- * @return mixed the array of stacked messages
- */
- public function getStackedMessages()
- {
- if ( is_array( $this->message_stack ) ) {
- $ret = [];
-
- // cycle through message types and set title and details appropriate
- foreach ($this->message_stack as $type => $messages ) {
- switch ( $type ) {
- case 'error':
- $ret['error'] = [
- 'title' => _("Es sind Fehler/Probleme aufgetreten!"),
- 'details' => $this->message_stack['error']
- ];
- break;
-
- case 'info':
- $ret['info'] = [
- 'title' => implode('<br>', $this->message_stack['info']),
- 'details' => []
- ];
- break;
-
- case 'success':
- $ret['success'] = [
- 'title' => _("Ihre Änderungen wurden gespeichert!"),
- 'details' => $this->message_stack['success']
- ];
- break;
- }
- }
-
- return $ret;
- }
-
- return false;
- }
-
- /**
- * return the next stacked messag-string
- *
- * @return string a message-string
- */
- public function getNextMessage()
- {
- if ($this->messages[0]) {
- $ret = $this->messages[0];
- unset ($this->messages[0]);
- sort($this->messages);
- return $ret;
- }
- return FALSE;
- }
-
- /**
- * stack an error-message
- *
- * @param string $text the message to stack
- */
- public function createError($text)
- {
- $this->messages[] = 'error§'.$text.'§';
- $this->message_stack['error'][] = $text;
- }
-
- /**
- * stack an info-message
- *
- * @param string $text the message to stack
- */
- public function createInfo($text)
- {
- $this->messages[] = 'info§'.$text.'§';
- $this->message_stack['info'][] = $text;
- }
-
- /**
- * stack a success-message
- *
- * @param string $text the message to stack
- */
- public function createMessage($text)
- {
- $this->messages[] = 'msg§'.$text.'§';
- $this->message_stack['success'][] = $text;
- }
-
- /**
- * add an array of messages to the message-stack
- *
- * @param mixed $messages array of pre-marked message-strings
- * @param bool returns true on success
- */
- public function appendMessages( $messages )
- {
- if (!is_array($messages)) return false;
-
- foreach ( $messages as $type => $msgs ) {
- foreach ($msgs as $msg) {
- $this->message_stack[$type][] = $msg;
- }
- }
- return true;
- }
-
- public function addCycle($data = [])
- {
- $new_id = $this->metadate->addCycle($data);
- if($new_id){
- $this->setStartWeek($data['startWeek'], $new_id);
- $this->setTurnus($data['turnus'], $new_id);
- }
- // logging >>>>>>
- if($new_id){
- $cycle_info = $this->metadate->cycles[$new_id]->toString();
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- StudipLog::log("SEM_ADD_CYCLE", $this->getId(), NULL, $cycle_info, '<pre>'.print_r($data,true).'</pre>');
- }
- // logging <<<<<<
- return $new_id;
- }
-
- /**
- * Change a regular timeslot of the seminar. The data is passed as an array
- * conatining the following fields:
- * start_stunde, start_minute, end_stunde, end_minute
- * description, turnus, startWeek, day, sws
- *
- * @param array $data the cycle-data
- *
- * @return void
- */
- public function editCycle($data = [])
- {
- $cycle = $this->metadate->cycles[$data['cycle_id']];
- $new_start = mktime($data['start_stunde'], $data['start_minute']);
- $new_end = mktime($data['end_stunde'], $data['end_minute']);
- $old_start = mktime($cycle->getStartStunde(),$cycle->getStartMinute());
- $old_end = mktime($cycle->getEndStunde(), $cycle->getEndMinute());
- $do_changes = false;
-
- // check, if the new timeslot exceeds the old one
- if (($new_start < $old_start) || ($new_end > $old_end) || ($data['day'] != $cycle->day) ) {
- $has_bookings = false;
-
- // check, if there are any booked rooms
- foreach($cycle->getSingleDates() as $singleDate) {
- if ($singleDate->getStarttime() > (time() - 3600) && $singleDate->hasRoom()) {
- $has_bookings = true;
- break;
- }
- }
-
- // if the timeslot exceeds the previous one and has some booked rooms
- // they would be lost, so ask the user for permission to do so.
- if (!$data['really_change'] && $has_bookings) {
- $link_params = [
- 'editCycle_x' => '1',
- 'editCycle_y' => '1',
- 'cycle_id' => $data['cycle_id'],
- 'start_stunde' => $data['start_stunde'],
- 'start_minute' => $data['start_minute'],
- 'end_stunde' => $data['end_stunde'],
- 'end_minute' => $data['end_minute'],
- 'day' => $data['day'],
- 'really_change' => 'true'
- ];
- $question = _("Wenn Sie die regelmäßige Zeit auf %s ändern, verlieren Sie die Raumbuchungen für alle in der Zukunft liegenden Termine!")
- ."\n". _("Sind Sie sicher, dass Sie die regelmäßige Zeit ändern möchten?");
- $question_time = '**'. strftime('%A', $data['day']) .', '. $data['start_stunde'] .':'. $data['start_minute']
- .' - '. $data['end_stunde'] .':'. $data['end_minute'] .'**';
-
- echo (string)QuestionBox::create(
- sprintf($question, $question_time),
- URLHelper::getURL('', $link_params)
- );
-
- } else {
- $do_changes = true;
- }
- } else {
- $do_changes = true;
- }
-
- $messages = false;
- $same_time = false;
-
- // only apply changes, if the user approved the change or
- // the change does not need any approval
- if ($do_changes) {
- if ($data['description'] != $cycle->getDescription()) {
- $this->createMessage(_("Die Beschreibung des regelmäßigen Eintrags wurde geändert."));
- $message = true;
- $do_changes = true;
- }
-
- if ($old_start == $new_start && $old_end == $new_end) {
- $same_time = true;
- }
- if ($data['startWeek'] != $cycle->week_offset) {
- $this->setStartWeek($data['startWeek'], $cycle->metadate_id);
- $message = true;
- $do_changes = true;
- }
- if ($data['turnus'] != $cycle->cycle) {
- $this->setTurnus($data['turnus'], $cycle->metadate_id);
- $message = true;
- $do_changes = true;
- }
- if ($data['day'] != $cycle->day) {
- $message = true;
- $same_time = false;
- $do_changes = true;
- }
- if (round(str_replace(',','.', $data['sws']),1) != $cycle->sws) {
- $cycle->sws = $data['sws'];
- $this->createMessage(_("Die Semesterwochenstunden für Lehrende des regelmäßigen Eintrags wurden geändert."));
- $message = true;
- $do_changes = true;
- }
-
- $change_from = $cycle->toString();
- if ($this->metadate->editCycle($data)) {
- if (!$same_time) {
- // logging >>>>>>
- StudipLog::log("SEM_CHANGE_CYCLE", $this->getId(), NULL, $change_from .' -> '. $cycle->toString());
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- // logging <<<<<<
- $this->createMessage(sprintf(_("Die regelmäßige Veranstaltungszeit wurde auf \"%s\" für alle in der Zukunft liegenden Termine geändert!"),
- '<b>'.getWeekday($data['day']) . ', ' . $data['start_stunde'] . ':' . $data['start_minute'].' - '.
- $data['end_stunde'] . ':' . $data['end_minute'] . '</b>'));
- $message = true;
- }
- } else {
- if (!$same_time) {
- $this->createInfo(sprintf(_("Die regelmäßige Veranstaltungszeit wurde auf \"%s\" geändert, jedoch gab es keine Termine die davon betroffen waren."),
- '<b>'.getWeekday($data['day']) . ', ' . $data['start_stunde'] . ':' . $data['start_minute'].' - '.
- $data['end_stunde'] . ':' . $data['end_minute'] . '</b>'));
- $message = true;
- }
- }
- $this->metadate->sortCycleData();
-
- if (!$message) {
- $this->createInfo("Sie haben keine Änderungen vorgenommen!");
- }
- }
- }
-
- public function deleteCycle($cycle_id)
- {
- // logging >>>>>>
- $cycle_info = $this->metadate->cycles[$cycle_id]->toString();
- StudipLog::log("SEM_DELETE_CYCLE", $this->getId(), NULL, $cycle_info);
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- // logging <<<<<<
- return $this->metadate->deleteCycle($cycle_id);
- }
-
- public function setTurnus($turnus, $metadate_id = false)
- {
- if ($this->metadate->getTurnus($metadate_id) != $turnus) {
- $this->metadate->setTurnus($turnus, $metadate_id);
- $key = $metadate_id ? $metadate_id : $this->metadate->getFirstMetadate()->metadate_id;
- $this->createMessage(sprintf(_("Der Turnus für den Termin %s wurde geändert."), $this->metadate->cycles[$key]->toString()));
- $this->metadate->createSingleDates($key);
- $this->metadate->cycles[$key]->termine = null;
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- }
- return TRUE;
- }
-
- public function getTurnus($metadate_id = false)
- {
- return $this->metadate->getTurnus($metadate_id);
- }
-
-
- /**
- * get StatOfNotBookedRooms returns an array:
- * open: number of rooms with no booking
- * all: number of singleDates, which can have a booking
- * open_rooms: array of singleDates which have no booking
- *
- * @param String $cycle_id Id of cycle
- * @return array as described above
- */
- public function getStatOfNotBookedRooms($cycle_id)
- {
- if (!isset($this->BookedRoomsStatTemp[$cycle_id])) {
- $this->BookedRoomsStatTemp[$cycle_id] = SeminarDB::getStatOfNotBookedRooms($cycle_id, $this->id, $this->filterStart, $this->filterEnd);
- }
- return $this->BookedRoomsStatTemp[$cycle_id];
- }
-
- public function getStatus()
- {
- return $this->status;
- }
-
- public function getBookedRoomsTooltip($cycle_id)
- {
- $stat = $this->getStatOfNotBookedRooms($cycle_id);
- $pattern = '%s , %s, %s-%s <br />';
- $return = '';
- if ($stat['open'] > 0 && $stat['open'] !== $stat['all']) {
- $return = _('Folgende Termine haben keine Raumbuchung:') . '<br />';
-
- foreach ($stat['open_rooms'] as $aSingleDate) {
- $return .= sprintf($pattern,strftime('%a', $aSingleDate['date']),
- strftime('%d.%m.%Y', $aSingleDate['date']),
- strftime('%H:%M', $aSingleDate['date']),
- strftime('%H:%M', $aSingleDate['end_time']));
- }
- }
-
- // are there any dates with declined room-requests?
- if ($stat['declined'] > 0) {
- $return .= _('Folgende Termine haben eine abgelehnte Raumanfrage') . '<br />';
- foreach ($stat['declined_dates'] as $aSingleDate) {
- $return .= sprintf($pattern,strftime('%a', $aSingleDate['date']),
- strftime('%d.%m.%Y', $aSingleDate['date']),
- strftime('%H:%M', $aSingleDate['date']),
- strftime('%H:%M', $aSingleDate['end_time']));
- }
- }
-
- return $return;
- }
-
- /**
- * @param $cycle_id
- * @return string
- */
- public function getCycleColorClass($cycle_id)
- {
- if (Config::get()->RESOURCES_ENABLE && Config::get()->RESOURCES_ENABLE_BOOKINGSTATUS_COLORING) {
- if (!$this->metadate->hasDates($cycle_id, $this->filterStart, $this->filterEnd)) {
- return 'red';
- }
-
- $stat = $this->getStatOfNotBookedRooms($cycle_id);
-
- if ($stat['open'] > 0 && $stat['open'] == $stat['all']) {
- return 'red';
- }
- if ($stat['open'] > 0) {
- return 'yellow ';
- }
- return 'green ';
- }
-
- return '';
- }
-
- public function &getIssues($force = false)
- {
- $this->readIssues($force);
- $this->renumberIssuePrioritys();
- if (is_array($this->issues)) {
- uasort($this->issues, function ($a, $b) {
- return $a->getPriority() - $b->getPriority();
- });
- }
- return $this->issues;
- }
-
- public function deleteIssue($issue_id)
- {
- $this->issues[$issue_id]->delete();
- unset($this->issues[$issue_id]);
- return TRUE;
- }
-
- public function &getIssue($issue_id)
- {
- $this->readIssues();
- return $this->issues[$issue_id];
- }
-
- /*
- * changeIssuePriority
- *
- * changes an issue with an given id to a new priority
- *
- * @param
- * issue_id the issue_id of the issue to be changed
- * new_priority the new priority
- */
- public function changeIssuePriority($issue_id, $new_priority)
- {
- /* REMARK:
- * This function only works, when an issue is moved ONE slote higher or lower
- * It does NOT work with ARBITRARY movements!
- */
- $this->readIssues();
- $old_priority = $this->issues[$issue_id]->getPriority(); // get old priority, so we can just exchange prioritys of two issues
- foreach ($this->issues as $id => $issue) { // search for the concuring issue
- if ($issue->getPriority() == $new_priority) {
- $this->issues[$id]->setPriority($old_priority); // the concuring issue gets the old id of the changed issue
- $this->issues[$id]->store(); // ###store_problem###
- }
- }
-
- $this->issues[$issue_id]->setPriority($new_priority); // changed issue gets the new priority
- $this->issues[$issue_id]->store(); // ###store_problem###
-
- }
-
- public function renumberIssuePrioritys()
- {
- if (is_array($this->issues)) {
-
- $sorter = [];
- foreach ($this->issues as $id => $issue) {
- $sorter[$id] = $issue->getPriority();
- }
- asort($sorter);
- $i = 0;
- foreach ($sorter as $id => $old_priority) {
- $this->issues[$id]->setPriority($i);
- $i++;
- }
- }
- }
-
- public function autoAssignIssues($themen, $cycle_id)
- {
- $this->metadate->cycles[$cycle_id]->autoAssignIssues($themen, $this->filterStart, $this->filterEnd);
- }
-
-
- public function applyTimeFilter($start, $end)
- {
- $this->filterStart = $start;
- $this->filterEnd = $end;
- }
-
- public function setFilter($timestamp)
- {
- if ($timestamp == 'all') {
- $_SESSION['raumzeitFilter'] = 'all';
- $this->applyTimeFilter(0, 0);
- } else {
- $filterSemester = Semester::findByTimestamp($timestamp);
- $_SESSION['raumzeitFilter'] = $filterSemester->beginn;
- $this->applyTimeFilter($filterSemester->beginn, $filterSemester->ende);
- }
- }
-
- public function registerCommand($command, $function)
- {
- $this->commands[$command] = $function;
- }
-
- public function processCommands()
- {
- global $cmd;
-
- // workaround for multiple submit-buttons with new Button-API
- foreach ($this->commands as $r_cmd => $func) {
- if (Request::submitted($r_cmd)) {
- $cmd = $r_cmd;
- }
- }
-
- if (!isset($cmd) && Request::option('cmd')) $cmd = Request::option('cmd');
- if (!isset($cmd)) return FALSE;
-
- if (isset($this->commands[$cmd])) {
- call_user_func($this->commands[$cmd], $this);
- }
- }
-
- public function getFreeTextPredominantRoom($cycle_id)
- {
- if (!($room = $this->metadate->cycles[$cycle_id]->getFreeTextPredominantRoom($this->filterStart, $this->filterEnd))) {
- return FALSE;
- }
- return $room;
- }
-
- public function getPredominantRoom($cycle_id, $list = FALSE)
- {
- if (!($rooms = $this->metadate->cycles[$cycle_id]->getPredominantRoom($this->filterStart, $this->filterEnd))) {
- return FALSE;
- }
- if ($list) {
- return $rooms;
- } else {
- return $rooms[0];
- }
- }
-
-
- public function hasDatesOutOfDuration($force = false)
- {
- if ($this->hasDatesOutOfDuration == -1 || $force) {
- $this->hasDatesOutOfDuration = SeminarDB::hasDatesOutOfDuration($this->getStartSemester(), $this->getEndSemesterVorlesEnde(), $this->id);
- }
- return $this->hasDatesOutOfDuration;
- }
-
- public function getStartWeek($metadate_id = false)
- {
- return $this->metadate->getStartWoche($metadate_id);
- }
-
- public function setStartWeek($week, $metadate_id = false)
- {
- if ($this->metadate->getStartWoche($metadate_id) == $week) {
- return FALSE;
- } else {
- $this->metadate->setStartWoche($week, $metadate_id);
- $key = $metadate_id ? $metadate_id : $this->metadate->getFirstMetadate()->metadate_id;
- $this->createMessage(sprintf(_("Die Startwoche für den Termin %s wurde geändert."), $this->metadate->cycles[$key]->toString()));
- $this->metadate->createSingleDates($key);
- $this->metadate->cycles[$key]->termine = null;
- NotificationCenter::postNotification("CourseDidChangeSchedule", $this);
- }
- }
-
-
- /**
- * instance method
- *
- * returns number of participants for each usergroup in seminar,
- * total, lecturers, tutors, authors, users
- *
- * @param string (optional) return count only for given usergroup
- *
- * @return array <description>
- */
-
- public function getNumberOfParticipants()
- {
- $args = func_get_args();
- array_unshift($args, $this->id);
- return call_user_func_array(["Seminar", "getNumberOfParticipantsBySeminarId"], $args);
- }
-
- /**
- * class method
- *
- * returns number of participants for each usergroup in given seminar,
- * total, lecturers, tutors, authors, users
- *
- * @param string seminar_id
- *
- * @param string (optional) return count only for given usergroup
- *
- * @return array <description>
- */
-
- public function getNumberOfParticipantsBySeminarId($sem_id)
- {
- $db = DBManager::get();
- $stmt1 = $db->prepare("SELECT
- COUNT(Seminar_id) AS anzahl,
- COUNT(IF(status='dozent',Seminar_id,NULL)) AS anz_dozent,
- COUNT(IF(status='tutor',Seminar_id,NULL)) AS anz_tutor,
- COUNT(IF(status='autor',Seminar_id,NULL)) AS anz_autor,
- COUNT(IF(status='user',Seminar_id,NULL)) AS anz_user
- FROM seminar_user
- WHERE Seminar_id = ?
- GROUP BY Seminar_id");
- $stmt1->execute([$sem_id]);
- $numbers = $stmt1->fetch(PDO::FETCH_ASSOC);
-
- $stmt2 = $db->prepare("SELECT COUNT(*) as anzahl
- FROM admission_seminar_user
- WHERE seminar_id = ?
- AND status = 'accepted'");
- $stmt2->execute([$sem_id]);
- $acceptedUsers = $stmt2->fetch(PDO::FETCH_ASSOC);
-
-
- $count = 0;
- if ($numbers["anzahl"]) {
- $count += $numbers["anzahl"];
- }
- if ($acceptedUsers["anzahl"]) {
- $count += $acceptedUsers["anzahl"];
- }
-
- $participant_count = [];
- $participant_count['total'] = $count;
- $participant_count['lecturers'] = $numbers['anz_dozent'] ? (int) $numbers['anz_dozent'] : 0;
- $participant_count['tutors'] = $numbers['anz_tutor'] ? (int) $numbers['anz_tutor'] : 0;
- $participant_count['authors'] = $numbers['anz_autor'] ? (int) $numbers['anz_autor'] : 0;
- $participant_count['users'] = $numbers['anz_user'] ? (int) $numbers['anz_user'] : 0;
-
- // return specific parameter if
- $params = func_get_args();
- if (sizeof($params) > 1) {
- if (in_array($params[1], array_keys($participant_count))) {
- return $participant_count[$params[1]];
- } else {
- trigger_error(get_class($this)."::__getParticipantInfos - unknown parameter requested");
- }
- }
-
- return $participant_count;
- }
-
-
- /**
- * Returns the IDs of this course's study areas.
- *
- * @return array an array of IDs
- */
- public function getStudyAreas()
- {
- $stmt = DBManager::get()->prepare("SELECT DISTINCT sem_tree_id ".
- "FROM seminar_sem_tree ".
- "WHERE seminar_id=?");
-
- $stmt->execute([$this->id]);
- return $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
- }
-
- /**
- * Sets the study areas of this course.
- *
- * @param array an array of IDs
- *
- * @return void
- */
- public function setStudyAreas($selected)
- {
- $old = $this->getStudyAreas();
- $sem_tree = TreeAbstract::GetInstance("StudipSemTree");
- $removed = array_diff($old, $selected);
- $added = array_diff($selected, $old);
- $count_removed = 0;
- $count_added = 0;
- foreach($removed as $one){
- $count_removed += $sem_tree->DeleteSemEntries($one, $this->getId());
- }
- foreach($added as $one){
- $count_added += $sem_tree->InsertSemEntry($one, $this->getId());
- }
- if ($count_added || $count_removed) {
- NotificationCenter::postNotification("CourseDidChangeStudyArea", $this);
- }
- return count($old) + $count_added - $count_removed;
- }
-
- /**
- * @return boolean returns TRUE if this course is publicly visible,
- * FALSE otherwise
- */
- public function isPublic()
- {
- return Config::get()->ENABLE_FREE_ACCESS && $this->read_level == 0;
- }
-
- /**
- * @return boolean returns TRUE if this course is a studygroup,
- * FALSE otherwise
- */
- public function isStudygroup()
- {
- global $SEM_CLASS, $SEM_TYPE;
- return $SEM_CLASS[$SEM_TYPE[$this->status]["class"]]["studygroup_mode"];
- }
-
- /**
- * @return int returns default colour group for new members (shown in meine_seminare.php)
- *
- **/
- public function getDefaultGroup()
- {
- if ($this->isStudygroup()) {
- return 8;
- } else {
- return select_group ($this->semester_start_time);
- }
- }
-
-
- /**
- * Deletes the current seminar
- *
- * @return void returns success-message if seminar could be deleted
- * otherwise an error-message
- */
-
- public function delete()
- {
- $s_id = $this->id;
-
- // Delete that Seminar.
-
- // Alle Benutzer aus dem Seminar rauswerfen.
- $db_ar = CourseMember::deleteBySQL('Seminar_id = ?', [$s_id]);
- if ($db_ar > 0) {
- $this->createMessage(sprintf(_("%s Teilnehmende und Lehrende archiviert."), $db_ar));
- }
-
- // Alle Benutzer aus Wartelisten rauswerfen
- AdmissionApplication::deleteBySQL('seminar_id = ?', [$s_id]);
-
- // Alle beteiligten Institute rauswerfen
- $query = "DELETE FROM seminar_inst WHERE Seminar_id = ?";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$s_id]);
- if (($db_ar = $statement->rowCount()) > 0) {
- $this->createMessage(sprintf(_("%s Zuordnungen zu Einrichtungen archiviert."), $db_ar));
- }
-
- // user aus den Statusgruppen rauswerfen
- $count = Statusgruppen::deleteBySQL('range_id = ?', [$s_id]);
- if ($count > 0) {
- $this->createMessage(sprintf(_('%s Funktionen/Gruppen gelöscht.'), $count));
- }
-
- // seminar_sem_tree entries are deleted automatically on deletion of the Course object.
-
- // Alle Termine mit allem was dranhaengt zu diesem Seminar loeschen.
- if (($db_ar = SingleDateDB::deleteAllDates($s_id)) > 0) {
- $this->createMessage(sprintf(_("%s Veranstaltungstermine archiviert."), $db_ar));
- }
-
- //Themen
- IssueDB::deleteAllIssues($s_id);
-
- //Cycles
- SeminarCycleDate::deleteBySQL('seminar_id = ' . DBManager::get()->quote($s_id));
-
- // Alle weiteren Postings zu diesem Seminar in den Forums-Modulen löschen
- foreach (PluginEngine::getPlugins('ForumModule') as $plugin) {
- $plugin->deleteContents($s_id); // delete content irrespective of plugin-activation in the seminar
-
- if ($plugin->isActivated($s_id)) { // only show a message, if the plugin is activated, to not confuse the user
- $this->createMessage(sprintf(_('Einträge in %s archiviert.'), $plugin->getPluginName()));
- }
- }
-
- // Alle Pluginzuordnungen entfernen
- PluginManager::getInstance()->deactivateAllPluginsForRange('sem', $s_id);
-
- // Alle Dokumente zu diesem Seminar loeschen.
- $folder = Folder::findTopFolder($s_id);
- if($folder) {
- if($folder->delete()) {
- $this->createMessage(_("Dokumente und Ordner archiviert."));
- }
- }
-
-
- // Freie Seite zu diesem Seminar löschen
- $db_ar = StudipScmEntry::deleteBySQL('range_id = ?', [$s_id]);
- if ($db_ar > 0) {
- $this->createMessage(_("Freie Seite der Veranstaltung archiviert."));
- }
-
- // Alle News-Verweise auf dieses Seminar löschen
- if ( ($db_ar = StudipNews::DeleteNewsRanges($s_id)) ) {
- $this->createMessage(sprintf(_("%s Ankündigungen gelöscht."), $db_ar));
- }
- //delete entry in news_rss_range
- StudipNews::UnsetRssId($s_id);
-
- //kill the datafields
- DataFieldEntry::removeAll($s_id);
-
- //kill all wiki-pages
- $db_wiki = WikiPage::deleteBySQL('range_id = ?', [$s_id]);
- if ($db_wiki > 0) {
- $this->createMessage(sprintf(_("%s Wiki-Seiten archiviert."), $db_wiki));
- }
-
- $query = "DELETE FROM wiki_links WHERE range_id = ?";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$s_id]);
-
- // delete course config values
- ConfigValue::deleteBySQL('range_id = ?', [$s_id]);
-
- // kill all the ressources that are assigned to the Veranstaltung (and all the linked or subordinated stuff!)
- if (Config::get()->RESOURCES_ENABLE) {
- ResourceBooking::deleteBySql(
- 'range_id = :course_id',
- [
- 'course_id' => $s_id
- ]
- );
- if ($rr = RoomRequest::existsByCourse($s_id)) {
- RoomRequest::find($rr)->delete();
- }
- }
-
- // kill virtual seminar-entries in calendar
- $query = "DELETE FROM schedule_seminare WHERE seminar_id = ?";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$s_id]);
-
- if(Config::get()->ELEARNING_INTERFACE_ENABLE){
- global $connected_cms;
- $del_cms = 0;
- $cms_types = ObjectConnections::GetConnectedSystems($s_id);
- if(count($cms_types)){
- foreach($cms_types as $system){
- ELearningUtils::loadClass($system);
- $del_cms += $connected_cms[$system]->deleteConnectedModules($s_id);
- }
- $this->createMessage(sprintf(_("%s Verknüpfungen zu externen Systemen gelöscht."), $del_cms ));
- }
- }
-
- //kill the object_user_vists for this seminar
- object_kill_visits(null, $s_id);
-
- // Logging...
- $query = "SELECT CONCAT(seminare.VeranstaltungsNummer, ' ', seminare.name, '(', semester_data.name, ')')
- FROM seminare
- LEFT JOIN semester_data ON (seminare.start_time = semester_data.beginn)
- WHERE seminare.Seminar_id = ?";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$s_id]);
- $semlogname = $statement->fetchColumn() ?: sprintf('unknown sem_id: %s', $s_id);
-
- StudipLog::log("SEM_ARCHIVE",$s_id,NULL,$semlogname);
- // ...logged
-
- // delete deputies if necessary
- Deputy::deleteByRange_id($s_id);
-
- UserDomain::removeUserDomainsForSeminar($s_id);
-
- AutoInsert::deleteSeminar($s_id);
-
- //Anmeldeset Zordnung entfernen
- $cs = $this->getCourseSet();
- if ($cs) {
- CourseSet::removeCourseFromSet($cs->getId(), $this->getId());
- $cs->load();
- if (!count($cs->getCourses())
- && $cs->isGlobal()
- && $cs->getUserid() != '') {
- $cs->delete();
- }
- }
- AdmissionPriority::unsetAllPrioritiesForCourse($this->getId());
- // und das Seminar loeschen.
- $this->course->delete();
- $this->restore();
- return true;
- }
-
- /**
- * returns a html representation of the seminar-dates
- *
- * @param array optional variables which are passed to the template
- * @return string the html-representation of the dates
- *
- * @author Till Glöggler <tgloeggl@uos.de>
- */
- public function getDatesHTML($params = [])
- {
- return $this->getDatesTemplate('dates/seminar_html.php', $params);
- }
-
- /**
- * returns a representation without html of the seminar-dates
- *
- * @param array optional variables which are passed to the template
- * @return string the representation of the dates without html
- *
- * @author Till Glöggler <tgloeggl@uos.de>
- */
- public function getDatesExport($params = [])
- {
- return $this->getDatesTemplate('dates/seminar_export.php', $params);
- }
-
- /**
- * returns a xml-representation of the seminar-dates
- *
- * @param array optional variables which are passed to the template
- * @return string the xml-representation of the dates
- *
- * @author Till Glöggler <tgloeggl@uos.de>
- */
- public function getDatesXML($params = [])
- {
- return $this->getDatesTemplate('dates/seminar_xml.php', $params);
- }
-
- /**
- * returns a representation of the seminar-dates with a specifiable template
- *
- * @param mixed this can be a template-object or a string pointing to a template in path_to_studip/templates
- * @param array optional parameters which are passed to the template
- * @return string the template output of the dates
- *
- * @author Till Glöggler <tgloeggl@uos.de>
- */
- public function getDatesTemplate($template, $params = [])
- {
- if (!$template instanceof Flexi_Template && is_string($template)) {
- $template = $GLOBALS['template_factory']->open($template);
- }
-
- if (!empty($params['semester_id'])) {
- $semester = Semester::find($params['semester_id']);
- if ($semester) {
- // apply filter
- $this->applyTimeFilter($semester->beginn, $semester->ende);
- }
- }
-
- $template->dates = $this->getUndecoratedData(isset($params['semester_id']));
- $template->seminar_id = $this->getId();
-
- $template->set_attributes($params);
- return trim($template->render());
- }
-
- /**
- * returns an asscociative array with the attributes of the seminar depending
- * on the field-names in the database
- * @return array
- */
- public function getData()
- {
- $data = $this->course->toArray();
- foreach($this->alias as $a => $o) {
- $data[$a] = $this->course->$o;
- }
- return $data;
- }
-
- /**
- * returns an array with all IDs of Institutes this seminar is related to
- * @param sem_id string: optional ID of a seminar, when null, this ID will be used
- * @return: array of IDs (not associative)
- */
- public function getInstitutes($sem_id = null)
- {
- if (!$sem_id && $this) {
- $sem_id = $this->id;
- }
-
- $query = "SELECT institut_id FROM seminar_inst WHERE seminar_id = :sem_id
- UNION
- SELECT Institut_id FROM seminare WHERE Seminar_id = :sem_id";
- $statement = DBManager::get()->prepare($query);
- $statement->execute(compact('sem_id'));
- return $statement->fetchAll(PDO::FETCH_COLUMN);
- }
-
- /**
- * set the entries for seminar_inst table in database
- * seminare.institut_id will always be added
- * @param institutes array: array of Institut_id's
- * @return bool: if something changed
- */
- public function setInstitutes($institutes = [])
- {
- if (is_array($institutes)) {
- $institutes[] = $this->institut_id;
- $institutes = array_unique($institutes);
-
- $query = "SELECT institut_id FROM seminar_inst WHERE seminar_id = ?";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$this->id]);
- $old_inst = $statement->fetchAll(PDO::FETCH_COLUMN);
-
- $todelete = array_diff($old_inst, $institutes);
-
- $query = "DELETE FROM seminar_inst WHERE seminar_id = ? AND institut_id = ?";
- $statement = DBManager::get()->prepare($query);
-
- foreach($todelete as $inst) {
- $tmp_instname= get_object_name($inst, 'inst');
- StudipLog::log('CHANGE_INSTITUTE_DATA', $this->id, $inst, 'Die beteiligte Einrichtung "'. $tmp_instname['name'] .'" wurde gelöscht.');
- $statement->execute([$this->id, $inst]);
- NotificationCenter::postNotification('SeminarInstitutionDidDelete', $inst, $this->id);
-
- }
-
- $toinsert = array_diff($institutes, $old_inst);
-
- $query = "INSERT INTO seminar_inst (seminar_id, institut_id) VALUES (?, ?)";
- $statement = DBManager::get()->prepare($query);
-
- foreach($toinsert as $inst) {
- $tmp_instname= get_object_name($inst, 'inst');
- StudipLog::log('CHANGE_INSTITUTE_DATA', $this->id, $inst, 'Die beteiligte Einrichtung "'. $tmp_instname['name'] .'" wurde hinzugefügt.');
- $statement->execute([$this->id, $inst]);
- NotificationCenter::postNotification('SeminarInstitutionDidCreate', $inst, $this->id);
- }
- if ($todelete || $toinsert) {
- NotificationCenter::postNotification("CourseDidChangeInstitutes", $this);
- }
- return $todelete || $toinsert;
- } else {
- $this->createError(_("Ungültige Eingabe der Institute. Es muss " .
- "mindestens ein Institut angegeben werden."));
- return false;
- }
- }
-
- /**
- * adds a user to the seminar with the given status
- * @param user_id string: ID of the user
- * @param status string: status of the user for the seminar "user", "autor", "tutor", "dozent"
- * @param force bool: if false (default) the user will only be upgraded and not degraded in his/her status
- */
- public function addMember($user_id, $status = 'autor', $force = false)
- {
-
- if (in_array($GLOBALS['perm']->get_perm($user_id), ["admin", "root"])) {
- $this->createError(_("Admin und Root dürfen nicht Mitglied einer Veranstaltung sein."));
- return false;
- }
- $db = DBManager::get();
-
- $rangordnung = array_flip(['user', 'autor', 'tutor', 'dozent']);
- if ($rangordnung[$status] > $rangordnung['autor'] && SeminarCategories::getByTypeId($this->status)->only_inst_user) {
- //überprüfe, ob im richtigen Institut:
- $user_institute_stmt = $db->prepare(
- "SELECT Institut_id " .
- "FROM user_inst " .
- "WHERE user_id = :user_id " .
- "");
- $user_institute_stmt->execute(['user_id' => $user_id]);
- $user_institute = $user_institute_stmt->fetchAll(PDO::FETCH_COLUMN, 0);
-
- if (!in_array($this->institut_id, $user_institute) && !count(array_intersect($user_institute, $this->getInstitutes()))) {
- $this->createError(_("Einzutragender Nutzer stammt nicht einem beteiligten Institut an."));
-
- return false;
- }
- }
- $course_member = CourseMember::findOneBySQL('user_id = ? AND Seminar_id = ?', [$user_id, $this->id]);
- $new_position = (int) DBManager::get()->fetchColumn(
- "SELECT MAX(position) + 1 FROM seminar_user WHERE status = ? AND Seminar_id = ?",
- [$status, $this->id]
- );
- $numberOfTeachers = CourseMember::countBySql("Seminar_id = ? AND status = 'dozent'", [$this->id]);
-
- if (!$course_member && !$force) {
- CourseMember::create([
- 'Seminar_id' => $this->id,
- 'user_id' => $user_id,
- 'status' => $status,
- 'position' => $new_position?:0,
- 'gruppe' => (int) select_group($this->getSemesterStartTime()),
- 'visible' => in_array($status, ['tutor', 'dozent']) ? 'yes' : 'unknown',
- ]);
- // delete the entries, user is now in the seminar
- if (AdmissionApplication::deleteBySQL('user_id = ? AND seminar_id = ?', [$user_id, $this->getId()])) {
- //renumber the waiting/accepted/lot list, a user was deleted from it
- AdmissionApplication::renumberAdmission($this->getId());
- }
- $cs = $this->getCourseSet();
- if ($cs) {
- AdmissionPriority::unsetPriority($cs->getId(), $user_id, $this->getId());
- }
-
- CalendarScheduleModel::deleteSeminarEntries($user_id, $this->getId());
- NotificationCenter::postNotification('CourseDidGetMember', $this, $user_id);
- NotificationCenter::postNotification('UserDidEnterCourse', $this->id, $user_id);
- StudipLog::log('SEM_USER_ADD', $this->id, $user_id, $status, 'Wurde in die Veranstaltung eingetragen');
- $this->course->resetRelation('members');
- $this->course->resetRelation('admission_applicants');
-
- // Check if we need to add user to parent course as well.
- if ($this->parent_course) {
- $parent = new Seminar($this->parent);
- $parent->addMember($user_id, $status, $force);
- }
-
- return $this;
- } elseif (
- ($force || $rangordnung[$course_member->status] < $rangordnung[$status])
- && ($course_member->status !== 'dozent' || $numberOfTeachers > 1)
- ) {
- $visibility = $course_member->visible;
- if (in_array($status, ['tutor', 'dozent'])) {
- $visibility = 'yes';
- }
- $course_member->status = $status;
- $course_member->visible = $visibility;
- $course_member->position = $new_position;
- $course_member->store();
-
- if ($course_member->status === 'dozent') {
- $termine = DBManager::get()->fetchFirst(
- "SELECT termin_id FROM termine WHERE range_id = ?",
- [$this->id]
- );
-
- DBManager::get()->execute(
- "DELETE FROM termin_related_persons WHERE range_id IN (?) AND user_id = ?",
- [$termine, $user_id]
- );
- }
- NotificationCenter::postNotification('CourseDidChangeMember', $this, $user_id);
- $this->course->resetRelation('members');
- $this->course->resetRelation('admission_applicants');
- return $this;
- } else {
- if ($course_member->status === 'dozent' && $numberOfTeachers <= 1) {
- $this->createError(sprintf(_('Die Person kann nicht herabgestuft werden, ' .
-'da mindestens ein/eine Veranstaltungsleiter/-in (%s) in die Veranstaltung eingetragen sein muss!'),
- get_title_for_status('dozent', 1, $this->status)) .
- ' ' . sprintf(_('Tragen Sie zunächst eine weitere Person als Veranstaltungsleiter/-in (%s) ein.'),
-get_title_for_status('dozent', 1, $this->status)));
- }
-
- return false;
- }
- }
-
- /**
- * Cancels a subscription to an admission.
- *
- * @param array $users
- * @param string $status
- * @return array
- * @throws NotificationVetoException
- */
- public function cancelAdmissionSubscription(array $users, string $status): array
- {
- $msgs = [];
- $messaging = new messaging;
- $course_set = $this->getCourseSet();
- $users = User::findMany($users);
- foreach ($users as $user) {
- $prio_delete = false;
- if ($course_set) {
- $prio_delete = AdmissionPriority::unsetPriority($course_set->getId(), $user->id, $this->getId());
- }
- $result = AdmissionApplication::deleteBySQL(
- 'seminar_id = ? AND user_id = ? AND status = ?',
- [$this->getId(), $user->id, $status]
- );
- if ($result || $prio_delete) {
- setTempLanguage($user->id);
- if ($status !== 'accepted') {
- $message = sprintf(
- _('Sie wurden von der Warteliste der Veranstaltung **%s** gestrichen und sind damit __nicht__ zugelassen worden.'),
- $this->getFullName()
- );
- } else {
- $message = sprintf(
- _('Sie wurden aus der Veranstaltung **%s** gestrichen und sind damit __nicht__ zugelassen worden.'),
- $this->getFullName()
- );
- }
- restoreLanguage();
- $messaging->insert_message(
- $message,
- $user->username,
- '____%system%____',
- false,
- false,
- '1',
- false,
- sprintf('%s %s', _('Systemnachricht:'), _('nicht zugelassen in Veranstaltung')),
- true
- );
- StudipLog::log('SEM_USER_DEL', $this->getId(), $user->id, 'Wurde aus der Veranstaltung entfernt');
- NotificationCenter::postNotification('UserDidLeaveCourse', $this->getId(), $user->id);
-
- $msgs[] = $user->getFullName();
- }
- }
- return $msgs;
- }
-
- /**
- * Cancels a subscription to a course
- * @param array $users
- * @return array
- * @throws Exception
- */
- public function cancelSubscription(array $users): array
- {
- $msgs = [];
- $messaging = new messaging;
- $users = User::findMany($users);
- foreach ($users as $user) {
- // delete member from seminar
- if ($this->deleteMember($user->id)) {
- setTempLanguage($user->id);
- $message = sprintf(
- _('Ihre Anmeldung zur Veranstaltung **%s** wurde aufgehoben.'),
- $this->getFullName()
- );
- restoreLanguage();
- $messaging->insert_message(
- $message,
- $user->username,
- '____%system%____',
- false,
- false,
- '1',
- false,
- sprintf('%s %s', _('Systemnachricht:'), _("Anmeldung aufgehoben")),
- true
- );
- $msgs[] = $user->getFullName();
- }
- }
-
- return $msgs;
- }
-
- /**
- * deletes a user from the seminar by respecting the rule that at least one
- * user with status "dozent" must stay there
- * @param string $user_id user_id of the user to delete
- * @return boolean
- */
- public function deleteMember($user_id): bool
- {
- $dozenten = $this->getMembers();
- if (count($dozenten) >= 2 || empty($dozenten[$user_id])) {
- $result = CourseMember::deleteBySQL('Seminar_id = ? AND user_id = ?', [$this->id, $user_id]);
- if ($result === 0) {
- return true;
- }
- // If this course is a child of another course...
- if ($this->parent_course) {
- // ... check if user is member in another sibling ...
- $other = CourseMember::countBySQL(
- "`user_id` = :user AND `Seminar_id` IN (:courses) AND `Seminar_id` != :this",
- ['user' => $user_id, 'courses' => $this->parent->children->pluck('seminar_id'), 'this' => $this->id]
- );
-
- // ... and delete from parent course if this was the only
- // course membership in this family.
- if ($other === 0) {
- $s = new Seminar($this->parent);
- $s->deleteMember($user_id);
- }
- }
-
- if ($this->children != null) {
- foreach ($this->children as $child) {
- $s = new Seminar($child);
- $s->deleteMember($user_id);
- }
- }
-
- if (!empty($dozenten[$user_id])) {
- $query = "SELECT termin_id FROM termine WHERE range_id = ?";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$this->id]);
- $termine = $statement->fetchAll(PDO::FETCH_COLUMN);
-
- $query = "DELETE FROM termin_related_persons WHERE range_id = ? AND user_id = ?";
- $statement = DBManager::get()->prepare($query);
-
- foreach ($termine as $termin_id) {
- $statement->execute([$termin_id, $user_id]);
- }
- if (Deputy::isActivated()) {
- $other_dozenten = array_diff(array_keys($dozenten), [$user_id]);
- foreach (Deputy::findByRange_id($user_id) as $default_deputy) {
- if ($default_deputy->user_id != $GLOBALS['user']->id &&
- !Deputy::countBySql("range_id IN (?)", [$other_dozenten])) {
- Deputy::deleteBySQL("range_id = ? AND user_id = ?", [$this->id, $default_deputy->user_id]);
- }
- }
- }
- }
-
- // Delete course related datafield entries
- DatafieldEntryModel::deleteBySQL('range_id = ? AND sec_range_id = ?', [$user_id, $this->id]);
-
- // Remove from associated status groups
- foreach (Statusgruppen::findBySeminar_id($this->id) as $group) {
- $group->removeUser($user_id, true);
- }
-
- $this->createMessage(sprintf(
- _('Nutzer %s wurde aus der Veranstaltung entfernt.'),
- '<i>' . htmlReady(get_fullname($user_id)) . '</i>'
- ));
- NotificationCenter::postNotification('CourseDidChangeMember', $this, $user_id);
- NotificationCenter::postNotification('UserDidLeaveCourse', $this->id, $user_id);
- StudipLog::log('SEM_USER_DEL', $this->id, $user_id, 'Wurde aus der Veranstaltung entfernt');
- $this->course->resetRelation('members');
- return true;
- } else {
- $this->createError(
- sprintf(
- _('Die Veranstaltung muss wenigstens <b>einen/eine</b> VeranstaltungsleiterIn (%s) eingetragen haben!'),
- get_title_for_status('dozent', 1, $this->status)
- )
- . ' ' . _('Tragen Sie zunächst einen anderen ein, um diesen zu löschen.')
- );
- return false;
- }
- }
-
- /**
- * sets the almost never used column position in the table seminar_user
- * @param array $members members array: array of user_id's - wrong IDs will be ignored
- * @return Seminar
- */
- public function setMemberPriority($members): Seminar
- {
- CourseMember::findEachBySQL(
- function (CourseMember $membership) use (&$members) {
- $membership->position = array_search($membership->user_id, $members);
- $membership->store();
- },
- "Seminar_id = ? AND user_id IN (?)",
- [$this->id, $members]
- );
- return $this;
- }
-
- /**
- * returns array with information about enrolment to this course for given user_id
- * ['enrolment_allowed'] : true or false
- * ['cause']: keyword to describe the cause
- * ['description'] : readable description of the cause
- *
- * @param string $user_id
- * @return array
- */
- public function getEnrolmentInfo($user_id)
- {
- $info = [];
- $user = User::find($user_id);
- if ($this->getSemClass()->isGroup()) {
- $info['enrolment_allowed'] = false;
- $info['cause'] = 'grouped';
- $info['description'] = _("Dies ist eine Veranstaltungsgruppe. Sie können sich nur in deren Unterveranstaltungen eintragen.");
- return $info;
- }
- if ($this->read_level == 0 && Config::get()->ENABLE_FREE_ACCESS && !$GLOBALS['perm']->get_studip_perm($this->getId(), $user_id)) {
- $info['enrolment_allowed'] = true;
- $info['cause'] = 'free_access';
- $info['description'] = _("Für die Veranstaltung ist keine Anmeldung erforderlich.");
- return $info;
- }
- if (!$user) {
- $info['enrolment_allowed'] = false;
- $info['cause'] = 'nobody';
- $info['description'] = _("Sie sind nicht in Stud.IP angemeldet.");
- return $info;
- }
- if ($GLOBALS['perm']->have_perm('root', $user_id)) {
- $info['enrolment_allowed'] = true;
- $info['cause'] = 'root';
- $info['description'] = _("Sie dürfen ALLES.");
- return $info;
- }
- if ($GLOBALS['perm']->have_studip_perm('admin', $this->getId(), $user_id)) {
- $info['enrolment_allowed'] = true;
- $info['cause'] = 'courseadmin';
- $info['description'] = _("Sie sind Administrator_in der Veranstaltung.");
- return $info;
- }
- if ($GLOBALS['perm']->have_perm('admin', $user_id)) {
- $info['enrolment_allowed'] = false;
- $info['cause'] = 'admin';
- $info['description'] = _("Als Administrator_in können Sie sich nicht für eine Veranstaltung anmelden.");
- return $info;
- }
- //Ist bereits Teilnehmer
- if ($GLOBALS['perm']->have_studip_perm('user', $this->getId(), $user_id)) {
- $info['enrolment_allowed'] = true;
- $info['cause'] = 'member';
- $info['description'] = _("Sie sind für die Veranstaltung angemeldet.");
- return $info;
- }
- $admission_status = $user->admission_applications->findBy('seminar_id', $this->getId())->val('status');
- if ($admission_status == 'accepted') {
- $info['enrolment_allowed'] = false;
- $info['cause'] = 'accepted';
- $info['description'] = _("Sie wurden für diese Veranstaltung vorläufig akzeptiert.");
- return $info;
- }
- if ($admission_status == 'awaiting') {
- $info['enrolment_allowed'] = false;
- $info['cause'] = 'awaiting';
- $info['description'] = _("Sie stehen auf der Warteliste für diese Veranstaltung.");
- return $info;
- }
- if ($GLOBALS['perm']->get_perm($user_id) == 'user') {
- $info['enrolment_allowed'] = false;
- $info['cause'] = 'user';
- $info['description'] = _("Sie haben nicht die erforderliche Berechtigung sich für eine Veranstaltung anzumelden.");
- return $info;
- }
- //falsche Nutzerdomäne
- $same_domain = true;
- $user_domains = UserDomain::getUserDomainsForUser($user_id);
- if (count($user_domains) > 0) {
- $seminar_domains = UserDomain::getUserDomainsForSeminar($this->getId());
- $same_domain = UserDomain::checkUserVisibility($seminar_domains, $user_domains);;
- }
- if (!$same_domain && !$this->isStudygroup()) {
- $info['enrolment_allowed'] = false;
- $info['cause'] = 'domain';
- $info['description'] = _("Sie sind nicht in einer zugelassenenen Nutzerdomäne, Sie können sich nicht eintragen!");
- return $info;
- }
- //Teilnehmerverwaltung mit Sperregel belegt
- if (LockRules::Check($this->getId(), 'participants')) {
- $info['enrolment_allowed'] = false;
- $info['cause'] = 'locked';
- $lockdata = LockRules::getObjectRule($this->getId());
- $info['description'] = _("In diese Veranstaltung können Sie sich nicht eintragen!") . ($lockdata['description'] ? '<br>' . formatLinks($lockdata['description']) : '');
- return $info;
- }
- //Veranstaltung unsichtbar für aktuellen Nutzer
- if (!$this->visible && !$this->isStudygroup() && !$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM, $user_id)) {
- $info['enrolment_allowed'] = false;
- $info['cause'] = 'invisible';
- $info['description'] = _("Die Veranstaltung ist gesperrt, Sie können sich nicht eintragen!");
- return $info;
- }
- if ($courseset = $this->getCourseSet()) {
- $info['enrolment_allowed'] = true;
- $info['cause'] = 'courseset';
- $info['description'] = _("Die Anmeldung zu dieser Veranstaltung folgt speziellen Regeln. Lesen Sie den Hinweistext.");
- $user_prio = AdmissionPriority::getPrioritiesByUser($courseset->getId(), $user_id);
- if (isset($user_prio[$this->getId()])) {
- if ($courseset->hasAdmissionRule('LimitedAdmission')) {
- $info['description'] .= ' ' . sprintf(_("(Sie stehen auf der Anmeldeliste für die automatische Platzverteilung mit der Priorität %s.)"), $user_prio[$this->getId()]);
- } else {
- $info['description'] .= ' ' . _("(Sie stehen auf der Anmeldeliste für die automatische Platzverteilung.)");
- }
- }
- return $info;
- }
- $info['enrolment_allowed'] = true;
- $info['cause'] = 'normal';
- $info['description'] = '';
- return $info;
- }
-
- /**
- * adds user with given id as preliminary member to course
- *
- * @param string $user_id
- * @return integer 1 if successfull
- */
- public function addPreliminaryMember($user_id, $comment = '')
- {
- $new_admission_member = new AdmissionApplication();
- $new_admission_member->user_id = $user_id;
- $new_admission_member->position = 0;
- $new_admission_member->status = 'accepted';
- $new_admission_member->comment = $comment;
- $this->course->admission_applicants[] = $new_admission_member;
- $ok = $new_admission_member->store();
- if ($ok && $this->isStudygroup()) {
- StudygroupModel::applicationNotice($this->getId(), $user_id);
- }
- $cs = $this->getCourseSet();
- if ($cs) {
- $prio_delete = AdmissionPriority::unsetPriority($cs->getId(), $user_id, $this->getId());
- }
- // LOGGING
- StudipLog::log('SEM_USER_ADD', $this->getId(), $user_id, 'accepted', 'Vorläufig akzeptiert');
- return $ok;
- }
-
- /**
- * returns courseset object for this course
- *
- * @return CourseSet courseset object or null
- */
- public function getCourseSet()
- {
- if ($this->course_set === null) {
- $this->course_set = CourseSet::getSetForCourse($this->id);
- if ($this->course_set === null) {
- $this->course_set = false;
- }
- }
- return $this->course_set ?: null;
- }
-
- /**
- * returns true if the number of participants of this course is limited
- *
- * @return boolean
- */
- public function isAdmissionEnabled()
- {
- $cs = $this->getCourseSet();
- return ($cs && $cs->isSeatDistributionEnabled());
- }
-
- /**
- * returns the number of free seats in the course or true if not limited
- *
- * @return integer
- */
- public function getFreeAdmissionSeats()
- {
- if ($this->isAdmissionEnabled()) {
- return $this->course->getFreeSeats();
- } else {
- return true;
- }
- }
-
- /**
- * returns true if the course is locked
- *
- * @return boolean
- */
- public function isAdmissionLocked()
- {
- $cs = $this->getCourseSet();
- return ($cs && $cs->hasAdmissionRule('LockedAdmission'));
- }
-
- /**
- * returns true if the course is password protected
- *
- * @return boolean
- */
- public function isPasswordProtected()
- {
- $cs = $this->getCourseSet();
- return ($cs && $cs->hasAdmissionRule('PasswordAdmission'));
- }
-
- /**
- * returns array with start and endtime of course enrolment timeframe
- * return null if there is no timeframe
- *
- * @return array assoc array with start_time end_time as keys timestamps as values
- */
- public function getAdmissionTimeFrame()
- {
- $cs = $this->getCourseSet();
- return ($cs && $cs->hasAdmissionRule('TimedAdmission')) ?
- ['start_time' => $cs->getAdmissionRule('TimedAdmission')->getStartTime(),
- 'end_time' => $cs->getAdmissionRule('TimedAdmission')->getEndTime()] : [];
- }
-
- /**
- * returns StudipModule object for given slot, null when deactivated or not available
- *
- * @param string $slot
- * @return StudipModule|null
- */
- public function getSlotModule($slot): ?StudipModule
- {
- $module = 'Core' . ucfirst($slot);
- if ($this->course->isToolActive($module)) {
- return PluginEngine::getPlugin($module);
- }
- return null;
- }
-
- /**
- * adds user with given id on waitinglist
- *
- * @param string $user_id
- * @param string $which_end 'last' or 'first'
- * @return integer|bool number on waitlist or false if not successful
- */
- public function addToWaitlist($user_id, $which_end = 'last')
- {
- if (AdmissionApplication::exists([$user_id, $this->id]) || CourseMember::find([$this->id, $user_id])) {
- return false;
- }
- switch ($which_end) {
- // Append users to waitlist end.
- case 'last':
- $maxpos = DBManager::get()->fetchColumn("SELECT MAX(`position`)
- FROM `admission_seminar_user`
- WHERE `seminar_id`=?
- AND `status`='awaiting'", [$this->id]);
- $waitpos = $maxpos+1;
- break;
- // Prepend users to waitlist start.
- case 'first':
- default:
- // Move all others on the waitlist up by the number of people to add.
- AdmissionApplication::renumberAdmission($this->id);
- $waitpos = 1;
- }
- $new_admission_member = new AdmissionApplication();
- $new_admission_member->user_id = $user_id;
- $new_admission_member->position = $waitpos;
- $new_admission_member->status = 'awaiting';
- $new_admission_member->seminar_id = $this->id;
- if ($new_admission_member->store()) {
- StudipLog::log('SEM_USER_ADD', $this->id, $user_id, 'awaiting', 'Auf Warteliste gesetzt, Position: ' . $waitpos);
- $this->course->resetRelation('admission_applicants');
- return $waitpos;
- }
- return false;
- }
-}