Files
WP-LIT-MCP/src/Integrations/Divi/Pages/DiviPageLoader.php
T
janniclas.loosenandClaude Opus 5.5 097fef2e32 fix: final review minors m-1 to m-8
- m-1: the no-change Divi result carries preview_url/edit_url too
- m-2: overview names replace-text's per-page tree_rev
- m-3: divi-shortform documents validation_failed vs not_found for unknown IDs
- m-4: DiviWriter/DiviPageLoader final (no mocks left), neutral NewDraft
  log detail, snapshots are Etappe 4
- m-5: Tested up to 7.1, changelog completed
- m-6: content-create warns when the extras changed the stored layout
- m-7: deleting a whole section outlines nothing instead of the next one
- m-8: uninstall removes the user meta lit_mcp_log_per_page; readme lists it

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-26 19:35:24 +02:00

106 lines
4.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi\Pages;
use LIT\MCP\Abilities\Errors;
use LIT\MCP\Integrations\Divi\BlockTree\MalformedMarkup;
use LIT\MCP\Integrations\Divi\BlockTree\NodeIndex;
use LIT\MCP\Integrations\Divi\BlockTree\Parser;
use LIT\MCP\Integrations\WordPress\PostGuard;
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
use LIT\MCP\Log;
use WP_Error;
defined('ABSPATH') || exit;
/**
* Loads an entry for the Divi tools: rights and status via PostGuard (spec §4.5), then the
* block tree. Divi 4 shortcode content and unbalanced markup are refused with a hint –
* spec §3.4: Divi 4 content is kept, never edited.
*/
final class DiviPageLoader
{
public const OUTLINE_HINT = 'Aktuellen Stand mit lit/divi-outline (direkt: lit-divi-outline) neu lesen und die '
. 'Änderung mit der neuen tree_rev wiederholen.';
public function __construct(private ContentSchema $schema, private Parser $parser = new Parser())
{
}
/** Readers pass $forWrite = false (trashed entries may be read, like lit-content-get). */
public function load(mixed $postId, bool $forWrite): DiviPage|WP_Error
{
$post = PostGuard::editable($postId, $this->schema, 'post_id', ! $forWrite);
if ($post instanceof WP_Error) {
return $post;
}
$content = (string) $post->post_content;
if (! str_contains($content, '<!-- wp:divi/') && str_contains($content, '[et_pb_')) {
return Errors::unsupported(
sprintf(
'Eintrag %d enthält Divi-4-Inhalt (Shortcodes); die Divi-Werkzeuge bearbeiten nur Divi 5.',
$post->ID
),
'Die Seite einmal im Divi-Builder öffnen und speichern – Divi 5 wandelt sie dabei um. Bis dahin '
. 'bleibt der Inhalt unverändert.'
);
}
try {
$document = $this->parser->parse($content);
} catch (MalformedMarkup $e) {
Log::failure(sprintf('divi parse of post %d', $post->ID), $e->getMessage());
return Errors::unsupported(
sprintf(
'Der Inhalt von Eintrag %d ist kein gültiges Block-Markup; nichts wurde gelesen oder geändert.',
$post->ID
),
'Die Seite im Divi-Builder öffnen und speichern (Divi repariert dabei die Struktur) oder den Nutzer '
. 'fragen, ob eine frühere Revision (lit/revisions-list) wiederhergestellt werden soll.'
);
}
return new DiviPage($post, $document, NodeIndex::build($document));
}
/** The entry loaded for writing and checked by writable() – the refusal of either step. */
public function loadWritable(mixed $postId): DiviPage|WP_Error
{
$page = $this->load($postId, true);
if ($page instanceof WP_Error) {
return $page;
}
return $this->writable($page) ?? $page;
}
/**
* Additional checks for writing: the type must use the Divi builder, the content must be a
* Divi 5 layout (or empty) and saving must not publish a missed schedule (spec §2).
*/
public function writable(DiviPage $page): ?WP_Error
{
$post = $page->post;
if (! $this->schema->diviEnabled((string) $post->post_type)) {
return Errors::unsupported(
sprintf('Für den Inhaltstyp "%s" ist der Divi-Builder nicht aktiviert.', $post->post_type),
'In Divi → Theme-Optionen → Builder den Builder für diesen Inhaltstyp aktivieren (Administrator).'
);
}
if (! $page->isDiviLayout()) {
return Errors::unsupported(
sprintf('Eintrag %d ist kein Divi-Layout (Block-Editor- oder klassischer Inhalt).', $post->ID),
'Den Inhalt mit lit/content-update (direkt: lit-content-update) bearbeiten, oder den Nutzer fragen, ob '
. 'die Seite im Divi-Builder neu aufgebaut werden soll.'
);
}
return PostGuard::statusStable($post);
}
}