feat: Divi save pipeline – tree_rev lock, kses-safe save, revision, flags, cache, ToolResult
DiviSaver/DiviWriter/DiviComposition/DiviChange, WpValueSanitizer (S4), WpMediaResolver, DiviFlags (S11), DynamicContentMap from Divi's live registry (S22), S31 wiring, S35 control strip at apply() entry. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -58,6 +58,8 @@ final class AttrWriter
|
||||
*/
|
||||
public function apply(string $module, array $attrs, array $changes, string $field): array
|
||||
{
|
||||
// Ruling S35: controls go before placeholder resolution ("{\0{post:title}}" is a placeholder).
|
||||
$changes = VariableRef::withoutControlsDeep($changes);
|
||||
$errors = [];
|
||||
$invalid = [];
|
||||
foreach ($changes as $path => $map) {
|
||||
|
||||
@@ -48,6 +48,8 @@ final class ShortformWriter
|
||||
*/
|
||||
public function apply(string $type, array $attrs, array $values, string $field): array
|
||||
{
|
||||
// Ruling S35: controls go before placeholder resolution and trim ("{\0{post:title}}").
|
||||
$values = VariableRef::withoutControlsDeep($values);
|
||||
$fields = $this->modules === null ? ShortformMap::fields($type) : ($this->modules[$type] ?? []);
|
||||
$errors = [];
|
||||
foreach ($values as $name => $value) {
|
||||
|
||||
@@ -146,6 +146,21 @@ final class VariableRef
|
||||
return (string) preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* withoutControls() on every string inside $value (keys stay: odd keys are rejected). Ruling
|
||||
* S35: AttrWriter::apply() and ShortformWriter::apply() run it once on their raw input, before
|
||||
* placeholder resolution and trim – so "{\0{post:title}}" is the placeholder, checked as one,
|
||||
* and never literal text that slipped past the placeholder check.
|
||||
*/
|
||||
public static function withoutControlsDeep(mixed $value): mixed
|
||||
{
|
||||
if (is_string($value)) {
|
||||
return self::withoutControls($value);
|
||||
}
|
||||
|
||||
return is_array($value) ? array_map([self::class, 'withoutControlsDeep'], $value) : $value;
|
||||
}
|
||||
|
||||
/** @param array<string, mixed>|stdClass $settings */
|
||||
public static function serialize(string $type, string $name, array|stdClass $settings): string
|
||||
{
|
||||
@@ -383,7 +398,8 @@ final class VariableRef
|
||||
}
|
||||
|
||||
// Ruling S29: meta key settings (post_meta_key's meta_key/select_meta_key, loop_meta_key …)
|
||||
// name a meta key – never a protected one.
|
||||
// name a meta key – never a protected one. Matched by the key SUFFIX "meta_key" (S29/S30):
|
||||
// re-check Divi's dynamic content options for new meta key settings on every Divi version bump.
|
||||
if (str_ends_with($key, 'meta_key') && $clean !== '' && ! self::isMetaKey((string) $clean)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Einstellung "%s" im Divi-Verweis: ungültiger Meta-Schlüssel (Buchstaben, Ziffern, "_" und "-", '
|
||||
|
||||
Reference in New Issue
Block a user