Split PHP
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
|
||||
require_once '/var/www/src/Config.php';
|
||||
require_once '/var/www/src/XmlTv.php';
|
||||
require_once '/var/www/src/Services/ChannelService.php';
|
||||
require_once '/var/www/src/Services/XmlTvCacheService.php';
|
||||
require_once '/var/www/src/Services/ProgrammeService.php';
|
||||
require_once '/var/www/src/View.php';
|
||||
|
||||
$config = new Config(
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
class ChannelService
|
||||
{
|
||||
public function synchronizeChannels(array $cachedChannels, Config $config): void
|
||||
{
|
||||
$storedChannels = $config->getChannels();
|
||||
|
||||
$maxNumber = 0;
|
||||
foreach ($storedChannels as $stored) {
|
||||
$maxNumber = max($maxNumber, (int)($stored['number'] ?? 0));
|
||||
}
|
||||
|
||||
foreach ($cachedChannels as $id => $channel) {
|
||||
if (!isset($storedChannels[$id])) {
|
||||
$maxNumber++;
|
||||
|
||||
$storedChannels[$id] = [
|
||||
'uuid' => bin2hex(random_bytes(16)),
|
||||
'name' => $channel['name'] ?? $id,
|
||||
'icon' => $channel['icon'] ?? '',
|
||||
'country' => '',
|
||||
'language' => '',
|
||||
'enabled' => true,
|
||||
'favorite' => false,
|
||||
'number' => $maxNumber,
|
||||
'group' => 'Unknown',
|
||||
];
|
||||
} else {
|
||||
$storedChannels[$id]['name'] = $channel['name'] ?? $storedChannels[$id]['name'];
|
||||
}
|
||||
}
|
||||
|
||||
uasort($storedChannels, function ($a, $b) {
|
||||
return ((int)($a['number'] ?? 999999)) <=> ((int)($b['number'] ?? 999999));
|
||||
});
|
||||
|
||||
$config->saveChannels($storedChannels);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
class ProgrammeService
|
||||
{
|
||||
private string $timezone;
|
||||
|
||||
public function __construct(string $timezone = 'Europe/Vienna')
|
||||
{
|
||||
$this->timezone = $timezone;
|
||||
}
|
||||
|
||||
public function load(array $data, ?Config $config = null): array
|
||||
{
|
||||
$channelConfig = $config ? $config->getChannels() : [];
|
||||
$channels = [];
|
||||
$programmes = [];
|
||||
|
||||
foreach ($data['channels'] ?? [] as $id => $channel) {
|
||||
$cfg = $channelConfig[$id] ?? [];
|
||||
|
||||
if (($cfg['enabled'] ?? true) !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$channels[$id] = [
|
||||
'id' => $id,
|
||||
'name' => $cfg['name'] ?? $channel['name'] ?? $id,
|
||||
'icon' => $cfg['icon'] ?? $channel['icon'] ?? '',
|
||||
'number' => (int)($cfg['number'] ?? 999999),
|
||||
'favorite' => (bool)($cfg['favorite'] ?? false),
|
||||
];
|
||||
|
||||
foreach ($channel['programmes'] ?? [] as $p) {
|
||||
$programmes[$id][] = [
|
||||
'title' => $p['title'] ?? '',
|
||||
'desc' => $p['description'] ?? '',
|
||||
'category' => $p['category'] ?? '',
|
||||
'start' => (new DateTime())->setTimestamp((int)$p['start'])->setTimezone(new DateTimeZone($this->timezone)),
|
||||
'stop' => (new DateTime())->setTimestamp((int)$p['stop'])->setTimezone(new DateTimeZone($this->timezone)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
uasort($channels, function ($a, $b) {
|
||||
return ($a['number'] ?? 999999) <=> ($b['number'] ?? 999999);
|
||||
});
|
||||
|
||||
return [$channels, $programmes];
|
||||
}
|
||||
|
||||
public function getCurrentProgrammes(array $data, ?Config $config = null): array
|
||||
{
|
||||
$channelConfig = $config ? $config->getChannels() : [];
|
||||
$now = time();
|
||||
$items = [];
|
||||
|
||||
foreach ($data['channels'] ?? [] as $id => $channel) {
|
||||
$cfg = $channelConfig[$id] ?? [];
|
||||
|
||||
if (($cfg['enabled'] ?? true) !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($channel['programmes'] ?? [] as $p) {
|
||||
$start = (int)($p['start'] ?? 0);
|
||||
$stop = (int)($p['stop'] ?? 0);
|
||||
|
||||
if ($now >= $start && $now < $stop) {
|
||||
$duration = max(1, $stop - $start);
|
||||
$elapsed = max(0, $now - $start);
|
||||
$percent = min(100, round(($elapsed / $duration) * 100));
|
||||
|
||||
$items[] = [
|
||||
'channel_id' => $id,
|
||||
'channel_name' => $cfg['name'] ?? $channel['name'] ?? $id,
|
||||
'channel_icon' => $cfg['icon'] ?? $channel['icon'] ?? '',
|
||||
'channel_number' => (int)($cfg['number'] ?? 999999),
|
||||
'favorite' => (bool)($cfg['favorite'] ?? false),
|
||||
'title' => $p['title'] ?? '',
|
||||
'subtitle' => $p['subtitle'] ?? '',
|
||||
'description' => $p['description'] ?? '',
|
||||
'category' => $p['category'] ?? '',
|
||||
'start' => $start,
|
||||
'stop' => $stop,
|
||||
'percent' => $percent,
|
||||
'remaining_minutes' => max(0, (int)ceil(($stop - $now) / 60)),
|
||||
];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usort($items, function ($a, $b) {
|
||||
return $a['channel_number'] <=> $b['channel_number'];
|
||||
});
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function getDayProgrammes(Config $config, array $data, string $date, ?string $channelId = null): array
|
||||
{
|
||||
$channelConfig = $config->getChannels();
|
||||
|
||||
$tz = new DateTimeZone($this->timezone);
|
||||
$dayStart = new DateTime($date . ' 00:00:00', $tz);
|
||||
$dayEnd = clone $dayStart;
|
||||
$dayEnd->modify('+1 day');
|
||||
|
||||
$startTs = $dayStart->getTimestamp();
|
||||
$endTs = $dayEnd->getTimestamp();
|
||||
|
||||
$items = [];
|
||||
|
||||
foreach ($data['channels'] ?? [] as $id => $channel) {
|
||||
if ($channelId !== null && $id !== $channelId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cfg = $channelConfig[$id] ?? [];
|
||||
|
||||
if (($cfg['enabled'] ?? true) !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$programmes = [];
|
||||
|
||||
foreach ($channel['programmes'] ?? [] as $p) {
|
||||
$start = (int)($p['start'] ?? 0);
|
||||
$stop = (int)($p['stop'] ?? 0);
|
||||
|
||||
if ($start < $endTs && $stop > $startTs) {
|
||||
$visibleStart = max($start, $startTs);
|
||||
$visibleStop = min($stop, $endTs);
|
||||
|
||||
$startDt = (new DateTime())->setTimestamp($visibleStart)->setTimezone($tz);
|
||||
$stopDt = (new DateTime())->setTimestamp($visibleStop)->setTimezone($tz);
|
||||
|
||||
$startMinute = ((int)$startDt->format('H') * 60) + (int)$startDt->format('i');
|
||||
$stopMinute = ((int)$stopDt->format('H') * 60) + (int)$stopDt->format('i');
|
||||
|
||||
if ($visibleStop >= $endTs) {
|
||||
$stopMinute = 1440;
|
||||
}
|
||||
|
||||
$durationMinutes = max(1, (int)(($visibleStop - $visibleStart) / 60));
|
||||
|
||||
$programmes[] = [
|
||||
'id' => md5($id . '|' . $start . '|' . $stop . '|' . ($p['title'] ?? '')),
|
||||
'title' => $p['title'] ?? '',
|
||||
'subtitle' => $p['subtitle'] ?? '',
|
||||
'description' => $p['description'] ?? '',
|
||||
'category' => $p['category'] ?? '',
|
||||
'start' => $start,
|
||||
'stop' => $stop,
|
||||
'visible_start' => $visibleStart,
|
||||
'visible_stop' => $visibleStop,
|
||||
'start_minute' => $startMinute,
|
||||
'stop_minute' => $stopMinute,
|
||||
'duration_minutes' => $durationMinutes,
|
||||
'is_current' => time() >= $start && time() < $stop,
|
||||
'is_past' => $stop < time(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$programmes) {
|
||||
continue;
|
||||
}
|
||||
|
||||
usort($programmes, function ($a, $b) {
|
||||
return $a['start'] <=> $b['start'];
|
||||
});
|
||||
|
||||
$items[] = [
|
||||
'channel_id' => $id,
|
||||
'channel_name' => $cfg['name'] ?? $channel['name'] ?? $id,
|
||||
'channel_icon' => $cfg['icon'] ?? $channel['icon'] ?? '',
|
||||
'channel_number' => (int)($cfg['number'] ?? 999999),
|
||||
'favorite' => (bool)($cfg['favorite'] ?? false),
|
||||
'programmes' => $programmes,
|
||||
];
|
||||
}
|
||||
|
||||
usort($items, function ($a, $b) {
|
||||
return $a['channel_number'] <=> $b['channel_number'];
|
||||
});
|
||||
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
class XmlTvCacheService
|
||||
{
|
||||
private string $file;
|
||||
private string $cacheFile;
|
||||
private string $timezone;
|
||||
|
||||
public function __construct(
|
||||
string $file,
|
||||
string $timezone = 'Europe/Vienna',
|
||||
string $cacheFile = '/var/www/cache/guide.json'
|
||||
) {
|
||||
$this->file = $file;
|
||||
$this->timezone = $timezone;
|
||||
$this->cacheFile = $cacheFile;
|
||||
}
|
||||
|
||||
public function getCachedData(): array
|
||||
{
|
||||
if (!file_exists($this->cacheFile)) {
|
||||
return $this->rebuildCache();
|
||||
}
|
||||
|
||||
$xmlMtime = file_exists($this->file) ? filemtime($this->file) : 0;
|
||||
$cacheMtime = filemtime($this->cacheFile);
|
||||
|
||||
if ($xmlMtime > $cacheMtime) {
|
||||
return $this->rebuildCache();
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents($this->cacheFile), true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
return $this->rebuildCache();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function rebuildCache(): array
|
||||
{
|
||||
$data = [
|
||||
'updated' => date('c'),
|
||||
'source' => $this->file,
|
||||
'channels' => [],
|
||||
];
|
||||
|
||||
if (!file_exists($this->file)) {
|
||||
$this->writeCache($data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
$xml = simplexml_load_file($this->file);
|
||||
|
||||
foreach ($xml->channel as $channel) {
|
||||
$id = (string)$channel['id'];
|
||||
|
||||
$data['channels'][$id] = [
|
||||
'id' => $id,
|
||||
'name' => (string)$channel->{'display-name'},
|
||||
'icon' => isset($channel->icon) ? (string)$channel->icon['src'] : '',
|
||||
'programmes' => [],
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($xml->programme as $programme) {
|
||||
$channelId = (string)$programme['channel'];
|
||||
|
||||
if (!isset($data['channels'][$channelId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$start = $this->parseTime((string)$programme['start']);
|
||||
$stop = $this->parseTime((string)$programme['stop']);
|
||||
|
||||
if (!$start || !$stop) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data['channels'][$channelId]['programmes'][] = [
|
||||
'title' => (string)$programme->title,
|
||||
'subtitle' => (string)$programme->{'sub-title'},
|
||||
'description' => (string)$programme->desc,
|
||||
'category' => (string)$programme->category,
|
||||
'start' => $start->getTimestamp(),
|
||||
'stop' => $stop->getTimestamp(),
|
||||
'duration' => $stop->getTimestamp() - $start->getTimestamp(),
|
||||
'year' => (string)$programme->date,
|
||||
'rating' => isset($programme->rating->value) ? (string)$programme->rating->value : '',
|
||||
'episode' => isset($programme->{'episode-num'}) ? (string)$programme->{'episode-num'} : '',
|
||||
'icon' => isset($programme->icon) ? (string)$programme->icon['src'] : '',
|
||||
'country' => (string)$programme->country,
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($data['channels'] as &$channel) {
|
||||
usort($channel['programmes'], function ($a, $b) {
|
||||
return $a['start'] <=> $b['start'];
|
||||
});
|
||||
}
|
||||
|
||||
unset($channel);
|
||||
|
||||
$this->writeCache($data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function writeCache(array $data): void
|
||||
{
|
||||
file_put_contents(
|
||||
$this->cacheFile,
|
||||
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
||||
);
|
||||
}
|
||||
|
||||
private function parseTime(string $value): ?DateTime
|
||||
{
|
||||
if (!preg_match('/^(\d{14})\s+([+-]\d{4})$/', trim($value), $m)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dt = DateTime::createFromFormat('YmdHis O', $m[1] . ' ' . $m[2]);
|
||||
|
||||
if (!$dt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dt->setTimezone(new DateTimeZone($this->timezone));
|
||||
return $dt;
|
||||
}
|
||||
}
|
||||
+14
-308
@@ -5,6 +5,8 @@ class XmlTv
|
||||
private string $file;
|
||||
private string $cacheFile;
|
||||
private string $timezone;
|
||||
private XmlTvCacheService $cacheService;
|
||||
private ProgrammeService $programmeService;
|
||||
|
||||
public function __construct(
|
||||
string $file,
|
||||
@@ -14,341 +16,45 @@ class XmlTv
|
||||
$this->file = $file;
|
||||
$this->timezone = $timezone;
|
||||
$this->cacheFile = $cacheFile;
|
||||
$this->cacheService = new XmlTvCacheService($file, $timezone, $cacheFile);
|
||||
$this->programmeService = new ProgrammeService($timezone);
|
||||
}
|
||||
|
||||
public function synchronizeChannels(Config $config): void
|
||||
{
|
||||
$service = new ChannelService();
|
||||
$data = $this->getCachedData();
|
||||
$storedChannels = $config->getChannels();
|
||||
|
||||
$maxNumber = 0;
|
||||
foreach ($storedChannels as $stored) {
|
||||
$maxNumber = max($maxNumber, (int)($stored['number'] ?? 0));
|
||||
}
|
||||
|
||||
foreach ($data['channels'] ?? [] as $id => $channel) {
|
||||
if (!isset($storedChannels[$id])) {
|
||||
$maxNumber++;
|
||||
|
||||
$storedChannels[$id] = [
|
||||
'uuid' => bin2hex(random_bytes(16)),
|
||||
'name' => $channel['name'] ?? $id,
|
||||
'icon' => $channel['icon'] ?? '',
|
||||
'country' => '',
|
||||
'language' => '',
|
||||
'enabled' => true,
|
||||
'favorite' => false,
|
||||
'number' => $maxNumber,
|
||||
'group' => 'Unknown',
|
||||
];
|
||||
} else {
|
||||
$storedChannels[$id]['name'] = $channel['name'] ?? $storedChannels[$id]['name'];
|
||||
}
|
||||
}
|
||||
|
||||
uasort($storedChannels, function ($a, $b) {
|
||||
return ((int)($a['number'] ?? 999999)) <=> ((int)($b['number'] ?? 999999));
|
||||
});
|
||||
|
||||
$config->saveChannels($storedChannels);
|
||||
$service->synchronizeChannels($data['channels'] ?? [], $config);
|
||||
}
|
||||
|
||||
public function load(?Config $config = null): array
|
||||
{
|
||||
$data = $this->getCachedData();
|
||||
|
||||
$channelConfig = $config ? $config->getChannels() : [];
|
||||
$channels = [];
|
||||
$programmes = [];
|
||||
|
||||
foreach ($data['channels'] ?? [] as $id => $channel) {
|
||||
$cfg = $channelConfig[$id] ?? [];
|
||||
|
||||
if (($cfg['enabled'] ?? true) !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$channels[$id] = [
|
||||
'id' => $id,
|
||||
'name' => $cfg['name'] ?? $channel['name'] ?? $id,
|
||||
'icon' => $cfg['icon'] ?? $channel['icon'] ?? '',
|
||||
'number' => (int)($cfg['number'] ?? 999999),
|
||||
'favorite' => (bool)($cfg['favorite'] ?? false),
|
||||
];
|
||||
|
||||
foreach ($channel['programmes'] ?? [] as $p) {
|
||||
$programmes[$id][] = [
|
||||
'title' => $p['title'] ?? '',
|
||||
'desc' => $p['description'] ?? '',
|
||||
'category' => $p['category'] ?? '',
|
||||
'start' => (new DateTime())->setTimestamp((int)$p['start'])->setTimezone(new DateTimeZone($this->timezone)),
|
||||
'stop' => (new DateTime())->setTimestamp((int)$p['stop'])->setTimezone(new DateTimeZone($this->timezone)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
uasort($channels, function ($a, $b) {
|
||||
return ($a['number'] ?? 999999) <=> ($b['number'] ?? 999999);
|
||||
});
|
||||
|
||||
return [$channels, $programmes];
|
||||
return $this->programmeService->load($this->getCachedData(), $config);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function rebuildCache(): array
|
||||
{
|
||||
$data = [
|
||||
'updated' => date('c'),
|
||||
'source' => $this->file,
|
||||
'channels' => [],
|
||||
];
|
||||
|
||||
if (!file_exists($this->file)) {
|
||||
$this->writeCache($data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
$xml = simplexml_load_file($this->file);
|
||||
|
||||
foreach ($xml->channel as $channel) {
|
||||
$id = (string)$channel['id'];
|
||||
|
||||
$data['channels'][$id] = [
|
||||
'id' => $id,
|
||||
'name' => (string)$channel->{'display-name'},
|
||||
'icon' => isset($channel->icon) ? (string)$channel->icon['src'] : '',
|
||||
'programmes' => [],
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($xml->programme as $programme) {
|
||||
$channelId = (string)$programme['channel'];
|
||||
|
||||
if (!isset($data['channels'][$channelId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$start = $this->parseTime((string)$programme['start']);
|
||||
$stop = $this->parseTime((string)$programme['stop']);
|
||||
|
||||
if (!$start || !$stop) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data['channels'][$channelId]['programmes'][] = [
|
||||
'title' => (string)$programme->title,
|
||||
'subtitle' => (string)$programme->{'sub-title'},
|
||||
'description' => (string)$programme->desc,
|
||||
'category' => (string)$programme->category,
|
||||
'start' => $start->getTimestamp(),
|
||||
'stop' => $stop->getTimestamp(),
|
||||
'duration' => $stop->getTimestamp() - $start->getTimestamp(),
|
||||
'year' => (string)$programme->date,
|
||||
'rating' => isset($programme->rating->value) ? (string)$programme->rating->value : '',
|
||||
'episode' => isset($programme->{'episode-num'}) ? (string)$programme->{'episode-num'} : '',
|
||||
'icon' => isset($programme->icon) ? (string)$programme->icon['src'] : '',
|
||||
'country' => (string)$programme->country,
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($data['channels'] as &$channel) {
|
||||
usort($channel['programmes'], function ($a, $b) {
|
||||
return $a['start'] <=> $b['start'];
|
||||
});
|
||||
}
|
||||
|
||||
unset($channel);
|
||||
|
||||
$this->writeCache($data);
|
||||
return $data;
|
||||
return $this->cacheService->rebuildCache();
|
||||
}
|
||||
|
||||
public function getCachedData(): array
|
||||
{
|
||||
if (!file_exists($this->cacheFile)) {
|
||||
return $this->rebuildCache();
|
||||
}
|
||||
|
||||
$xmlMtime = file_exists($this->file) ? filemtime($this->file) : 0;
|
||||
$cacheMtime = filemtime($this->cacheFile);
|
||||
|
||||
if ($xmlMtime > $cacheMtime) {
|
||||
return $this->rebuildCache();
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents($this->cacheFile), true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
return $this->rebuildCache();
|
||||
}
|
||||
|
||||
return $data;
|
||||
return $this->cacheService->getCachedData();
|
||||
}
|
||||
|
||||
public function getCurrentProgrammes(?Config $config = null): array
|
||||
{
|
||||
$data = $this->getCachedData();
|
||||
$channelConfig = $config ? $config->getChannels() : [];
|
||||
$now = time();
|
||||
$items = [];
|
||||
|
||||
foreach ($data['channels'] ?? [] as $id => $channel) {
|
||||
$cfg = $channelConfig[$id] ?? [];
|
||||
|
||||
if (($cfg['enabled'] ?? true) !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($channel['programmes'] ?? [] as $p) {
|
||||
$start = (int)($p['start'] ?? 0);
|
||||
$stop = (int)($p['stop'] ?? 0);
|
||||
|
||||
if ($now >= $start && $now < $stop) {
|
||||
$duration = max(1, $stop - $start);
|
||||
$elapsed = max(0, $now - $start);
|
||||
$percent = min(100, round(($elapsed / $duration) * 100));
|
||||
|
||||
$items[] = [
|
||||
'channel_id' => $id,
|
||||
'channel_name' => $cfg['name'] ?? $channel['name'] ?? $id,
|
||||
'channel_icon' => $cfg['icon'] ?? $channel['icon'] ?? '',
|
||||
'channel_number' => (int)($cfg['number'] ?? 999999),
|
||||
'favorite' => (bool)($cfg['favorite'] ?? false),
|
||||
'title' => $p['title'] ?? '',
|
||||
'subtitle' => $p['subtitle'] ?? '',
|
||||
'description' => $p['description'] ?? '',
|
||||
'category' => $p['category'] ?? '',
|
||||
'start' => $start,
|
||||
'stop' => $stop,
|
||||
'percent' => $percent,
|
||||
'remaining_minutes' => max(0, (int)ceil(($stop - $now) / 60)),
|
||||
];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usort($items, function ($a, $b) {
|
||||
return $a['channel_number'] <=> $b['channel_number'];
|
||||
});
|
||||
|
||||
return $items;
|
||||
return $this->programmeService->getCurrentProgrammes($this->getCachedData(), $config);
|
||||
}
|
||||
|
||||
private function writeCache(array $data): void
|
||||
{
|
||||
file_put_contents(
|
||||
$this->cacheFile,
|
||||
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
||||
);
|
||||
}
|
||||
|
||||
private function parseTime(string $value): ?DateTime
|
||||
{
|
||||
if (!preg_match('/^(\d{14})\s+([+-]\d{4})$/', trim($value), $m)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dt = DateTime::createFromFormat('YmdHis O', $m[1] . ' ' . $m[2]);
|
||||
|
||||
if (!$dt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dt->setTimezone(new DateTimeZone($this->timezone));
|
||||
return $dt;
|
||||
}
|
||||
|
||||
public function getDayProgrammes(Config $config, string $date, ?string $channelId = null): array
|
||||
{
|
||||
$data = $this->getCachedData();
|
||||
$channelConfig = $config->getChannels();
|
||||
|
||||
$tz = new DateTimeZone($this->timezone);
|
||||
$dayStart = new DateTime($date . ' 00:00:00', $tz);
|
||||
$dayEnd = clone $dayStart;
|
||||
$dayEnd->modify('+1 day');
|
||||
|
||||
$startTs = $dayStart->getTimestamp();
|
||||
$endTs = $dayEnd->getTimestamp();
|
||||
|
||||
$items = [];
|
||||
|
||||
foreach ($data['channels'] ?? [] as $id => $channel) {
|
||||
if ($channelId !== null && $id !== $channelId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cfg = $channelConfig[$id] ?? [];
|
||||
|
||||
if (($cfg['enabled'] ?? true) !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$programmes = [];
|
||||
|
||||
foreach ($channel['programmes'] ?? [] as $p) {
|
||||
$start = (int)($p['start'] ?? 0);
|
||||
$stop = (int)($p['stop'] ?? 0);
|
||||
|
||||
if ($start < $endTs && $stop > $startTs) {
|
||||
|
||||
$visibleStart = max($start, $startTs);
|
||||
$visibleStop = min($stop, $endTs);
|
||||
|
||||
$startDt = (new DateTime())->setTimestamp($visibleStart)->setTimezone($tz);
|
||||
$stopDt = (new DateTime())->setTimestamp($visibleStop)->setTimezone($tz);
|
||||
|
||||
$startMinute = ((int)$startDt->format('H') * 60) + (int)$startDt->format('i');
|
||||
$stopMinute = ((int)$stopDt->format('H') * 60) + (int)$stopDt->format('i');
|
||||
|
||||
if ($visibleStop >= $endTs) {
|
||||
$stopMinute = 1440;
|
||||
}
|
||||
|
||||
$durationMinutes = max(1, (int)(($visibleStop - $visibleStart) / 60));
|
||||
|
||||
$programmes[] = [
|
||||
'id' => md5($id . '|' . $start . '|' . $stop . '|' . ($p['title'] ?? '')),
|
||||
'title' => $p['title'] ?? '',
|
||||
'subtitle' => $p['subtitle'] ?? '',
|
||||
'description' => $p['description'] ?? '',
|
||||
'category' => $p['category'] ?? '',
|
||||
'start' => $start,
|
||||
'stop' => $stop,
|
||||
'visible_start' => $visibleStart,
|
||||
'visible_stop' => $visibleStop,
|
||||
'start_minute' => $startMinute,
|
||||
'stop_minute' => $stopMinute,
|
||||
'duration_minutes' => $durationMinutes,
|
||||
'is_current' => time() >= $start && time() < $stop,
|
||||
'is_past' => $stop < time(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$programmes) {
|
||||
continue;
|
||||
}
|
||||
|
||||
usort($programmes, function ($a, $b) {
|
||||
return $a['start'] <=> $b['start'];
|
||||
});
|
||||
|
||||
$items[] = [
|
||||
'channel_id' => $id,
|
||||
'channel_name' => $cfg['name'] ?? $channel['name'] ?? $id,
|
||||
'channel_icon' => $cfg['icon'] ?? $channel['icon'] ?? '',
|
||||
'channel_number' => (int)($cfg['number'] ?? 999999),
|
||||
'favorite' => (bool)($cfg['favorite'] ?? false),
|
||||
'programmes' => $programmes,
|
||||
];
|
||||
}
|
||||
|
||||
usort($items, function ($a, $b) {
|
||||
return $a['channel_number'] <=> $b['channel_number'];
|
||||
});
|
||||
|
||||
return $items;
|
||||
return $this->programmeService->getDayProgrammes($config, $this->getCachedData(), $date, $channelId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user