aboutsummaryrefslogtreecommitdiff
path: root/lib/raumzeit/MetaDate.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/raumzeit/MetaDate.class.php
parentda0022e5c1abbf9825ae76debaabdff7e8623bb4 (diff)
parent97a188592c679890a25c37ab78463add76a52ff7 (diff)
Merge branch 'main' into issue-3911issue-3911
Diffstat (limited to 'lib/raumzeit/MetaDate.class.php')
-rw-r--r--lib/raumzeit/MetaDate.class.php697
1 files changed, 0 insertions, 697 deletions
diff --git a/lib/raumzeit/MetaDate.class.php b/lib/raumzeit/MetaDate.class.php
deleted file mode 100644
index 0af632d..0000000
--- a/lib/raumzeit/MetaDate.class.php
+++ /dev/null
@@ -1,697 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-// +--------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// MetaDate.class.php
-//
-// Repräsentiert die Zeit- und Turnusdaten einer Veranstaltung
-//
-// +--------------------------------------------------------------------------+
-// 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 any later version.
-// +--------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// +--------------------------------------------------------------------------+
-
-
-/**
- * MetaDate.class.php
- *
- *
- * @author Till Glöggler <tgloeggl@uos.de>
- * @version 28. Juni 2007
- * @access protected
- * @package raumzeit
- */
-class MetaDate
-{
- var $seminar_id = '';
- var $seminarStartTime = 0;
- var $seminarDurationTime = 0;
- var $cycles = [];
- var $hasDatesTmp = [];
-
- /**
- * Constructor
- * @param string $seminar_id
- */
- function __construct($seminar_id = '')
- {
- if ($seminar_id != '') {
- $this->seminar_id = $seminar_id;
- $this->restore();
- }
-
- }
-
- /**
- * returns start week (Semesterwoche) for a cycledate
- * for compatibility the first cycledate is chosen if no one is specified
- *
- * @deprecated
- * @param string id of cycledate
- * @return int
- */
- function getStartWoche($metadate_id = null)
- {
- if ($metadate_id) {
- return $this->cycles[$metadate_id]->week_offset;
- } else {
- $first_metadate = $this->getFirstMetadate();
- return $first_metadate ? $first_metadate->week_offset : null;
- }
- }
-
- /**
- * sets start week (Semesterwoche) for a cycledate
- * for compatibility the first cycledate is chosen if no one is specified
- *
- * @deprecated
- * @param int $start_woche
- * @param string $metadate_id
- * @return null|Ambigous <NULL, unknown>
- */
- function setStartWoche($start_woche, $metadate_id = null)
- {
- if ($metadate_id) {
- return $this->cycles[$metadate_id]->week_offset = $start_woche;
- } else {
- $first_metadate = $this->getFirstMetadate();
- return $first_metadate ? $first_metadate->week_offset = $start_woche : null;
- }
- }
-
- /**
- * returns first cycledate
- *
- * @return CycleData
- */
- function getFirstMetadate()
- {
- $cycles = array_keys($this->cycles);
- $first_metadate_id = array_shift($cycles);
- return $first_metadate_id ? $this->cycles[$first_metadate_id] : null;
- }
-
- /**
- * returns the cycle for a cycledate
- * for compatibility the first cycledate is chosen if no one is specified
- *
- * @deprecated
- * @param string $metadate_id
- * @return int 0,1,2 for weekly, biweekly ...
- */
- function getTurnus($metadate_id = null)
- {
- if ($metadate_id) {
- return $this->cycles[$metadate_id]->cycle;
- } else {
- $first_metadate = $this->getFirstMetadate();
- return $first_metadate ? $first_metadate->cycle : null;
- }
- }
-
- /**
- * set the cycle for a cycledate
- * for compatibility the first cycledate is chosen if no one is specified
- *
- * @deprecated
- * @param int 0,1,2 for weekly, biweekly ...
- * @param string $metadate_id
- * @return int
- */
- function setTurnus($turnus, $metadate_id = null)
- {
- if ($metadate_id) {
- return $this->cycles[$metadate_id]->cycle = $turnus;
- } else {
- $first_metadate = $this->getFirstMetadate();
- return $first_metadate ? $first_metadate->cycle = $turnus : null;
- }
- }
-
- function setSeminarStartTime($start)
- {
- $this->seminarStartTime = $start;
- }
-
- function setSeminarDurationTime($duration)
- {
- $this->seminarDurationTime = $duration;
- }
-
- function getSeminarID()
- {
- return $this->seminar_id;
- }
-
- /**
- * internal method to apply cycledate data from assoc array to a given
- * CycleData object. checks the start and endtime and retruns false if wrong
- *
- * @deprecated
- * @param array assoc, see CycleData, metadate_id must be in $data['cycle_id']
- * @param CycleData $cycle
- * @return boolean
- */
- function setCycleData($data, $cycle)
- {
- $cycle->seminar_id = $this->getSeminarId();
- $cycles = array_keys($this->cycles);
- if ($last_one = array_pop($cycles)) {
- $cycle->sorter = $this->cycles[$last_one]->sorter > 0 ? $this->cycles[$last_one]->sorter + 1 : 0;
- }
- if ($cycle->getDescription() != $data['description']) {
- $cycle->setDescription($data['description']);
- }
-
- if (isset($data['weekday'])) $cycle->weekday = (int)$data['weekday'];
- if (isset($data['week_offset'])) $cycle->week_offset = (int)$data['week_offset'];
- if (isset($data['cycle'])) $cycle->cycle = (int)$data['cycle'];
- if (isset($data['sws'])) $cycle->sws = $data['sws'];
- if (isset($data['endWeek'])) $cycle->end_offset = (int)$data['endWeek'];
- if (isset($data['day']) && isset($data['start_stunde']) && isset($data['start_minute']) && isset($data['end_stunde']) && isset($data['end_minute'])) {
-
- if (
- ($data['start_stunde'] > 23) || ($data['start_stunde'] < 0) ||
- ($data['end_stunde'] > 23) || ($data['end_stunde'] < 0) ||
- ($data['start_minute'] > 59) || ($data['start_minute'] < 0) ||
- ($data['end_minute'] > 59) || ($data['end_minute'] < 0)
- ) {
- return FALSE;
- }
-
- if (mktime((int)$data['start_stunde'], (int)$data['start_minute']) < mktime((int)$data['end_stunde'], (int)$data['end_minute'])) {
- $cycle->setDay($data['day']);
- $cycle->setStart($data['start_stunde'], $data['start_minute']);
- $cycle->setEnd($data['end_stunde'], $data['end_minute']);
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
-
- /**
- * adds a new cycledate, single dates are created if second param is true
- *
- * @param array assoc, see CycleData, metadate_id must be in $data['cycle_id']
- * @param bool $create_single_dates
- * @return string|boolean metadate_id of created cycle
- */
- function addCycle($data = [], $create_single_dates = true)
- {
- $data['day'] = (int)$data['day'];
- $data['start_stunde'] = (int)$data['start_stunde'];
- $data['start_minute'] = (int)$data['start_minute'];
- $data['end_stunde'] = (int)$data['end_stunde'];
- $data['end_minute'] = (int)$data['end_minute'];
-
- $cycle = new CycleData();
-
- if ($this->setCycleData($data, $cycle)) {
- $this->cycles[$cycle->getMetadateID()] = $cycle;
- $this->sortCycleData();
- if ($create_single_dates) $this->createSingleDates($cycle->getMetadateID());
- return $cycle->getMetadateID();
- }
- return FALSE;
- }
-
- /**
- * change existing cycledate, changes also corresponding single dates
- *
- * @param array assoc, see CycleData, metadate_id must be in $data['cycle_id']
- * @return number|boolean
- */
- function editCycle($data = [])
- {
- $cycle = $this->cycles[$data['cycle_id']];
- $new_start = mktime((int)$data['start_stunde'], (int)$data['start_minute']);
- $new_end = mktime((int)$data['end_stunde'], (int)$data['end_minute']);
- $old_start = mktime($cycle->getStartStunde(), $cycle->getStartMinute());
- $old_end = mktime($cycle->getEndStunde(), $cycle->getEndMinute());
-
- if (($new_start >= $old_start) && ($new_end <= $old_end) && ($data['day'] == $cycle->day) && ($data['endWeek'] == $cycle->end_offset)) {
- // Zeitraum wurde verkuerzt, Raumbuchungen bleiben erhalten...
- if ($this->setCycleData($data, $cycle)) {
- $termine = $cycle->getSingleDates();
- foreach ($termine as $key => $val) {
- $tos = $val->getStartTime();
- $toe = $val->getEndTime();
- if ($toe > time()) {
- $t_start = mktime((int)$data['start_stunde'], (int)$data['start_minute'], 0, date('m', $tos), date('d', $tos), date('Y', $tos));
- $t_end = mktime((int)$data['end_stunde'], (int)$data['end_minute'], 0, date('m', $toe), date('d', $toe), date('Y', $toe));
- $termine[$key]->setTime($t_start, $t_end);
- $termine[$key]->store();
- } else {
- unset($termine[$key]);
- }
- }
- $this->sortCycleData();
- }
- return sizeof($termine);
- } else {
- if ($this->setCycleData($data, $cycle)) {
- // collect all existing themes (issues) for this cycle:
- $issues = [];
- $issue_objects = [];
- $singledate_count = 0;
-
- // loop through the single dates and look for themes (issues)
- $termine = $cycle->getSingleDates();
- foreach ($termine as $key => $termin) {
- // get all isues of this date ( zero, one, or more, if the expert view is activated)
- // and store them at the relative position of this single date
- $issues[$singledate_count] = $termin->getIssueIDs();
- $singledate_count++;
- }
- // remove all SingleDates in the future for this CycleData
- $count = CycleDataDB::deleteNewerSingleDates($data['cycle_id'], time());
- // create new SingleDates
- $this->createSingleDates(['metadate_id' => $cycle->getMetaDateId(),
- 'startAfterTimeStamp' => time()
- ]);
-
- // clear all loaded SingleDates so no odd ones remain. The Seminar-Class will load them fresh when needed
- $cycle->termine = NULL;
-
- // read all new single dates
- $termine = $cycle->getSingleDates();
-
- // new dates counter
- $new_singledate_count = 0;
-
- // loop through the single dates and add the themes (issues)
- foreach ($termine as $key => $termin) {
- // check, if there are issues for this single date
- if ($issues[$new_singledate_count] != NULL) {
- // add all issues:
- foreach ($issues[$new_singledate_count] as $issue_key => $issue_id) {
- $termin->addIssueID($issue_id);
- $termin->store();
- }
- }
- unset($issues[$new_singledate_count]);
- $new_singledate_count++;
- }
-
- // delete issues, that are not assigned to a single date because of to few dates
- // (only if the schedule expert view is off)
- if (!Config::get()->RESOURCES_ENABLES_EXPERT_SCHEDULE_VIEW) {
- if ($new_singledate_count < $singledate_count) {
- for ($i = $new_singledate_count; $i < $singledate_count; $i++) {
- if ($issues[$i] != NULL) {
- foreach ($issues[$i] as $issue_id) {
- // delete this issue
- IssueDB::deleteIssue($issue_id);
- }
- }
- }
- }
- }
- $this->sortCycleData();
- return $count;
- }
- }
- return FALSE;
- }
-
- /**
- * completey remove cycledate
- * @see CycleData::delete()
- * @param string $cycle_id
- * @return boolean
- */
- function deleteCycle($cycle_id)
- {
- $this->cycles[$cycle_id]->delete();
- unset ($this->cycles[$cycle_id]);
- return TRUE;
- }
-
- function deleteSingleDate($cycle_id, $date_id, $filterStart, $filterEnd)
- {
- $this->cycles[$cycle_id]->deleteSingleDate($date_id, $filterStart, $filterEnd);
- }
-
- function unDeleteSingleDate($cycle_id, $date_id, $filterStart, $filterEnd)
- {
- return $this->cycles[$cycle_id]->unDeleteSingleDate($date_id, $filterStart, $filterEnd);
- }
-
- /**
- * store all changes to cycledates for the course, removed cycles are deleted from database
- * @return int > 0 if changes where made
- */
- function store()
- {
- $old_cycle_dates = [];
- $changed = 0;
- foreach (SeminarCycleDate::findBySeminar($this->seminar_id) as $c) {
- $old_cycle_dates[$c->getId()] = $c;
- }
- $removed = array_diff(array_keys($old_cycle_dates), array_keys($this->cycles));
- foreach ($removed as $one) {
- $changed += $old_cycle_dates[$one]->delete();
- }
- foreach ($this->cycles as $one) {
- $changed += $one->storeCycleDate();
- }
- $this->sortCycleData();
- return $changed;
- }
-
-
- /**
- * load all cycledates from database
- */
- function restore()
- {
- $this->cycles = [];
- foreach (SeminarCycleDate::findBySeminar($this->seminar_id) as $c) {
- $this->cycles[$c->getId()] = new CycleData($c);
- }
- $this->sortCycleData();
- }
-
- function delete($removeSingleDates = TRUE)
- {
- //TODO: Löschen eines MetaDate-Eintrages (CycleData);
- }
-
- /**
- * sort cycledates by sorter column and date
- */
- function sortCycleData()
- {
- uasort($this->cycles, function ($a, $b) {
- return $a->sorter - $b->sorter
- ?: $a->weekday - $b->weekday
- ?: $a->start_hour - $b->start_hour;
- });
- }
-
- /**
- * returns cycledates as arrays
- *
- * @param bool $show_invisibles if cycles without dates should
- * be in the array, defaults to false
- * @return array assoc of cycledate data arrays
- */
- function getCycleData($show_invisibles = false)
- {
- $ret = [];
-
- foreach ($this->cycles as $val) {
- if ($val->is_visible || $show_invisibles) {
- $ret[$val->getMetaDateID()] = $val->toArray();
- }
- }
- return $ret;
- }
-
- /**
- * returns the cycledate objects
- * @return array of CycleData objects
- */
- function getCycles()
- {
- return $this->cycles;
- }
-
- /**
- * returns an array of SingleDate objects corresponding to the given cycle id
- * use the optional params to specify a timerange
- *
- * @param string a cycle id
- * @param int unix timestamp
- * @param int unix timestamp
- * @return array of SingleDate objects
- */
- function getSingleDates($metadate_id, $filterStart = 0, $filterEnd = 0)
- {
- if (!$this->cycles[$metadate_id]->termine) {
- $this->readSingleDates($metadate_id, $filterStart, $filterEnd);
- }
-
- return $this->cycles[$metadate_id]->termine;
- }
-
- /**
- * reload SingleDate objects for a given cycle id
- *
- * @param string $metadate_id
- * @param int $start
- * @param int $end
- * @return bool
- */
- function readSingleDates($metadate_id, $start = 0, $end = 0)
- {
- return $this->cycles[$metadate_id]->readSingleDates($start, $end);
- }
-
- /**
- * returns true if a given cycle has at least one date at all or in the given time range
- *
- * @param string $metadate_id
- * @param int $filterStart
- * @param int $filterEnd
- * @return bool
- */
- function hasDates($metadate_id, $filterStart = 0, $filterEnd = 0)
- {
- if (!isset($this->hasDatesTmp[$metadate_id])) {
- $this->hasDatesTmp[$metadate_id] = MetaDateDB::has_dates($metadate_id, $this->getSeminarID(), $filterStart, $filterEnd);
- }
-
- return $this->hasDatesTmp[$metadate_id];
- }
-
- /**
- * create single dates for one cycle and all semester and store them in database, deleting obsolete ones
- *
- * @param mixed cycle id (string) or array with 'metadate_id' => string cycle id, 'startAfterTimeStamp' => int timestamp to override semester start
- */
- function createSingleDates($data)
- {
- foreach ($this->getVirtualSingleDates($data) as $semester_id => $dates_for_semester) {
- list($dates, $dates_to_delete) = array_values($dates_for_semester);
- foreach ($dates_to_delete as $d) $d->delete();
- foreach ($dates as $d) {
- if ($d->isUpdate()) continue; //vorhandene Termine nicht speichern wg. chdate
- $d->store();
- }
- }
- //das sollte nicht nötig sein, muss aber erst genauer untersucht werden
- $this->store();
- $this->restore();
- }
-
- /**
- * generate single date objects for one cycle and all semester, existing dates are merged in
- *
- * @param mixed cycle id (string) or array with 'metadate_id' => string cycle id, 'startAfterTimeStamp' => int timestamp to override semester start
- * @return array array of arrays, for each semester id an array of two arrays of SingleDate objects: 'dates' => all new and surviving dates, 'dates_to_delete' => obsolete dates
- */
- function getVirtualSingleDates($data)
- {
- if (is_array($data)) {
- $metadate_id = $data['metadate_id'];
- $startAfterTimeStamp = $data['startAfterTimeStamp'];
- } else {
- $metadate_id = $data;
- $startAfterTimeStamp = 0;
- }
-
- $ret = [];
-
- $all_semester = Semester::findAllVisible(false);
- $sem_begin = null;
- $sem_end = null;
- // get the starting-point for creating singleDates for the choosen cycleData
- foreach ($all_semester as $val) {
- if (($this->seminarStartTime >= $val["beginn"]) && ($this->seminarStartTime <= $val["ende"])) {
- $sem_begin = mktime(0, 0, 0, date("n", $val["vorles_beginn"]), date("j", $val["vorles_beginn"]), date("Y", $val["vorles_beginn"]));
- }
- }
-
- // get the end-point
- if ($this->seminarDurationTime == -1) {
- foreach ($all_semester as $val) {
- $sem_end = $val['vorles_ende'];
- }
- } else {
- $i = 0;
- foreach ($all_semester as $val) {
- $i++;
- $timestamp = $this->seminarDurationTime + $this->seminarStartTime;
- if (($timestamp >= $val['beginn']) && ($timestamp <= $val['ende'])) {
- $sem_end = $val["vorles_ende"];
- }
- }
- }
-
- $passed = false;
- foreach ($all_semester as $val) {
- if ($sem_begin <= $val['vorles_beginn']) {
- $passed = true;
- }
- if ($passed && ($sem_end >= $val['vorles_ende']) && ($startAfterTimeStamp <= $val['ende'])) {
- $ret[$val['semester_id']] = $this->getVirtualSingleDatesForSemester($metadate_id, $val['vorles_beginn'], $val['vorles_ende'], $startAfterTimeStamp);
- }
- }
-
- return $ret;
- }
-
- /**
- * generate single date objects for one cycle and one semester, existing dates are merged in
- *
- * @param string cycle id
- * @param int timestamp of semester start
- * @param int timestamp of semester end
- * @param int alternative timestamp to start from
- * @param int correction calculation (obsolete)
- * @return array returns an array of two arrays of SingleDate objects: 'dates' => all new and surviving dates, 'dates_to_delete' => obsolete dates
- */
- function getVirtualSingleDatesForSemester($metadate_id, $sem_begin, $sem_end, $startAfterTimeStamp, $corr = 0)
- {
- $dates = [];
- $dates_to_delete = [];
-
- // loads the singledates of the by metadate_id denoted regular time-entry into the object
- $this->readSingleDates($metadate_id);
-
- // The currently existing singledates for the by metadate_id denoted regular time-entry
- $existingSingleDates =& $this->cycles[$metadate_id]->getSingleDates();
-
- $start_woche = $this->cycles[$metadate_id]->week_offset;
- $end_woche = $this->cycles[$metadate_id]->end_offset;
-
- $turnus = $this->cycles[$metadate_id]->cycle;
-
- // This variable is used to check if a given singledate shall be created in a bi-weekly seminar.
- if ($start_woche == -1) $start_woche = 0;
-
- $week = 0;
-
- // get the first presence date after sem_begin
- $day_of_week = date('l', strtotime('Sunday + ' . $this->cycles[$metadate_id]->day . ' days'));
- $stamp = strtotime('this week ' . $day_of_week, $sem_begin);
-
- $start_time = mktime(
- (int)$this->cycles[$metadate_id]->start_stunde, // Hour
- (int)$this->cycles[$metadate_id]->start_minute, // Minute
- 0, // Second
- date("n", $stamp), // Month
- date("j", $stamp), // Day
- date("Y", $stamp)); // Year
-
- $end_time = mktime(
- (int)$this->cycles[$metadate_id]->end_stunde, // Hour
- (int)$this->cycles[$metadate_id]->end_minute, // Minute
- 0, // Second
- date("n", $stamp), // Month
- date("j", $stamp), // Day
- date("Y", $stamp)); // Year
-
- // loop through all possible singledates for this regular time-entry
- do {
-
- // if dateExists is true, the singledate will not be created. Default is of course to create the singledate
- $dateExists = false;
-
- // do not create singledates if they are earlier than the semester start
- if ($end_time < $sem_begin) $dateExists = true;
-
- // do not create singledates, if they are earlier then the chosen start-week
- if ($start_woche > $week || (isset($end_woche) && $week > $end_woche)) $dateExists = true;
-
- // bi-weekly check
- if ($turnus > 0 && ($week - $start_woche) > 0 && (($week - $start_woche) % ($turnus + 1))) {
- $dateExists = true;
- }
-
- /*
- * We only create dates, which do not already exist, so we do not overwrite existing dates.
- *
- * Additionally, we delete singledates which are not needed any more (bi-weekly, changed start-week, etc.)
- */
- foreach ($existingSingleDates as $key => $val) {
- // take only the singledate into account, that maps the current timepoint
- if ($start_time > $startAfterTimeStamp && ($val->date == $start_time) && ($val->end_time == $end_time)) {
-
- // bi-weekly check
- if ($turnus > 0 && ($week - $start_woche) > 0 && (($week - $start_woche) % ($turnus + 1))) {
- $dates_to_delete[$key] = $val;
- unset($existingSingleDates[$key]);
- }
-
- // delete singledates if they are earlier than the chosen start-week
- if ($start_woche > $week || (isset($end_woche) && $week > $end_woche)) {
- $dates_to_delete[$key] = $val;
- unset($existingSingleDates[$key]);
- }
-
- $dateExists = true;
- if (isset($existingSingleDates[$key])) {
- $dates[$key] = $val;
- }
- }
- }
-
- if ($start_time < $startAfterTimeStamp) {
- $dateExists = true;
- }
-
- if (!$dateExists) {
-
- $termin = new SingleDate(['seminar_id' => $this->seminar_id]);
-
- $all_holiday = SemesterHoliday::getAll(); // fetch all Holidays
- foreach ($all_holiday as $val2) {
- if (($val2["beginn"] <= $start_time) && ($start_time <= $val2["ende"])) {
- $termin->setExTermin(true);
- }
- }
-
- //check for calculatable holidays
- if (!$termin->isExTermin()) {
- $holy_type = holiday($start_time);
- if ($holy_type["col"] == 3) {
- $termin->setExTermin(true);
- }
- }
-
- // fill the singleDate-Object with data
- $termin->setMetaDateID($metadate_id);
- $termin->setTime($start_time, $end_time);
- $termin->setDateType(1); //best guess
-
- $dates[$termin->getTerminID()] = $termin;
- }
-
- //inc the week, create timestamps for the next singledate
- $start_time = strtotime('+1 week', $start_time);
- $end_time = strtotime('+1 week', $end_time);
-
- $week++;
-
- } while ($end_time < $sem_end);
-
- return ['dates' => $dates, 'dates_to_delete' => $dates_to_delete];
- }
-}