fix: phpcs-fixer

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-02-05 21:32:04 +01:00
parent ba874480ee
commit c55cd62ec7
65 changed files with 346 additions and 355 deletions

View File

@@ -10,7 +10,6 @@ use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
#[AsDecorator('api_platform.openapi.factory')] #[AsDecorator('api_platform.openapi.factory')]
class OpenApiFactoryDecorator implements OpenApiFactoryInterface class OpenApiFactoryDecorator implements OpenApiFactoryInterface
{ {
public function __construct(private OpenApiFactoryInterface $decorated) public function __construct(private OpenApiFactoryInterface $decorated)
{ {
} }

View File

@@ -7,8 +7,8 @@ use GuzzleHttp\ClientInterface as GuzzleInterface;
class MangadexClient implements ClientInterface class MangadexClient implements ClientInterface
{ {
private CONST AUTHENTICATION_URL = 'https://auth.mangadex.org/realms/mangadex/protocol/openid-connect/token'; private const AUTHENTICATION_URL = 'https://auth.mangadex.org/realms/mangadex/protocol/openid-connect/token';
private CONST API_URL = 'https://api.mangadex.org'; private const API_URL = 'https://api.mangadex.org';
private GuzzleInterface $httpClient; private GuzzleInterface $httpClient;
private string $clientId; private string $clientId;
private string $clientSecret; private string $clientSecret;

View File

@@ -19,8 +19,7 @@ class ActivityController extends AbstractController
private readonly Connection $connection, private readonly Connection $connection,
private readonly ChapterRepository $chapterRepository, private readonly ChapterRepository $chapterRepository,
private readonly ToolbarFactory $toolbarFactory private readonly ToolbarFactory $toolbarFactory
) ) {
{
} }
@@ -57,7 +56,7 @@ class ActivityController extends AbstractController
return new JsonResponse($status); return new JsonResponse($status);
} }
// TODO refactorer ce code avec celui du QueueStatusSubscriber // TODO refactorer ce code avec celui du QueueStatusSubscriber
private function getQueueStatus(): array private function getQueueStatus(): array
{ {
// Requête pour récupérer les messages en attente // Requête pour récupérer les messages en attente

View File

@@ -17,8 +17,7 @@ class ConversionController extends AbstractController
public function __construct( public function __construct(
private readonly CbrToCbzConverter $cbrToCbzConverter, private readonly CbrToCbzConverter $cbrToCbzConverter,
private readonly NotificationService $notificationService private readonly NotificationService $notificationService
) ) {
{
} }
#[Route('/convert', name: 'app_convert')] #[Route('/convert', name: 'app_convert')]

View File

@@ -27,8 +27,7 @@ class ImportController extends AbstractController
private readonly NotificationService $notificationService, private readonly NotificationService $notificationService,
private readonly MangaRepository $mangaRepository, private readonly MangaRepository $mangaRepository,
private readonly CbrToCbzConverter $cbrToCbzConverter private readonly CbrToCbzConverter $cbrToCbzConverter
) ) {
{
} }

View File

@@ -49,8 +49,7 @@ class MangaController extends AbstractController
private readonly EntityManagerInterface $entityManager, private readonly EntityManagerInterface $entityManager,
private readonly NotificationService $notificationService, private readonly NotificationService $notificationService,
private readonly ContentSourceRepository $contentSourceRepository private readonly ContentSourceRepository $contentSourceRepository
) ) {
{
$this->imageManager = new ImageManager(new Driver()); $this->imageManager = new ImageManager(new Driver());
} }
@@ -75,7 +74,7 @@ class MangaController extends AbstractController
#[Route('/manga/chapters/{mangaSlug}', name: 'app_manga_show')] #[Route('/manga/chapters/{mangaSlug}', name: 'app_manga_show')]
public function showChapters(string $mangaSlug, Request $request): Response public function showChapters(string $mangaSlug, Request $request): Response
{ {
// $manga = $this->mangaRepository->findOneWithChapterBy(['slug' => $mangaSlug]); // $manga = $this->mangaRepository->findOneWithChapterBy(['slug' => $mangaSlug]);
$manga = $this->mangaRepository->findOneBy(['slug' => $mangaSlug]); $manga = $this->mangaRepository->findOneBy(['slug' => $mangaSlug]);
if (!$manga) { if (!$manga) {
@@ -98,7 +97,7 @@ class MangaController extends AbstractController
{ {
try { try {
foreach ($manga->getChapters() as $chapter) { foreach ($manga->getChapters() as $chapter) {
file_exists($chapter->getCbzPath()) ?? unlink($chapter->getCbzPath()); file_exists($chapter->getCbzPath()) ?? unlink($chapter->getCbzPath());
$this->entityManager->remove($chapter); $this->entityManager->remove($chapter);
} }
$this->entityManager->remove($manga); $this->entityManager->remove($manga);
@@ -135,8 +134,7 @@ class MangaController extends AbstractController
Request $request, Request $request,
Manga $manga, Manga $manga,
ContentSourceRepository $contentSourceRepository ContentSourceRepository $contentSourceRepository
): JsonResponse ): JsonResponse {
{
$data = json_decode($request->getContent(), true); $data = json_decode($request->getContent(), true);
$preferredSourceIds = $data['preferredSources'] ?? []; $preferredSourceIds = $data['preferredSources'] ?? [];
@@ -144,7 +142,7 @@ class MangaController extends AbstractController
// This will maintain the order of the sources as they were sent in the request // This will maintain the order of the sources as they were sent in the request
$orderedPreferredSources = array_map( $orderedPreferredSources = array_map(
fn($id) => current(array_filter($preferredSources, fn($s) => $s->getId() == $id)), fn ($id) => current(array_filter($preferredSources, fn ($s) => $s->getId() == $id)),
$preferredSourceIds $preferredSourceIds
); );
@@ -194,7 +192,7 @@ class MangaController extends AbstractController
return new JsonResponse(['error' => 'No CBZ path for this chapter.'], 400); return new JsonResponse(['error' => 'No CBZ path for this chapter.'], 400);
} }
file_exists($cbzPath) ?? unlink($cbzPath); file_exists($cbzPath) ?? unlink($cbzPath);
$chapter->setCbzPath(null); $chapter->setCbzPath(null);
$this->entityManager->persist($chapter); $this->entityManager->persist($chapter);

View File

@@ -16,8 +16,7 @@ class ReaderController extends AbstractController
private readonly MangaRepository $mangaRepository, private readonly MangaRepository $mangaRepository,
private readonly CbzService $cbzService, private readonly CbzService $cbzService,
private readonly NotificationService $notificationService, private readonly NotificationService $notificationService,
) ) {
{
} }
#[Route('/read/{mangaSlug}/{chapterNumber}', name: 'app_reader')] #[Route('/read/{mangaSlug}/{chapterNumber}', name: 'app_reader')]
@@ -80,12 +79,12 @@ class ReaderController extends AbstractController
} }
$chapters = $manga->getChapters() $chapters = $manga->getChapters()
->filter(fn($chapter) => $chapter->isVisible() && !is_null($chapter->getCbzPath())) ->filter(fn ($chapter) => $chapter->isVisible() && !is_null($chapter->getCbzPath()))
->toArray(); ->toArray();
usort($chapters, fn($a, $b) => $b->getNumber() <=> $a->getNumber()); usort($chapters, fn ($a, $b) => $b->getNumber() <=> $a->getNumber());
$chapters = array_values(array_map(fn($chapter) => [ $chapters = array_values(array_map(fn ($chapter) => [
'number' => $chapter->getNumber(), 'number' => $chapter->getNumber(),
'title' => $chapter->getTitle(), 'title' => $chapter->getTitle(),
], $chapters)); ], $chapters));
@@ -102,10 +101,10 @@ class ReaderController extends AbstractController
} }
$chapters = $manga->getChapters() $chapters = $manga->getChapters()
->filter(fn($chapter) => $chapter->isVisible() && $chapter->getNumber() < $currentChapterNumber) ->filter(fn ($chapter) => $chapter->isVisible() && $chapter->getNumber() < $currentChapterNumber)
->toArray(); ->toArray();
usort($chapters, fn($a, $b) => $b->getNumber() <=> $a->getNumber()); usort($chapters, fn ($a, $b) => $b->getNumber() <=> $a->getNumber());
$previousChapter = reset($chapters) ?: null; $previousChapter = reset($chapters) ?: null;
@@ -124,10 +123,10 @@ class ReaderController extends AbstractController
} }
$nextChapter = $manga->getChapters() $nextChapter = $manga->getChapters()
->filter(fn($chapter) => $chapter->isVisible() && $chapter->getNumber() > $currentChapterNumber) ->filter(fn ($chapter) => $chapter->isVisible() && $chapter->getNumber() > $currentChapterNumber)
->toArray(); ->toArray();
usort($nextChapter, fn($a, $b) => $a->getNumber() <=> $b->getNumber()); usort($nextChapter, fn ($a, $b) => $a->getNumber() <=> $b->getNumber());
$nextChapter = reset($nextChapter) ?: null; $nextChapter = reset($nextChapter) ?: null;

