Files
Mangarr/src/Domain/Conversion/Infrastructure/Service/ConversionService.php
ext.jeremy.guillot@maxicoffee.domains 5ed303612a feat: migrer vers Symfony 8, PHP 8.4 et les dépendances majeures associées
- PHP 8.3 → 8.4 (Dockerfile + composer.json)
- Symfony 7.0 → 8.0 (tous les composants symfony/*)
- API Platform 3.x → 4.x : migration openapiContext → openapi: new Operation(...)
- Doctrine DBAL 3 → 4 : suppression use_savepoints, replace prepare/executeQuery
- Doctrine ORM 2.x → 3.x : ClassMetadataInfo → ClassMetadata, setParameters → setParameter
- Doctrine Bundle 2.x → 3.x, Fixtures Bundle 3.x → 4.x
- zenstruck/foundry 1.x → 2.x : ModelFactory → PersistentObjectFactory, getDefaults → defaults
- phpmd/phpmd 2.x → 3.x-dev (seule version supportant Symfony 8)
- phparkitect 0.3 → 0.8 : NotDependsOnTheseNamespaces prend un array
- symfony/mercure-bundle 0.3 → 0.4, symfony/monolog-bundle 3 → 4
- Suppression de runtime/frankenphp-symfony (intégré nativement dans symfony/runtime 8)
- worker.Caddyfile : suppression de APP_RUNTIME (détection automatique Symfony 8)
- Routes errors.xml/wdt.xml/profiler.xml → .php (Symfony 8 supprime le XML)
- Types::ARRAY → Types::JSON dans Entity/Manga.php (DBAL 4 retire array type)
- Suppression de src/Schedule.php (doublon vide avec MonitoringSchedule)
- Tests : hydra:Collection → Collection, hydra:member → member (API Platform 4)
2026-03-26 17:55:12 +01:00

92 lines
3.0 KiB
PHP

<?php
namespace App\Domain\Conversion\Infrastructure\Service;
use App\Domain\Conversion\Domain\Contract\ConversionServiceInterface;
use App\Domain\Conversion\Domain\Exception\ConversionException;
use App\Domain\Conversion\Domain\Model\ConversionRequest;
use App\Domain\Conversion\Domain\Model\ConversionResult;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\Process;
final class ConversionService implements ConversionServiceInterface
{
private readonly string $tempDir;
private readonly Filesystem $filesystem;
public function __construct(string $projectDir)
{
$this->tempDir = $projectDir.'/public/tmp';
$this->filesystem = new Filesystem();
}
public function convert(ConversionRequest $request): ConversionResult
{
try {
$convertedFilePath = $this->convertCbrToCbz($request->getFilePath());
$convertedFileSize = file_exists($convertedFilePath) ? filesize($convertedFilePath) : 0;
return new ConversionResult(
convertedFilePath: $convertedFilePath,
outputFilename: $request->getOutputFilename(),
originalFileSize: $request->getFileSize(),
convertedFileSize: $convertedFileSize
);
} catch (\Exception $e) {
throw ConversionException::conversionFailed($e->getMessage());
}
}
private function convertCbrToCbz(string $cbrPath): string
{
$tempDir = $this->tempDir.'/'.uniqid('cbr_conversion_');
$this->filesystem->mkdir($tempDir);
$extractDir = $tempDir.'/extract';
$this->filesystem->mkdir($extractDir);
// Essayer d'extraire avec unrar-free
$process = new Process(['unrar-free', 'x', $cbrPath, $extractDir]);
$process->run();
// Si unrar échoue, essayer avec 7z
if (!$process->isSuccessful()) {
$process = new Process(['7z', 'x', $cbrPath, "-o$extractDir"]);
$process->run();
if (!$process->isSuccessful()) {
throw new \RuntimeException('Extraction failed: '.$process->getErrorOutput());
}
}
// Créer le CBZ
$cbzFileName = pathinfo($cbrPath, PATHINFO_FILENAME).'.cbz';
$cbzPath = $this->tempDir.'/'.$cbzFileName;
$zip = new \ZipArchive();
if (true !== $zip->open($cbzPath, \ZipArchive::CREATE)) {
throw new \RuntimeException('Cannot create ZIP file');
}
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($extractDir),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($extractDir) + 1);
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
// Nettoyer le dossier temporaire d'extraction
$this->filesystem->remove($tempDir);
return $cbzPath;
}
}