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:
parent
75f8e1686c
commit
d753761556
@@ -104,15 +104,17 @@ readonly class FetchMangaChaptersHandler
|
|||||||
* Harmonise les volumes des chapitres:
|
* 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 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
|
* - 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
|
private function harmonizeVolumes(array &$chaptersByNumber): void
|
||||||
{
|
{
|
||||||
// Trie les chapitres par numéro pour faciliter la recherche des adjacents
|
// 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);
|
$chapterNumbers = array_keys($chaptersByNumber);
|
||||||
$count = count($chapterNumbers);
|
$count = count($chapterNumbers);
|
||||||
|
|
||||||
|
// Première passe : harmonisation locale (chapitres adjacents)
|
||||||
for ($i = 1; $i < $count - 1; $i++) {
|
for ($i = 1; $i < $count - 1; $i++) {
|
||||||
$prevChapterNum = $chapterNumbers[$i - 1];
|
$prevChapterNum = $chapterNumbers[$i - 1];
|
||||||
$currentChapterNum = $chapterNumbers[$i];
|
$currentChapterNum = $chapterNumbers[$i];
|
||||||
@@ -137,18 +139,107 @@ readonly class FetchMangaChaptersHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($shouldUpdateVolume) {
|
if ($shouldUpdateVolume) {
|
||||||
// On doit créer un nouveau chapitre car les objets sont immuables
|
$chaptersByNumber[$currentChapterNum] = $this->createChapterWithNewVolume($currentChapter, $newVolume);
|
||||||
$chaptersByNumber[$currentChapterNum] = new Chapter(
|
}
|
||||||
id: new ChapterId($currentChapter->getId()),
|
}
|
||||||
mangaId: $currentChapter->getMangaId(),
|
|
||||||
number: $currentChapter->getNumber(),
|
// Deuxième passe : remplissage des trous de volumes
|
||||||
title: $currentChapter->getTitle(),
|
$this->fillVolumeGaps($chaptersByNumber);
|
||||||
volume: $newVolume, // On met à jour le volume
|
}
|
||||||
isVisible: $currentChapter->isVisible(),
|
|
||||||
isAvailable: $currentChapter->isAvailable(),
|
/**
|
||||||
createdAt: $currentChapter->getCreatedAt()
|
* 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()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user