diff --git a/api/app/Http/Controllers/ProgramController.php b/api/app/Http/Controllers/ProgramController.php index 1c95611..5c8e46d 100644 --- a/api/app/Http/Controllers/ProgramController.php +++ b/api/app/Http/Controllers/ProgramController.php @@ -11,8 +11,8 @@ class ProgramController extends Controller { private static $SCHEDULE_SQL = <<= :startdate)) AND @@ -55,13 +55,15 @@ QUERY; $schedule = []; $START = 1; $END = -1; - $WEEK = new \DateInterval('P7D'); + $WEEK = new \DateInterval('P7D'); $DAY = new \DateInterval('P1D'); $WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" /* == 0 and 7 */]; $scheduleItems = app('db')->select(self::$SCHEDULE_SQL, ['enddate' => $end->format('Y-m-d'), 'startdate' => $start->format('Y-m-d')]); $scheduleChanges = new \SplPriorityQueue(); $active = []; foreach($scheduleItems as $item) { + if($item->startdate) { $item->startdate = new \DateTimeImmutable($item->startdate); } + if($item->enddate) { $item->enddate = (new \DateTimeImmutable($item->enddate))->add($DAY); } // Find the start time and end time of the last occurrence on or before the start time $itemStart = new \DateTime("last " . $WEEKDAYS[$item->startday] . " " . $start->format('Y-m-d') . " " . $item->starttime); $itemEnd = new \DateTime("last " . $WEEKDAYS[$item->endday] . " " . $start->format('Y-m-d') . " " . $item->endtime); @@ -97,76 +99,84 @@ QUERY; while(true) { $item = $scheduleChanges->extract(); - if($DEBUG) print "{$item[1]->format('d-m-Y H:i')}: {$item[2]->name} " . ($item[0] == $START ? "begint" : "eindigt") . "
"; - // If we passed the end time, we are (almost) done if($item[1] > $end) { if($DEBUG) { print "Reached end at {$item[1]->format('d-m-Y H:i')} ({$item[2]->name}).
"; } break; } - - $priority = $item[2]->priority; - if($item[0] == $START) { - if($active[$priority] != null) { - print( "Error:" . $item[2]->name . ' starts at ' . $item[1]->format('d-m-Y H:i') . ' but ' . $active[$priority]->name . ' is still active then.' ); - print "
"; var_dump($active); print "
"; - } - - // When a program starts, it becomes the active program in its layer - $active[$priority] = $item[2]; - // In addition, if it has higher priority than the currently active program, it replaces that. - if($activeProgram == null || $priority < $activeProgram->priority) { - if(($activeProgram != null) && ($item[1] > $start)) { - if($DEBUG) print "{$activeProgramStart->format('d-m-Y H:i')} -- {$item[1]->format('d-m-Y H:i')}: {$activeProgram->name} (reason: {$item[2]->name} starts).
"; - $this->addToSchedule($schedule, $activeProgramStart, $item[1], $activeProgram); - } - - $activeProgramStart = ($item[1] < $start) ? $start : clone $item[1]; - $activeProgram = $item[2]; - } - - } else if($item[0] == $END) { - if($active[$priority] == null) { - print( "Error:" . $item[2]->name . ' ends at ' . $item[1]->format('d-m-Y H:i') . ' but no program is active at that priority and timestamp.'); - print "
"; var_dump($active); print "
"; - } - - // When the program ends, its layer becomes inactive. - $active[$priority] = null; - - // In addition, when the ending program was the active program, we need to schedule it and find the new currently active program - if($activeProgram == $item[2]) { - if($DEBUG) print "{$activeProgramStart->format('d-m-Y H:i')} -- {$item[1]->format('d-m-Y H:i')}: {$activeProgram->name} (reason: {$item[2]->name} ends).
"; - $this->addToSchedule($schedule, $activeProgramStart, $item[1], $activeProgram); - - $activeProgram = null; - foreach($active as $newPriority => $newActive) { - if(($newActive != null) && ($activeProgram == null || $newPriority < $activeProgram->priority)) { - $activeProgram = $newActive; - } + // Only use this item if it is valid + if(($item[2]->startdate == null || $item[2]->startdate <= $activeProgramStart) && ($item[2]->enddate == null || $item[2]->enddate > $activeProgramStart)) + { + if($DEBUG) print "{$item[1]->format('d-m-Y H:i')}: {$item[2]->name} {$item[2]->suffix} " . ($item[0] == $START ? "begint" : "eindigt") . "
"; + + $priority = $item[2]->priority; + if($item[0] == $START) { + if($active[$priority] != null) { + print( "Error:" . $item[2]->name . ' starts at ' . $item[1]->format('d-m-Y H:i') . ' but ' . $active[$priority]->name . ' is still active then.' ); + print "
"; var_dump($active); print "
"; } - - if($activeProgram != null) { - $activeProgramStart = clone $item[1]; + + // When a program starts, it becomes the active program in its layer + $active[$priority] = $item[2]; + + // In addition, if it has higher priority than the currently active program, it replaces that. + if($activeProgram == null || $priority < $activeProgram->priority) { + if(($activeProgram != null) && ($item[1] > $start)) { + if($DEBUG) print "{$activeProgramStart->format('d-m-Y H:i')} -- {$item[1]->format('d-m-Y H:i')}: {$activeProgram->name} (reason: {$item[2]->name} starts).
"; + $this->addToSchedule($schedule, $activeProgramStart, $item[1], $activeProgram); + } + + $activeProgramStart = ($item[1] < $start) ? $start : clone $item[1]; + $activeProgram = $item[2]; } - - if($DEBUG) print " New active program is " . ($activeProgram ? $activeProgram->name : "---") . "
"; + + } else if($item[0] == $END) { + if($active[$priority] == null) { + print( "Error:" . $item[2]->name . ' ends at ' . $item[1]->format('d-m-Y H:i') . ' but no program is active at that priority and timestamp.'); + print "
"; var_dump($active); print "
"; + } + + // When the program ends, its layer becomes inactive. + $active[$priority] = null; + + // In addition, when the ending program was the active program, we need to schedule it and find the new currently active program + if($activeProgram == $item[2]) { + if($DEBUG) print "{$activeProgramStart->format('d-m-Y H:i')} -- {$item[1]->format('d-m-Y H:i')}: {$activeProgram->name} (reason: {$item[2]->name} ends).
"; + $this->addToSchedule($schedule, $activeProgramStart, $item[1], $activeProgram); + + $activeProgram = null; + foreach($active as $newPriority => $newActive) { + if(($newActive != null) && ($activeProgram == null || $newPriority < $activeProgram->priority)) { + $activeProgram = $newActive; + } + } + + if($activeProgram != null) { + $activeProgramStart = clone $item[1]; + } + + if($DEBUG) print " New active program is " . ($activeProgram ? $activeProgram->name : "---") . "
"; + } + } else { + return response()->abort(500, "Invalid item type: expected START ($START) or END ($END), but got {$item[0]}."); } - } else { - return response()->abort(500, "Invalid item type: expected START ($START) or END ($END), but got {$item[0]}."); + } else if($DEBUG) { + print "Skipped {$item[2]->name} {$item[2]->suffix} on {$item[1]->format('d-m-Y H:i')} " + . " because startdate is " . ($item[2]->startdate == null ? "[null]" : $item[2]->startdate->format('d-m-Y H:i')) + . " and end date is " . ($item[2]->enddate == null ? "[null]" : $item[2]->enddate->format('d-m-Y H:i')) . "
"; } // The item will recur in a week $item[1]->add($WEEK); $scheduleChanges->insert($item, [-$item[1]->getTimestamp(), -$item[0]]); } - + if(($activeProgram != null) && ($activeProgramStart != $end)) { if($DEBUG) print "{$activeProgramStart->format('d-m-Y H:i')} -- {$end->format('d-m-Y H:i')}: {$activeProgram->name} (reason: schedule finished).
"; $this->addToSchedule($schedule, $activeProgramStart, $end, $activeProgram); } - + return ['startdate' => $start, 'enddate' => $end, 'schedule' => $schedule]; } @@ -204,15 +214,15 @@ QUERY; } $now = new \DateTimeImmutable('now'); - $past = $this->createSchedule($now->add(\DateInterval::createFromDateString('-3 weeks')), $now->add(\DateInterval::createFromDateString('+1 week'))); + $past = $this->createSchedule($now->add(\DateInterval::createFromDateString('-2 weeks')), $now->add(\DateInterval::createFromDateString('+1 week'))); $program->recent = []; $program->next = []; - foreach($past['schedule'] as $item) { + foreach(array_reverse($past['schedule']) as $item) { if($item['program']->id == $id) { - if(($item['start'] > $now) && !($program->next)) { - $program->next = $item['start']; - } else if(($item['start'] < $now) && count($program->recent) < 2) { - $program->recent[] = $item['start']; + if($item['start'] > $now) { + array_unshift($program->next, ['start' => $item['start'], 'name' => $item['program']->name, 'nonstop' => $item['program']->nonstop, 'rerun' => $item['program']->rerun]); + } else if($item['program']->priority < 3 && $item['start'] < $now) { + $program->recent[] = ['start' => $item['start'], 'name' => $item['program']->name, 'nonstop' => $item['program']->nonstop, 'rerun' => $item['program']->rerun]; } } } diff --git a/common/classes/Program.php b/common/classes/Program.php index 5c2b8da..2ad8c89 100644 --- a/common/classes/Program.php +++ b/common/classes/Program.php @@ -7,6 +7,8 @@ class Program extends Model { public $name; public $description; public $email; + public $nonstop; + public $rerun; public $priority; public $hosts; @@ -20,10 +22,14 @@ class Program extends Model { $this->name .= ' ' . $data->suffix; } - parent::ConvertToDateTime($this->next); if($this->recent && $this->recent) { foreach($this->recent as &$recent) { - parent::ConvertToDateTime($recent); + parent::ConvertToDateTime($recent->start); + } + } + if($this->next && $this->next) { + foreach($this->next as &$next) { + parent::ConvertToDateTime($next->start); } } @@ -31,6 +37,11 @@ class Program extends Model { $this->email = substr($data->email, 0, $mailComma); } + if(isset($data->state)) { + $this->nonstop = $data->state == 0; + $this->rerun = $data->state == 3; + } + $this->url = "/{$this->id}/" . parent::url_slug($this->name); }