View File

@@ -15,7 +15,7 @@ class SecurityController extends AbstractController
#[Route('/login', name: 'app_login', methods: ['GET', 'POST'])] #[Route('/login', name: 'app_login', methods: ['GET', 'POST'])]
public function login(IriConverterInterface $iriConverter, #[CurrentUser] User $user = null): Response public function login(IriConverterInterface $iriConverter, #[CurrentUser] User $user = null): Response
{ {
if(!$user){ if(!$user) {
return $this->json([ return $this->json([
'error' => 'Invalid credentials' 'error' => 'Invalid credentials'
], 401); ], 401);

View File

@@ -26,8 +26,7 @@ class SettingsController extends AbstractController
private EntityManagerInterface $entityManager, private EntityManagerInterface $entityManager,
private NotificationService $notificationService, private NotificationService $notificationService,
private ContentSourceRepository $contentSourceRepository private ContentSourceRepository $contentSourceRepository
) ) {
{
} }
@@ -117,7 +116,7 @@ class SettingsController extends AbstractController
try { try {
$scrapedData = $this->mangaScraperService->testScraping($mangaSlug, $chapterNumber, $contentSource); $scrapedData = $this->mangaScraperService->testScraping($mangaSlug, $chapterNumber, $contentSource);
}catch (\Exception $e){ } catch (\Exception $e) {
$this->notificationService->sendUpdate(['status' => 'error', 'message' => $e->getMessage()]); $this->notificationService->sendUpdate(['status' => 'error', 'message' => $e->getMessage()]);
return new JsonResponse([ return new JsonResponse([
'success' => false, 'success' => false,

View File

@@ -34,8 +34,7 @@ class TestController extends AbstractController
private string $projectDir, private string $projectDir,
private SluggerInterface $slugger, private SluggerInterface $slugger,
private MangaRepository $mangaRepository private MangaRepository $mangaRepository
) ) {
{
$this->imageManager = new ImageManager(new Driver()); $this->imageManager = new ImageManager(new Driver());
} }
@@ -45,9 +44,9 @@ class TestController extends AbstractController
$mangas = $this->mangaRepository->findAll(); $mangas = $this->mangaRepository->findAll();
$changed = 0; $changed = 0;
foreach ($mangas as $manga){ foreach ($mangas as $manga) {
//si getImageUrl() retourne un lien sous la forme d'une URL (https ou http) //si getImageUrl() retourne un lien sous la forme d'une URL (https ou http)
if($manga->getImageUrl()){ if($manga->getImageUrl()) {
$imageUrls = $this->processAndSaveImage($manga->getImageUrl()); $imageUrls = $this->processAndSaveImage($manga->getImageUrl());
$manga->setThumbnailUrl($imageUrls['thumbnail']); $manga->setThumbnailUrl($imageUrls['thumbnail']);
$this->mangaRepository->save($manga, true); $this->mangaRepository->save($manga, true);
@@ -81,8 +80,8 @@ class TestController extends AbstractController
$thumbnail->save($this->projectDir . '/public/images/thumbnails/' . $newFilename, quality: 85); $thumbnail->save($this->projectDir . '/public/images/thumbnails/' . $newFilename, quality: 85);
// Sauvegarder l'image en taille réelle // Sauvegarder l'image en taille réelle
// $fullImage = $this->imageManager->read($tempImagePath); // $fullImage = $this->imageManager->read($tempImagePath);
// $fullImage->save($this->projectDir . '/public/images/full/' . $newFilename, quality: 90); // $fullImage->save($this->projectDir . '/public/images/full/' . $newFilename, quality: 90);
// Fermer et supprimer le fichier temporaire // Fermer et supprimer le fichier temporaire
fclose($tempImage); fclose($tempImage);

View File

@@ -7,4 +7,4 @@ use App\Domain\Scraping\Domain\Model\Manga;
interface MangaRepositoryInterface interface MangaRepositoryInterface
{ {
public function getById(string $id): ?Manga; public function getById(string $id): ?Manga;
} }

View File

@@ -9,4 +9,4 @@ interface ScraperInterface
public function createScrapingJob(string $mangaId, string $chapterId, string $sourceId): ScrapingJob; public function createScrapingJob(string $mangaId, string $chapterId, string $sourceId): ScrapingJob;
public function scrape(ScrapingJob $job): void; public function scrape(ScrapingJob $job): void;
public function supports(string $sourceType): bool; public function supports(string $sourceType): bool;
} }

View File

@@ -7,7 +7,8 @@ class ChapterScrapingCompleted
public function __construct( public function __construct(
private readonly string $jobId, private readonly string $jobId,
private readonly array $scrapedPages private readonly array $scrapedPages
) {} ) {
}
public function getJobId(): string public function getJobId(): string
{ {
@@ -18,4 +19,4 @@ class ChapterScrapingCompleted
{ {
return $this->scrapedPages; return $this->scrapedPages;
} }
} }

View File

@@ -7,7 +7,8 @@ class ChapterScrapingFailed
public function __construct( public function __construct(
private readonly string $chapterId, private readonly string $chapterId,
private readonly string $reason private readonly string $reason
) {} ) {
}
public function getChapterId(): string public function getChapterId(): string
{ {
@@ -18,4 +19,4 @@ class ChapterScrapingFailed
{ {
return $this->reason; return $this->reason;
} }
} }

View File

@@ -6,7 +6,8 @@ class ChapterScrapingStarted
{ {
public function __construct( public function __construct(
private readonly string $jobId private readonly string $jobId
) {} ) {
}
public function getJobId(): string public function getJobId(): string
{ {

View File

@@ -9,7 +9,8 @@ class PageScrapingProgressed
public function __construct( public function __construct(
private readonly string $jobId, private readonly string $jobId,
private readonly ScrapingProgress $progress private readonly ScrapingProgress $progress
) {} ) {
}
public function getJobId(): string public function getJobId(): string
{ {
@@ -20,4 +21,4 @@ class PageScrapingProgressed
{ {
return $this->progress; return $this->progress;
} }
} }

View File

@@ -10,7 +10,8 @@ class Manga
private readonly string $slug, private readonly string $slug,
private readonly string $description, private readonly string $description,
private readonly string $author, private readonly string $author,
) {} ) {
}
public function getId(): string public function getId(): string
{ {
@@ -36,4 +37,4 @@ class Manga
{ {
return $this->author; return $this->author;
} }
} }

View File

@@ -87,4 +87,4 @@ class ScrapingJob
{ {
return $this->completedAt; return $this->completedAt;
} }
} }

View File

@@ -7,7 +7,8 @@ class ScrapingProgress
public function __construct( public function __construct(
private readonly int $pagesScraped, private readonly int $pagesScraped,
private readonly int $totalPages private readonly int $totalPages
) {} ) {
}
public function getPercentage(): float public function getPercentage(): float
{ {
@@ -16,4 +17,4 @@ class ScrapingProgress
} }
return ($this->pagesScraped / $this->totalPages) * 100; return ($this->pagesScraped / $this->totalPages) * 100;
} }
} }

View File

@@ -8,4 +8,4 @@ enum ScrapingStatus: string
case IN_PROGRESS = 'in_progress'; case IN_PROGRESS = 'in_progress';
case COMPLETED = 'completed'; case COMPLETED = 'completed';
case FAILED = 'failed'; case FAILED = 'failed';
} }

View File

@@ -15,7 +15,8 @@ class Source
private readonly bool $isActive, private readonly bool $isActive,
private readonly DateTimeImmutable $createdAt, private readonly DateTimeImmutable $createdAt,
private readonly DateTimeImmutable $updatedAt private readonly DateTimeImmutable $updatedAt
) {} ) {
}
public function getId(): string public function getId(): string
{ {
@@ -56,4 +57,4 @@ class Source
{ {
return $this->updatedAt; return $this->updatedAt;
} }
} }

View File

@@ -15,4 +15,4 @@ class ChapterId
{ {
return $this->value; return $this->value;
} }
} }

