fix: Snapshot-Option je Bereich auf 8 MB begrenzen, älteste Einträge fallen heraus

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-16 18:03:49 +02:00
co-authored by Claude Opus 5.5
parent fe8a01f878
commit 60c31f9697
2 changed files with 50 additions and 3 deletions
+24 -3
View File
@@ -11,8 +11,9 @@ defined('ABSPATH') || exit;
/**
* Snapshots of the design system (spec §5, G6): one option per area (lit_mcp_snapshots_<area>, never autoloaded),
* newest first, at most LIMIT entries – the oldest falls out. An entry keeps the area's raw inventory as Divi stores
* it plus who made it with which tool and the change log entry. The only way back for colors, variables and presets:
* newest first, at most LIMIT entries and TOTAL_BYTES together – the oldest fall out, the newest always stays.
* An entry keeps the area's raw inventory as Divi stores it plus who made it with which tool and the change log
* entry. The only way back for colors, variables and presets:
* Divi 5 keeps no server-side history (formats §7.6). Not final so abilities can be tested with a mock.
*/
class SnapshotStore
@@ -24,6 +25,9 @@ class SnapshotStore
/** Spec §5: a larger snapshot refuses the change. */
public const MAX_BYTES = 2000000;
/** Final review I-4: all entries of one area together (sum of "size"). */
public const TOTAL_BYTES = 8000000;
private const PREFIX = 'lit_mcp_snapshots_';
public static function option(string $area): string
@@ -63,13 +67,30 @@ class SnapshotStore
'size' => $size,
'data' => $data,
]);
if (! update_option(self::option($area), array_slice($entries, 0, self::LIMIT), false)) {
if (! update_option(self::option($area), self::trimmed($entries), false)) {
throw new RuntimeException(sprintf('snapshot %s could not be stored', $area));
}
return $id;
}
/**
* The newest LIMIT entries, minus the oldest while all together exceed TOTAL_BYTES; the newest always stays.
*
* @param list<array{size: int}> $entries Newest first.
* @return list<array{size: int}>
*/
private static function trimmed(array $entries): array
{
$entries = array_slice($entries, 0, self::LIMIT);
$total = array_sum(array_column($entries, 'size'));
while (count($entries) > 1 && $total > self::TOTAL_BYTES) {
$total -= array_pop($entries)['size'];
}
return $entries;
}
/** Notes the change log entry of the change the snapshot belongs to (the log entry is written after it). */
public function attachLog(string $area, string $id, ?int $logId): void
{