refactor(compat): Prüfbausteine nach src/Compatibility, Matrix und ManifestCheck generisch
Requirement, Call, ConstantRequirement, Mirror, Problem, FeatureStatus, CompatibilityMatrix, Manifest, ManifestCheck sowie Fingerprints und LineDiff liegen jetzt im divi-freien Kern. Neu: GlobalRequirement, CompatibilityMatrix::fromProblems(), ManifestCheck-Option signatures, DiviManifestCheck::create() und DiviAreas. Divi-Verhalten unverändert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9beb55e228
commit
b511ef6348
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Compatibility;
|
||||
|
||||
use Closure;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* One failed manifest check and the capabilities it concerns (Manifest::featuresOf()). The kind decides how the
|
||||
* resolver weighs it (E1): call, mirror, constant and global lock their features for every version, released
|
||||
* or not; signature and reference-missing only matter for a version without release (automatic release). A problem
|
||||
* without features concerns every feature (fail closed).
|
||||
*/
|
||||
final class Problem
|
||||
{
|
||||
public const CALL = 'call';
|
||||
public const SIGNATURE = 'signature';
|
||||
public const MIRROR = 'mirror';
|
||||
public const CONSTANT = 'constant';
|
||||
public const GLOBAL = 'global';
|
||||
public const REFERENCE_MISSING = 'reference-missing';
|
||||
public const RESOLVER = 'resolver';
|
||||
|
||||
private const KINDS = [
|
||||
self::CALL,
|
||||
self::SIGNATURE,
|
||||
self::MIRROR,
|
||||
self::CONSTANT,
|
||||
self::GLOBAL,
|
||||
self::REFERENCE_MISSING,
|
||||
self::RESOLVER,
|
||||
];
|
||||
private const HARD = [self::CALL, self::MIRROR, self::CONSTANT, self::GLOBAL, self::RESOLVER];
|
||||
|
||||
/**
|
||||
* @param string $label German, e.g. "Seiten: et_x()" (the labels of ManifestCheck).
|
||||
* @param list<Capability> $features
|
||||
* @param string $kind One of the constants above.
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly string $label,
|
||||
public readonly array $features,
|
||||
public readonly string $kind
|
||||
) {
|
||||
}
|
||||
|
||||
/** Locks its features whatever the release (the third-party code no longer fits or a mirror differs). */
|
||||
public function isHard(): bool
|
||||
{
|
||||
return in_array($this->kind, self::HARD, true);
|
||||
}
|
||||
|
||||
public function concerns(Capability $feature): bool
|
||||
{
|
||||
return $this->features === [] || in_array($feature, $this->features, true);
|
||||
}
|
||||
|
||||
/** @return array{label: string, kind: string, features: list<string>} For the transient. */
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'label' => $this->label,
|
||||
'kind' => $this->kind,
|
||||
'features' => array_map(static fn (Capability $feature): string => $feature->id(), $this->features),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The problem of toArray(), or null for anything else (an unknown kind or feature included).
|
||||
*
|
||||
* @param Closure(string): ?Capability $capability Finds a capability by its ID, null for an unknown one.
|
||||
*/
|
||||
public static function fromArray(mixed $row, Closure $capability): ?self
|
||||
{
|
||||
if (
|
||||
! is_array($row)
|
||||
|| ! is_string($row['label'] ?? null)
|
||||
|| ! in_array($row['kind'] ?? null, self::KINDS, true)
|
||||
|| ! is_array($row['features'] ?? null)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$features = [];
|
||||
foreach ($row['features'] as $value) {
|
||||
$feature = is_string($value) ? $capability($value) : null;
|
||||
if ($feature === null) {
|
||||
return null;
|
||||
}
|
||||
$features[] = $feature;
|
||||
}
|
||||
|
||||
return new self($row['label'], $features, $row['kind']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user