feat: amélioration de l'harmonisation des volumes des chapitres en ajoutant une méthode pour remplir les trous de volumes manquants, et refactorisation de la création de chapitres avec un nouveau volume.

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-06-20 15:43:10 +02:00
parent 75f8e1686c
commit d753761556

View File

@@ -104,15 +104,17 @@ readonly class FetchMangaChaptersHandler
* Harmonise les volumes des chapitres:
* - Si le chapitre précédent et suivant ont un volume null, alors le chapitre actuel aussi
* - Si le chapitre précédent et suivant ont le même volume, alors le chapitre actuel aura ce volume
* - Remplit les "trous" de volumes manquants dans une séquence
*/
private function harmonizeVolumes(array &$chaptersByNumber): void
{
// Trie les chapitres par numéro pour faciliter la recherche des adjacents
ksort($chaptersByNumber);
uksort($chaptersByNumber, fn($a, $b) => (float)$a <=> (float)$b);
$chapterNumbers = array_keys($chaptersByNumber);
$count = count($chapterNumbers);
// Première passe : harmonisation locale (chapitres adjacents)
for ($i = 1; $i < $count - 1; $i++) {
$prevChapterNum = $chapterNumbers[$i - 1];
$currentChapterNum = $chapterNumbers[$i];
@@ -137,18 +139,107 @@ readonly class FetchMangaChaptersHandler
}
if ($shouldUpdateVolume) {
// On doit créer un nouveau chapitre car les objets sont immuables
$chaptersByNumber[$currentChapterNum] = new Chapter(
id: new ChapterId($currentChapter->getId()),
mangaId: $currentChapter->getMangaId(),
number: $currentChapter->getNumber(),
title: $currentChapter->getTitle(),
volume: $newVolume, // On met à jour le volume
isVisible: $currentChapter->isVisible(),
isAvailable: $currentChapter->isAvailable(),
createdAt: $currentChapter->getCreatedAt()
$chaptersByNumber[$currentChapterNum] = $this->createChapterWithNewVolume($currentChapter, $newVolume);
}
}
// Deuxième passe : remplissage des trous de volumes
$this->fillVolumeGaps($chaptersByNumber);
}
/**
* Remplit les "trous" de volumes dans une séquence de chapitres.
* Par exemple, si on a : Ch.317(Vol.34), Ch.318(Vol.34), Ch.319(null), Ch.320(null), Ch.321(Vol.34)
* Alors Ch.319 et Ch.320 seront assignés au Vol.34
*/
private function fillVolumeGaps(array &$chaptersByNumber): void
{
$chapterNumbers = array_keys($chaptersByNumber);
$count = count($chapterNumbers);
for ($i = 0; $i < $count; $i++) {
$currentChapterNum = $chapterNumbers[$i];
$currentChapter = $chaptersByNumber[$currentChapterNum];
// Si le chapitre actuel n'a pas de volume, on cherche à le combler
if ($currentChapter->getVolume() === null) {
$volumeToAssign = $this->findVolumeForGap($chaptersByNumber, $chapterNumbers, $i);
if ($volumeToAssign !== null) {
$chaptersByNumber[$currentChapterNum] = $this->createChapterWithNewVolume($currentChapter, $volumeToAssign);
}
}
}
}
/**
* Trouve le volume à assigner pour un chapitre sans volume en analysant son contexte
*/
private function findVolumeForGap(array $chaptersByNumber, array $chapterNumbers, int $currentIndex): ?int
{
$count = count($chapterNumbers);
// Cherche le volume précédent non-null
$prevVolume = null;
for ($i = $currentIndex - 1; $i >= 0; $i--) {
$prevChapter = $chaptersByNumber[$chapterNumbers[$i]];
if ($prevChapter->getVolume() !== null) {
$prevVolume = $prevChapter->getVolume();
break;
}
}
// Cherche le volume suivant non-null
$nextVolume = null;
for ($i = $currentIndex + 1; $i < $count; $i++) {
$nextChapter = $chaptersByNumber[$chapterNumbers[$i]];
if ($nextChapter->getVolume() !== null) {
$nextVolume = $nextChapter->getVolume();
break;
}
}
// Si les volumes précédent et suivant sont identiques et non-null, on utilise ce volume
if ($prevVolume !== null && $prevVolume === $nextVolume) {
return $prevVolume;
}
// Si on a seulement un volume précédent, on vérifie s'il est raisonnable de l'utiliser
// (pas plus de 10 chapitres d'écart pour éviter les erreurs)
if ($prevVolume !== null && $nextVolume === null) {
$currentChapterNumber = (float) $chapterNumbers[$currentIndex];
// Trouve le numéro du chapitre qui a ce volume précédent
for ($i = $currentIndex - 1; $i >= 0; $i--) {
$prevChapter = $chaptersByNumber[$chapterNumbers[$i]];
if ($prevChapter->getVolume() === $prevVolume) {
$prevChapterNumber = (float) $chapterNumbers[$i];
// Si l'écart est raisonnable (moins de 10 chapitres), on assigne le volume
if ($currentChapterNumber - $prevChapterNumber <= 10) {
return $prevVolume;
}
break;
}
}
}
return null;
}
/**
* Crée un nouveau chapitre avec un volume différent (les chapitres sont immuables)
*/
private function createChapterWithNewVolume(Chapter $chapter, ?int $newVolume): Chapter
{
return new Chapter(
id: new ChapterId($chapter->getId()),
mangaId: $chapter->getMangaId(),
number: $chapter->getNumber(),
title: $chapter->getTitle(),
volume: $newVolume,
isVisible: $chapter->isVisible(),
isAvailable: $chapter->isAvailable(),
createdAt: $chapter->getCreatedAt()
);
}
}
}
}