262 lines
12 KiB
PHP
262 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', true);
|
|
|
|
class ProgramController extends Controller
|
|
{
|
|
private static $SCHEDULE_SQL = <<<QUERY
|
|
SELECT `schedule`.`id` AS `scheduleid`, `programs`.`id` AS `id`, `programs`.`longname` AS `name`, `programs`.`description` AS `description`, `programs`.`email`, `schedule`.`priority`,
|
|
`schedule`.`startdate`, `schedule`.`startday`, `schedule`.`starttime`,
|
|
`schedule`.`enddate`, `schedule`.`endday`, `schedule`.`endtime`, `schedule`.`shortnamesuffix` AS `suffix`
|
|
FROM `programs_schedule` AS `schedule` LEFT JOIN `programs` ON `schedule`.`program` = `programs`.`id`
|
|
WHERE ((`schedule`.`startdate` IS NULL) OR (`schedule`.`startdate` < :enddate)) AND
|
|
((`schedule`.`enddate` IS NULL) OR (`schedule`.`enddate` >= :startdate)) AND
|
|
`schedule`.`active` = 1 AND
|
|
`schedule`.`final` = 1
|
|
ORDER BY `schedule`.`priority` DESC, MOD(`startday` + 6, 7) + 1, `schedule`.`starttime` ASC
|
|
QUERY;
|
|
|
|
/**
|
|
* Create a new controller instance.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __construct()
|
|
{
|
|
//
|
|
}
|
|
|
|
/**
|
|
* Details over een specifiek programma, inclusief schema en podcasts
|
|
*/
|
|
public function details($id) {
|
|
$programs = app('db')->select("SELECT `id`, `longname` AS `name`, `description`, `email` FROM `programs` WHERE `id` = :id", ['id' => (int)$id]);
|
|
if(count($programs) != 1) {
|
|
return abort(404);
|
|
}
|
|
|
|
$program = $programs[0];
|
|
|
|
$hosts = app('db')->select("SELECT `programs_users`.`user` AS `id`, `medewerkers`.`adressering` AS `name`, `user_emailaddresses`.`email` AS `email`
|
|
FROM `programs_users`
|
|
LEFT JOIN `users` ON `programs_users`.`user` = `users`.`id`
|
|
LEFT JOIN `medewerkers` ON `users`.`medewerkersid` = `medewerkers`.`id`
|
|
LEFT JOIN `user_emailaddresses` ON `user_emailaddresses`.`user` = `users`.`id`
|
|
WHERE `programs_users`.`program` = :program
|
|
AND `user_emailaddresses`.`preference` = 0
|
|
AND `programs_users`.`active` = 1
|
|
ORDER BY `name`", ['program' => $program->id]);
|
|
foreach($hosts as $host) {
|
|
$program->hosts[] = new \Model\ProgramHost($host);
|
|
}
|
|
|
|
$schedule = app('db')->select(<<<QUERY
|
|
SELECT `schedule`.`startdate`, `schedule`.`startday`, `schedule`.`starttime`, `schedule`.`enddate`, `schedule`.`endday`, `schedule`.`endtime`, `schedule`.`shortnamesuffix` AS `suffix`, `schedule`.`priority`
|
|
FROM `programs_schedule` AS `schedule`
|
|
WHERE (schedule.`program` = :program) AND (`schedule`.`active` = 1) AND (`schedule`.`final` = 1)
|
|
ORDER BY `schedule`.`priority` DESC, MOD(`startday` + 6, 7) + 1, `schedule`.`starttime` ASC
|
|
QUERY
|
|
, ['program' => $program->id] );
|
|
$recentSchedule = $this->recent($schedule);
|
|
$program->schedule = $recentSchedule;
|
|
|
|
return response()->json($program);
|
|
}
|
|
|
|
private function recent($schedule) {
|
|
$now = new \DateTimeImmutable();
|
|
$ONE_DAY = \DateInterval::createFromDateString('1 day');
|
|
$ONE_WEEK = \DateInterval::createFromDateString('1 week');
|
|
$recent = [];
|
|
$next = [];
|
|
|
|
// Vind voor elke regel in de uitzendmomenten de eerstvolgende en twee meest recente.
|
|
$isCurrent = false;
|
|
foreach($schedule as $broadcast) {
|
|
$broadcast->startdate = ($broadcast->startdate == null) ? null : new \DateTimeImmutable($broadcast->startdate);
|
|
$broadcast->enddate = ($broadcast->enddate == null) ? null : new \DateTimeImmutable($broadcast->enddate);
|
|
$startTijd = new \DateTimeImmutable($broadcast->starttime);
|
|
$endDate = ($broadcast->enddate == null) ? $now : $broadcast->enddate;
|
|
$endDate = $endDate->setTime($startTijd->format('H'), $startTijd->format('i'), $startTijd->format('s'));
|
|
$endDateWeekday = $endDate->format('N');
|
|
|
|
// Zoek de laatste uitzending voor de einddatum (of voor het huidige tijdstip), op de juiste weekdag
|
|
while($endDateWeekday != $broadcast->startday) {
|
|
$endDate = $endDate->sub($ONE_DAY);
|
|
if(--$endDateWeekday < 0) { $endDateWeekday += 7; }
|
|
}
|
|
|
|
$eindTijd = new \DateTimeImmutable($broadcast->endtime);
|
|
$endOfBroadcast = $endDate->setTime($eindTijd->format('H'), $eindTijd->format('i'), $eindTijd->format('s'));
|
|
if($endOfBroadcast < $endDate) { $endOfBroadcast = $endOfBroadcast->add($ONE_DAY); }
|
|
|
|
if($isInProgress = (($endDate <= $now) && ($endOfBroadcast > $now))) {
|
|
$isCurrent = true;
|
|
}
|
|
|
|
// Als de uitzending niet al afgelopen is, telt hij als volgende.
|
|
// Dit gebeurt als de uitzending later vandaag is of nu loopt.
|
|
if($endOfBroadcast >= $now) {
|
|
$endDate = $endDate->sub($ONE_WEEK);
|
|
$endOfBroadcast = $endOfBroadcast->sub($ONE_WEEK);
|
|
}
|
|
|
|
if((($broadcast->startdate == null) || ($broadcast->startdate <= $endDate))
|
|
&& (($broadcast->enddate == null) || ($broadcast->enddate >= $endDate->setTime(0,0,0)))) {
|
|
$recent[] = ['time' => $endDate, 'suffix' => $broadcast->suffix, 'isSpecial' => ($broadcast->priority < 2)];
|
|
}
|
|
|
|
|
|
$previous = $endDate->sub($ONE_WEEK);
|
|
if((($broadcast->startdate == null) || ($broadcast->startdate <= $previous))
|
|
&& (($broadcast->enddate == null) || ($broadcast->enddate >= $previous->setTime(0,0,0)))) {
|
|
$recent[] = ['time' => $previous, 'suffix' => $broadcast->suffix, 'isSpecial' => ($broadcast->priority < 2)];
|
|
}
|
|
|
|
$following = $endDate->add($ONE_WEEK);
|
|
if(($broadcast->enddate == null) || ($broadcast->enddate->setTime(23,59,59) > $following)) {
|
|
if($following < $now) {
|
|
$isCurrent = true;
|
|
}
|
|
|
|
$next[] = ['time' => $following, 'suffix' => $broadcast->suffix, 'isSpecial' => ($broadcast->priority < 2)];
|
|
}
|
|
}
|
|
|
|
sort($next);
|
|
rsort($recent);
|
|
return ['recent' => array_reverse(array_splice($recent, 0, 2)), 'next' => count($next) ? $next[0] : null, 'iscurrent' => $isCurrent];
|
|
}
|
|
|
|
/**
|
|
* Programmas nu en straks (24 uur vooruit)
|
|
*/
|
|
public function comingup() {
|
|
$start = new \DateTimeImmutable('now');
|
|
$einde = $start->add(\DateInterval::createFromDateString('today + 48 hours'));
|
|
$schema = $this->createSchedule($start, $einde);
|
|
|
|
return response()->json($schema);
|
|
}
|
|
|
|
/**
|
|
* Programmaschema per week
|
|
*/
|
|
public function schedule(Request $request, $shiftWeeks = null) {
|
|
$start = (new \DateTimeImmutable('Monday this week'))->add(\DateInterval::createFromDateString((int)$shiftWeeks . ' weeks'));
|
|
$einde = $start->add(\DateInterval::createFromDateString('1 week'));
|
|
|
|
return response()->json($this->createSchedule($start, $einde));
|
|
}
|
|
|
|
private function createSchedule($start, $einde) {
|
|
if(!defined('PROGRAMMA_START')) {
|
|
define('PROGRAMMA_START', 1);
|
|
define('PROGRAMMA_EINDE', -1);
|
|
|
|
define('PW_TIJDSTIP', 0);
|
|
define('PW_TYPE', 1);
|
|
define('PW_PROGRAMMA', 2);
|
|
}
|
|
|
|
$oneWeek = \DateInterval::createFromDateString('1 week');
|
|
|
|
$programmas = app('db')->select(self::$SCHEDULE_SQL,
|
|
['enddate' => $einde->format('Y-m-d'), 'startdate' => $start->format('Y-m-d')]);
|
|
$programmaInfo = [];
|
|
|
|
// Maak een lijstje van alle start en eindtijden en welk programma dan begint/eindigt
|
|
$startEinde = [];
|
|
$startMaandag = $start->modify('Monday this week');
|
|
foreach($programmas as $programma) {
|
|
if($programma->suffix) $programma->name .= ' ' . $programma->suffix;
|
|
$programmaInfo[$programma->scheduleid] = new \Model\Program($programma);
|
|
|
|
$programmaStart = $startMaandag->add(\DateInterval::createFromDateString(($programma->startday - 1) % 7 . ' days'));
|
|
$programmaEinde = $startMaandag->add(\DateInterval::createFromDateString(($programma->endday - 1) % 7 . ' days'));
|
|
|
|
$startTijd = new \DateTime($programma->starttime);
|
|
$eindTijd = new \DateTime($programma->endtime);
|
|
|
|
$programmaStart = $programmaStart->setTime($startTijd->format('H'), $startTijd->format('i'), $startTijd->format('s'));
|
|
$programmaEinde = $programmaEinde->setTime($eindTijd->format('H'), $eindTijd->format('i'), $eindTijd->format('s'));
|
|
|
|
if($programmaEinde <= $programmaStart) {
|
|
$programmaEinde = $programmaEinde->add($oneWeek);
|
|
}
|
|
|
|
if($programmaEinde < $start) {
|
|
$programmaStart = $programmaStart->add($oneWeek);
|
|
$programmaEinde = $programmaEinde->add($oneWeek);
|
|
}
|
|
|
|
while($programmaStart < $einde) {
|
|
if((($programma->startdate == null) || ($programmaStart >= new \DateTime($programma->startdate)))
|
|
&& (($programma->enddate == null) || ($programmaStart <= (new \DateTimeImmutable($programma->enddate))->setTime(23,59,59)))
|
|
&& (($programmaEinde >= $start) && ($programmaStart <= $einde)))
|
|
{
|
|
$startEinde[] = [$programmaStart, PROGRAMMA_START, $programma->scheduleid];
|
|
$startEinde[] = [$programmaEinde, PROGRAMMA_EINDE, $programma->scheduleid];
|
|
}
|
|
|
|
$programmaStart = $programmaStart->add($oneWeek);
|
|
$programmaEinde = $programmaEinde->add($oneWeek);
|
|
}
|
|
}
|
|
|
|
array_multisort($startEinde);
|
|
|
|
$actieveProgrammas = [null, null, null, null];
|
|
$schema = [];
|
|
$fouten = [];
|
|
$index = -1;
|
|
foreach($startEinde as $programmaWissel) {
|
|
$scheduleId = $programmaWissel[PW_PROGRAMMA];
|
|
$programma = $programmaInfo[$scheduleId];
|
|
$tijdstip = $programmaWissel[PW_TIJDSTIP];
|
|
if($programmaWissel[PW_TIJDSTIP] < $start) { $tijdstip = $start; }
|
|
if($programmaWissel[PW_TIJDSTIP] > $einde) { $tijdstip = $einde; }
|
|
if($tijdstip == $einde) { break; }
|
|
|
|
if($programmaWissel[PW_TYPE] == PROGRAMMA_START) {
|
|
if($actieveProgrammas[$programma->priority] != null) {
|
|
$fouten[] = [$tijdstip, "Begin van {$programma->name} maar {$actieveProgrammas[$programma->priority]->name} is nog actief."];
|
|
}
|
|
|
|
$actieveProgrammas[$programma->priority] = $scheduleId;
|
|
for($prio = $programma->priority; $prio >= 0; --$prio) {
|
|
if($actieveProgrammas[$prio] != null) {
|
|
if(($index == -1) || ($schema[$index]['starttime'] != $tijdstip)) { $index++; }
|
|
$schema[$index] = ['starttime' => $tijdstip, 'endtime' => null, 'program' => $programmaInfo[$actieveProgrammas[$prio]]];
|
|
break;
|
|
}
|
|
}
|
|
} else /*if($programmaWissel[PW_TYPE] == PROGRAMMA_EINDE)*/ {
|
|
$actieveProgrammas[$programma->priority] = null;
|
|
if(($index == -1) || ($schema[$index]['program'] != null)) { $index++; }
|
|
$schema[$index] = ['starttime' => $tijdstip, 'program' => null];
|
|
for($prio = $programma->priority; $prio < count($actieveProgrammas); ++$prio) {
|
|
if($actieveProgrammas[$prio] != null) {
|
|
$schema[$index] = ['starttime' => $tijdstip, 'endtime' => null, 'program' => $programmaInfo[$actieveProgrammas[$prio]]];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for($i = 1; $i <= count($schema); $i++) {
|
|
$eindTijd = ($i == count($schema)) ? $einde : $schema[$i]['starttime'];
|
|
$schema[$i - 1]['endtime'] = $eindTijd;
|
|
//$programma = $schema[$i-1]['program'];
|
|
//print $schema[$i-1]['starttime']->format('D d-m-Y, H:i:s') . " - " . $eindTijd->format('D d-m-Y, H:i:s') . ": " . ($programma != null ? $programma->name : "NULL") . "\n";
|
|
}
|
|
|
|
return ['startdate' => $start, 'enddate' => $einde, 'schedule' => $schema, 'errors' => $fouten];
|
|
}
|
|
}
|