Working state

This commit is contained in:
julien
2026-03-16 13:40:18 +01:00
parent dec76fa2c7
commit 557360dfde
57 changed files with 1044 additions and 1668 deletions

View File

@@ -6,38 +6,32 @@ namespace App\Media;
use App\Media\Exception\FileTooLargeException;
use App\Media\Exception\InvalidMimeTypeException;
use App\Media\Exception\StorageException;
use App\Post\PostRepositoryInterface;
use App\Shared\Pagination\PaginatedResult;
use PDOException;
use Psr\Http\Message\UploadedFileInterface;
final class MediaService implements MediaServiceInterface
{
private const ALLOWED_MIME_TYPES = [
'image/jpeg',
'image/png',
'image/gif',
'image/webp',
];
private const ALLOWED_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
private const WEBP_CONVERTIBLE = ['image/jpeg', 'image/png'];
private const MIME_EXTENSIONS = [
'image/jpeg' => 'webp',
'image/png' => 'webp',
'image/gif' => 'gif',
'image/webp' => 'webp',
];
private const MIME_EXTENSIONS_FALLBACK = [
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/webp' => 'webp',
];
private const MAX_PIXELS = 40000000;
public function __construct(
private readonly MediaRepositoryInterface $mediaRepository,
private readonly PostRepositoryInterface $postRepository,
private readonly string $uploadDir,
private readonly string $uploadUrl,
private readonly int $maxSize,
@@ -49,11 +43,45 @@ final class MediaService implements MediaServiceInterface
return $this->mediaRepository->findAll();
}
/**
* @return PaginatedResult<Media>
*/
public function findPaginated(int $page, int $perPage): PaginatedResult
{
$page = max(1, $page);
$total = $this->mediaRepository->countAll();
$offset = ($page - 1) * $perPage;
return new PaginatedResult(
$this->mediaRepository->findPage($perPage, $offset),
$total,
$page,
$perPage,
);
}
public function findByUserId(int $userId): array
{
return $this->mediaRepository->findByUserId($userId);
}
/**
* @return PaginatedResult<Media>
*/
public function findByUserIdPaginated(int $userId, int $page, int $perPage): PaginatedResult
{
$page = max(1, $page);
$total = $this->mediaRepository->countByUserId($userId);
$offset = ($page - 1) * $perPage;
return new PaginatedResult(
$this->mediaRepository->findByUserPage($userId, $perPage, $offset),
$total,
$page,
$perPage,
);
}
public function findById(int $id): ?Media
{
return $this->mediaRepository->findById($id);
@@ -106,7 +134,7 @@ final class MediaService implements MediaServiceInterface
}
$hash = $rawHash;
$existing = $this->mediaRepository->findByHash($hash);
$existing = $this->mediaRepository->findByHashForUser($hash, $userId);
if ($existing !== null) {
if ($converted) {
@@ -119,9 +147,7 @@ final class MediaService implements MediaServiceInterface
throw new StorageException("Impossible de créer le répertoire d'upload");
}
$extension = $converted
? self::MIME_EXTENSIONS[$mime]
: self::MIME_EXTENSIONS_FALLBACK[$mime];
$extension = $converted ? self::MIME_EXTENSIONS[$mime] : self::MIME_EXTENSIONS_FALLBACK[$mime];
$filename = uniqid('', true) . '_' . bin2hex(random_bytes(4)) . '.' . $extension;
$destPath = $this->uploadDir . DIRECTORY_SEPARATOR . $filename;
@@ -141,19 +167,27 @@ final class MediaService implements MediaServiceInterface
try {
$this->mediaRepository->create($media);
} catch (PDOException $e) {
$duplicate = $this->mediaRepository->findByHash($hash);
@unlink($destPath);
$duplicate = $this->mediaRepository->findByHashForUser($hash, $userId);
if ($duplicate !== null) {
@unlink($destPath);
return $duplicate->getUrl();
}
@unlink($destPath);
throw $e;
}
return $url;
}
public function getUsageSummary(Media $media, int $sampleLimit = 5): array
{
return [
'count' => $this->postRepository->countByEmbeddedMediaUrl($media->getUrl()),
'posts' => $this->postRepository->findByEmbeddedMediaUrl($media->getUrl(), $sampleLimit),
];
}
public function delete(Media $media): void
{
$filePath = $this->uploadDir . DIRECTORY_SEPARATOR . $media->getFilename();