View File

@@ -21,4 +21,4 @@ class ImageUrl
{ {
return pathinfo(parse_url($this->url, PHP_URL_PATH), PATHINFO_EXTENSION); return pathinfo(parse_url($this->url, PHP_URL_PATH), PATHINFO_EXTENSION);
} }
} }

View File

@@ -21,4 +21,4 @@ class PageNumber
{ {
return sprintf('%03d', $this->number); return sprintf('%03d', $this->number);
} }
} }

View File

@@ -2,7 +2,7 @@
namespace App\Domain\Scraping\Domain\Model\ValueObject; namespace App\Domain\Scraping\Domain\Model\ValueObject;
class SourceId class SourceId
{ {
public function __construct(private readonly string $value) public function __construct(private readonly string $value)
{ {
@@ -15,4 +15,4 @@ class SourceId
{ {
return $this->value; return $this->value;
} }
} }

View File

@@ -15,4 +15,4 @@ class TempDirectory
{ {
return $this->path; return $this->path;
} }
} }

View File

@@ -24,11 +24,9 @@ readonly class ScrapeChapterRequest
#[ApiProperty(description: 'ID du chapitre à scraper')] #[ApiProperty(description: 'ID du chapitre à scraper')]
#[Assert\NotBlank] #[Assert\NotBlank]
public string $chapterId, public string $chapterId,
#[ApiProperty(description: 'ID de la source à utiliser')] #[ApiProperty(description: 'ID de la source à utiliser')]
#[Assert\NotBlank] #[Assert\NotBlank]
public string $sourceId, public string $sourceId,
#[ApiProperty(description: 'ID du manga')] #[ApiProperty(description: 'ID du manga')]
#[Assert\NotBlank] #[Assert\NotBlank]
public string $mangaId, public string $mangaId,

View File

