fix: lit/divi-presets-assign verweigert leeren Text als Preset (Eingabe und Gruppen); Stapelgrenze und Preset-Schema aus PresetAssignment
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
6b5de199f9
commit
b805ed64dd
@@ -25,12 +25,11 @@ defined('ABSPATH') || exit;
|
||||
*/
|
||||
final class DiviPresetsAssignAbility implements Ability
|
||||
{
|
||||
public const MAX_STACK = 10;
|
||||
|
||||
/** Path prefix for PresetAssignment's errors; removed again so fields name the input keys. */
|
||||
private const ROOT = 'input';
|
||||
|
||||
private const USE_DETACH = 'null entfernt site-weit nichts; Preset-Verweise entfernt lit/divi-design-detach';
|
||||
private const USE_DETACH = 'null und leerer Text entfernen site-weit nichts; '
|
||||
. 'Preset-Verweise entfernt lit/divi-design-detach';
|
||||
|
||||
/** @param Closure(): PresetAssignment $assignment A fresh assignment (own preset book) per call. */
|
||||
public function __construct(
|
||||
@@ -70,18 +69,16 @@ final class DiviPresetsAssignAbility implements Ability
|
||||
'type' => 'object',
|
||||
'properties' => [
|
||||
'module' => ['type' => 'string', 'description' => 'Modul, z. B. "button" oder "divi/button".'],
|
||||
'preset' => [
|
||||
'type' => ['string', 'array'],
|
||||
'items' => ['type' => 'string'],
|
||||
'minItems' => 1,
|
||||
'maxItems' => self::MAX_STACK,
|
||||
'description' => 'Modul-Preset (Name oder ID) oder Stapel; bei gleicher Priorität gewinnt das '
|
||||
. 'letzte Preset im Stapel (Divi-Verhalten).',
|
||||
],
|
||||
'preset' => PresetAssignment::valueSchema(
|
||||
false,
|
||||
'Modul-Preset (Name oder ID) oder Stapel; bei gleicher Priorität gewinnt das '
|
||||
. 'letzte Preset im Stapel (Divi-Verhalten).'
|
||||
),
|
||||
'group_presets' => [
|
||||
'type' => 'object',
|
||||
'description' => '{"<Gruppe>": "<Name>" | ["<Name>", …]}; Gruppe als Kurzname (font-body), voller '
|
||||
. 'Name (divi/font-body) oder Attributpfad.',
|
||||
'additionalProperties' => PresetAssignment::valueSchema(false),
|
||||
],
|
||||
'post_ids' => PostIdsInput::schema(),
|
||||
'only_without_preset' => [
|
||||
@@ -224,7 +221,7 @@ final class DiviPresetsAssignAbility implements Ability
|
||||
}
|
||||
|
||||
/**
|
||||
* preset and group_presets as given; null removes nothing site-wide (lit/divi-design-detach does).
|
||||
* preset and group_presets as given; null and "" remove nothing site-wide (lit/divi-design-detach does).
|
||||
*
|
||||
* @param array<string, mixed> $input
|
||||
* @param array<string, string> $errors
|
||||
@@ -236,7 +233,7 @@ final class DiviPresetsAssignAbility implements Ability
|
||||
if ($spec === []) {
|
||||
$errors['preset'] = 'preset oder group_presets angeben';
|
||||
}
|
||||
if (array_key_exists('preset', $spec) && $spec['preset'] === null) {
|
||||
if (array_key_exists('preset', $spec) && in_array($spec['preset'], [null, ''], true)) {
|
||||
$errors['preset'] = self::USE_DETACH;
|
||||
}
|
||||
$groups = $spec['group_presets'] ?? null;
|
||||
@@ -244,7 +241,7 @@ final class DiviPresetsAssignAbility implements Ability
|
||||
$errors['group_presets'] = 'mindestens eine Gruppe angeben';
|
||||
}
|
||||
foreach (is_array($groups) ? $groups : [] as $key => $value) {
|
||||
if ($value === null) {
|
||||
if (in_array($value, [null, ''], true)) {
|
||||
$errors['group_presets.' . $key] = self::USE_DETACH;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@ defined('ABSPATH') || exit;
|
||||
*/
|
||||
final class PresetAssignment
|
||||
{
|
||||
private const MAX_STACK = 10;
|
||||
/** The most presets one module (or group entry) can carry as a stack. */
|
||||
public const MAX_STACK = 10;
|
||||
|
||||
private ?PresetBook $loaded = null;
|
||||
|
||||
@@ -60,6 +61,29 @@ final class PresetAssignment
|
||||
return ['attrs' => $attrs, 'errors' => $errors];
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON schema of a preset value: a name or ID, a stack of 1..MAX_STACK of them and, when $nullable, null.
|
||||
* Without null (site-wide tools) empty strings are refused too: they would mean "remove", which only null or
|
||||
* lit/divi-design-detach may do there. The single source for every tool that takes a preset value.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function valueSchema(bool $nullable, string $description = ''): array
|
||||
{
|
||||
$schema = [
|
||||
'type' => $nullable ? ['string', 'array', 'null'] : ['string', 'array'],
|
||||
'items' => ['type' => 'string'],
|
||||
'minItems' => 1,
|
||||
'maxItems' => self::MAX_STACK,
|
||||
];
|
||||
if (! $nullable) {
|
||||
$schema['minLength'] = 1;
|
||||
$schema['items']['minLength'] = 1;
|
||||
}
|
||||
|
||||
return $description === '' ? $schema : $schema + ['description' => $description];
|
||||
}
|
||||
|
||||
/**
|
||||
* The attributes without the local values that lie on values of the presets the block names (ruling R4).
|
||||
*
|
||||
|
||||
@@ -8,6 +8,7 @@ use LIT\MCP\Abilities\Annotations;
|
||||
use LIT\MCP\Abilities\Errors;
|
||||
use LIT\MCP\Integrations\Divi\BlockTree\Block;
|
||||
use LIT\MCP\Integrations\Divi\Compose\ColumnWidths;
|
||||
use LIT\MCP\Integrations\Divi\Design\PresetAssignment;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
@@ -36,8 +37,8 @@ final class DiviUpdateAbility extends DiviWriteAbility
|
||||
{
|
||||
return 'Ändert vorhandene Divi-Knoten: changes = Liste von {id, set: {Kurzform-Felder}, attrs: {Attributpfad: '
|
||||
. '{Breakpoint: Wert}}, preset, group_presets, clear_overrides, label}. null entfernt einen Wert. '
|
||||
. 'preset = Name/ID oder Liste (Stapel, bis 10; bei gleicher Priorität gewinnt das letzte Preset im '
|
||||
. 'Stapel); group_presets = {Gruppe: Preset}, z. B. {"font-body": "Fließtext"}. Überdecken lokale Werte '
|
||||
. 'preset = Name/ID oder Liste (Stapel, bis ' . PresetAssignment::MAX_STACK . '; bei gleicher Priorität '
|
||||
. 'gewinnt das letzte Preset im Stapel); group_presets = {Gruppe: Preset}, z. B. {"font-body": "Fließtext"}. Überdecken lokale Werte '
|
||||
. 'ein Preset, meldet die Antwort das; clear_overrides: true entfernt sie (nach set/attrs). Nicht '
|
||||
. 'genannte Einstellungen bleiben unverändert. Jeder Knoten nur einmal pro Aufruf; denselben Pfad nicht '
|
||||
. 'zugleich über set und attrs. tree_rev aus lit-divi-outline ist Pflicht; alles oder nichts.';
|
||||
@@ -61,16 +62,18 @@ final class DiviUpdateAbility extends DiviWriteAbility
|
||||
'type' => 'object',
|
||||
'description' => 'Vollform: Attributpfad → Breakpoint-Werte.',
|
||||
],
|
||||
'preset' => self::presetValue(
|
||||
'Preset-Name oder -ID, Liste (Stapel, 1–10) oder null zum Entfernen. Bei gleicher '
|
||||
. 'Priorität gewinnt das letzte Preset im Stapel.'
|
||||
'preset' => PresetAssignment::valueSchema(
|
||||
true,
|
||||
'Preset-Name oder -ID, Liste (Stapel, 1–' . PresetAssignment::MAX_STACK
|
||||
. ') oder null zum Entfernen. Bei gleicher Priorität gewinnt das letzte '
|
||||
. 'Preset im Stapel.'
|
||||
),
|
||||
'group_presets' => [
|
||||
'type' => 'object',
|
||||
'description' => 'Gruppen-Presets: {Gruppe: Preset-Name | Liste | null}. Gruppe = '
|
||||
. 'Kurzname (font-body), voller Name (divi/font-body) oder Attributpfad; null '
|
||||
. 'entfernt den Eintrag der Gruppe.',
|
||||
'additionalProperties' => self::presetValue(),
|
||||
'additionalProperties' => PresetAssignment::valueSchema(true),
|
||||
],
|
||||
'clear_overrides' => [
|
||||
'type' => 'boolean',
|
||||
@@ -172,21 +175,4 @@ final class DiviUpdateAbility extends DiviWriteAbility
|
||||
|
||||
return $change;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schema of one preset value: a name or id, a stack of 1–10 of them, or null.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private static function presetValue(string $description = ''): array
|
||||
{
|
||||
$schema = [
|
||||
'type' => ['string', 'array', 'null'],
|
||||
'items' => ['type' => 'string'],
|
||||
'minItems' => 1,
|
||||
'maxItems' => 10,
|
||||
];
|
||||
|
||||
return $description === '' ? $schema : $schema + ['description' => $description];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user