Files
SkinbaseNova/app/Console/Commands/ValidateSitemapsCommand.php

148 lines
5.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Console\Commands;
use App\Services\Sitemaps\SitemapBuildService;
use App\Services\Sitemaps\SitemapReleaseManager;
use App\Services\Sitemaps\SitemapReleaseValidator;
use App\Services\Sitemaps\SitemapValidationService;
use Illuminate\Console\Command;
final class ValidateSitemapsCommand extends Command
{
protected $signature = 'skinbase:sitemaps:validate
{--only=* : Limit validation to one or more sitemap families}
{--release= : Validate a specific sitemap release}
{--active : Validate the active published sitemap release when available}';
protected $description = 'Validate sitemap XML, shard integrity, and public URL safety.';
public function handle(SitemapValidationService $validation, SitemapBuildService $build, SitemapReleaseManager $releases, SitemapReleaseValidator $releaseValidator): int
{
$startedAt = microtime(true);
$families = $this->selectedFamilies($build);
$releaseId = ($value = $this->option('release')) !== null && trim((string) $value) !== ''
? trim((string) $value)
: ((bool) $this->option('active') ? $releases->activeReleaseId() : $releases->activeReleaseId());
if (is_string($releaseId) && $releaseId !== '') {
$report = $releaseValidator->validate($releaseId);
foreach ((array) ($report['families'] ?? []) as $familyReport) {
$this->line(sprintf(
'Family [%s]: documents=%d urls=%d shards=%d',
(string) $familyReport['family'],
(int) $familyReport['documents'],
(int) $familyReport['url_count'],
(int) $familyReport['shard_count'],
));
foreach ((array) ($familyReport['warnings'] ?? []) as $warning) {
$this->warn(' - ' . $warning);
}
foreach ((array) ($familyReport['errors'] ?? []) as $error) {
$this->error(' - ' . $error);
}
}
$this->info(sprintf(
'Sitemap release validation finished in %.2fs. release=%s families=%d documents=%d urls=%d shards=%d',
microtime(true) - $startedAt,
$releaseId,
(int) data_get($report, 'totals.families', 0),
(int) data_get($report, 'totals.documents', 0),
(int) data_get($report, 'totals.urls', 0),
(int) data_get($report, 'totals.shards', 0),
));
if ((bool) ($report['ok'] ?? false)) {
$this->info('Sitemap validation passed.');
return self::SUCCESS;
}
return self::FAILURE;
}
if ($families === []) {
$this->error('No valid sitemap families were selected for validation.');
return self::INVALID;
}
$report = $validation->validate($families);
foreach ((array) ($report['index']['errors'] ?? []) as $error) {
$this->error('Index: ' . $error);
}
foreach ((array) ($report['families'] ?? []) as $familyReport) {
$this->line(sprintf(
'Family [%s]: documents=%d urls=%d shards=%d',
(string) $familyReport['family'],
(int) $familyReport['documents'],
(int) $familyReport['url_count'],
(int) $familyReport['shard_count'],
));
foreach ((array) ($familyReport['warnings'] ?? []) as $warning) {
$this->warn(' - ' . $warning);
}
foreach ((array) ($familyReport['errors'] ?? []) as $error) {
$this->error(' - ' . $error);
}
}
if ((array) ($report['duplicates'] ?? []) !== []) {
foreach ((array) $report['duplicates'] as $duplicate) {
$this->error('Duplicate URL detected: ' . $duplicate);
}
}
$this->info(sprintf(
'Sitemap validation finished in %.2fs. families=%d documents=%d urls=%d shards=%d',
microtime(true) - $startedAt,
(int) data_get($report, 'totals.families', 0),
(int) data_get($report, 'totals.documents', 0),
(int) data_get($report, 'totals.urls', 0),
(int) data_get($report, 'totals.shards', 0),
));
if ((bool) ($report['ok'] ?? false)) {
$this->info('Sitemap validation passed.');
return self::SUCCESS;
}
return self::FAILURE;
}
/**
* @return list<string>
*/
private function selectedFamilies(SitemapBuildService $build): array
{
$only = [];
foreach ((array) $this->option('only') as $value) {
foreach (explode(',', (string) $value) as $family) {
$normalized = trim($family);
if ($normalized !== '') {
$only[] = $normalized;
}
}
}
$enabled = $build->enabledFamilies();
if ($only === []) {
return $enabled;
}
return array_values(array_filter($enabled, fn (string $family): bool => in_array($family, $only, true)));
}
}