Files
TVGuide/app/src/XmlTv.php
T

135 lines
3.9 KiB
PHP

<?php
class XmlTv
{
private string $file;
private string $timezone;
public function __construct(string $file, string $timezone = 'Europe/Vienna')
{
$this->file = $file;
$this->timezone = $timezone;
}
public function load(?Config $config = null): array
{
$channels = [];
$programmes = [];
$channelConfig = $config ? $config->getChannels() : [];
if (!file_exists($this->file)) {
return [$channels, $programmes];
}
$xml = simplexml_load_file($this->file);
foreach ($xml->channel as $channel) {
$id = (string)$channel['id'];
$cfg = $channelConfig[$id] ?? [];
if (($cfg['enabled'] ?? true) !== true) {
continue;
}
$channels[$id] = [
'id' => $id,
'name' => $cfg['name'] ?? (string)$channel->{'display-name'},
'icon' => $cfg['icon'] ?? (isset($channel->icon) ? (string)$channel->icon['src'] : null),
'number' => (int)($cfg['number'] ?? 999999),
'favorite' => (bool)($cfg['favorite'] ?? false),
];
}
foreach ($xml->programme as $programme) {
$channelId = (string)$programme['channel'];
if (!isset($channels[$channelId])) {
continue;
}
$start = $this->parseTime((string)$programme['start']);
$stop = $this->parseTime((string)$programme['stop']);
if (!$start || !$stop) {
continue;
}
$programmes[$channelId][] = [
'title' => (string)$programme->title,
'desc' => (string)$programme->desc,
'category' => (string)$programme->category,
'start' => $start,
'stop' => $stop,
];
}
uasort($channels, function ($a, $b) {
return ($a['number'] ?? 999999) <=> ($b['number'] ?? 999999);
});
return [$channels, $programmes];
}
public function synchronizeChannels(Config $config): void
{
if (!file_exists($this->file)) {
return;
}
$xml = simplexml_load_file($this->file);
$storedChannels = $config->getChannels();
$maxNumber = 0;
foreach ($storedChannels as $stored) {
$maxNumber = max($maxNumber, (int)($stored['number'] ?? 0));
}
foreach ($xml->channel as $channel) {
$id = (string)$channel['id'];
$name = (string)$channel->{'display-name'};
$icon = isset($channel->icon) ? (string)$channel->icon['src'] : '';
if (!isset($storedChannels[$id])) {
$maxNumber++;
$storedChannels[$id] = [
'uuid' => bin2hex(random_bytes(16)),
'name' => $name,
'icon' => $icon,
'country' => '',
'language' => '',
'enabled' => true,
'favorite' => false,
'number' => $maxNumber,
'group' => 'Unknown',
];
} else {
$storedChannels[$id]['name'] = $name;
$storedChannels[$id]['icon'] = $icon;
}
}
uasort($storedChannels, function ($a, $b) {
return ((int)($a['number'] ?? 999999)) <=> ((int)($b['number'] ?? 999999));
});
$config->saveChannels($storedChannels);
}
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;
}
}