@@ -31,13 +31,10 @@ readonly class ScrapingStatusResponse
public function __construct( public function __construct(
#[ApiProperty(identifier: true)] #[ApiProperty(identifier: true)]
public string $jobId, public string $jobId,
#[ApiProperty] #[ApiProperty]
public string $status, public string $status,
#[ApiProperty] #[ApiProperty]
public ?float $progress = null, public ?float $progress = null,
#[ApiProperty] #[ApiProperty]
public ?string $error = null public ?string $error = null
) { ) {

View File

@@ -12,7 +12,8 @@ final class ScrapeChapterStateProcessor implements ProcessorInterface
{ {
public function __construct( public function __construct(
private readonly MessageBusInterface $commandBus private readonly MessageBusInterface $commandBus
) {} ) {
}
/** /**
* @param ScrapeChapterRequest $data * @param ScrapeChapterRequest $data

View File

@@ -11,7 +11,8 @@ class DoctrineMangaRepository implements MangaRepositoryInterface
{ {
public function __construct( public function __construct(
private readonly EntityManagerInterface $entityManager private readonly EntityManagerInterface $entityManager
) {} ) {
}
public function getById(string $id): ?Manga public function getById(string $id): ?Manga
{ {
@@ -19,4 +20,4 @@ class DoctrineMangaRepository implements MangaRepositoryInterface
return $manga ? $manga->toDomain() : null; return $manga ? $manga->toDomain() : null;
} }
} }

View File

@@ -11,16 +11,17 @@ class DoctrineSourceRepository implements SourceRepositoryInterface
{ {
public function __construct( public function __construct(
private readonly EntityManagerInterface $entityManager private readonly EntityManagerInterface $entityManager
) {} ) {
}
public function getById(string $id): ?Source public function getById(string $id): ?Source
{ {
$sourceEntity = $this->entityManager->getRepository(SourceEntityEntity::class)->find($id); $sourceEntity = $this->entityManager->getRepository(SourceEntityEntity::class)->find($id);
if (!$sourceEntity) { if (!$sourceEntity) {
return null; return null;
} }
return $sourceEntity->toDomain(); return $sourceEntity->toDomain();
} }
} }

View File

@@ -56,7 +56,7 @@ class MangaEntity
$entity->description = $manga->getDescription(); $entity->description = $manga->getDescription();
$entity->author = $manga->getAuthor(); $entity->author = $manga->getAuthor();
return $entity; return $entity;
} }

View File

@@ -45,7 +45,7 @@ class ScrapingJobEntity
$entity->status = $job->getStatus()->value; $entity->status = $job->getStatus()->value;
$entity->createdAt = $job->getCreatedAt(); $entity->createdAt = $job->getCreatedAt();
$entity->completedAt = $job->getCompletedAt(); $entity->completedAt = $job->getCompletedAt();
return $entity; return $entity;
} }
@@ -60,4 +60,4 @@ class ScrapingJobEntity
return $job; return $job;
} }
} }

View File

@@ -45,7 +45,7 @@ class SourceEntity
$entity->isActive = $source->isActive(); $entity->isActive = $source->isActive();
$entity->createdAt = $source->getCreatedAt(); $entity->createdAt = $source->getCreatedAt();
$entity->updatedAt = $source->getUpdatedAt(); $entity->updatedAt = $source->getUpdatedAt();
return $entity; return $entity;
} }
@@ -62,4 +62,4 @@ class SourceEntity
$this->updatedAt $this->updatedAt
); );
} }
} }

View File

@@ -4,20 +4,21 @@ namespace App\Domain\Scraping\Infrastructure\Service;
use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\HttpClient\HttpClientInterface;
class ImageDownloader class ImageDownloader
{ {
public function __construct( public function __construct(
private readonly HttpClientInterface $httpClient private readonly HttpClientInterface $httpClient
) {} ) {
}
public function download(string $url, string $destination): void public function download(string $url, string $destination): void
{ {
$response = $this->httpClient->request('GET', $url); $response = $this->httpClient->request('GET', $url);
if (!str_starts_with($response->getHeaders()['content-type'][0], 'image/')) { if (!str_starts_with($response->getHeaders()['content-type'][0], 'image/')) {
throw new \RuntimeException('Invalid content type'); throw new \RuntimeException('Invalid content type');
} }
file_put_contents($destination, $response->getContent()); file_put_contents($destination, $response->getContent());
} }
} }

View File

@@ -19,7 +19,8 @@ abstract class AbstractScraper implements ScraperInterface
public function __construct( public function __construct(
protected readonly ImageDownloader $imageDownloader, protected readonly ImageDownloader $imageDownloader,
protected readonly MessageBusInterface $eventBus protected readonly MessageBusInterface $eventBus
) {} ) {
}
public function createScrapingJob(string $mangaId, string $chapterId, string $sourceId): ScrapingJob public function createScrapingJob(string $mangaId, string $chapterId, string $sourceId): ScrapingJob
{ {
@@ -32,7 +33,7 @@ abstract class AbstractScraper implements ScraperInterface
} }
abstract public function scrape(ScrapingJob $job): void; abstract public function scrape(ScrapingJob $job): void;
abstract protected function scrapePages(ScrapingJob $job, Source $source): array; abstract protected function scrapePages(ScrapingJob $job, Source $source): array;
protected function cleanupTempDirectory(string $tempDir): void protected function cleanupTempDirectory(string $tempDir): void
@@ -82,4 +83,4 @@ abstract class AbstractScraper implements ScraperInterface
} }
abstract public function supports(string $sourceType): bool; abstract public function supports(string $sourceType): bool;
} }

View File

@@ -30,7 +30,7 @@ class HtmlScraper extends AbstractScraper
try { try {
$pages = $this->scrapePages($job, $sourceConfig); $pages = $this->scrapePages($job, $sourceConfig);
foreach ($pages as $index => $imageUrl) { foreach ($pages as $index => $imageUrl) {
$pageNumber = new PageNumber($index + 1); $pageNumber = new PageNumber($index + 1);
$extension = pathinfo(parse_url($imageUrl, PHP_URL_PATH), PATHINFO_EXTENSION); $extension = pathinfo(parse_url($imageUrl, PHP_URL_PATH), PATHINFO_EXTENSION);
@@ -43,7 +43,7 @@ class HtmlScraper extends AbstractScraper
$this->downloadImage($imageUrl, $destination); $this->downloadImage($imageUrl, $destination);
$job->addPage($pageNumber, new ImageUrl($imageUrl)); $job->addPage($pageNumber, new ImageUrl($imageUrl));
$this->dispatchProgressEvent($job, $index + 1, count($pages)); $this->dispatchProgressEvent($job, $index + 1, count($pages));
} }
@@ -61,7 +61,7 @@ class HtmlScraper extends AbstractScraper
if (!$sourceConfig['next_page_selector']) { if (!$sourceConfig['next_page_selector']) {
return $this->scrapeVerticalReader($job, $sourceConfig); return $this->scrapeVerticalReader($job, $sourceConfig);
} }
return $this->scrapeHorizontalReader($job, $sourceConfig); return $this->scrapeHorizontalReader($job, $sourceConfig);
} }
@@ -69,7 +69,7 @@ class HtmlScraper extends AbstractScraper
{ {
$html = $this->fetchHtml($this->buildChapterUrl($job, $sourceConfig)); $html = $this->fetchHtml($this->buildChapterUrl($job, $sourceConfig));
$crawler = new Crawler($html); $crawler = new Crawler($html);
return $crawler->filter($sourceConfig['image_selector']) return $crawler->filter($sourceConfig['image_selector'])
->each(function ($node) { ->each(function ($node) {
return $this->cleanImageUrl( return $this->cleanImageUrl(
@@ -86,11 +86,11 @@ class HtmlScraper extends AbstractScraper
while ($currentUrl) { while ($currentUrl) {
$html = $this->fetchHtml($currentUrl); $html = $this->fetchHtml($currentUrl);
$crawler = new Crawler($html); $crawler = new Crawler($html);
$imageUrl = $crawler->filter($sourceConfig['image_selector']) $imageUrl = $crawler->filter($sourceConfig['image_selector'])
->attr('src') ?: $crawler->filter($sourceConfig['image_selector']) ->attr('src') ?: $crawler->filter($sourceConfig['image_selector'])
->attr('data-src'); ->attr('data-src');
$pages[] = $this->cleanImageUrl($imageUrl); $pages[] = $this->cleanImageUrl($imageUrl);
$nextLink = $crawler->filter($sourceConfig['next_page_selector']); $nextLink = $crawler->filter($sourceConfig['next_page_selector']);
@@ -103,11 +103,11 @@ class HtmlScraper extends AbstractScraper
private function fetchHtml(string $url): string private function fetchHtml(string $url): string
{ {
$response = $this->httpClient->request('GET', $url); $response = $this->httpClient->request('GET', $url);
if ($response->getStatusCode() >= 400) { if ($response->getStatusCode() >= 400) {
throw new \RuntimeException('Failed to fetch page: ' . $url); throw new \RuntimeException('Failed to fetch page: ' . $url);
} }
return $response->getContent(); return $response->getContent();
} }
@@ -130,4 +130,4 @@ class HtmlScraper extends AbstractScraper
{ {
return 'html' === $sourceType; return 'html' === $sourceType;
} }
} }

View File

@@ -9,7 +9,6 @@ use Random\RandomException;
#[ORM\Entity(repositoryClass: ApiTokenRepository::class)] #[ORM\Entity(repositoryClass: ApiTokenRepository::class)]
class ApiToken class ApiToken
{ {
private const string PERSONAL_ACCESS_TOKEN_PREFIX = 'mgr_'; private const string PERSONAL_ACCESS_TOKEN_PREFIX = 'mgr_';
public const string SCOPE_USER_EDIT = 'ROLE_USER_EDIT'; public const string SCOPE_USER_EDIT = 'ROLE_USER_EDIT';
public const string SCOPE_PROJECT_CREATE = 'ROLE_PROJECT_CREATE'; public const string SCOPE_PROJECT_CREATE = 'ROLE_PROJECT_CREATE';

View File

@@ -21,24 +21,24 @@ class ExceptionListener
public function onKernelException(ExceptionEvent $event): void public function onKernelException(ExceptionEvent $event): void
{ {
// $exception = $event->getThrowable(); // $exception = $event->getThrowable();
// //
// $response = match(true) { // $response = match(true) {
// $exception instanceof FilterValidationException, // $exception instanceof FilterValidationException,
// $exception instanceof BadRequestException => $this->createResponse($exception, Response::HTTP_BAD_REQUEST), // $exception instanceof BadRequestException => $this->createResponse($exception, Response::HTTP_BAD_REQUEST),
// $exception instanceof NotFoundHttpException, // $exception instanceof NotFoundHttpException,
// $exception instanceof ItemNotFoundException => $this->createResponse($exception, Response::HTTP_NOT_FOUND), // $exception instanceof ItemNotFoundException => $this->createResponse($exception, Response::HTTP_NOT_FOUND),
// $exception instanceof AccessDeniedHttpException => $this->createResponse($exception, Response::HTTP_FORBIDDEN), // $exception instanceof AccessDeniedHttpException => $this->createResponse($exception, Response::HTTP_FORBIDDEN),
// $exception instanceof ValidationException, // $exception instanceof ValidationException,
// $exception instanceof NotNormalizableValueException => $this->createResponse($exception, Response::HTTP_UNPROCESSABLE_ENTITY), // $exception instanceof NotNormalizableValueException => $this->createResponse($exception, Response::HTTP_UNPROCESSABLE_ENTITY),
// default => null, // default => null,
// }; // };
// //
// if ($response) { // if ($response) {
// $event->setResponse($response); // $event->setResponse($response);
// }else{ // }else{
// $this->logger->error($exception->getMessage(), ['exception' => $exception]); // $this->logger->error($exception->getMessage(), ['exception' => $exception]);
// } // }
} }
private function createResponse(\Throwable $exception, int $statusCode): Response private function createResponse(\Throwable $exception, int $statusCode): Response

View File

@@ -19,8 +19,7 @@ class QueueStatusSubscriber implements EventSubscriberInterface
private ActivityService $activityService, private ActivityService $activityService,
private Connection $connection, private Connection $connection,
private ChapterRepository $chapterRepository private ChapterRepository $chapterRepository
) ) {
{
} }
public static function getSubscribedEvents(): array public static function getSubscribedEvents(): array

View File

@@ -30,8 +30,8 @@ use Zenstruck\Foundry\RepositoryProxy;
*/ */
final class UserFactory extends ModelFactory final class UserFactory extends ModelFactory
{ {
const array FIRST_NAMES = ["ALAIN", "ALEXANDRE", "ANDRÉ", "ANNIE", "ANTHONY", "AUDREY", "AURÉLIE", "BERNARD", "BRIGITTE", "BRUNO", "CATHERINE", "CEDRIC", "CHANTAL", "CHRISTELLE", "CHRISTIAN", "CHRISTIANE", "CHRISTINE", "CHRISTOPHE", "CLAUDE", "CORINNE", "CÉLINE", "DANIEL", "DANIELLE", "DAVID", "DENISE", "DIDIER", "DOMINIQUE", "ELODIE", "EMILIE", "ENZO", "ERIC", "FABRICE", "FLORENCE", "FRANCK", "FRANÇOISE", "FRÉDÉRIC", "GEORGES", "GERMAINE", "GUILLAUME", "GUY", "GÉRARD", "HENRI", "ISABELLE", "JACQUELINE", "JACQUES", "JEAN", "JEAN-CLAUDE", "JEAN-PIERRE", "JEANNE", "JEANNINE", "JEREMY", "JEROME", "JONATHAN", "JOSEPH", "JULIE", "JULIEN", "KARINE", "KEVIN", "LAETITIA", "LAURA", "LAURENCE", "LAURENT", "LOUIS", "LUCAS", "LÉA", "MADELEINE", "MANON", "MARCEL", "MARCELLE", "MARGUERITE", "MARIE", "MARINE", "MARTINE", "MAURICE", "MAXIME", "MICHEL", "MICHÈLE", "MONIQUE", "NATHALIE", "NICOLAS", "NICOLE", "ODETTE", "OLIVIER", "PASCAL", "PASCALE", "PATRICIA", "PATRICK", "PAUL", "PAULETTE", "PHILIPPE", "PIERRE", "RENÉ", "ROBERT", "ROGER", "ROMAIN", "SANDRA", "SANDRINE", "SERGE", "SOPHIE", "STÉPHANE", "STÉPHANIE", "SUZANNE", "SYLVIE", "SÉBASTIEN", "THIERRY", "THOMAS", "THÉO", "VALÉRIE", "VIRGINIE", "VÉRONIQUE", "YVETTE", "YVONNE"]; public const array FIRST_NAMES = ["ALAIN", "ALEXANDRE", "ANDRÉ", "ANNIE", "ANTHONY", "AUDREY", "AURÉLIE", "BERNARD", "BRIGITTE", "BRUNO", "CATHERINE", "CEDRIC", "CHANTAL", "CHRISTELLE", "CHRISTIAN", "CHRISTIANE", "CHRISTINE", "CHRISTOPHE", "CLAUDE", "CORINNE", "CÉLINE", "DANIEL", "DANIELLE", "DAVID", "DENISE", "DIDIER", "DOMINIQUE", "ELODIE", "EMILIE", "ENZO", "ERIC", "FABRICE", "FLORENCE", "FRANCK", "FRANÇOISE", "FRÉDÉRIC", "GEORGES", "GERMAINE", "GUILLAUME", "GUY", "GÉRARD", "HENRI", "ISABELLE", "JACQUELINE", "JACQUES", "JEAN", "JEAN-CLAUDE", "JEAN-PIERRE", "JEANNE", "JEANNINE", "JEREMY", "JEROME", "JONATHAN", "JOSEPH", "JULIE", "JULIEN", "KARINE", "KEVIN", "LAETITIA", "LAURA", "LAURENCE", "LAURENT", "LOUIS", "LUCAS", "LÉA", "MADELEINE", "MANON", "MARCEL", "MARCELLE", "MARGUERITE", "MARIE", "MARINE", "MARTINE", "MAURICE", "MAXIME", "MICHEL", "MICHÈLE", "MONIQUE", "NATHALIE", "NICOLAS", "NICOLE", "ODETTE", "OLIVIER", "PASCAL", "PASCALE", "PATRICIA", "PATRICK", "PAUL", "PAULETTE", "PHILIPPE", "PIERRE", "RENÉ", "ROBERT", "ROGER", "ROMAIN", "SANDRA", "SANDRINE", "SERGE", "SOPHIE", "STÉPHANE", "STÉPHANIE", "SUZANNE", "SYLVIE", "SÉBASTIEN", "THIERRY", "THOMAS", "THÉO", "VALÉRIE", "VIRGINIE", "VÉRONIQUE", "YVETTE", "YVONNE"];
const array LAST_NAMES = ["Adam", "Andre", "Antoine", "Arnaud", "Aubert", "Aubry", "Bailly", "Barbier", "Baron", "Barre", "Barthelemy", "Benard", "Benoit", "Berger", "Bernard", "Bertin", "Bertrand", "Besson", "Blanc", "Blanchard", "Bonnet", "Boucher", "Bouchet", "Boulanger", "Bourgeois", "Bouvier", "Boyer", "Breton", "Brun", "Brunet", "Carlier", "Caron", "Carpentier", "Carre", "Charles", "Charpentier", "Chauvin", "Chevalier", "Chevallier", "Clement", "Colin", "Collet", "Collin", "Cordier", "Cousin", "Da Silva", "Daniel", "David", "Delaunay", "Denis", "Deschamps", "Dubois", "Dufour", "Dumas", "Dumont", "Dupont", "Dupuis", "Dupuy", "Durand", "Duval", "Etienne", "Fabre", "Faure", "Fernandez", "Fleury", "Fontaine", "Fournier", "Francois", "Gaillard", "Garcia", "Garnier", "Gauthier", "Gautier", "Gay", "Gerard", "Germain", "Gilbert", "Gillet", "Girard", "Giraud", "Gonzalez", "Grondin", "Guerin", "Guichard", "Guillaume", "Guillot", "Guyot", "Hamon", "Henry", "Herve", "Hoarau", "Hubert", "Huet", "Humbert", "Jacob", "Jacquet", "Jean", "Joly", "Julien", "Klein", "Lacroix", "Lambert", "Lamy", "Langlois", "Laporte", "Laurent", "Le Gall", "Le Goff", "Le Roux", "Leblanc", "Lebrun", "Leclerc", "Leclercq", "Lecomte", "Lefebvre", "Lefevre", "Leger", "Legrand", "Lejeune", "Lemaire", "Lemaitre", "Lemoine", "Leroux", "Leroy", "Leveque", "Lopez", "Louis", "Lucas", "Maillard", "Mallet", "Marchal", "Marchand", "Marechal", "Marie", "Martin", "Martinez", "Marty", "Masson", "Mathieu", "Menard", "Mercier", "Meunier", "Meyer", "Michaud", "Michel", "Millet", "Monnier", "Moreau", "Morel", "Morin", "Moulin", "Muller", "Nicolas", "Noel", "Olivier", "Paris", "Pasquier", "Payet", "Pelletier", "Perez", "Perret", "Perrier", "Perrin", "Perrot", "Petit", "Philippe", "Picard", "Pichon", "Pierre", "Poirier", "Poulain", "Prevost", "Remy", "Renard", "Renaud", "Renault", "Rey", "Reynaud", "Richard", "Riviere", "Robert", "Robin", "Roche", "Rodriguez", "Roger", "Rolland", "Rousseau", "Roussel", "Roux", "Roy", "Royer", "Sanchez", "Schmitt", "Schneider", "Simon", "Tessier", "Thomas", "Vasseur", "Vidal", "Vincent", "Weber"]; public const array LAST_NAMES = ["Adam", "Andre", "Antoine", "Arnaud", "Aubert", "Aubry", "Bailly", "Barbier", "Baron", "Barre", "Barthelemy", "Benard", "Benoit", "Berger", "Bernard", "Bertin", "Bertrand", "Besson", "Blanc", "Blanchard", "Bonnet", "Boucher", "Bouchet", "Boulanger", "Bourgeois", "Bouvier", "Boyer", "Breton", "Brun", "Brunet", "Carlier", "Caron", "Carpentier", "Carre", "Charles", "Charpentier", "Chauvin", "Chevalier", "Chevallier", "Clement", "Colin", "Collet", "Collin", "Cordier", "Cousin", "Da Silva", "Daniel", "David", "Delaunay", "Denis", "Deschamps", "Dubois", "Dufour", "Dumas", "Dumont", "Dupont", "Dupuis", "Dupuy", "Durand", "Duval", "Etienne", "Fabre", "Faure", "Fernandez", "Fleury", "Fontaine", "Fournier", "Francois", "Gaillard", "Garcia", "Garnier", "Gauthier", "Gautier", "Gay", "Gerard", "Germain", "Gilbert", "Gillet", "Girard", "Giraud", "Gonzalez", "Grondin", "Guerin", "Guichard", "Guillaume", "Guillot", "Guyot", "Hamon", "Henry", "Herve", "Hoarau", "Hubert", "Huet", "Humbert", "Jacob", "Jacquet", "Jean", "Joly", "Julien", "Klein", "Lacroix", "Lambert", "Lamy", "Langlois", "Laporte", "Laurent", "Le Gall", "Le Goff", "Le Roux", "Leblanc", "Lebrun", "Leclerc", "Leclercq", "Lecomte", "Lefebvre", "Lefevre", "Leger", "Legrand", "Lejeune", "Lemaire", "Lemaitre", "Lemoine", "Leroux", "Leroy", "Leveque", "Lopez", "Louis", "Lucas", "Maillard", "Mallet", "Marchal", "Marchand", "Marechal", "Marie", "Martin", "Martinez", "Marty", "Masson", "Mathieu", "Menard", "Mercier", "Meunier", "Meyer", "Michaud", "Michel", "Millet", "Monnier", "Moreau", "Morel", "Morin", "Moulin", "Muller", "Nicolas", "Noel", "Olivier", "Paris", "Pasquier", "Payet", "Pelletier", "Perez", "Perret", "Perrier", "Perrin", "Perrot", "Petit", "Philippe", "Picard", "Pichon", "Pierre", "Poirier", "Poulain", "Prevost", "Remy", "Renard", "Renaud", "Renault", "Rey", "Reynaud", "Richard", "Riviere", "Robert", "Robin", "Roche", "Rodriguez", "Roger", "Rolland", "Rousseau", "Roussel", "Roux", "Roy", "Royer", "Sanchez", "Schmitt", "Schneider", "Simon", "Tessier", "Thomas", "Vasseur", "Vidal", "Vincent", "Weber"];
/** /**
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services
@@ -63,7 +63,7 @@ final class UserFactory extends ModelFactory
protected function initialize(): self protected function initialize(): self
{ {
return $this return $this
->afterInstantiate(function(User $user): void { ->afterInstantiate(function (User $user): void {
$user->setPassword($this->passwordHasher->hashPassword( $user->setPassword($this->passwordHasher->hashPassword(
$user, $user,
$user->getPassword() $user->getPassword()

View File

@@ -6,6 +6,6 @@ use App\Entity\Manga;
interface ContentProviderInterface interface ContentProviderInterface
{ {
public function getAvailableContent(Manga $manga): array; public function getAvailableContent(Manga $manga): array;
public function getContent(Manga $manga): array; public function getContent(Manga $manga): array;
} }

View File

@@ -17,7 +17,7 @@ class Kernel extends BaseKernel
#[Override] #[Override]
protected function build(ContainerBuilder $container): void protected function build(ContainerBuilder $container): void
{ {
$container->addCompilerPass(new class() implements CompilerPassInterface { $container->addCompilerPass(new class () implements CompilerPassInterface {
public function process(ContainerBuilder $container): void public function process(ContainerBuilder $container): void
{ {
$container->getDefinition('doctrine.orm.default_configuration') $container->getDefinition('doctrine.orm.default_configuration')

View File

@@ -4,7 +4,6 @@ namespace App\Manager\Toolbar\Element;
class ToolbarButton extends AbstractToolbarElement class ToolbarButton extends AbstractToolbarElement
{ {
protected array $data; protected array $data;
public function __construct(string $icon, string $label, string $action, array $data = []) public function __construct(string $icon, string $label, string $action, array $data = [])

View File

@@ -9,15 +9,15 @@ final class RefreshAndDownloadChapters
* to hold the data for this message class. * to hold the data for this message class.
*/ */
// private $name; // private $name;
// public function __construct(string $name) // public function __construct(string $name)
// { // {
// $this->name = $name; // $this->name = $name;
// } // }
// public function getName(): string // public function getName(): string
// { // {
// return $this->name; // return $this->name;
// } // }
} }

View File

@@ -21,8 +21,7 @@ final readonly class RefreshAndDownloadChaptersHandler
private MangadexProvider $mangadexProvider, private MangadexProvider $mangadexProvider,
private EntityManagerInterface $entityManager, private EntityManagerInterface $entityManager,
private MessageBusInterface $bus private MessageBusInterface $bus
) ) {
{
} }

View File

@@ -18,8 +18,7 @@ readonly class RefreshMetadataHandler
private MangadexProvider $mangadexProvider, private MangadexProvider $mangadexProvider,
private EntityManagerInterface $entityManager, private EntityManagerInterface $entityManager,
private NotificationService $notificationService private NotificationService $notificationService
) ) {
{
} }
public function __invoke(RefreshMetadata $message): void public function __invoke(RefreshMetadata $message): void

