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:
@@ -7,6 +7,8 @@ namespace LIT\MCP\Integrations\WordPress\Content;
|
||||
use Throwable;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Builds the content of a new entry for lit/content-create from a structured description
|
||||
* (spec §6.2: "optional Divi-Inhalt in Kurzform"). Implemented by the Divi integration, so the
|
||||
|
||||
@@ -17,6 +17,8 @@ use Throwable;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/content-create: new entry, always a draft. All or nothing (spec §8.2): input is
|
||||
* validated before the insert; if fields, terms or the featured image cannot be written
|
||||
|
||||
@@ -10,6 +10,8 @@ use LIT\MCP\Integrations\WordPress\PostGuard;
|
||||
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class ContentGetAbility implements Ability
|
||||
{
|
||||
public function __construct(private ContentSchema $schema, private PostPresenter $presenter)
|
||||
|
||||
@@ -14,6 +14,8 @@ use LIT\MCP\Integrations\WordPress\Schema\FieldDefinition;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class ContentQueryAbility implements Ability
|
||||
{
|
||||
private const STATUSES = ['publish', 'draft', 'pending', 'private', 'future'];
|
||||
|
||||
@@ -10,6 +10,8 @@ use LIT\MCP\Abilities\Errors;
|
||||
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class ContentTypesAbility implements Ability
|
||||
{
|
||||
public function __construct(private ContentSchema $schema)
|
||||
|
||||
@@ -22,6 +22,8 @@ use Throwable;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/content-update: changes an entry without touching its status. rev (from
|
||||
* lit/content-get) is required so parallel edits are never overwritten (spec §2
|
||||
|
||||
@@ -12,6 +12,8 @@ use RuntimeException;
|
||||
use Throwable;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* The transaction of lit/content-create: inserting the draft and every way back out of it.
|
||||
* The three exits side by side:
|
||||
|
||||
@@ -11,6 +11,8 @@ use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use LIT\MCP\Integrations\WordPress\Schema\FieldDefinition;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Output format of an entry for the content tools. Not final so abilities can be
|
||||
* unit-tested with a mock.
|
||||
|
||||
@@ -14,6 +14,8 @@ use Throwable;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Shared validation and write logic of lit/content-create and lit/content-update.
|
||||
* prepare() validates everything before the first write (all or nothing, spec §8.2);
|
||||
|
||||
@@ -12,6 +12,8 @@ use LIT\MCP\Abilities\ToolResult;
|
||||
use LIT\MCP\ChangeLog\ChangeLog;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/menu-assign-location: assigns a menu to a theme location (menu_id 0 removes
|
||||
* the assignment – the menu then disappears from the site, so removing an existing
|
||||
|
||||
@@ -13,6 +13,8 @@ use LIT\MCP\Abilities\ToolResult;
|
||||
use LIT\MCP\ChangeLog\ChangeLog;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/menu-create: creates an empty menu and optionally assigns it to a theme
|
||||
* location. Menu items are added afterwards via lit/menu-set-items (Task 14).
|
||||
|
||||
@@ -10,6 +10,8 @@ use LIT\MCP\Abilities\Errors;
|
||||
use LIT\MCP\Abilities\Rev;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/menu-get: a menu as a tree (P4 ruling: same node shape lit/menu-set-items,
|
||||
* Task 14, accepts as input, so the result can be edited and sent back as-is).
|
||||
|
||||
@@ -9,6 +9,8 @@ use LIT\MCP\Abilities\Annotations;
|
||||
use LIT\MCP\Abilities\Errors;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/menu-list: overview of all menus and the theme's menu locations, and which
|
||||
* menu (if any) currently sits at each location.
|
||||
|
||||
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\WordPress\Menus;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Theme menu locations (theme mod nav_menu_locations).
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace LIT\MCP\Integrations\WordPress\Menus;
|
||||
use LIT\MCP\Abilities\Errors;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Applies add/move/remove operations to the current menu tree and returns the
|
||||
* desired tree for MenuWriter – so single operations and the declarative mode
|
||||
|
||||
@@ -14,6 +14,8 @@ use LIT\MCP\Abilities\WriteFailed;
|
||||
use LIT\MCP\ChangeLog\ChangeLog;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/menu-set-items: sets a menu's items, declaratively (items = whole target tree) or
|
||||
* as add/move/remove operations. Both run through one path: operations are applied to
|
||||
|
||||
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\WordPress\Menus;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Turns the flat wp_get_nav_menu_items() list into a nested tree. The node shape
|
||||
* (node()) is deliberately the same shape lit/menu-set-items (Task 14) accepts as
|
||||
|
||||
@@ -10,6 +10,8 @@ use Throwable;
|
||||
use WP_Post;
|
||||
use WP_Term;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Validates a desired menu tree against the current items and writes it.
|
||||
*
|
||||
|
||||
@@ -10,6 +10,8 @@ use RuntimeException;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Loads entries and post types for abilities, including the capability checks
|
||||
* of spec §4.5. Every error is ready to be returned from permission()/execute().
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace LIT\MCP\Integrations\WordPress;
|
||||
use RuntimeException;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Internal writes of post-row columns through wp_update_post() (slashed, WP_Error mode):
|
||||
* rollbacks, clone rows, media metadata. Refusals become RuntimeExceptions with an internal
|
||||
|
||||
@@ -10,6 +10,8 @@ use LIT\MCP\Abilities\ToolResult;
|
||||
use LIT\MCP\ChangeLog\ChangeLog;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* What every post tool does once its write is saved: fire lit_mcp_after_save, re-read the
|
||||
* post, write the change log and build the ToolResult with the new rev. From here on a
|
||||
|
||||
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\WordPress;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/** Post statuses shared by the plugin's own SQL queries. */
|
||||
final class PostStatuses
|
||||
{
|
||||
|
||||
@@ -10,6 +10,8 @@ use LIT\MCP\Integrations\WordPress\PostGuard;
|
||||
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/page-render-summary: what a visitor sees in the content area – headings, texts, links,
|
||||
* images with alt text and obvious problems (spec §5.7, §8.1). Works for every managed entry,
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace LIT\MCP\Integrations\WordPress\Render;
|
||||
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Renders the content area of an entry in-process, like the front end does for the_content
|
||||
* (Divi 5 renders its blocks there – verified in DDEV). Header, footer and Theme Builder
|
||||
|
||||
@@ -10,6 +10,8 @@ use DOMNode;
|
||||
use DOMXPath;
|
||||
use LIT\MCP\Abilities\Text;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Structured excerpt of rendered HTML (spec §5.7 lit/page-render-summary): headings, text
|
||||
* blocks, links, images with alt text and the obvious problems. Every extracted string is
|
||||
|
||||
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\WordPress;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Restore point before a change (spec §2 principle 7): WordPress stores the
|
||||
* current state as a revision (only if it differs from the newest one) and the
|
||||
|
||||
@@ -17,6 +17,8 @@ use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/revision-restore: restores title, content and excerpt of an entry from one of
|
||||
* its own revisions; the status is not touched. Because this overwrites the current
|
||||
|
||||
@@ -13,6 +13,8 @@ use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/revisions-list: revisions of an entry, newest first. Autosaves are included
|
||||
* (marked autosave: true) rather than filtered out, so the client can decide. Each
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace LIT\MCP\Integrations\WordPress\Schema;
|
||||
|
||||
use LogicException;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Detects the content model of this installation (spec §6.1): post types with a
|
||||
* UI, their taxonomies and their fields merged from all field sources.
|
||||
|
||||
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\WordPress\Schema;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Description of one field of a post type, independent of where it comes from.
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace LIT\MCP\Integrations\WordPress\Schema;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* A provider of field definitions for post types that can also read and write
|
||||
* the values of its own fields (Pods via the Pods API, everything else via meta).
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace LIT\MCP\Integrations\WordPress\Schema;
|
||||
|
||||
use DateTimeImmutable;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Checks field values against the detected schema before anything is written.
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace LIT\MCP\Integrations\WordPress\Schema;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Shared read/write via the post meta API. write() throws when WordPress did not
|
||||
* store a value, so callers can roll back (all or nothing, spec §8.2).
|
||||
|
||||
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\WordPress\Schema;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Fields registered with register_meta()/register_post_meta().
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\WordPress\Schema;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Meta keys actually used by the most recent posts of a type. Keys starting with
|
||||
* "_" are internal and only shown when another source knows them.
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace LIT\MCP\Integrations\WordPress\Schema;
|
||||
use RuntimeException;
|
||||
use WP_Term;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Resolves term input ({taxonomy: [id | name, …]}) and replaces a post's terms.
|
||||
* resolve() never writes, so a whole call can be validated first (all or nothing).
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace LIT\MCP\Integrations\WordPress\Settings;
|
||||
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* The WordPress options LIT MCP may read and write (spec §6.5), with validation.
|
||||
*
|
||||
|
||||
@@ -9,6 +9,8 @@ use LIT\MCP\Abilities\Annotations;
|
||||
use LIT\MCP\Abilities\Errors;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class WpSettingsGetAbility implements Ability
|
||||
{
|
||||
public function __construct(private SettingsWhitelist $whitelist)
|
||||
|
||||
@@ -16,6 +16,8 @@ use RuntimeException;
|
||||
use Throwable;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/wp-settings-update: writes whitelisted WordPress options, all or nothing.
|
||||
*
|
||||
|
||||
@@ -13,6 +13,8 @@ use Throwable;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Copies entries (draft copy, trashed backup) and swaps a copy's content back into its
|
||||
* original. Meta is copied byte-exact: the stored meta_value strings are read and
|
||||
|
||||
@@ -14,6 +14,8 @@ use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/post-duplicate: creates a draft copy of an entry (spec §6.2). The original –
|
||||
* ID, URL, menu items, content – is not touched. A failure after the insert deletes
|
||||
|
||||
@@ -16,6 +16,8 @@ use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/post-publish: publishes an entry immediately. A scheduled ("future") or
|
||||
* future-dated entry is republished now instead of staying in the future (spec §6.2);
|
||||
|
||||
@@ -20,6 +20,8 @@ use Throwable;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/post-replace-with-copy: swaps a copy made by lit/post-duplicate into its original
|
||||
* (spec §6.2). ID, URL, status and menu items of the original stay. rev of the original
|
||||
|
||||
@@ -17,6 +17,8 @@ use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/post-schedule: schedules an entry for publication at a future point in time
|
||||
* (site local time). An entry that is currently published stays live until then only
|
||||
|
||||
@@ -16,6 +16,8 @@ use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/post-trash: moves an entry to the trash – never a permanent delete. Trashing the
|
||||
* static front page, the posts page or an entry linked in a menu is allowed but named in
|
||||
|
||||
@@ -15,6 +15,8 @@ use LIT\MCP\Integrations\WordPress\PostGuard;
|
||||
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* lit/post-unpublish: withdraws a published, scheduled or private entry back to draft.
|
||||
* An entry that is already not public (draft, pending, auto-draft) is a no-op.
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace LIT\MCP\Integrations\WordPress\Status;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Thrown by PostCloner::replace(). $parts lists the parts of the original replace()
|
||||
* had started to write (post, meta, terms) – only those need to be restored.
|
||||
|
||||
@@ -9,6 +9,8 @@ use LIT\MCP\ChangeLog\ChangeLog;
|
||||
use Throwable;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Runs the one WordPress call of a status tool (wp_update_post(), wp_trash_post()). If a
|
||||
* hook throws inside it, the row may already be written – the entry's state is unknown,
|
||||
|
||||
@@ -39,6 +39,8 @@ use LIT\MCP\Integrations\WordPress\Status\PostScheduleAbility;
|
||||
use LIT\MCP\Integrations\WordPress\Status\PostTrashAbility;
|
||||
use LIT\MCP\Integrations\WordPress\Status\PostUnpublishAbility;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* WordPress basics (spec §6): content, status, copies, revisions, menus, settings, and the
|
||||
* rendered-content summary lit/page-render-summary (spec §5.7 – useful for every entry).
|
||||
|
||||
Reference in New Issue
Block a user