139 lines
5.1 KiB
PHP
139 lines
5.1 KiB
PHP
<?php
|
|
|
|
namespace App\Controller;
|
|
|
|
use App\Repository\MangaRepository;
|
|
use App\Service\CbzService;
|
|
use App\Service\NotificationService;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\Routing\Attribute\Route;
|
|
|
|
class ReaderController extends AbstractController
|
|
{
|
|
public function __construct(
|
|
private readonly MangaRepository $mangaRepository,
|
|
private readonly CbzService $cbzService,
|
|
private readonly NotificationService $notificationService,
|
|
) {
|
|
}
|
|
|
|
#[Route('/read/{mangaSlug}/{chapterNumber}', name: 'app_reader')]
|
|
public function read(string $mangaSlug, float $chapterNumber): Response
|
|
{
|
|
$manga = $this->mangaRepository->findOneBy(['slug' => $mangaSlug]);
|
|
if (!$manga) {
|
|
throw $this->createNotFoundException("Le manga demandé n'existe pas.");
|
|
}
|
|
|
|
$chapter = $manga->getChapterByNumber($chapterNumber);
|
|
if (!$chapter) {
|
|
throw $this->createNotFoundException("Le chapitre demandé n'existe pas.");
|
|
}
|
|
|
|
if (is_null($chapter->getCbzPath())) {
|
|
$this->notificationService->sendUpdate([
|
|
'status' => 'error',
|
|
'message' => 'Le chapitre demandé n\'est pas encore disponible.',
|
|
]);
|
|
return $this->redirectToRoute('app_manga_show', ['mangaSlug' => $mangaSlug]);
|
|
}
|
|
|
|
$totalPages = $this->cbzService->getPageCount($chapter->getCbzPath());
|
|
|
|
return $this->render('reader/index.html.twig', [
|
|
'manga' => $manga,
|
|
'chapter' => $chapter,
|
|
'totalPages' => $totalPages,
|
|
]);
|
|
}
|
|
|
|
#[Route('/api/read/{mangaSlug}/{chapterNumber}/{pageNumber}', name: 'app_reader_page')]
|
|
public function getPage(string $mangaSlug, float $chapterNumber, int $pageNumber): Response
|
|
{
|
|
$manga = $this->mangaRepository->findOneBy(['slug' => $mangaSlug]);
|
|
if (!$manga) {
|
|
throw $this->createNotFoundException("Le manga demandé n'existe pas.");
|
|
}
|
|
|
|
$chapter = $manga->getChapterByNumber($chapterNumber);
|
|
if (!$chapter) {
|
|
throw $this->createNotFoundException("Le chapitre demandé n'existe pas.");
|
|
}
|
|
|
|
$pageContent = $this->cbzService->getPageContent($chapter->getCbzPath(), $pageNumber);
|
|
if (!$pageContent) {
|
|
throw $this->createNotFoundException("La page demandée n'existe pas.");
|
|
}
|
|
|
|
return new Response(base64_encode($pageContent), 200, ['Content-Type' => 'text/plain']);
|
|
}
|
|
|
|
#[Route('/api/chapters/{mangaSlug}', name: 'app_reader_chapters')]
|
|
public function getChapters(string $mangaSlug): JsonResponse
|
|
{
|
|
$manga = $this->mangaRepository->findOneBy(['slug' => $mangaSlug]);
|
|
if (!$manga) {
|
|
throw $this->createNotFoundException("Le manga demandé n'existe pas.");
|
|
}
|
|
|
|
$chapters = $manga->getChapters()
|
|
->filter(fn ($chapter) => $chapter->isVisible() && !is_null($chapter->getCbzPath()))
|
|
->toArray();
|
|
|
|
usort($chapters, fn ($a, $b) => $b->getNumber() <=> $a->getNumber());
|
|
|
|
$chapters = array_values(array_map(fn ($chapter) => [
|
|
'number' => $chapter->getNumber(),
|
|
'title' => $chapter->getTitle(),
|
|
], $chapters));
|
|
|
|
return $this->json($chapters);
|
|
}
|
|
|
|
#[Route('/api/previous-chapter/{mangaSlug}/{currentChapterNumber}', name: 'app_reader_previous_chapter')]
|
|
public function getPreviousChapter(string $mangaSlug, float $currentChapterNumber): JsonResponse
|
|
{
|
|
$manga = $this->mangaRepository->findOneBy(['slug' => $mangaSlug]);
|
|
if (!$manga) {
|
|
throw $this->createNotFoundException("Le manga demandé n'existe pas.");
|
|
}
|
|
|
|
$chapters = $manga->getChapters()
|
|
->filter(fn ($chapter) => $chapter->isVisible() && $chapter->getNumber() < $currentChapterNumber)
|
|
->toArray();
|
|
|
|
usort($chapters, fn ($a, $b) => $b->getNumber() <=> $a->getNumber());
|
|
|
|
$previousChapter = reset($chapters) ?: null;
|
|
|
|
return $this->json($previousChapter ? [
|
|
'number' => $previousChapter->getNumber(),
|
|
'title' => $previousChapter->getTitle(),
|
|
] : null);
|
|
}
|
|
|
|
#[Route('/api/next-chapter/{mangaSlug}/{currentChapterNumber}', name: 'app_reader_next_chapter')]
|
|
public function getNextChapter(string $mangaSlug, float $currentChapterNumber): JsonResponse
|
|
{
|
|
$manga = $this->mangaRepository->findOneBy(['slug' => $mangaSlug]);
|
|
if (!$manga) {
|
|
throw $this->createNotFoundException("Le manga demandé n'existe pas.");
|
|
}
|
|
|
|
$nextChapter = $manga->getChapters()
|
|
->filter(fn ($chapter) => $chapter->isVisible() && $chapter->getNumber() > $currentChapterNumber)
|
|
->toArray();
|
|
|
|
usort($nextChapter, fn ($a, $b) => $a->getNumber() <=> $b->getNumber());
|
|
|
|
$nextChapter = reset($nextChapter) ?: null;
|
|
|
|
return $this->json($nextChapter ? [
|
|
'number' => $nextChapter->getNumber(),
|
|
'title' => $nextChapter->getTitle(),
|
|
] : null);
|
|
}
|
|
}
|