feat: Reader beginning
This commit is contained in:
parent
e90c0a140e
commit
55945adc53
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Domain\Reader\Infrastructure\Persistence;
|
||||
|
||||
use App\Domain\Reader\Domain\Contract\Repository\ChapterRepositoryInterface;
|
||||
use App\Domain\Reader\Domain\Exception\ChapterNotFoundException;
|
||||
use App\Domain\Reader\Domain\Model\ChapterContext;
|
||||
use App\Domain\Reader\Domain\Model\Page;
|
||||
use App\Domain\Reader\Domain\ValueObject\ChapterId;
|
||||
use App\Domain\Reader\Domain\ValueObject\PageNumber;
|
||||
use App\Entity\Chapter as ChapterEntity;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use ZipArchive;
|
||||
|
||||
readonly class LegacyChapterRepository implements ChapterRepositoryInterface
|
||||
{
|
||||
public function __construct(
|
||||
private EntityManagerInterface $entityManager
|
||||
) {}
|
||||
|
||||
public function getPagesForChapter(ChapterId $chapterId, int $page = 1, int $itemsPerPage = 20): array
|
||||
{
|
||||
$chapter = $this->entityManager->getRepository(ChapterEntity::class)->findOneBy([
|
||||
'id' => $chapterId->getValue()
|
||||
]);
|
||||
|
||||
$cbzPath = $chapter->getCbzPath();
|
||||
|
||||
if (!$cbzPath) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($cbzPath);
|
||||
|
||||
$pages = [];
|
||||
$start = ($page - 1) * $itemsPerPage;
|
||||
$end = min($start + $itemsPerPage, $zip->numFiles);
|
||||
|
||||
for ($i = $start; $i < $end; $i++) {
|
||||
$stat = $zip->statIndex($i);
|
||||
if ($stat === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$imageContent = $zip->getFromIndex($i);
|
||||
if ($imageContent === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$imageSize = @getimagesizefromstring($imageContent);
|
||||
if ($imageSize === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pages[] = new Page(
|
||||
$stat['name'],
|
||||
new PageNumber($i + 1),
|
||||
sprintf('/api/chapters/%s/pages/%d', $chapterId->getValue(), $i + 1),
|
||||
$imageSize[0],
|
||||
$imageSize[1]
|
||||
);
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
return $pages;
|
||||
}
|
||||
|
||||
public function getChapterContext(ChapterId $chapterId): ChapterContext
|
||||
{
|
||||
/** @var ChapterEntity $chapter */
|
||||
$chapter = $this->entityManager->getRepository(ChapterEntity::class)->findOneBy([
|
||||
'id' => $chapterId->getValue()
|
||||
]);
|
||||
|
||||
if (!$chapter) {
|
||||
throw ChapterNotFoundException::forChapter($chapterId);
|
||||
}
|
||||
|
||||
return new ChapterContext(
|
||||
id: $chapterId,
|
||||
previousChapterId: $this->getPreviousChapterId($chapterId),
|
||||
nextChapterId: $this->getNextChapterId($chapterId),
|
||||
mangaTitle: $chapter->getManga()->getTitle(),
|
||||
number: $chapter->getNumber(),
|
||||
chapterTitle: $chapter->getTitle(),
|
||||
cbzPath: $chapter->getCbzPath(),
|
||||
volume: $chapter->getVolume(),
|
||||
totalPages: 0,
|
||||
isVisible: $chapter->isVisible(),
|
||||
createdAt: new \DateTimeImmutable()
|
||||
);
|
||||
}
|
||||
|
||||
public function getTotalPagesForChapter(ChapterId $chapterId): int
|
||||
{
|
||||
$chapter = $this->entityManager->getRepository(ChapterEntity::class)->findOneBy([
|
||||
'id' => $chapterId->getValue()
|
||||
]);
|
||||
|
||||
$cbzPath = $chapter->getCbzPath();
|
||||
|
||||
if (!$cbzPath) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($cbzPath);
|
||||
return $zip->numFiles;
|
||||
}
|
||||
|
||||
public function getPreviousChapterId(ChapterId $chapterId): ?ChapterId
|
||||
{
|
||||
$currentChapter = $this->entityManager->getRepository(ChapterEntity::class)->findOneBy([
|
||||
'id' => $chapterId->getValue()
|
||||
]);
|
||||
|
||||
$qb = $this->entityManager->createQueryBuilder();
|
||||
$qb->select('c')
|
||||
->from(ChapterEntity::class, 'c')
|
||||
->where('c.manga = :manga')
|
||||
->andWhere('c.number < :number')
|
||||
->orderBy('c.number', 'DESC')
|
||||
->setMaxResults(1)
|
||||
->setParameters([
|
||||
'manga' => $currentChapter->getManga(),
|
||||
'number' => $currentChapter->getNumber()
|
||||
]);
|
||||
|
||||
$previousChapter = $qb->getQuery()->getOneOrNullResult();
|
||||
|
||||
return $previousChapter ? new ChapterId((string) $previousChapter->getId()) : null;
|
||||
}
|
||||
|
||||
public function getNextChapterId(ChapterId $chapterId): ?ChapterId
|
||||
{
|
||||
$currentChapter = $this->entityManager->getRepository(ChapterEntity::class)->findOneBy([
|
||||
'id' => $chapterId->getValue()
|
||||
]);
|
||||
|
||||
$qb = $this->entityManager->createQueryBuilder();
|
||||
$qb->select('c')
|
||||
->from(ChapterEntity::class, 'c')
|
||||
->where('c.manga = :manga')
|
||||
->andWhere('c.number > :number')
|
||||
->orderBy('c.number', 'ASC')
|
||||
->setMaxResults(1)
|
||||
->setParameters([
|
||||
'manga' => $currentChapter->getManga(),
|
||||
'number' => $currentChapter->getNumber()
|
||||
]);
|
||||
|
||||
$nextChapter = $qb->getQuery()->getOneOrNullResult();
|
||||
|
||||
return $nextChapter ? new ChapterId((string) $nextChapter->getId()) : null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user