feat: Divi tools write library entries; global ones with dry run, confirm and backup (E2, F2)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ use LIT\MCP\Integrations\Divi\BlockTree\NodeIndex;
|
||||
use LIT\MCP\Integrations\Divi\BlockTree\Outline;
|
||||
use LIT\MCP\Integrations\Divi\BlockTree\Serializer;
|
||||
use LIT\MCP\Integrations\Divi\Design\DesignSystemReader;
|
||||
use LIT\MCP\Integrations\Divi\Library\GlobalEdits;
|
||||
use LIT\MCP\Integrations\WordPress\PostSaveFollowUp;
|
||||
use WP_Error;
|
||||
|
||||
@@ -23,7 +24,8 @@ defined('ABSPATH') || exit;
|
||||
* (ruling P16; a mismatch is rev_mismatch and nothing is written), let the ability change the
|
||||
* tree – only when its whole input validated (all or nothing) –, serialize, save via DiviSaver,
|
||||
* then lit_mcp_after_save, change log and the ToolResult with changed nodes, affected outline,
|
||||
* quality warnings (spec §5.5), revision_id, the new rev and tree_rev.
|
||||
* quality warnings (spec §5.5), revision_id, the new rev and tree_rev. commit() is the entry point
|
||||
* of the tools: library entries additionally pass GlobalEdits (shape, dry run/confirm, backup).
|
||||
*/
|
||||
final class DiviWriter
|
||||
{
|
||||
@@ -35,7 +37,8 @@ final class DiviWriter
|
||||
private DiviSaver $saver,
|
||||
private ChangeLog $log,
|
||||
private DesignSystemReader $design,
|
||||
private DiviComposition $composition
|
||||
private DiviComposition $composition,
|
||||
private ?GlobalEdits $globals = null
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -79,8 +82,13 @@ final class DiviWriter
|
||||
* @return array<string, mixed>
|
||||
* @throws WriteFailed
|
||||
*/
|
||||
public function save(string $ability, DiviPage $page, DiviChange $change, array $input): array
|
||||
{
|
||||
public function save(
|
||||
string $ability,
|
||||
DiviPage $page,
|
||||
DiviChange $change,
|
||||
array $input,
|
||||
SaveScope $scope = SaveScope::Page
|
||||
): array {
|
||||
$post = $page->post;
|
||||
$content = Serializer::document($page->document);
|
||||
if ($content === (string) $post->post_content) {
|
||||
@@ -97,7 +105,7 @@ final class DiviWriter
|
||||
$warnings = array_merge($change->warnings(), $quality);
|
||||
|
||||
try {
|
||||
$saved = $this->saver->save($post, $content);
|
||||
$saved = $this->saver->save($post, $content, $scope);
|
||||
} catch (WriteFailed $e) {
|
||||
if (! $e->rolledBack) {
|
||||
$this->log->recordPartial(
|
||||
@@ -140,6 +148,46 @@ final class DiviWriter
|
||||
return $tool->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* save() for the Divi tools (E2): pages as before; a library entry keeps its shape, a global one
|
||||
* needs confirm (dry run first), gets a backup when revisions are off and clears every page's
|
||||
* cache; the result then names the affected pages.
|
||||
*
|
||||
* @param array<string, mixed> $input
|
||||
* @return array<string, mixed>|WP_Error
|
||||
* @throws WriteFailed
|
||||
*/
|
||||
public function commit(string $ability, DiviPage $page, DiviChange $change, array $input): array|WP_Error
|
||||
{
|
||||
if (! $page->isLibraryItem()) {
|
||||
return $this->save($ability, $page, $change, $input);
|
||||
}
|
||||
|
||||
if ($this->globals === null) {
|
||||
return Errors::unsupported(
|
||||
'Bibliothekseinträge lassen sich über diese Verbindung nicht ändern.',
|
||||
'Den Eintrag im Divi-Builder bearbeiten.'
|
||||
);
|
||||
}
|
||||
|
||||
if (Serializer::document($page->document) === (string) $page->post->post_content) {
|
||||
return $this->save($ability, $page, $change, $input, SaveScope::LibraryItem);
|
||||
}
|
||||
|
||||
$prepared = $this->globals->prepare($page, $input);
|
||||
if ($prepared instanceof WP_Error) {
|
||||
return $prepared;
|
||||
}
|
||||
|
||||
return array_merge($this->save($ability, $page, $change, $input, $prepared['scope']), $prepared['details']);
|
||||
}
|
||||
|
||||
/** A tool's confirm_required on a global library entry, extended by the affected pages. */
|
||||
public function notice(DiviPage $page, WP_Error $error): WP_Error
|
||||
{
|
||||
return $page->isLibraryItem() && $this->globals !== null ? $this->globals->notice($page, $error) : $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outline of the sections that contain changed nodes (breadth limit of ruling S18). A removed
|
||||
* node has no block any more, but its ID from before the removal still names the (surviving)
|
||||
|
||||
Reference in New Issue
Block a user