View File

@@ -21,28 +21,28 @@ class ApiTokenRepository extends ServiceEntityRepository
parent::__construct($registry, ApiToken::class); parent::__construct($registry, ApiToken::class);
} }
// /** // /**
// * @return ApiToken[] Returns an array of ApiToken objects // * @return ApiToken[] Returns an array of ApiToken objects
// */ // */
// public function findByExampleField($value): array // public function findByExampleField($value): array
// { // {
// return $this->createQueryBuilder('a') // return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val') // ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->orderBy('a.id', 'ASC') // ->orderBy('a.id', 'ASC')
// ->setMaxResults(10) // ->setMaxResults(10)
// ->getQuery() // ->getQuery()
// ->getResult() // ->getResult()
// ; // ;
// } // }
// public function findOneBySomeField($value): ?ApiToken // public function findOneBySomeField($value): ?ApiToken
// { // {
// return $this->createQueryBuilder('a') // return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val') // ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->getQuery() // ->getQuery()
// ->getOneOrNullResult() // ->getOneOrNullResult()
// ; // ;
// } // }
} }

View File

@@ -21,28 +21,28 @@ class AppSettingsRepository extends ServiceEntityRepository
parent::__construct($registry, AppSettings::class); parent::__construct($registry, AppSettings::class);
} }
// /** // /**
// * @return AppSettings[] Returns an array of AppSettings objects // * @return AppSettings[] Returns an array of AppSettings objects
// */ // */
// public function findByExampleField($value): array // public function findByExampleField($value): array
// { // {
// return $this->createQueryBuilder('a') // return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val') // ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->orderBy('a.id', 'ASC') // ->orderBy('a.id', 'ASC')
// ->setMaxResults(10) // ->setMaxResults(10)
// ->getQuery() // ->getQuery()
// ->getResult() // ->getResult()
// ; // ;
// } // }
// public function findOneBySomeField($value): ?AppSettings // public function findOneBySomeField($value): ?AppSettings
// { // {
// return $this->createQueryBuilder('a') // return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val') // ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->getQuery() // ->getQuery()
// ->getOneOrNullResult() // ->getOneOrNullResult()
// ; // ;
// } // }
} }

