feat: ajout de la gestion des commandes pour la suppression des fichiers CBZ et des chapitres, avec création des gestionnaires et des ressources API correspondantes
This commit is contained in:
parent
7fe4ac0d3b
commit
37e1b202c2
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\Resource;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Delete;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\State\Processor\DeleteCbzProcessor;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider\DeleteCbzProvider;
|
||||
|
||||
#[ApiResource(
|
||||
shortName: 'Cbz',
|
||||
operations: [
|
||||
new Delete(
|
||||
uriTemplate: '/manga/chapters/{id}/cbz',
|
||||
provider: DeleteCbzProvider::class,
|
||||
processor: DeleteCbzProcessor::class,
|
||||
name: 'delete_cbz',
|
||||
openapiContext: [
|
||||
'summary' => 'Delete chapter CBZ file',
|
||||
'description' => 'Removes the CBZ file for a specific chapter and updates the chapter accordingly',
|
||||
'parameters' => [
|
||||
[
|
||||
'name' => 'id',
|
||||
'in' => 'path',
|
||||
'required' => true,
|
||||
'schema' => [
|
||||
'type' => 'string'
|
||||
],
|
||||
'description' => 'The chapter ID'
|
||||
]
|
||||
],
|
||||
'responses' => [
|
||||
'204' => [
|
||||
'description' => 'CBZ file successfully deleted'
|
||||
],
|
||||
'404' => [
|
||||
'description' => 'Chapter or CBZ file not found'
|
||||
]
|
||||
]
|
||||
]
|
||||
)
|
||||
]
|
||||
)]
|
||||
class DeleteCbzResource
|
||||
{
|
||||
public function __construct(
|
||||
public string $id
|
||||
) {}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\Resource;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Delete;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\State\Processor\DeleteChapterProcessor;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider\DeleteChapterProvider;
|
||||
|
||||
#[ApiResource(
|
||||
shortName: 'Chapters',
|
||||
operations: [
|
||||
new Delete(
|
||||
uriTemplate: '/manga/chapters/{id}',
|
||||
provider: DeleteChapterProvider::class,
|
||||
processor: DeleteChapterProcessor::class,
|
||||
name: 'delete_chapter',
|
||||
openapiContext: [
|
||||
'summary' => 'Delete a chapter (soft delete)',
|
||||
'description' => 'Marks a chapter as deleted by setting its visibility to false',
|
||||
'parameters' => [
|
||||
[
|
||||
'name' => 'id',
|
||||
'in' => 'path',
|
||||
'required' => true,
|
||||
'schema' => [
|
||||
'type' => 'string'
|
||||
],
|
||||
'description' => 'The chapter ID'
|
||||
]
|
||||
],
|
||||
'responses' => [
|
||||
'204' => [
|
||||
'description' => 'Chapter successfully deleted'
|
||||
],
|
||||
'404' => [
|
||||
'description' => 'Chapter not found'
|
||||
]
|
||||
]
|
||||
]
|
||||
)
|
||||
]
|
||||
)]
|
||||
class DeleteChapterResource
|
||||
{
|
||||
public function __construct(
|
||||
public string $id
|
||||
) {}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\Resource;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider\DownloadCbzProvider;
|
||||
|
||||
#[ApiResource(
|
||||
shortName: 'Cbz',
|
||||
operations: [
|
||||
new Get(
|
||||
uriTemplate: '/manga/chapters/{id}/download',
|
||||
provider: DownloadCbzProvider::class,
|
||||
output: false,
|
||||
name: 'download_chapter_cbz'
|
||||
)
|
||||
]
|
||||
)]
|
||||
class DownloadCbzResource
|
||||
{
|
||||
public function __construct(
|
||||
public string $id
|
||||
) {}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\Resource;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider\DownloadVolumeProvider;
|
||||
|
||||
#[ApiResource(
|
||||
shortName: 'Cbz',
|
||||
operations: [
|
||||
new Get(
|
||||
uriTemplate: '/mangas/{id}/volumes/{volume}/download',
|
||||
provider: DownloadVolumeProvider::class,
|
||||
output: false,
|
||||
name: 'download_manga_volume'
|
||||
)
|
||||
]
|
||||
)]
|
||||
class DownloadVolumeResource
|
||||
{
|
||||
public function __construct(
|
||||
public string $id,
|
||||
public int $volume
|
||||
) {}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ use App\Domain\Manga\Infrastructure\ApiPlatform\State\Processor\FetchMangaChapte
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[ApiResource(
|
||||
shortName: 'MangaChapters',
|
||||
shortName: 'Chapters',
|
||||
operations: [
|
||||
new Post(
|
||||
uriTemplate: '/manga/chapters/fetch',
|
||||
@@ -23,4 +23,4 @@ class FetchMangaChaptersResource
|
||||
#[Assert\NotBlank]
|
||||
public string $externalId
|
||||
) {}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ use App\Domain\Manga\Infrastructure\ApiPlatform\Dto\ChapterCollection;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider\GetMangaChaptersStateProvider;
|
||||
|
||||
#[ApiResource(
|
||||
shortName: 'MangaChapters',
|
||||
shortName: 'Chapters',
|
||||
operations: [
|
||||
new Get(
|
||||
uriTemplate: '/mangas/{id}/chapters',
|
||||
@@ -63,4 +63,4 @@ use App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider\GetMangaChaptersS
|
||||
)]
|
||||
class MangaChaptersResource
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\State\Processor;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProcessorInterface;
|
||||
use App\Domain\Manga\Application\Command\DeleteCbz;
|
||||
use App\Domain\Manga\Application\CommandHandler\DeleteCbzHandler;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\Resource\DeleteCbzResource;
|
||||
|
||||
readonly class DeleteCbzProcessor implements ProcessorInterface
|
||||
{
|
||||
public function __construct(
|
||||
private DeleteCbzHandler $handler
|
||||
) {}
|
||||
|
||||
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): void
|
||||
{
|
||||
assert($data instanceof DeleteCbzResource);
|
||||
|
||||
$command = new DeleteCbz($data->id);
|
||||
$this->handler->handle($command);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\State\Processor;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProcessorInterface;
|
||||
use App\Domain\Manga\Application\Command\DeleteChapter;
|
||||
use App\Domain\Manga\Application\CommandHandler\DeleteChapterHandler;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
readonly class DeleteChapterProcessor implements ProcessorInterface
|
||||
{
|
||||
public function __construct(
|
||||
private DeleteChapterHandler $handler
|
||||
) {}
|
||||
|
||||
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): void
|
||||
{
|
||||
if (!isset($uriVariables['id'])) {
|
||||
throw new \InvalidArgumentException('Chapter ID is required');
|
||||
}
|
||||
|
||||
try {
|
||||
$command = new DeleteChapter($uriVariables['id']);
|
||||
$this->handler->handle($command);
|
||||
} catch (ChapterNotFoundException $e) {
|
||||
throw new NotFoundHttpException('Chapter not found');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
use App\Domain\Manga\Domain\Contract\Repository\ChapterRepositoryInterface;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
|
||||
use App\Domain\Manga\Domain\Exception\CbzFileNotFoundException;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\Resource\DeleteCbzResource;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
readonly class DeleteCbzProvider implements ProviderInterface
|
||||
{
|
||||
public function __construct(
|
||||
private ChapterRepositoryInterface $chapterRepository
|
||||
) {}
|
||||
|
||||
public function provide(Operation $operation, array $uriVariables = [], array $context = []): DeleteCbzResource
|
||||
{
|
||||
if (!isset($uriVariables['id'])) {
|
||||
throw new NotFoundHttpException('Chapter ID is required');
|
||||
}
|
||||
|
||||
$chapterId = $uriVariables['id'];
|
||||
|
||||
try {
|
||||
$chapter = $this->chapterRepository->findVisibleById($chapterId);
|
||||
|
||||
if (!$chapter) {
|
||||
throw new ChapterNotFoundException($chapterId);
|
||||
}
|
||||
|
||||
if (!$chapter->isAvailable()) {
|
||||
throw new CbzFileNotFoundException($chapterId);
|
||||
}
|
||||
|
||||
return new DeleteCbzResource($chapterId);
|
||||
|
||||
} catch (ChapterNotFoundException $e) {
|
||||
throw new NotFoundHttpException('Chapter not found');
|
||||
} catch (CbzFileNotFoundException $e) {
|
||||
throw new NotFoundHttpException('CBZ file not found for this chapter');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
use App\Domain\Manga\Domain\Contract\Repository\ChapterRepositoryInterface;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\Resource\DeleteChapterResource;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
readonly class DeleteChapterProvider implements ProviderInterface
|
||||
{
|
||||
public function __construct(
|
||||
private ChapterRepositoryInterface $chapterRepository
|
||||
) {}
|
||||
|
||||
public function provide(Operation $operation, array $uriVariables = [], array $context = []): DeleteChapterResource
|
||||
{
|
||||
if (!isset($uriVariables['id'])) {
|
||||
throw new NotFoundHttpException('Chapter ID is required');
|
||||
}
|
||||
|
||||
$chapterId = $uriVariables['id'];
|
||||
|
||||
try {
|
||||
$chapter = $this->chapterRepository->findVisibleById($chapterId);
|
||||
|
||||
if (!$chapter) {
|
||||
throw new ChapterNotFoundException($chapterId);
|
||||
}
|
||||
|
||||
return new DeleteChapterResource($chapterId);
|
||||
|
||||
} catch (ChapterNotFoundException $e) {
|
||||
throw new NotFoundHttpException('Chapter not found');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
use App\Domain\Manga\Application\Query\DownloadCbz;
|
||||
use App\Domain\Manga\Application\QueryHandler\DownloadCbzHandler;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
|
||||
use App\Domain\Manga\Domain\Exception\ChapterNotAvailableException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
readonly class DownloadCbzProvider implements ProviderInterface
|
||||
{
|
||||
public function __construct(
|
||||
private DownloadCbzHandler $handler
|
||||
) {}
|
||||
|
||||
public function provide(Operation $operation, array $uriVariables = [], array $context = []): Response
|
||||
{
|
||||
if (!isset($uriVariables['id'])) {
|
||||
throw new \InvalidArgumentException('Chapter ID is required');
|
||||
}
|
||||
|
||||
$query = new DownloadCbz($uriVariables['id']);
|
||||
|
||||
try {
|
||||
$downloadResponse = $this->handler->handle($query);
|
||||
return $downloadResponse->httpResponse;
|
||||
} catch (ChapterNotAvailableException|ChapterNotFoundException $e) {
|
||||
throw new NotFoundHttpException($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
use App\Domain\Manga\Application\Query\DownloadVolume;
|
||||
use App\Domain\Manga\Application\QueryHandler\DownloadVolumeHandler;
|
||||
use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
|
||||
use App\Domain\Manga\Domain\Exception\VolumeNotFoundException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
readonly class DownloadVolumeProvider implements ProviderInterface
|
||||
{
|
||||
public function __construct(
|
||||
private DownloadVolumeHandler $handler
|
||||
) {}
|
||||
|
||||
public function provide(Operation $operation, array $uriVariables = [], array $context = []): Response
|
||||
{
|
||||
if (!isset($uriVariables['id']) || !isset($uriVariables['volume'])) {
|
||||
throw new \InvalidArgumentException('Manga ID and volume are required');
|
||||
}
|
||||
|
||||
$query = new DownloadVolume($uriVariables['id'], (int) $uriVariables['volume']);
|
||||
|
||||
try {
|
||||
$downloadResponse = $this->handler->handle($query);
|
||||
return $downloadResponse->httpResponse;
|
||||
} catch (MangaNotFoundException|VolumeNotFoundException $e) {
|
||||
throw new NotFoundHttpException($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,8 +52,8 @@ readonly class GetMangaChaptersStateProvider implements ProviderInterface
|
||||
title: $chapter->title,
|
||||
volume: $chapter->volume,
|
||||
isVisible: $chapter->isVisible,
|
||||
isAvailable: $chapter->isAvailable,
|
||||
isAvailable: $chapter->cbzPath !== null,
|
||||
createdAt: $chapter->createdAt->format(\DateTimeInterface::RFC3339)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user