148 lines
5.2 KiB
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)));
|
|
}
|
|
} |