Files
Mangarr/src/Domain/System/Application/QueryHandler/GetSystemStatusQueryHandler.php
ext.jeremy.guillot@maxicoffee.domains ca8791cc0d feat(system): page Status avec endpoint API Platform et composants Vue
- Nouveau domaine System/Domain/Model/SystemStatus (value object)
- QueryHandler agrégeant métriques mangas, chapitres, jobs (global/24h/7j), stockage et sources
- Endpoint GET /api/system/status via API Platform (singleton)
- Calcul de l'espace disque par RecursiveDirectoryIterator sur public/images
- Page Vue /system/status avec 6 cards (Mangas, Chapitres, Jobs, Stockage, Sources, Système)
- Nettoyage du router : suppression des PlaceholderComponent et routes placeholder
- Sidebar : suppression des entrées sans page réelle
2026-03-17 22:04:48 +01:00

94 lines
4.1 KiB
PHP

<?php
namespace App\Domain\System\Application\QueryHandler;
use App\Domain\Shared\Domain\Contract\JobRepositoryInterface;
use App\Domain\Shared\Domain\Model\JobStatus;
use App\Domain\System\Application\Query\GetSystemStatusQuery;
use App\Domain\System\Domain\Contract\Repository\SystemStatusRepositoryInterface;
use App\Domain\System\Domain\Model\SystemStatus;
readonly class GetSystemStatusQueryHandler
{
public function __construct(
private SystemStatusRepositoryInterface $systemStatusRepository,
private JobRepositoryInterface $jobRepository,
private string $mangaDataPath,
private string $imagesStoragePath,
) {
}
public function handle(GetSystemStatusQuery $query): SystemStatus
{
$now = new \DateTimeImmutable();
$last24h = $now->modify('-24 hours');
$last7d = $now->modify('-7 days');
$totalJobs = $this->jobRepository->countByCriteria([]);
$completedJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::COMPLETED]);
$failedJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::FAILED]);
$pendingJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::PENDING]);
$inProgressJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::IN_PROGRESS]);
$totalJobsLast24h = $this->jobRepository->countByCriteria(['createdAfter' => $last24h]);
$completedJobsLast24h = $this->jobRepository->countByCriteria(['status' => JobStatus::COMPLETED, 'createdAfter' => $last24h]);
$failedJobsLast24h = $this->jobRepository->countByCriteria(['status' => JobStatus::FAILED, 'createdAfter' => $last24h]);
$totalJobsLast7d = $this->jobRepository->countByCriteria(['createdAfter' => $last7d]);
$completedJobsLast7d = $this->jobRepository->countByCriteria(['status' => JobStatus::COMPLETED, 'createdAfter' => $last7d]);
$failedJobsLast7d = $this->jobRepository->countByCriteria(['status' => JobStatus::FAILED, 'createdAfter' => $last7d]);
$storagePath = $this->imagesStoragePath;
$storageTotalBytes = (int) (@disk_total_space($storagePath) ?: 0);
$storageFreeBytes = (int) (@disk_free_space($storagePath) ?: 0);
$storageUsedBytes = $this->computeDirectorySize($storagePath);
return new SystemStatus(
totalMangas: $this->systemStatusRepository->countMangas(),
monitoredMangas: $this->systemStatusRepository->countMonitoredMangas(),
mangasByStatus: $this->systemStatusRepository->countMangasByStatus(),
totalChapters: $this->systemStatusRepository->countChapters(),
downloadedChapters: $this->systemStatusRepository->countDownloadedChapters(),
totalJobs: $totalJobs,
completedJobs: $completedJobs,
failedJobs: $failedJobs,
pendingJobs: $pendingJobs,
inProgressJobs: $inProgressJobs,
totalJobsLast24h: $totalJobsLast24h,
completedJobsLast24h: $completedJobsLast24h,
failedJobsLast24h: $failedJobsLast24h,
totalJobsLast7d: $totalJobsLast7d,
completedJobsLast7d: $completedJobsLast7d,
failedJobsLast7d: $failedJobsLast7d,
storagePath: $this->mangaDataPath,
storageTotalBytes: $storageTotalBytes,
storageFreeBytes: $storageFreeBytes,
storageUsedBytes: $storageUsedBytes,
totalSources: $this->systemStatusRepository->countContentSources(),
sourcesByHealth: $this->systemStatusRepository->countContentSourcesByHealth(),
phpVersion: PHP_VERSION,
generatedAt: $now,
);
}
private function computeDirectorySize(string $path): int
{
if (!is_dir($path)) {
return 0;
}
$size = 0;
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS)
);
foreach ($iterator as $file) {
if ($file->isFile()) {
$size += $file->getSize();
}
}
return $size;
}
}