fix(security): no direct HTTP access to plugin PHP files (audit L2, cheap part)

Every file under src/ exits outside WordPress (defined('ABSPATH') ||
exit; after the use block, so a direct request no longer prints a fatal
error with the server path); divi-convert-fixture.php gets the WP_CLI
guard the other integration scripts have. A unit test keeps both true;
PSR1 side-effects warning excluded for the guard.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
2026-09-26 19:32:12 +02:00
co-authored by Claude Opus 5.5
parent 4d4bf57c9f
commit b24eb6c3e9
185 changed files with 418 additions and 1 deletions
@@ -7,6 +7,8 @@ namespace LIT\MCP\Integrations\Divi\BlockTree;
use InvalidArgumentException;
use stdClass;
defined('ABSPATH') || exit;
/**
* Divi 5 attributes addressed by dotted paths ("title.decoration.font.font"). The value at
* a path is a breakpoint map: {"desktop": {"value": …, "hover": …}, "phone": {"value": …}}.
@@ -8,6 +8,8 @@ use InvalidArgumentException;
use LogicException;
use stdClass;
defined('ABSPATH') || exit;
/**
* One block of the tree. A parsed block keeps its original opener/closer bytes; they are
* dropped only when the block itself changes (setAttrs(), a void block getting children),
@@ -7,6 +7,8 @@ namespace LIT\MCP\Integrations\Divi\BlockTree;
use InvalidArgumentException;
use LogicException;
defined('ABSPATH') || exit;
/**
* Ordered parts of a document or of a block's inner content: blocks and the raw text
* between them (whitespace, freeform HTML, Divi 4 shortcodes). Keeping every byte of that
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi\BlockTree;
defined('ABSPATH') || exit;
/**
* The parsed post_content: top-level blocks and the text between them.
*/
+2
View File
@@ -7,6 +7,8 @@ namespace LIT\MCP\Integrations\Divi\BlockTree;
use JsonException;
use stdClass;
defined('ABSPATH') || exit;
/**
* JSON of block attributes. PHP arrays cannot tell an empty JSON object from an empty list,
* nor an object with the keys "0", "1", … from a list. decodeObject() therefore keeps such
@@ -6,6 +6,8 @@ namespace LIT\MCP\Integrations\Divi\BlockTree;
use RuntimeException;
defined('ABSPATH') || exit;
/**
* post_content is no balanced block markup (closer without opener, unclosed block, PCRE
* failure). The Divi tools then refuse to read or write the entry – nothing is guessed.
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi\BlockTree;
defined('ABSPATH') || exit;
/**
* Path IDs of a Document (spec §5.3): s0, s0.r1, s0.r1.c0.m2. One letter per role –
* s section, r row / row-inner, c column / column-inner, m module (incl. group and child
@@ -6,6 +6,8 @@ namespace LIT\MCP\Integrations\Divi\BlockTree;
use LIT\MCP\Abilities\Text;
defined('ABSPATH') || exit;
/**
* Short human-readable facts about a node for the outline: admin label, first text,
* preset IDs, column layout. Pure PHP.
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi\BlockTree;
defined('ABSPATH') || exit;
/**
* The page tree as rows and as compact text (lit-divi-outline, spec §5.3/§5.7; also the
* "outline" of write results). Preset IDs are shown with their names when known.
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi\BlockTree;
defined('ABSPATH') || exit;
/**
* Parses block markup into a Document without WordPress (spec §4.4, §5.2). Uses the
* block-delimiter pattern of WP_Block_Parser, but records the exact bytes of every
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi\BlockTree;
defined('ABSPATH') || exit;
/**
* Turns a Document back into block markup. Unchanged blocks reuse their original
* delimiters; changed or new blocks get delimiters generated exactly like WordPress'