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>
112 lines
3.5 KiB
PHP
112 lines
3.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace LIT\MCP\Compatibility;
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
/**
|
|
* Versions of one profile released on this site after a green admin check (spec §5.3, source "database"), option
|
|
* lit_mcp_<profile>_releases. An entry holds for the plugin version that ran the check only.
|
|
*
|
|
* Not final so the resolver can be tested with a mock.
|
|
*/
|
|
class ReleaseStore
|
|
{
|
|
/** @param string $versionKey Row key of the version (Divi: 'divi_version', so stored rows stay as they are). */
|
|
public function __construct(private string $profileId, private string $versionKey = 'version')
|
|
{
|
|
}
|
|
|
|
public static function forProfile(Profile $profile): self
|
|
{
|
|
return new self($profile->id, $profile->reportVersionKey);
|
|
}
|
|
|
|
/**
|
|
* @return list<array<string, string|int>> Rows with the keys <versionKey>, plugin_version, user_id, released_at,
|
|
* report_id.
|
|
*/
|
|
public function entries(): array
|
|
{
|
|
$raw = get_option($this->option(), []);
|
|
$entries = [];
|
|
foreach (is_array($raw) ? $raw : [] as $row) {
|
|
if (
|
|
is_array($row)
|
|
&& is_string($row[$this->versionKey] ?? null)
|
|
&& is_string($row['plugin_version'] ?? null)
|
|
&& is_int($row['user_id'] ?? null)
|
|
&& is_string($row['released_at'] ?? null)
|
|
&& is_string($row['report_id'] ?? null)
|
|
) {
|
|
$entries[] = [
|
|
$this->versionKey => $row[$this->versionKey],
|
|
'plugin_version' => $row['plugin_version'],
|
|
'user_id' => $row['user_id'],
|
|
'released_at' => $row['released_at'],
|
|
'report_id' => $row['report_id'],
|
|
];
|
|
}
|
|
}
|
|
|
|
return $entries;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, string|int>|null
|
|
*/
|
|
public function find(string $version, string $pluginVersion): ?array
|
|
{
|
|
foreach ($this->entries() as $entry) {
|
|
if ($entry[$this->versionKey] === $version && $entry['plugin_version'] === $pluginVersion) {
|
|
return $entry;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function add(string $version, string $pluginVersion, int $userId, string $reportId): void
|
|
{
|
|
$entries = $this->without($version, $pluginVersion);
|
|
$entries[] = [
|
|
$this->versionKey => $version,
|
|
'plugin_version' => $pluginVersion,
|
|
'user_id' => $userId,
|
|
'released_at' => gmdate('c'),
|
|
'report_id' => $reportId,
|
|
];
|
|
update_option($this->option(), $entries, false);
|
|
}
|
|
|
|
public function withdraw(string $version, string $pluginVersion): bool
|
|
{
|
|
if ($this->find($version, $pluginVersion) === null) {
|
|
return false;
|
|
}
|
|
update_option($this->option(), $this->without($version, $pluginVersion), false);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @return list<array<string, string|int>> Rows with the keys <versionKey>, plugin_version, user_id, released_at,
|
|
* report_id.
|
|
*/
|
|
private function without(string $version, string $pluginVersion): array
|
|
{
|
|
return array_values(array_filter(
|
|
$this->entries(),
|
|
fn (array $entry): bool => $entry[$this->versionKey] !== $version
|
|
|| $entry['plugin_version'] !== $pluginVersion
|
|
));
|
|
}
|
|
|
|
private function option(): string
|
|
{
|
|
return 'lit_mcp_' . $this->profileId . '_releases';
|
|
}
|
|
}
|