feat: ThemeOptionDiff – Diff und Zusammenfassung der Theme-Optionen

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-19 17:48:16 +02:00
co-authored by Claude Sonnet 5.5
parent d9c4bc3751
commit 8740e9b8dc
2 changed files with 163 additions and 0 deletions
@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi\Design;
defined('ABSPATH') || exit;
/**
* What a theme-options change does (spec §4 step 4, "diff"): per key added (not set before), changed or reset
* (removed afterwards – Divi falls back to its default). Values are compared strictly, so false (Divi's default
* font) and a type change (1 versus "1") count. before/after carry the raw values, null where the key is not set.
* In the order of ThemeOptionSpec::KEYS. Pure PHP.
*/
final class ThemeOptionDiff
{
/**
* @return list<array{key: string, label: string, action: string, before: mixed, after: mixed}>
* action: added|changed|reset
*/
public static function between(ThemeOptionBook $before, ThemeOptionBook $after): array
{
$rows = [];
foreach (ThemeOptionSpec::KEYS as $key) {
$action = match (true) {
! $before->has($key) && $after->has($key) => 'added',
$before->has($key) && ! $after->has($key) => 'reset',
$before->get($key) !== $after->get($key) => 'changed',
default => null,
};
if ($action !== null) {
$rows[] = [
'key' => $key,
'label' => ThemeOptionSpec::definition($key)['label'],
'action' => $action,
'before' => $before->get($key),
'after' => $after->get($key),
];
}
}
return $rows;
}
/**
* One German sentence for the dry run and the change log (spec §4 step 6).
*
* @param list<array<string, mixed>> $diff
*/
public static function summary(array $diff): string
{
$count = array_count_values(array_map(static fn (array $row): string => (string) $row['action'], $diff));
$parts = [];
foreach (['added' => 'gesetzt', 'changed' => 'geändert', 'reset' => 'zurückgesetzt'] as $action => $word) {
if (isset($count[$action])) {
$parts[] = $count[$action] . ' ' . $word;
}
}
return 'Theme-Optionen: ' . ($parts === [] ? 'keine Änderung' : implode(', ', $parts)) . '.';
}
}