refactor(compat): Freigabe-Bausteine generisch
ReleaseStore, CheckReportStore, CheckReport, CheckStep und CompatibilityCheck liegen im Kern und arbeiten je Profil (Optionen lit_mcp_<id>_releases|_check_report; Divi behält Namen und Schlüssel divi_version). Divi hängt Katalog-, Format- und Schreibtest über Profile::extraSteps an. Ein roter Prüfbericht für den aktuellen Stand sperrt LockOnFailure-Profile bis zur nächsten grünen Prüfung; Sperrgründe nennen nur Schritt-Labels, Ausnahmen gehen ins Error-Log. Profile bekommt testedVersions, stateKey, extraSteps, manifestCheck und reportVersionKey und wird mit benannten Argumenten gebaut. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c85131603b
commit
7d6a97a54e
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Compatibility;
|
||||
|
||||
use Closure;
|
||||
use LIT\MCP\Log;
|
||||
use LIT\MCP\Plugin;
|
||||
use Throwable;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* The admin check of one profile (spec §6.2) – also wp lit-mcp divi-check: manifest (code and registrations),
|
||||
* fingerprints (only when a manifest has mirrors), then the extra steps of the profile. A step that throws is a red
|
||||
* step. Not final so the route and the command can be tested with a mock.
|
||||
*/
|
||||
class CompatibilityCheck
|
||||
{
|
||||
public function __construct(private Profile $profile, private ManifestCheck $manifests)
|
||||
{
|
||||
}
|
||||
|
||||
public static function forProfile(Profile $profile, ?ManifestCheck $check = null): self
|
||||
{
|
||||
return new self($profile, $check ?? $profile->checker());
|
||||
}
|
||||
|
||||
public function run(int $userId): CheckReport
|
||||
{
|
||||
$label = $this->profile->label;
|
||||
$manifest = self::guarded(fn (): array => ManifestCheck::failed(
|
||||
array_merge($this->manifests->codeChecks(), $this->manifests->registrationChecks())
|
||||
));
|
||||
$steps = [new CheckStep(
|
||||
CheckStep::MANIFEST,
|
||||
$manifest,
|
||||
false,
|
||||
CheckStep::genericLabel(CheckStep::MANIFEST, $label)
|
||||
)];
|
||||
if (array_filter($this->profile->manifests, static fn (Manifest $m): bool => $m->mirrors !== []) !== []) {
|
||||
$steps[] = new CheckStep(
|
||||
CheckStep::MIRRORS,
|
||||
self::guarded(fn (): array => ManifestCheck::failed($this->manifests->mirrorChecks())),
|
||||
false,
|
||||
CheckStep::genericLabel(CheckStep::MIRRORS, $label)
|
||||
);
|
||||
}
|
||||
if ($this->profile->extraSteps !== null) {
|
||||
$steps = [...$steps, ...($this->profile->extraSteps)($manifest === [])];
|
||||
}
|
||||
$version = (string) ($this->profile->version === null ? '' : ($this->profile->version)());
|
||||
|
||||
return new CheckReport(
|
||||
wp_generate_uuid4(),
|
||||
gmdate('c'),
|
||||
$userId,
|
||||
$version,
|
||||
Plugin::VERSION,
|
||||
$this->profile->stateKey === null ? '' : ($this->profile->stateKey)($version),
|
||||
$steps
|
||||
);
|
||||
}
|
||||
|
||||
/** @return list<string> The step's problems; a throwing step is one problem. */
|
||||
public static function guarded(Closure $step): array
|
||||
{
|
||||
try {
|
||||
return array_values(array_filter((array) $step(), 'is_string'));
|
||||
} catch (Throwable $e) {
|
||||
// The report reaches MCP clients through the lock reason; the exception text stays in the log.
|
||||
Log::failure('compat check step', $e);
|
||||
|
||||
return ['Prüfschritt abgebrochen (Details im PHP-Error-Log).'];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user