View File

@@ -39,28 +39,28 @@ class ChapterRepository extends ServiceEntityRepository
} }
} }
// /** // /**
// * @return Chapter[] Returns an array of Chapter objects // * @return Chapter[] Returns an array of Chapter objects
// */ // */
// public function findByExampleField($value): array // public function findByExampleField($value): array
// { // {
// return $this->createQueryBuilder('c') // return $this->createQueryBuilder('c')
// ->andWhere('c.exampleField = :val') // ->andWhere('c.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->orderBy('c.id', 'ASC') // ->orderBy('c.id', 'ASC')
// ->setMaxResults(10) // ->setMaxResults(10)
// ->getQuery() // ->getQuery()
// ->getResult() // ->getResult()
// ; // ;
// } // }
// public function findOneBySomeField($value): ?Chapter // public function findOneBySomeField($value): ?Chapter
// { // {
// return $this->createQueryBuilder('c') // return $this->createQueryBuilder('c')
// ->andWhere('c.exampleField = :val') // ->andWhere('c.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->getQuery() // ->getQuery()
// ->getOneOrNullResult() // ->getOneOrNullResult()
// ; // ;
// } // }
} }

View File

@@ -21,28 +21,28 @@ class ContentSourceRepository extends ServiceEntityRepository
parent::__construct($registry, ContentSource::class); parent::__construct($registry, ContentSource::class);
} }
// /** // /**
// * @return ContentSource[] Returns an array of ContentSource objects // * @return ContentSource[] Returns an array of ContentSource objects
// */ // */
// public function findByExampleField($value): array // public function findByExampleField($value): array
// { // {
// return $this->createQueryBuilder('c') // return $this->createQueryBuilder('c')
// ->andWhere('c.exampleField = :val') // ->andWhere('c.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->orderBy('c.id', 'ASC') // ->orderBy('c.id', 'ASC')
// ->setMaxResults(10) // ->setMaxResults(10)
// ->getQuery() // ->getQuery()
// ->getResult() // ->getResult()
// ; // ;
// } // }
// public function findOneBySomeField($value): ?ContentSource // public function findOneBySomeField($value): ?ContentSource
// { // {
// return $this->createQueryBuilder('c') // return $this->createQueryBuilder('c')
// ->andWhere('c.exampleField = :val') // ->andWhere('c.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->getQuery() // ->getQuery()
// ->getOneOrNullResult() // ->getOneOrNullResult()
// ; // ;
// } // }
} }

View File

