126 lines
4.2 KiB
PHP
126 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Service;
|
|
|
|
use App\Entity\Chapter;
|
|
use App\Entity\Manga;
|
|
use App\Interface\ClientInterface;
|
|
use App\Interface\MetadataProviderInterface;
|
|
use Doctrine\Common\Collections\ArrayCollection;
|
|
use Doctrine\Common\Collections\Collection;
|
|
use Symfony\Component\String\Slugger\SluggerInterface;
|
|
|
|
readonly class MangadexProvider implements MetadataProviderInterface
|
|
{
|
|
public function __construct(private ClientInterface $client, private SluggerInterface $slugger)
|
|
{
|
|
}
|
|
|
|
public function search(?string $title): Collection
|
|
{
|
|
if($title === null) {
|
|
return new ArrayCollection();
|
|
}
|
|
|
|
$results = $this->client->get('/manga', [
|
|
'title' => $title,
|
|
'contentRating' => ['safe', 'suggestive'],
|
|
'includes' => ['cover_art', 'author'],
|
|
'limit' => 25
|
|
]);
|
|
|
|
$mangas = [];
|
|
foreach ($results['data'] as $result) {
|
|
$mangas[] = (new Manga())
|
|
->setExternalId($result['id'])
|
|
->setTitle($result['attributes']['title']['en'])
|
|
->setSlug($this->slugger->slug($result['attributes']['title']['en'])->lower())
|
|
->setDescription($result['attributes']['description']['fr'] ?? $result['attributes']['description']['en'] ?? '')
|
|
->setPublicationYear($result['attributes']['year'])
|
|
;
|
|
$tags = [];
|
|
foreach($result['attributes']['tags'] as $tag){
|
|
$tags[] = $tag['attributes']['name']['en'];
|
|
}
|
|
|
|
$mangas[count($mangas) - 1]->setGenres($tags);
|
|
|
|
foreach($result['relationships'] as $relationship) {
|
|
if($relationship['type'] === 'author') {
|
|
$mangas[count($mangas) - 1]->setAuthor($relationship['attributes']['name']);
|
|
}
|
|
|
|
if($relationship['type'] === 'cover_art') {
|
|
$mangas[count($mangas) - 1]->setImageUrl('https://mangadex.org/covers/' . $result['id'] . '/' .$relationship['attributes']['fileName']);
|
|
}
|
|
}
|
|
}
|
|
|
|
$test = array_map(fn($manga) => $manga->getExternalId(), $mangas);
|
|
|
|
$ratings = $this->client->get('/statistics/manga', [
|
|
'manga' => $test
|
|
]);
|
|
|
|
foreach($mangas as $manga) {
|
|
$manga->setRating($ratings['statistics'][$manga->getExternalId()]['rating']['average']);
|
|
}
|
|
|
|
return new ArrayCollection($mangas);
|
|
}
|
|
|
|
public function getFeed(Manga $manga): Manga
|
|
{
|
|
if($manga->getExternalId() === null) {
|
|
return $manga;
|
|
}
|
|
|
|
$chapters = [];
|
|
$page = 0;
|
|
|
|
do {
|
|
$results = $this->getFeedWithPagination($manga->getExternalId(), $page);
|
|
if (isset($results['data'])) {
|
|
$chapters = array_merge($chapters, $results['data']);
|
|
} else {
|
|
break;
|
|
}
|
|
$page++;
|
|
} while (count($chapters) < $results['total']);
|
|
|
|
foreach($chapters as $result) {
|
|
$chapterNumber = (float)$result['attributes']['chapter'];
|
|
|
|
// Utilisez la méthode exists de Doctrine pour vérifier si un chapitre avec le même numéro existe déjà
|
|
$chapterExists = $manga->getChapters()->exists(function($key, $existingChapter) use ($chapterNumber) {
|
|
return $existingChapter->getNumber() === $chapterNumber;
|
|
});
|
|
|
|
// Si le chapitre existe déjà, on skip
|
|
if ($chapterExists) {
|
|
continue;
|
|
}
|
|
|
|
// Créez et ajoutez le nouveau chapitre
|
|
$chapter = new Chapter();
|
|
$chapter->setNumber($chapterNumber)
|
|
->setTitle($result['attributes']['title'])
|
|
->setVolume((int)$result['attributes']['volume'] ?? null);
|
|
|
|
$manga->addChapter($chapter);
|
|
}
|
|
|
|
return $manga;
|
|
}
|
|
|
|
private function getFeedWithPagination(string $externalId, int $page): array
|
|
{
|
|
return $this->client->get('/manga/' . $externalId . '/feed', [
|
|
'limit' => 500,
|
|
'translatedLanguage' =>['en'],
|
|
'order' => ['chapter' => 'asc'],
|
|
'offset' => $page * 500
|
|
]);
|
|
}
|
|
}
|