AzuraCast/src/Flysystem/FilesystemManager.php

104 lines
3.4 KiB
PHP

<?php
namespace App\Flysystem;
use App\Entity;
use Cache\Prefixed\PrefixedCachePool;
use League\Flysystem\Adapter\AbstractAdapter;
use League\Flysystem\AdapterInterface;
use League\Flysystem\AwsS3v3\AwsS3Adapter;
use League\Flysystem\Cached\CachedAdapter;
use League\Flysystem\Cached\Storage\Psr6Cache;
use Psr\Cache\CacheItemPoolInterface;
/**
* A wrapper and manager class for accessing assets on the filesystem.
*/
class FilesystemManager
{
public const PREFIX_MEDIA = 'media';
public const PREFIX_PLAYLISTS = 'playlists';
public const PREFIX_CONFIG = 'config';
public const PREFIX_RECORDINGS = 'recordings';
public const PREFIX_TEMP = 'temp';
protected CacheItemPoolInterface $cachePool;
public function __construct(CacheItemPoolInterface $cachePool)
{
$this->cachePool = new PrefixedCachePool($cachePool, 'fs|');
}
public function getForStation(Entity\Station $station, bool $cached = true): StationFilesystemGroup
{
/** @var AdapterInterface[] $aliases */
$aliases = [
self::PREFIX_MEDIA => $station->getRadioMediaDirAdapter(),
self::PREFIX_PLAYLISTS => $station->getRadioPlaylistsDirAdapter(),
self::PREFIX_CONFIG => $station->getRadioConfigDirAdapter(),
self::PREFIX_RECORDINGS => $station->getRadioRecordingsDirAdapter(),
self::PREFIX_TEMP => $station->getRadioTempDirAdapter(),
];
$cachableFilesystems = [
self::PREFIX_MEDIA,
self::PREFIX_RECORDINGS,
];
$filesystems = [];
foreach ($aliases as $alias => $adapter) {
$cacheThisAdapter = (in_array($alias, $cachableFilesystems, true))
? $cached
: false;
$filesystems[$alias] = $this->getFilesystemForAdapter($adapter, $cacheThisAdapter);
}
return new StationFilesystemGroup($filesystems);
}
public function getFilesystemForAdapter(AdapterInterface $adapter, bool $cached = false): Filesystem
{
if ($cached) {
$cachedClient = new Psr6Cache($this->cachePool, $this->getCacheKey($adapter), 3600);
$adapter = new CachedAdapter($adapter, $cachedClient);
}
return new Filesystem($adapter);
}
public function flushCacheForAdapter(AdapterInterface $adapter, bool $inMemoryOnly = false): void
{
$fs = $this->getFilesystemForAdapter($adapter, true);
$fs->clearCache($inMemoryOnly);
}
protected function getCacheKey(AdapterInterface $adapter): string
{
if ($adapter instanceof CachedAdapter) {
$adapter = $adapter->getAdapter();
}
if ($adapter instanceof AwsS3Adapter) {
$s3Client = $adapter->getClient();
$bucket = $adapter->getBucket();
$objectUrl = $s3Client->getObjectUrl($bucket, $adapter->applyPathPrefix('/cache'));
return $this->filterCacheKey($objectUrl);
}
if ($adapter instanceof AbstractAdapter) {
return $this->filterCacheKey(ltrim($adapter->getPathPrefix(), '/'));
}
throw new \InvalidArgumentException('Adapter does not have a cache key.');
}
protected function filterCacheKey(string $cacheKey): string
{
if (preg_match('|[\{\}\(\)/\\\@\:]|', $cacheKey)) {
return preg_replace('|[\{\}\(\)/\\\@\:]|', '_', $cacheKey);
}
return $cacheKey;
}
}