@@ -116,28 +116,28 @@ class MangaRepository extends ServiceEntityRepository
return $qb->getQuery()->getResult(); return $qb->getQuery()->getResult();
} }
// /** // /**
// * @return Manga[] Returns an array of Manga objects // * @return Manga[] Returns an array of Manga objects
// */ // */
// public function findByExampleField($value): array // public function findByExampleField($value): array
// { // {
// return $this->createQueryBuilder('m') // return $this->createQueryBuilder('m')
// ->andWhere('m.exampleField = :val') // ->andWhere('m.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->orderBy('m.id', 'ASC') // ->orderBy('m.id', 'ASC')
// ->setMaxResults(10) // ->setMaxResults(10)
// ->getQuery() // ->getQuery()
// ->getResult() // ->getResult()
// ; // ;
// } // }
// public function findOneBySomeField($value): ?Manga // public function findOneBySomeField($value): ?Manga
// { // {
// return $this->createQueryBuilder('m') // return $this->createQueryBuilder('m')
// ->andWhere('m.exampleField = :val') // ->andWhere('m.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->getQuery() // ->getQuery()
// ->getOneOrNullResult() // ->getOneOrNullResult()
// ; // ;
// } // }
} }

View File

@@ -39,28 +39,28 @@ class PageRepository extends ServiceEntityRepository
} }
} }
// /** // /**
// * @return Page[] Returns an array of Page objects // * @return Page[] Returns an array of Page objects
// */ // */
// public function findByExampleField($value): array // public function findByExampleField($value): array
// { // {
// return $this->createQueryBuilder('p') // return $this->createQueryBuilder('p')
// ->andWhere('p.exampleField = :val') // ->andWhere('p.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->orderBy('p.id', 'ASC') // ->orderBy('p.id', 'ASC')
// ->setMaxResults(10) // ->setMaxResults(10)
// ->getQuery() // ->getQuery()
// ->getResult() // ->getResult()
// ; // ;
// } // }
// public function findOneBySomeField($value): ?Page // public function findOneBySomeField($value): ?Page
// { // {
// return $this->createQueryBuilder('p') // return $this->createQueryBuilder('p')
// ->andWhere('p.exampleField = :val') // ->andWhere('p.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->getQuery() // ->getQuery()
// ->getOneOrNullResult() // ->getOneOrNullResult()
// ; // ;
// } // }
} }

View File

@@ -39,28 +39,28 @@ class SourceRepository extends ServiceEntityRepository
} }
} }
// /** // /**
// * @return Source[] Returns an array of Source objects // * @return Source[] Returns an array of Source objects
// */ // */
// public function findByExampleField($value): array // public function findByExampleField($value): array
// { // {
// return $this->createQueryBuilder('s') // return $this->createQueryBuilder('s')
// ->andWhere('s.exampleField = :val') // ->andWhere('s.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->orderBy('s.id', 'ASC') // ->orderBy('s.id', 'ASC')
// ->setMaxResults(10) // ->setMaxResults(10)
// ->getQuery() // ->getQuery()
// ->getResult() // ->getResult()
// ; // ;
// } // }
// public function findOneBySomeField($value): ?Source // public function findOneBySomeField($value): ?Source
// { // {
// return $this->createQueryBuilder('s') // return $this->createQueryBuilder('s')
// ->andWhere('s.exampleField = :val') // ->andWhere('s.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->getQuery() // ->getQuery()
// ->getOneOrNullResult() // ->getOneOrNullResult()
// ; // ;
// } // }
} }

View File

@@ -40,28 +40,28 @@ class UserRepository extends ServiceEntityRepository implements PasswordUpgrader
$this->getEntityManager()->flush(); $this->getEntityManager()->flush();
} }
// /** // /**
// * @return User[] Returns an array of User objects // * @return User[] Returns an array of User objects
// */ // */
// public function findByExampleField($value): array // public function findByExampleField($value): array
// { // {
// return $this->createQueryBuilder('u') // return $this->createQueryBuilder('u')
// ->andWhere('u.exampleField = :val') // ->andWhere('u.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->orderBy('u.id', 'ASC') // ->orderBy('u.id', 'ASC')
// ->setMaxResults(10) // ->setMaxResults(10)
// ->getQuery() // ->getQuery()
// ->getResult() // ->getResult()
// ; // ;
// } // }
// public function findOneBySomeField($value): ?User // public function findOneBySomeField($value): ?User
// { // {
// return $this->createQueryBuilder('u') // return $this->createQueryBuilder('u')
// ->andWhere('u.exampleField = :val') // ->andWhere('u.exampleField = :val')
// ->setParameter('val', $value) // ->setParameter('val', $value)
// ->getQuery() // ->getQuery()
// ->getOneOrNullResult() // ->getOneOrNullResult()
// ; // ;
// } // }
} }

View File

