refactor: Divi catalog adapter with manifest

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-30 00:54:48 +02:00
co-authored by Claude Opus 5.5
parent 5e6d5ff3e1
commit fc7a84d239
8 changed files with 164 additions and 46 deletions
+68 -3
View File
@@ -5,17 +5,51 @@ declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi\Schema;
use ET\Builder\Packages\ModuleLibrary\ModuleRegistration;
use LIT\MCP\Integrations\Divi\BlockTree\GlobalInstance;
use LIT\MCP\Integrations\Divi\Library\DiviLibraryStore;
use LIT\MCP\Integrations\Divi\Release\Call;
use LIT\MCP\Integrations\Divi\Release\DiviAdapter;
use LIT\MCP\Integrations\Divi\Release\Manifest;
use LIT\MCP\Integrations\Divi\ThemeBuilder\DiviThemeBuilder;
defined('ABSPATH') || exit;
/**
* Reads Divi's module metadata once per request (Divi 5 only). Not final so abilities can be
* unit-tested with a mock.
* Adapter "Katalog" (spec §3): Divi's module metadata once per request (Divi 5 only), Divi's own post types and
* its per-type builder switch for the content tools, and whether Divi knows a block type. Not final so abilities
* can be unit-tested with a mock.
*/
class DiviModules
class DiviModules implements DiviAdapter
{
/** Divi's own post types the content tools leave alone (library, Theme Builder, canvases, speculation). */
public const INTERNAL_POST_TYPES = [
DiviLibraryStore::POST_TYPE,
DiviThemeBuilder::THEME_BUILDER,
DiviThemeBuilder::TEMPLATE,
DiviThemeBuilder::LAYOUT_TYPES['header'],
DiviThemeBuilder::LAYOUT_TYPES['body'],
DiviThemeBuilder::LAYOUT_TYPES['footer'],
'et_pb_canvas',
'_et_pb_speculation',
];
private ?ModuleCatalog $catalog = null;
public static function manifest(): Manifest
{
return new Manifest(
Manifest::CATALOG,
calls: [
new Call(ModuleRegistration::class . '::get_all_core_modules_metadata', 0),
new Call(ModuleRegistration::class . '::get_default_attrs', 2),
new Call('et_builder_enabled_for_post_type', 1),
],
constants: ['ET_BUILDER_PRODUCT_VERSION'],
blockTypes: [GlobalInstance::BLOCK],
keys: ['et_pb_canvas', '_et_pb_speculation']
);
}
public static function isAvailable(): bool
{
return class_exists(ModuleRegistration::class);
@@ -43,4 +77,35 @@ class DiviModules
{
return defined('ET_BUILDER_PRODUCT_VERSION') ? (string) ET_BUILDER_PRODUCT_VERSION : '5.2.1';
}
/**
* Whether Divi's builder is switched on for $postType (Divi → Theme-Optionen → Builder); false without Divi.
*/
public static function builderEnabledFor(string $postType): bool
{
return function_exists('et_builder_enabled_for_post_type')
&& (bool) et_builder_enabled_for_post_type($postType);
}
/**
* Whether Divi still has block type $name: registered with WordPress, or in Divi's core module metadata (Divi
* renders global instances itself and does not always register the type with WordPress).
*/
public static function knowsBlock(string $name): bool
{
if (class_exists('WP_Block_Type_Registry') && \WP_Block_Type_Registry::get_instance()->is_registered($name)) {
return true;
}
if (! self::isAvailable()) {
return false;
}
foreach ((array) ModuleRegistration::get_all_core_modules_metadata() as $module) {
if (is_array($module) && ($module['name'] ?? null) === $name) {
return true;
}
}
return false;
}
}