131 lines
3.3 KiB
PHP
131 lines
3.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support\News;
|
|
|
|
final class NewsCoverImage
|
|
{
|
|
public const MANAGED_PREFIX = 'news/covers/';
|
|
|
|
public const VARIANTS = [
|
|
'mobile' => [
|
|
'width' => 400,
|
|
'quality' => 74,
|
|
'suffix' => 'mobile',
|
|
],
|
|
'desktop' => [
|
|
'width' => 768,
|
|
'quality' => 76,
|
|
'suffix' => 'desktop',
|
|
],
|
|
];
|
|
|
|
public static function isManagedPath(?string $path): bool
|
|
{
|
|
$trimmed = ltrim(trim((string) $path), '/');
|
|
|
|
return $trimmed !== '' && str_starts_with($trimmed, self::MANAGED_PREFIX);
|
|
}
|
|
|
|
public static function normalizePath(?string $path): string
|
|
{
|
|
return ltrim(trim((string) $path), '/');
|
|
}
|
|
|
|
public static function path(string $hash): string
|
|
{
|
|
return sprintf(
|
|
'news/covers/%s/%s/%s.webp',
|
|
substr($hash, 0, 2),
|
|
substr($hash, 2, 2),
|
|
$hash,
|
|
);
|
|
}
|
|
|
|
public static function variantPath(string $path, string $variant): string
|
|
{
|
|
$trimmed = self::normalizePath($path);
|
|
$config = self::VARIANTS[$variant] ?? null;
|
|
|
|
if ($trimmed === '' || $config === null) {
|
|
return $trimmed;
|
|
}
|
|
|
|
$directory = pathinfo($trimmed, PATHINFO_DIRNAME);
|
|
$filename = pathinfo($trimmed, PATHINFO_FILENAME);
|
|
$extension = pathinfo($trimmed, PATHINFO_EXTENSION) ?: 'webp';
|
|
|
|
return ($directory !== '.' ? $directory . '/' : '') . $filename . '-' . $config['suffix'] . '.' . $extension;
|
|
}
|
|
|
|
public static function managedPaths(string $path): array
|
|
{
|
|
$trimmed = self::normalizePath($path);
|
|
|
|
if (! self::isManagedPath($trimmed)) {
|
|
return [];
|
|
}
|
|
|
|
$paths = [$trimmed];
|
|
|
|
foreach (array_keys(self::VARIANTS) as $variant) {
|
|
$paths[] = self::variantPath($trimmed, $variant);
|
|
}
|
|
|
|
return array_values(array_unique($paths));
|
|
}
|
|
|
|
public static function url(?string $path): ?string
|
|
{
|
|
$trimmed = self::normalizePath($path);
|
|
|
|
if ($trimmed === '') {
|
|
return null;
|
|
}
|
|
|
|
if (str_starts_with($trimmed, 'http://') || str_starts_with($trimmed, 'https://')) {
|
|
return $trimmed;
|
|
}
|
|
|
|
if (self::isManagedPath($trimmed)) {
|
|
return rtrim((string) config('cdn.files_url', 'https://files.skinbase.org'), '/') . '/' . $trimmed;
|
|
}
|
|
|
|
return asset('storage/' . $trimmed);
|
|
}
|
|
|
|
public static function variantUrl(?string $path, string $variant): ?string
|
|
{
|
|
$trimmed = self::normalizePath($path);
|
|
|
|
if (! self::isManagedPath($trimmed)) {
|
|
return null;
|
|
}
|
|
|
|
return self::url(self::variantPath($trimmed, $variant));
|
|
}
|
|
|
|
public static function srcset(?string $path): ?string
|
|
{
|
|
$trimmed = self::normalizePath($path);
|
|
|
|
if (! self::isManagedPath($trimmed)) {
|
|
return null;
|
|
}
|
|
|
|
$entries = [];
|
|
|
|
foreach (self::VARIANTS as $variant => $config) {
|
|
$url = self::variantUrl($trimmed, $variant);
|
|
|
|
if ($url === null) {
|
|
continue;
|
|
}
|
|
|
|
$entries[] = $url . ' ' . $config['width'] . 'w';
|
|
}
|
|
|
|
return $entries === [] ? null : implode(', ', $entries);
|
|
}
|
|
} |