client->searchManga($title); if (empty($results['data'])) { return new MangaCollection([]); } $mangas = $this->createMangasFromResults($results['data']); $this->enrichWithRatings($mangas); usort($mangas, fn ($a, $b) => ($b->getRating() ?? 0) <=> ($a->getRating() ?? 0)); return new MangaCollection($mangas); } /** * @param array $results * @return Manga[] */ private function createMangasFromResults(array $results): array { $mangas = []; foreach ($results as $result) { $manga = $this->createMangaFromResult($result); if ($manga !== null) { $mangas[] = $manga; } } return $mangas; } private function createMangaFromResult(array $result): ?Manga { try { $attributes = $result['attributes']; $title = $attributes['title']['en'] ?? null; if (!$title) { return null; } $genres = array_map( fn ($tag) => $tag['attributes']['name']['en'], $attributes['tags'] ); $author = ''; $imageUrl = null; foreach ($result['relationships'] as $relationship) { if ($relationship['type'] === 'author') { $author = $relationship['attributes']['name']; } if ($relationship['type'] === 'cover_art') { $imageUrl = sprintf( 'https://mangadex.org/covers/%s/%s', $result['id'], $relationship['attributes']['fileName'] ); } } return new Manga( id: new MangaId((string) Uuid::uuid4()), title: new MangaTitle($title), slug: new MangaSlug($this->slugger->slug($title)->lower()), description: $attributes['description']['fr'] ?? $attributes['description']['en'] ?? '', author: $author, publicationYear: $attributes['year'] ?? 0, genres: $genres, status: $attributes['status'], externalId: new ExternalId($result['id']), imageUrl: $imageUrl, rating: null, imageUrls: null, createdAt: new \DateTimeImmutable(), ); } catch (\Exception $e) { return null; } } /** * @param Manga[] $mangas */ private function enrichWithRatings(array $mangas): void { $externalIds = array_map( fn (Manga $manga) => $manga->getExternalId()->getValue(), $mangas ); try { $ratings = $this->client->getMangaRatings($externalIds); } catch (\Exception $e) { return; } if (isset($ratings['statistics'])) { foreach ($mangas as $manga) { $externalId = $manga->getExternalId()->getValue(); if (isset($ratings['statistics'][$externalId]['rating']['average'])) { $manga->setRating($ratings['statistics'][$externalId]['rating']['average']); } } } } public function findByExternalId(ExternalId $externalId): ?Manga { try { $result = $this->client->getManga($externalId->getValue()); if (!isset($result['data'])) { return null; } $manga = $this->createMangaFromResult($result['data']); if ($manga) { $this->enrichWithRatings([$manga]); } return $manga; } catch (\Exception) { return null; } } }