This repository has been archived on 2025-05-19. You can view files and clone it, but cannot push or open issues or pull requests.
Files
old/src/app/Core/ChannelLogo.php

198 lines
4.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace App\Core;
class ChannelLogo implements \Stringable
{
/**
* @var string Валидированная ссылка на изображение
*/
public readonly string $url;
/**
* @var string|null Хэш от ссылки на изображение
*/
public readonly ?string $hash;
/**
* @var string|null Путь к файлу изображению на диске
*/
protected ?string $path;
/**
* @var string|null MIME-тип изображения
*/
protected ?string $mimeType = null;
/**
* @var false|string|null Сырое изображение:
* null -- не загружалось;
* false -- ошибка загрузки;
* string -- бинарные данные.
*/
protected false|string|null $rawData = null;
/**
* Конструктор
*
* @param string $url Внешняя ссылка на изображение
*/
public function __construct(string $url)
{
$url = $this->prepareUrl($url);
if (is_string($url)) {
$this->url = $url;
$this->hash = md5($url);
$this->path = cache_path("tv-logos/$this->hash");
}
}
/**
* Валидирует и очищает ссылку на изображение
*
* @param string $url
* @return false|string
*/
protected function prepareUrl(string $url): false|string
{
$url = filter_var(trim($url), FILTER_VALIDATE_URL);
if ($url === false) {
return false;
}
$parts = parse_url($url);
if (!is_array($parts)) {
return false;
}
return $parts['scheme'] . '://' . $parts['host'] . $parts['path'];
}
/**
* Загружает сырое изображение по ссылке и определяет его MIME-тип
*
* @return bool
*/
public function fetch(): bool
{
$this->rawData = @file_get_contents($this->url);
$isFetched = is_string($this->rawData);
if (!$isFetched) {
return false;
}
$this->mimeType = $this->mimeType();
return true;
}
/**
* Сохраняет сырое изображение в кэш
*
* @return bool
*/
public function store(): bool
{
return is_string($this->rawData)
&& $this->prepareCacheDir()
&& @file_put_contents($this->path, $this->rawData);
}
/**
* Считывает изображение из кэша
*
* @return bool
*/
public function readFile(): bool
{
if (!file_exists($this->path)) {
return false;
}
$this->rawData = @file_get_contents($this->path);
return is_string($this->rawData);
}
/**
* Считывает дефолтный эскиз вместо логотипа
*
* @return bool
*/
public function setDefault(): bool
{
$this->path = root_path('public/no-tvg-logo.png');
return$this->readFile();
}
/**
* Возвращает base64-кодированное изображение
*
* @return string|null
*/
public function asBase64(): ?string
{
if (!is_string($this->rawData)) {
return null;
}
return "data:$this->mimeType;base64," . base64_encode($this->rawData);
}
/**
* Возвращает сырое изображение
*
* @return false|string|null
*/
public function raw(): false|string|null
{
return $this->rawData;
}
/**
* Проверяет готовность директории кэша изображений, создавая её при необходимости
*
* @return bool
*/
public function prepareCacheDir(): bool
{
$cacheFileDir = cache_path('tv-logos');
return is_dir($cacheFileDir)
|| @mkdir($cacheFileDir, 0775, true);
}
/**
* Возвращает MIME-тип сырого изображения
*
* @return string|null
*/
public function mimeType(): ?string
{
if (!is_string($this->rawData)) {
return null;
}
$finfo = new \finfo(FILEINFO_MIME_TYPE);
return $finfo->buffer($this->rawData) ?: null;
}
/**
* Возвращает размер сырого изображения в байтах
*
* @return int
*/
public function size(): int
{
return strlen((string)$this->rawData);
}
/**
* @inheritDoc
*/
public function __toString(): string
{
return $this->asBase64();
}
}