134 lines
3.3 KiB
PHP
134 lines
3.3 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Copyright (c) 2025, Антон Аксенов
|
|
* This file is part of m3u.su project
|
|
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Core;
|
|
|
|
use App\Exceptions\FileReadException;
|
|
use App\Exceptions\IniParsingException;
|
|
use App\Exceptions\PlaylistNotFoundException;
|
|
use ArrayAccess;
|
|
use Override;
|
|
use Throwable;
|
|
|
|
/**
|
|
* Класс для работы со списком плейлистов
|
|
*
|
|
* @phpstan-type TIniFile array{}|TPlaylistDefinition[]
|
|
* @phpstan-type TPlaylistDefinition array{name?: string, desc?: string, url: string, src?: string}
|
|
* @template TKey as non-falsy-string
|
|
* @template TValue as TPlaylistDefinition
|
|
* @implements ArrayAccess<TKey, TValue>
|
|
*/
|
|
class IniFile implements ArrayAccess
|
|
{
|
|
/**
|
|
* @var array{}|array<TKey, TValue> Коллекция подгруженных плейлистов
|
|
*/
|
|
protected array $playlists;
|
|
|
|
/**
|
|
* @var positive-int Дата последнего обновления списка
|
|
*/
|
|
protected int $updatedAt;
|
|
|
|
/**
|
|
* Загружает ini-файл и инициализирует плейлисты
|
|
*
|
|
* @param string $filepath
|
|
* @throws FileReadException
|
|
* @throws IniParsingException
|
|
*/
|
|
public function __construct(
|
|
protected string $filepath,
|
|
) {
|
|
try {
|
|
$content = file_get_contents($this->filepath);
|
|
} catch (Throwable) {
|
|
$content = false;
|
|
}
|
|
|
|
$content === false && throw new FileReadException($this->filepath);
|
|
|
|
$parsed = parse_ini_string($content, true);
|
|
$parsed === false && throw new IniParsingException($this->filepath);
|
|
$this->playlists = $parsed;
|
|
|
|
/** @var positive-int $timestamp */
|
|
$timestamp = is_readable($this->filepath) ? filemtime($this->filepath) : time();
|
|
$this->updatedAt = $timestamp;
|
|
}
|
|
|
|
/**
|
|
* Возвращает определение плейлиста по его коду
|
|
*
|
|
* @param TKey $code
|
|
* @return TValue
|
|
* @throws PlaylistNotFoundException
|
|
*/
|
|
public function playlist(string $code): array
|
|
{
|
|
return $this->playlists[$code] ?? throw new PlaylistNotFoundException($code);
|
|
}
|
|
|
|
/**
|
|
* Возвращает дату обновления ini-файла
|
|
*
|
|
* @return string
|
|
*/
|
|
public function updatedAt(): string
|
|
{
|
|
return date('d.m.Y h:i', $this->updatedAt);
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
* @param non-falsy-string $offset
|
|
* @return bool
|
|
*/
|
|
#[Override]
|
|
public function offsetExists(mixed $offset): bool
|
|
{
|
|
return isset($this->playlists[$offset]);
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
* @param TKey $offset
|
|
* @return TPlaylistDefinition
|
|
* @throws PlaylistNotFoundException
|
|
*/
|
|
#[Override]
|
|
public function offsetGet(mixed $offset): array
|
|
{
|
|
return $this->playlist($offset);
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
* @param TKey $offset
|
|
* @param TValue $value
|
|
* @return void
|
|
*/
|
|
#[Override]
|
|
public function offsetSet(mixed $offset, mixed $value): void
|
|
{
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
* @param non-falsy-string $offset
|
|
* @return void
|
|
*/
|
|
#[Override]
|
|
public function offsetUnset(mixed $offset): void
|
|
{
|
|
}
|
|
}
|