Files
WP-LIT-MCP/src/Integrations/Divi/Release/CompatibilityMatrix.php
T

149 lines
4.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi\Release;
defined('ABSPATH') || exit;
/**
* The release state of every Divi feature (E1). A feature the constructor did not get is incompatible (fail
* closed), so of() always answers. The overall state of the matrix is its worst feature state.
*/
final class CompatibilityMatrix
{
public const MISSING = 'Für diese Fähigkeit liegt kein Prüfergebnis vor.';
/** @var array<string, FeatureStatus> keyed by DiviFeature value, in DiviFeature::cases() order */
private array $features = [];
/** @param array<string, FeatureStatus> $features keyed by DiviFeature value */
public function __construct(array $features)
{
foreach (DiviFeature::cases() as $feature) {
$status = $features[$feature->value] ?? null;
$this->features[$feature->value] = $status instanceof FeatureStatus && $status->feature === $feature
? $status
: new FeatureStatus($feature, ReleaseState::Incompatible, [self::MISSING]);
}
}
public static function allReleased(string $source = ReleaseStatus::SOURCE_CODE): self
{
return self::uniform(ReleaseState::Released, [], $source);
}
public static function allIncompatible(string $problem): self
{
return self::uniform(ReleaseState::Incompatible, [$problem]);
}
/**
* Every feature in $state – the matrix of a status built without one (ReleaseStatus' constructor).
*
* @param list<string> $problems
*/
public static function uniform(ReleaseState $state, array $problems = [], ?string $source = null): self
{
$released = $state === ReleaseState::Released;
$features = [];
foreach (DiviFeature::cases() as $feature) {
$features[$feature->value] = new FeatureStatus(
$feature,
$state,
$released ? [] : $problems,
$released ? ($source ?? ReleaseStatus::SOURCE_CODE) : null
);
}
return new self($features);
}
public function of(DiviFeature $feature): FeatureStatus
{
return $this->features[$feature->value];
}
/** @param list<DiviFeature> $features */
public function usable(array $features): bool
{
foreach ($features as $feature) {
if (! $this->of($feature)->usable()) {
return false;
}
}
return true;
}
/**
* The statuses of those of $features that are not usable – each once, in the order of $features. The one answer
* to "what locks this call" for the gate (DiviFeatureGate), the adapters (ReleaseGate::assertFeatures()) and the
* refusal (ReleaseStatus::refusalFor()).
*
* @param list<DiviFeature> $features
* @return list<FeatureStatus>
*/
public function locked(array $features): array
{
$locked = [];
foreach ($features as $feature) {
$status = $this->of($feature);
if (! $status->usable()) {
$locked[$feature->value] = $status;
}
}
return array_values($locked);
}
/** @return list<FeatureStatus> */
public function unusable(): array
{
return array_values(array_filter(
$this->features,
static fn (FeatureStatus $status): bool => ! $status->usable()
));
}
/** Incompatible before untested before released. */
public function state(): ReleaseState
{
$states = array_map(static fn (FeatureStatus $status): ReleaseState => $status->state, $this->features);
return match (true) {
in_array(ReleaseState::Incompatible, $states, true) => ReleaseState::Incompatible,
in_array(ReleaseState::Untested, $states, true) => ReleaseState::Untested,
default => ReleaseState::Released,
};
}
/** The common source of a fully released matrix; null when not all released or the sources differ. */
public function source(): ?string
{
$sources = array_unique(array_map(
static fn (FeatureStatus $status): string => (string) $status->source,
$this->features
));
return $this->state() === ReleaseState::Released && count($sources) === 1 ? (string) reset($sources) : null;
}
/** @return list<string> Every problem label once, in feature order. */
public function problems(): array
{
$problems = [];
foreach ($this->features as $status) {
$problems = array_merge($problems, $status->problems);
}
return array_values(array_unique($problems));
}
/** @return list<array{id: string, label: string, state: string, problems: list<string>, source: ?string}> */
public function toArray(): array
{
return array_values(array_map(static fn (FeatureStatus $status): array => $status->toArray(), $this->features));
}
}