feat: analyse import + all tests fixed

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-10-15 16:14:15 +02:00
parent fbe9619224
commit 3170a7c60e
74 changed files with 4318 additions and 183 deletions

View File

@@ -0,0 +1,111 @@
<?php
declare(strict_types=1);
namespace App\Domain\Shared\Infrastructure\Service;
use App\Domain\Shared\Domain\Contract\FileUploadInterface;
use App\Domain\Shared\Domain\Contract\MangaPathManagerInterface;
/**
* Implémentation centralisée basée sur la logique éprouvée de CbzGenerator.
*/
readonly class MangaFileManager implements MangaPathManagerInterface
{
public function __construct(
private string $projectDir,
private FileUploadInterface $fileUpload,
) {
}
public function getMangaDirectory(string $mangaTitle, string $publicationYear): string
{
$mangaDirName = ucfirst($this->slugify($mangaTitle)) . ' (' . $publicationYear . ')';
$dir = sprintf('%s/public/cbz/%s', $this->projectDir, $mangaDirName);
$this->ensureDirectory($dir);
return $dir;
}
public function getVolumeDirectory(string $mangaTitle, string $publicationYear, int $volumeNumber): string
{
$mangaDir = $this->getMangaDirectory($mangaTitle, $publicationYear);
$dir = sprintf('%s/volume_%02d', $mangaDir, $volumeNumber);
$this->ensureDirectory($dir);
return $dir;
}
public function buildChapterCbzPath(string $mangaTitle, string $publicationYear, int $volumeNumber, string $chapterNumber): string
{
$volumeDir = $this->getVolumeDirectory($mangaTitle, $publicationYear, $volumeNumber);
return sprintf(
'%s/%s_vol%d_ch%s.cbz',
$volumeDir,
$this->slugify($mangaTitle),
$volumeNumber,
$chapterNumber,
);
}
public function buildVolumeCbzPath(string $mangaTitle, string $publicationYear, int $volumeNumber): string
{
$volumeDir = $this->getVolumeDirectory($mangaTitle, $publicationYear, $volumeNumber);
return sprintf(
'%s/%s_vol%d.cbz',
$volumeDir,
$this->slugify($mangaTitle),
$volumeNumber,
);
}
/** @param array<int, string> $files */
public function createCbzArchive(array $files, string $cbzPath): void
{
$zip = new \ZipArchive();
if ($zip->open($cbzPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
throw new \RuntimeException('Failed to create CBZ archive');
}
foreach ($files as $file) {
if (!file_exists($file)) {
throw new \RuntimeException("File not found: $file");
}
$zip->addFile($file, basename($file));
}
if (!$zip->close()) {
throw new \RuntimeException('Failed to close CBZ archive');
}
}
public function moveFileTo(string $sourcePath, string $destinationPath): void
{
$destinationDir = dirname($destinationPath);
$this->ensureDirectory($destinationDir);
$this->fileUpload->moveFile($sourcePath, $destinationPath);
}
public function fileExists(string $path): bool
{
return $this->fileUpload->fileExists($path);
}
private function ensureDirectory(string $dir): void
{
if (!is_dir($dir)) {
$this->fileUpload->createDirectory($dir);
}
}
private function slugify(string $text): string
{
$text = preg_replace('~[^\pL\d]+~u', '-', $text);
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
$text = preg_replace('~[^-\w]+~', '', $text);
$text = trim($text, '-');
$text = preg_replace('~-+~', '-', $text);
$text = strtolower($text);
return $text ?: 'n-a';
}
}

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace App\Domain\Shared\Infrastructure\Service;
use App\Domain\Shared\Domain\Contract\FileUploadInterface;
use App\Domain\Shared\Domain\Exception\FileProcessingException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
readonly class SymfonyFileUpload implements FileUploadInterface
{
public function __construct(
private Filesystem $filesystem,
private string $uploadsDirectory
) {
}
public function moveUploadedFile(string $sourcePath, string $targetDirectory, string $originalName): string
{
try {
$targetPath = $targetDirectory . '/' . uniqid() . '_' . $originalName;
$this->filesystem->copy($sourcePath, $targetPath);
return $targetPath;
} catch (FileException $e) {
throw FileProcessingException::uploadFailed($originalName, $e->getMessage());
}
}
public function fileExists(string $filePath): bool
{
return $this->filesystem->exists($filePath);
}
public function deleteFile(string $filePath): void
{
if ($this->filesystem->exists($filePath)) {
$this->filesystem->remove($filePath);
}
}
public function moveFile(string $sourcePath, string $targetPath): void
{
try {
$this->filesystem->rename($sourcePath, $targetPath, true);
} catch (FileException $e) {
throw FileProcessingException::uploadFailed(
basename($sourcePath),
$e->getMessage()
);
}
}
public function createDirectory(string $path): void
{
if (!$this->filesystem->exists($path)) {
$this->filesystem->mkdir($path, 0755);
}
}
public function validateFileFormat(string $filePath, array $allowedExtensions): bool
{
$extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
return in_array($extension, $allowedExtensions, true);
}
}

View File

@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace App\Domain\Shared\Infrastructure\Service;
use App\Domain\Shared\Domain\Contract\NotificationInterface;
use Symfony\Component\Mercure\HubInterface;
use Symfony\Component\Mercure\Update;
readonly class SymfonyNotification implements NotificationInterface
{
public function __construct(
private HubInterface $hub
) {
}
public function sendSuccess(string $message): void
{
$this->sendUpdate([
'status' => 'success',
'message' => $message
]);
}
public function sendError(string $message): void
{
$this->sendUpdate([
'status' => 'error',
'message' => $message
]);
}
public function sendUpdate(array $data): void
{
$update = new Update(
'notifications',
json_encode($data)
);
$this->hub->publish($update);
}
}