196 lines
4.8 KiB
PHP
196 lines
4.8 KiB
PHP
<?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 = empty($url) ? base_url('public/no-tvg-logo.png') : $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
|
|
{
|
|
$parts = parse_url(trim($url));
|
|
if (!is_array($parts) || count($parts) < 2) {
|
|
return false;
|
|
}
|
|
|
|
$result = $parts['scheme'] . '://' . $parts['host'];
|
|
$result .= (empty($parts['port']) ? '' : ':' . $parts['port']);
|
|
|
|
return $result . $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();
|
|
}
|
|
}
|