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:
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\Divi\Pages;
|
||||
|
||||
use LIT\MCP\Integrations\Divi\Compose\AttrWriter;
|
||||
use LIT\MCP\Integrations\Divi\Compose\Composer;
|
||||
use LIT\MCP\Integrations\Divi\Compose\MediaResolver;
|
||||
use LIT\MCP\Integrations\Divi\Compose\Placeholders;
|
||||
use LIT\MCP\Integrations\Divi\Compose\ShortformWriter;
|
||||
use LIT\MCP\Integrations\Divi\Compose\StructureRules;
|
||||
use LIT\MCP\Integrations\Divi\Compose\TreeEditor;
|
||||
use LIT\MCP\Integrations\Divi\Compose\ValueSanitizer;
|
||||
use LIT\MCP\Integrations\Divi\Compose\Warnings;
|
||||
use LIT\MCP\Integrations\Divi\Design\DesignSystemReader;
|
||||
use LIT\MCP\Integrations\Divi\Schema\DiviModules;
|
||||
|
||||
/**
|
||||
* Wires the pure Compose classes with the live catalog, design system, Divi's dynamic content
|
||||
* registry and the WordPress sanitizer/media lookup – once per request and entry. Ruling S31:
|
||||
* ONE Placeholders instance (carrying the live dynamic content map of the entry, S22) is shared
|
||||
* by AttrWriter and ShortformWriter, and the same AttrWriter serves ShortformWriter and Composer.
|
||||
*
|
||||
* forPost() binds the composition to the entry being written (DiviWriter::composition() does it
|
||||
* for the abilities); unbound, VariableRef's default map applies. Not final so abilities can be
|
||||
* tested with a mock.
|
||||
*/
|
||||
class DiviComposition
|
||||
{
|
||||
private ?int $postId = null;
|
||||
private ?Placeholders $placeholders = null;
|
||||
private ?AttrWriter $attrWriter = null;
|
||||
private ?Composer $composer = null;
|
||||
|
||||
public function __construct(
|
||||
private DiviModules $modules,
|
||||
private DesignSystemReader $design,
|
||||
private ValueSanitizer $sanitizer = new WpValueSanitizer(),
|
||||
private MediaResolver $media = new WpMediaResolver(),
|
||||
private DynamicContentMap $dynamicContent = new DynamicContentMap()
|
||||
) {
|
||||
}
|
||||
|
||||
/** A fresh composition for entry $postId (own Placeholders with that entry's live map). */
|
||||
public function forPost(int $postId): static
|
||||
{
|
||||
$bound = clone $this;
|
||||
$bound->postId = $postId;
|
||||
$bound->placeholders = null;
|
||||
$bound->attrWriter = null;
|
||||
$bound->composer = null;
|
||||
|
||||
return $bound;
|
||||
}
|
||||
|
||||
/** The one Placeholders instance of this composition (ruling S31). */
|
||||
public function placeholders(): Placeholders
|
||||
{
|
||||
return $this->placeholders ??= new Placeholders(
|
||||
$this->design->read(),
|
||||
$this->postId === null ? null : $this->dynamicContent->forPost($this->postId)
|
||||
);
|
||||
}
|
||||
|
||||
public function attrWriter(): AttrWriter
|
||||
{
|
||||
return $this->attrWriter ??= new AttrWriter($this->modules->catalog(), $this->placeholders(), $this->sanitizer);
|
||||
}
|
||||
|
||||
public function composer(): Composer
|
||||
{
|
||||
return $this->composer ??= new Composer(
|
||||
$this->modules->catalog(),
|
||||
$this->rules(),
|
||||
new ShortformWriter($this->placeholders(), $this->media, $this->attrWriter()),
|
||||
$this->attrWriter(),
|
||||
$this->design->read(),
|
||||
$this->modules->builderVersion()
|
||||
);
|
||||
}
|
||||
|
||||
public function rules(): StructureRules
|
||||
{
|
||||
return new StructureRules($this->modules->catalog());
|
||||
}
|
||||
|
||||
public function editor(): TreeEditor
|
||||
{
|
||||
return new TreeEditor($this->rules());
|
||||
}
|
||||
|
||||
public function warnings(): Warnings
|
||||
{
|
||||
return new Warnings($this->design->read());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user