* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace mod_timetable; require_once('lesson.php'); defined('MOODLE_INTERNAL') || die(); const FLAG_Entfall = 0b0000000000000001; const FLAG_Betreuung = 0b0000000000000010; const FLAG_Sondereinsatz = 0b0000000000000100; const FLAG_Wegverlegung = 0b0000000000001000; const FLAG_Freisetzung = 0b0000000000010000; const FLAG_PlusVertreter = 0b0000000000100000; const FLAG_Teilverlegung = 0b0000000001000000; const FLAG_Hinverlegung = 0b0000000010000000; function lesson_in_lessons($obj, $array) { for($n=0;$nlessonid== $array[$n]->lessonid && $obj->teacher == $array[$n]->teacher && $obj->subject == $array[$n]->subject && $obj->class == $array[$n]->class && $obj->room == $array[$n]->room) return true; } return false; } function collapse_lessons($array) { $result = array(); foreach ($array as $lesson) { $integrated = false; foreach ($result as $rlesson) { if ($rlesson->integrate($lesson)) $integrated = true; } if (!$integrated) $result[] = $lesson; } return $result; } /** * Class timetable * * @package mod_timetable * @copyright 2020 Raphael Dannecker * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class timetable { /** @var array the data of timetable */ public $data; //public $lessons; //public $lessons_canceled; /** * Class constructor * * @param string $type The type of the timetable [class, room, teacher] * @param string $name Name of class or room or teacher */ public function __construct($type, $name) { $this->type = $type; $this->name = $name; $this->periodmax=0; $this->clear_data(); } public function clear_data() { $this->data = array(); $this->lessons = array(); $this->lessons_canceled = array(); $this->lessons_event = array(); for ($i=1; $i<=6; $i++) { $this->data[$i] = array(); $this->lessons[$i] = array(); $this->lessons_canceled[$i] = array(); $this->lessons_event[$i] = array(); for ($j=1; $j<=13; $j++) { $this->lessons[$i][$j] = array(); $this->lessons_canceled[$i][$j] = array(); $this->lessons_event[$i][$j] = array(); } } } /** * * @param int $week The week of timetable */ public function read_db($week) { global $USER, $DB, $CFG; $this->clear_data(); $this->numdayweek = 5 + get_config('timetable', 'saturday'); $this->week = $week; $this->monday = new \DateTime(); $this->monday->setISODate($this->monday->format("Y"), $week); $dayofweek = $this->monday->format('w'); if ($dayofweek > $this->numdayweek) { $this->monday->add(new \DateInterval("P".(8-$dayofweek)."D")); } elseif ($dayofweek < 1) { $this->monday->add(new \DateInterval("P1D")); } else { $this->monday->sub(new \DateInterval("P".($dayofweek-1)."D")); } $this->week = $this->monday->format("W"); $this->lastday = new \DateTime($this->monday->format('Y-m-d\TH:i:sP')); $this->lastday->add(new \DateInterval("P".($this->numdayweek-1)."D")); $sql = "$this->type = '$this->name' AND NOT lessonid=0 AND (mid(week, $this->week, 1) = '1')"; $result = $DB->get_records_select('timetable_lesson',$sql); foreach ($result as $lesson) { if (!lesson_in_lessons($lesson, $this->lessons[$lesson->day][$lesson->period])) $this->lessons[$lesson->day][$lesson->period][] = new lesson($lesson); // Todo: if ($this->periodmax < $lesson->period) $this->periodmax = $lesson->period; } $sql = "$this->type = '$this->name' AND lessonid=0 AND (mid(week, $this->week, 1) = '1')"; $result = $DB->get_records_select('timetable_lesson',$sql); foreach ($result as $lesson) { if (!lesson_in_lessons($lesson, $this->lessons_event[$lesson->day][$lesson->period])) $this->lessons_event[$lesson->day][$lesson->period][] = new lesson($lesson); // Todo: if ($this->periodmax < $lesson->period) $this->periodmax = $lesson->period; } $sql = "$this->type = '$this->name' and (mid(week, $this->week, 1) = 'x')"; $result = $DB->get_records_select('timetable_lesson',$sql); foreach ($result as $lesson) { if (!lesson_in_lessons($lesson, $this->lessons_canceled[$lesson->day][$lesson->period])) $this->lessons_canceled[$lesson->day][$lesson->period][] = new lesson($lesson); // Todo: if ($this->periodmax < $lesson->period) $this->periodmax = $lesson->period; } $day = new \DateTime($this->monday->format('Y-m-d\TH:i:sP')); for ($i=0; $i<$this->numdayweek; $i++) { $sql = "date = '".$day->format('Ymd')."' AND ({$this->type}a RLIKE '(^|~){$this->name}($|~)' OR {$this->type}b RLIKE '(^|~){$this->name}($|~)')"; $result = $DB->get_records_select('timetable_substitution',$sql); foreach ($result as $substitution) { foreach ($this->lessons[$i+1][$substitution->period] as $lesson) { $lesson->process_substitution($substitution); } foreach ($this->lessons_canceled[$i+1][$substitution->period] as $lesson) { $lesson->process_substitution($substitution); } foreach ($this->lessons_event[$i+1][$substitution->period] as $lesson) { $lesson->process_substitution($substitution); } } // Todo: if ($this->periodmax < $lesson->period) $this->periodmax = $lesson->period; $types = array('teacher'=>'L', 'class'=>'K', 'room'=>'R'); $sql = "startdate <= '".$day->format('Ymd')."' AND enddate >= '".$day->format('Ymd')."' AND type = '{$types[$this->type]}' AND name = '{$this->name}'"; $result = $DB->get_records_select('timetable_absence',$sql); foreach ($result as $absence) { for ($j=$absence->startperiod; $j<=$absence->endperiod; $j++) { foreach ($this->lessons_event[$i+1][$j] as $lesson) { $lesson->process_absence($absence); } } } $day->add(new \DateInterval("P1D")); } for ($i=0; $i<$this->numdayweek; $i++) { foreach($this->lessons[$i+1] as &$lessons) $lessons = collapse_lessons($lessons); foreach($this->lessons_canceled[$i+1] as &$lessons) $lessons = collapse_lessons($lessons); } if ($this->type == 'teacher') { if ($result = $DB->get_record("timetable_$this->type",[$this->type => $this->name])) { $this->description = "$result->surname, $result->firstname"; } } else { if ($result = $DB->get_record("timetable_$this->type",[$this->type => $this->name])) { $this->description = $result->description; } } $sql = "day = 1 ORDER BY period asc"; $this->times = $DB->get_records_select('timetable_time',$sql); } public function get_periodmax() { //$maxperiod = get_config('timetable', 'numperiod'); $maxperiod = 0; for ($i=0; $i<$this->numdayweek; $i++) { foreach($this->lessons[$i+1] as $period => $lessons) if ($period > $maxperiod && count($lessons)) $maxperiod = $period; foreach($this->lessons_canceled[$i+1] as $period => $lessons) if ($period > $maxperiod && count($lessons)) $maxperiod = $period; foreach($this->lessons_event[$i+1] as $period => $lessons) if ($period > $maxperiod && count($lessons)) $maxperiod = $period; } return $maxperiod; } public function prepare_output() { $resultdata = array(); $numperiod = max($this->get_periodmax(), get_config('timetable', 'numperiod')); $numdayweek = 5 + get_config('timetable', 'saturday'); if ($numdayweek == 6) $resultdata['saturday'] = 1; else $resultdata['saturday'] = 0; $resultdata['type'] = $this->type; $resultdata['viewteacher'] = ($this->type == 'teacher') ? "1" : "";; $resultdata['viewclass'] = ($this->type == 'class') ? "1" : "";; $resultdata['viewroom'] = ($this->type == 'room') ? "1" : "";; $resultdata['name'] = $this->name; $resultdata['description'] = $this->description; $resultdata['date'] = $this->monday->format('d.m') . " - " . $this->lastday->format('d.m'); $resultdata['week'] = $this->week; $resultdata['prevweek'] = $this->week-1; $resultdata['nextweek'] = $this->week+1; $resultdata['id'] = \substr(\md5(\rand()), 0, 7); $periods = array(); for ($period=0; $period<$numperiod; $period++) { $days = array(); for ($day=0; $day<$numdayweek; $day++) { $days[$day] = array(); $days[$day]['substitutionold'] = ""; $days[$day]['lessons'] = array(); foreach ($this->lessons_event[$day+1][$period+1] as $lesson) { $mylesson = array(); $mylesson['class'] = $lesson->class; $mylesson['teacher'] = $lesson->teacher; $mylesson['room'] = $lesson->room; $mylesson['subject'] = $lesson->subject; $mylesson['classa'] = $lesson->classa; $mylesson['teachera'] = $lesson->teachera; $mylesson['rooma'] = $lesson->rooma; $mylesson['subjecta'] = $lesson->subjecta; $mylesson['classb'] = property_exists($lesson,'classb') ? $lesson->classb : null; $mylesson['teacherb'] = property_exists($lesson,'teacherb') ? $lesson->teacherb : null; $mylesson['roomb'] = property_exists($lesson,'roomb') ? $lesson->roomb : null; $mylesson['subjectb'] = property_exists($lesson,'subjectb') ? $lesson->subjectb : null; $mylesson['subjectchanged'] = $lesson->subjectchanged; $mylesson['teacherchanged'] = $lesson->teacherchanged; $mylesson['classchanged'] = $lesson->classchanged; $mylesson['roomchanged'] = $lesson->roomchanged; $mylesson['substitution'] = $lesson->substitution; $mylesson['cancel'] = ""; $mylesson['cancel4me'] = ""; $mylesson['event'] = $lesson->reason ? $lesson->reason : "Event"; $mylesson['status'] = "1"; $mylesson['flag'] = "1"; $mylesson['text'] = $lesson->text; $mylesson['subtype'] = Array(); if ($lesson->type) { for ($i=0; $i<32; $i++) { if ($lesson->type & (1<<$i)) $mylesson['subtype'][] = $i+1; } } $days[$day]['substitutionold'] .= $lesson->text; $days[$day]['lessons'][] = $mylesson; } foreach ($this->lessons[$day+1][$period+1] as $lesson) { $mylesson = array(); $mylesson['class'] = $lesson->class; $mylesson['teacher'] = $lesson->teacher; $mylesson['room'] = $lesson->room; $mylesson['subject'] = $lesson->subject; $mylesson['classa'] = $lesson->classa; $mylesson['teachera'] = $lesson->teachera; $mylesson['rooma'] = $lesson->rooma; $mylesson['subjecta'] = $lesson->subjecta; $mylesson['classb'] = property_exists($lesson,'classb') ? $lesson->classb : null; $mylesson['teacherb'] = property_exists($lesson,'teacherb') ? $lesson->teacherb : null; $mylesson['roomb'] = property_exists($lesson,'roomb') ? $lesson->roomb : null; $mylesson['subjectb'] = property_exists($lesson,'subjectb') ? $lesson->subjectb : null; $mylesson['substitution'] = $lesson->substitution; $mylesson['subjectchanged'] = $lesson->subjectchanged; $mylesson['teacherchanged'] = $lesson->teacherchanged; $mylesson['classchanged'] = $lesson->classchanged; $mylesson['roomchanged'] = $lesson->roomchanged; $mylesson['cancel'] = ""; $mylesson['cancel4me'] = ""; $mylesson['event'] = ""; $mylesson['status'] = ""; $mylesson['flag'] = ""; $mylesson['text'] = $lesson->text; $mylesson['subtype'] = Array(); if ($lesson->type) { for ($i=0; $i<32; $i++) { if ($lesson->type & (1<<$i)) $mylesson['subtype'][] = $i+1; } } $days[$day]['substitutionold'] .= $lesson->text; $days[$day]['lessons'][] = $mylesson; } foreach ($this->lessons_canceled[$day+1][$period+1] as $lesson) { $mylesson = array(); $mylesson['class'] = $lesson->class; $mylesson['teacher'] = $lesson->teacher; $mylesson['room'] = $lesson->room; $mylesson['subject'] = $lesson->subject; $mylesson['classa'] = $lesson->classa; $mylesson['teachera'] = $lesson->teachera; $mylesson['rooma'] = $lesson->rooma; $mylesson['subjecta'] = $lesson->subjecta; $mylesson['classb'] = property_exists($lesson,'classb') ? $lesson->classb : null; $mylesson['teacherb'] = property_exists($lesson,'teacherb') ? $lesson->teacherb : null; $mylesson['roomb'] = property_exists($lesson,'roomb') ? $lesson->roomb : null; $mylesson['subjectb'] = property_exists($lesson,'subjectb') ? $lesson->subjectb : null; $mylesson['substitution'] = $lesson->substitution; $mylesson['cancel'] = "1"; $mylesson['cancel4me'] = ""; if (($lesson->teacherchanged && $this->type == 'teacher') || ($lesson->classchanged && $this->type == 'class') || ($lesson->roomchanged && $this->type == 'room')) $mylesson['cancel4me'] = "cancel4me"; $mylesson['subjectchanged'] = $lesson->subjectchanged; $mylesson['teacherchanged'] = $lesson->teacherchanged; $mylesson['classchanged'] = $lesson->classchanged; $mylesson['roomchanged'] = $lesson->roomchanged; #if ((property_exists($lesson,'teacherb') && $this->type == 'teacher') || # (property_exists($lesson,'classb') && $this->type == 'class') || # (property_exists($lesson,'roomb') && $this->type == 'room')) $mylesson['cancel4me'] = "cancel4me"; $mylesson['event'] = ""; $mylesson['status'] = "1"; $mylesson['flag'] = "1"; // status und flag werden vertauscht (im Template bzw. extern-lib.php $mylesson['text'] = $lesson->text; $mylesson['subtype'] = Array(); if ($lesson->type) { for ($i=0; $i<32; $i++) { if ($lesson->type & (1<<$i)) $mylesson['subtype'][] = $i+1; } } $days[$day]['substitutionold'] .= $lesson->text; $days[$day]['lessons'][] = $mylesson; } } $periods[$period] = array(); $periods[$period]['days'] = $days; $periods[$period]['number'] = $period+1; $periods[$period]['starttime'] = substr_replace($this->times[$period+1]->starttime, ":",-2,0); $periods[$period]['endtime'] = substr_replace($this->times[$period+1]->endtime, ":",-2,0); } $resultdata['periods'] = $periods; return $resultdata; } }