@@ -12,7 +12,6 @@ use Symfony\Contracts\Cache\CacheInterface;
#[AsSchedule] #[AsSchedule]
class MainSchedule implements ScheduleProviderInterface class MainSchedule implements ScheduleProviderInterface
{ {
public function __construct(private CacheInterface $cache) public function __construct(private CacheInterface $cache)
{ {
} }

View File

@@ -10,7 +10,6 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
readonly class ApiTokenHandler implements AccessTokenHandlerInterface readonly class ApiTokenHandler implements AccessTokenHandlerInterface
{ {
public function __construct(private ApiTokenRepository $apiTokenRepository) public function __construct(private ApiTokenRepository $apiTokenRepository)
{ {
@@ -24,7 +23,7 @@ readonly class ApiTokenHandler implements AccessTokenHandlerInterface
throw new BadCredentialsException(); throw new BadCredentialsException();
} }
if(!$token->isValid()){ if(!$token->isValid()) {
throw new CustomUserMessageAuthenticationException('Token expired'); throw new CustomUserMessageAuthenticationException('Token expired');
} }

View File

@@ -41,7 +41,7 @@ class CbrToCbzConverter
$cbzFileName = pathinfo($cbrPath, PATHINFO_FILENAME) . '.cbz'; $cbzFileName = pathinfo($cbrPath, PATHINFO_FILENAME) . '.cbz';
$cbzPath = $this->tempDir . '/' . $cbzFileName; $cbzPath = $this->tempDir . '/' . $cbzFileName;
$zip = new \ZipArchive(); $zip = new \ZipArchive();
if ($zip->open($cbzPath, \ZipArchive::CREATE) !== TRUE) { if ($zip->open($cbzPath, \ZipArchive::CREATE) !== true) {
throw new \RuntimeException("Cannot create ZIP file"); throw new \RuntimeException("Cannot create ZIP file");
} }

View File

@@ -17,8 +17,7 @@ readonly class MangaImportService
private EntityManagerInterface $entityManager, private EntityManagerInterface $entityManager,
private ChapterRepository $chapterRepository, private ChapterRepository $chapterRepository,
private SluggerInterface $slugger private SluggerInterface $slugger
) ) {
{
} }
/** /**

View File

@@ -26,15 +26,14 @@ use Symfony\Component\Panther\Client as PantherClient;
class MangaScraperService class MangaScraperService
{ {
const string PUBLIC_CBZ = '/public/cbz'; public const string PUBLIC_CBZ = '/public/cbz';
public function __construct( public function __construct(
private readonly string $projectDir, private readonly string $projectDir,
private readonly EventDispatcherInterface $eventDispatcher, private readonly EventDispatcherInterface $eventDispatcher,
private readonly EntityManagerInterface $entityManager, private readonly EntityManagerInterface $entityManager,
private readonly MangaRepository $mangaRepository, private readonly MangaRepository $mangaRepository,
) ) {
{
} }
private function extractMangaPageData(string $html, ContentSource $mangaSource): array private function extractMangaPageData(string $html, ContentSource $mangaSource): array
@@ -43,11 +42,11 @@ class MangaScraperService
$imgUrl = $crawler->filter($mangaSource->getImageSelector())->attr('src') $imgUrl = $crawler->filter($mangaSource->getImageSelector())->attr('src')
?? $crawler->filter($mangaSource->getImageSelector())->attr('data-src'); ?? $crawler->filter($mangaSource->getImageSelector())->attr('data-src');
// dd($imgUrl); // dd($imgUrl);
// if (empty($imgUrl)) { // if (empty($imgUrl)) {
// throw new \Exception('No valid image found on the page.'); // throw new \Exception('No valid image found on the page.');
// } // }
$nextLink = $crawler->filter($mangaSource->getNextPageSelector()); $nextLink = $crawler->filter($mangaSource->getNextPageSelector());
$nextUrl = $nextLink->count() > 0 ? $nextLink->attr('href') : null; $nextUrl = $nextLink->count() > 0 ? $nextLink->attr('href') : null;
@@ -204,7 +203,7 @@ class MangaScraperService
} }
} }
} catch (\Exception $e) { } catch (\Exception $e) {
// $this->logger->warning('Erreur lors de la sélection du chapitre : ' . $e->getMessage()); // $this->logger->warning('Erreur lors de la sélection du chapitre : ' . $e->getMessage());
$pantherClient->close(); $pantherClient->close();
return false; return false;
} }
@@ -221,7 +220,7 @@ class MangaScraperService
} }
} catch (\Exception $e) { } catch (\Exception $e) {
throw $e; throw $e;
// $this->logger->warning('Erreur lors du scraping du chapitre ' . $chapter->getNumber() . ' du manga ' . $manga->getTitle() . ': ' . $e->getMessage()); // $this->logger->warning('Erreur lors du scraping du chapitre ' . $chapter->getNumber() . ' du manga ' . $manga->getTitle() . ': ' . $e->getMessage());
} finally { } finally {
$pantherClient->close(); $pantherClient->close();
} }
@@ -295,7 +294,7 @@ class MangaScraperService
$pageNumber++; $pageNumber++;
} catch (\Exception $e) { } catch (\Exception $e) {
throw $e; throw $e;
// $this->logger->warning('Erreur lors du scraping de la page ' . $pageNumber . ' du chapitre ' . $chapter->getNumber() . ': ' . $e->getMessage()); // $this->logger->warning('Erreur lors du scraping de la page ' . $pageNumber . ' du chapitre ' . $chapter->getNumber() . ': ' . $e->getMessage());
break; break;
} }
} }
@@ -308,10 +307,10 @@ class MangaScraperService
// Appeler le script Puppeteer avec les paramètres nécessaires // Appeler le script Puppeteer avec les paramètres nécessaires
$output = []; $output = [];
$command = sprintf('node puppeteer-script.js "%s" "%s" "%s" 2>&1', $url, $imageSelector, $nextButtonSelector); // Redirect stderr to stdout $command = sprintf('node puppeteer-script.js "%s" "%s" "%s" 2>&1', $url, $imageSelector, $nextButtonSelector); // Redirect stderr to stdout
// dump($command); // dump($command);
// exec($command, $output, $return_var); // exec($command, $output, $return_var);
// dd($command, $output); // dd($command, $output);
// Convertir la sortie JSON en tableau PHP // Convertir la sortie JSON en tableau PHP
return json_decode(implode("", $output), true); return json_decode(implode("", $output), true);
@@ -455,8 +454,8 @@ class MangaScraperService
$this->downloadAndSaveImage($imgUrl, $imagePath); $this->downloadAndSaveImage($imgUrl, $imagePath);
// $event = new PageScrappingProgressEvent($chapter->getId(), $index + 1, 0); // $event = new PageScrappingProgressEvent($chapter->getId(), $index + 1, 0);
// $this->eventDispatcher->dispatch($event, PageScrappingProgressEvent::NAME); // $this->eventDispatcher->dispatch($event, PageScrappingProgressEvent::NAME);
$pageData[] = [ $pageData[] = [
'image_url' => $imgUrl, 'image_url' => $imgUrl,
@@ -516,13 +515,13 @@ class MangaScraperService
if (str_starts_with($contentType, 'image/')) { if (str_starts_with($contentType, 'image/')) {
file_put_contents($destinationPath, $response->getBody()->getContents()); file_put_contents($destinationPath, $response->getBody()->getContents());
// if ($this->scrapingType === 'mangadex') { // if ($this->scrapingType === 'mangadex') {
// $this->sendReport($imageUrl, true, $isCached, (int)$contentLength, ($endTime - $startTime) * 1000); // $this->sendReport($imageUrl, true, $isCached, (int)$contentLength, ($endTime - $startTime) * 1000);
// } // }
} else { } else {
// if ($this->scrapingType === 'mangadex') { // if ($this->scrapingType === 'mangadex') {
// $this->sendReport($imageUrl, false, $isCached, (int)$contentLength, ($endTime - $startTime) * 1000); // $this->sendReport($imageUrl, false, $isCached, (int)$contentLength, ($endTime - $startTime) * 1000);
// } // }
throw new \Exception('Le contenu récupéré n\'est pas une image. Type de contenu : ' . $contentType); throw new \Exception('Le contenu récupéré n\'est pas une image. Type de contenu : ' . $contentType);
} }
} catch } catch
@@ -582,7 +581,7 @@ class MangaScraperService
{ {
$zip = new \ZipArchive(); $zip = new \ZipArchive();
if ($zip->open($cbzFilePath, \ZipArchive::CREATE) === TRUE) { if ($zip->open($cbzFilePath, \ZipArchive::CREATE) === true) {
foreach ($pageData as $page) { foreach ($pageData as $page) {
$zip->addFile($page['local_image_url'], basename($page['local_image_url'])); $zip->addFile($page['local_image_url'], basename($page['local_image_url']));
} }
@@ -593,7 +592,8 @@ class MangaScraperService
private function generateCbzPath(Manga $manga, Chapter $chapter): string private function generateCbzPath(Manga $manga, Chapter $chapter): string
{ {
$volumeDir = $this->createDirectories($manga, $chapter->getVolume()); $volumeDir = $this->createDirectories($manga, $chapter->getVolume());
$fileName = sprintf('%s_vol%d_ch%s.cbz', $fileName = sprintf(
'%s_vol%d_ch%s.cbz',
$manga->getSlug(), $manga->getSlug(),
$chapter->getVolume(), $chapter->getVolume(),
$chapter->getNumber() $chapter->getNumber()

View File

@@ -54,7 +54,8 @@ abstract class AbstractScraper implements ScraperInterface
{ {
$mangaDir = $this->fileSystemManager->createMangaDirectory($manga->getSlug(), $manga->getPublicationYear()); $mangaDir = $this->fileSystemManager->createMangaDirectory($manga->getSlug(), $manga->getPublicationYear());
$volumeDir = $this->fileSystemManager->createVolumeDirectory($mangaDir, $chapter->getVolume()); $volumeDir = $this->fileSystemManager->createVolumeDirectory($mangaDir, $chapter->getVolume());
$fileName = sprintf('%s_vol%d_ch%s.cbz', $fileName = sprintf(
'%s_vol%d_ch%s.cbz',
$manga->getSlug(), $manga->getSlug(),
$chapter->getVolume(), $chapter->getVolume(),
$chapter->getNumber() $chapter->getNumber()

View File

@@ -21,10 +21,10 @@ final class DownloadChapter
public function downloadChapter(MangaRepository $mangaRepository, ChapterRepository $chapterRepository): int public function downloadChapter(MangaRepository $mangaRepository, ChapterRepository $chapterRepository): int
{ {
// $mangaSlug = $this->mangaSlug; // $mangaSlug = $this->mangaSlug;
// $chapter = $this->chapter; // $chapter = $this->chapter;
// $manga = $mangaRepository->findOneBy(['slug' => $mangaSlug]); // $manga = $mangaRepository->findOneBy(['slug' => $mangaSlug]);
// $chapter = $chapterRepository->findOneBy(['manga' => $manga, 'number' => $chapter]); // $chapter = $chapterRepository->findOneBy(['manga' => $manga, 'number' => $chapter]);
return 0; return 0;

View File

@@ -11,6 +11,6 @@ class DropdownMenu
{ {
use DefaultActionTrait; use DefaultActionTrait;
#[LiveProp (writable: true)] #[LiveProp(writable: true)]
public ?array $items = null; public ?array $items = null;
} }

View File

@@ -14,7 +14,7 @@ final class Search
{ {
use DefaultActionTrait; use DefaultActionTrait;
#[LiveProp (writable: true)] #[LiveProp(writable: true)]
public ?string $query = null; public ?string $query = null;
public function __construct(private readonly MangaRepository $mangaRepository) public function __construct(private readonly MangaRepository $mangaRepository)

View File

@@ -10,6 +10,6 @@ use Symfony\UX\LiveComponent\DefaultActionTrait;
final class ToolBarButton final class ToolBarButton
{ {
use DefaultActionTrait; use DefaultActionTrait;
#[LiveProp (writable: true)] #[LiveProp(writable: true)]
public ?array $data = null; public ?array $data = null;
} }