Files
WP-LIT-MCP/src/Integrations/Divi/Schema/DiviCatalogAbility.php
T
janniclas.loosenandClaude Opus 5.5 10c98cd3c6 docs: Divi guides shortform/placeholders, hints name the write tools; test: Divi write end-to-end; version 0.3.0
- Hints (PostPresenter::DIVI_NOTE, outline, catalog) and server instructions (tree_rev rule)
  name the Divi write tools; guides divi-shortform and divi-placeholders, additions to
  divi-structure, divi-attrs, overview (tool groups, 'nur lesen'), workflows, content-types.
- D7 wording and the S7 exception in readme, guides and spec 1.3/5.2; readme 0.3.0.
- ToolNamingTest: every referenced guide topic exists; overview lists exactly the topics.
- tests/Integration/divi-write-smoke.sh: all write tools via OAuth, editor without
  unfiltered_html with benign probes (S6), Divi's own save filters on the new fixture
  synthetic-divi-filters.html (S7); admin-render.php accepts the new wrap class.

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

160 lines
6.1 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\Schema;
use LIT\MCP\Abilities\Ability;
use LIT\MCP\Abilities\Errors;
use LIT\MCP\Abilities\JsonMap;
use WP_Error;
/**
* lit/divi-catalog: the modules of this Divi installation with their short-form fields;
* with "module" the details of one module incl. all known attribute paths (spec §5.7).
*/
final class DiviCatalogAbility implements Ability
{
public const CODE_NOTE = 'Code-Modul (code) nur verwenden, wenn kein natives Modul passt – es ist im '
. 'Divi-Builder nicht visuell bearbeitbar.';
public function __construct(private DiviModules $modules)
{
}
public function name(): string
{
return 'lit/divi-catalog';
}
public function label(): string
{
return 'Divi-Modulkatalog';
}
public function description(): string
{
return 'Listet die Divi-Module dieser Website (Name, Titel, Art, erlaubte Kind-Module) und welche eine '
. 'Kurzform haben; ohne module alle Module. Mit module: Kurzform-Felder und alle gültigen '
. 'Attributpfade des Moduls für die Vollform, je Pfad nach Möglichkeit mit Feldart (path_kinds), bei '
. 'zusammengesetzten Pfaden als Zuordnung Unterfeld => Feldart.';
}
public function inputSchema(): array
{
return [
'type' => 'object',
'properties' => [
'module' => ['type' => 'string', 'description' => 'Modul, z. B. "button" oder "divi/button".'],
],
'additionalProperties' => false,
];
}
public function outputSchema(): ?array
{
return [
'type' => 'object',
'properties' => [
'modules' => [
'type' => 'array',
'items' => [
'type' => 'object',
'properties' => [
'name' => ['type' => 'string'],
'title' => ['type' => 'string'],
'category' => ['type' => 'string'],
'children' => ['type' => 'array', 'items' => ['type' => 'string']],
'shortform' => ['type' => 'boolean'],
],
'required' => ['name', 'title', 'category', 'children', 'shortform'],
],
],
'module' => [
'type' => 'object',
'properties' => [
'name' => ['type' => 'string'],
'title' => ['type' => 'string'],
'category' => ['type' => 'string'],
'children' => ['type' => 'array', 'items' => ['type' => 'string']],
'item_type' => ['type' => ['string', 'null']],
'shortform' => ['type' => 'object'],
'paths' => ['type' => 'array', 'items' => ['type' => 'string']],
'path_kinds' => [
'type' => 'object',
'description' => 'Bekannter Attributpfad => Feldart (text, richtext, code, url, '
. 'image, color, enum, onoff, number, list, icon), soweit aus den Divi-Metadaten '
. 'ableitbar. Bei einem zusammengesetzten Pfad (ein oder mehrere benannte '
. 'Unterfelder unter einem Pfad, z. B. buttonOne.innerContent mit "text" und '
. '"linkUrl") ist der Wert '
. 'stattdessen eine Zuordnung Unterfeld => Feldart, soweit für die einzelnen '
. 'Unterfelder ableitbar. Fehlende Pfade oder Unterfelder gelten als unbekannt.',
],
],
'required' => ['name', 'title', 'category', 'children', 'shortform', 'paths', 'path_kinds'],
],
'notes' => ['type' => 'array', 'items' => ['type' => 'string']],
],
'required' => ['notes'],
];
}
public function annotations(): array
{
return ['readonly' => true, 'destructive' => false, 'idempotent' => true];
}
public function isDirect(): bool
{
return true;
}
public function permission(array $input): bool|WP_Error
{
return current_user_can('edit_posts')
? true
: Errors::forbidden('Keine Berechtigung, Inhalte zu bearbeiten.');
}
public function execute(array $input): mixed
{
$catalog = $this->modules->catalog();
$notes = [self::CODE_NOTE, 'Details und Beispiele: lit-guide mit topic "divi-shortform" bzw. "divi-attrs".'];
if (! is_string($input['module'] ?? null) || $input['module'] === '') {
$modules = [];
foreach ($catalog->summary() as $module) {
$shortName = ModuleCatalog::shortName($module['name']);
$modules[] = $module + ['shortform' => ShortformMap::has($shortName)];
}
return ['modules' => $modules, 'notes' => $notes];
}
$name = ModuleCatalog::normalize($input['module']);
if (! $catalog->has($name)) {
return Errors::notFound(
sprintf('Modul "%s" gibt es auf dieser Website nicht.', $input['module']),
'Verfügbare Module mit lit-divi-catalog ohne module abrufen.'
);
}
$short = ModuleCatalog::shortName($name);
$item = ShortformMap::childType($short);
return [
'module' => [
'name' => $name,
'title' => $catalog->title($name),
'category' => $catalog->category($name),
'children' => $catalog->childrenOf($name),
'item_type' => $item,
'shortform' => JsonMap::of(ShortformMap::fields($short)),
'paths' => $catalog->paths($name),
'path_kinds' => JsonMap::of($catalog->kinds($name)),
],
'notes' => $notes,
];
}
}