Files
web/app/Core/IniFile.php
T
2026-01-01 21:10:46 +08:00

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
{
}
}