refactor: Kern ohne Divi – Ports BuilderDetector, MediaUsageSource, EnvironmentComponent und ausgeschlossene Post-Typen im ContentSchema; Divi-Implementierungen und Verdrahtung über DiviIntegration/Plugin; CoreIndependenceTest

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-18 21:49:28 +02:00
co-authored by Claude Sonnet 5.5
parent abeb4b0eed
commit 06148fb8c1
33 changed files with 952 additions and 154 deletions
@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi;
use LIT\MCP\Integrations\Divi\Pages\DiviPages;
use LIT\MCP\Integrations\Divi\Schema\DiviModules;
use LIT\MCP\Integrations\WordPress\BuilderDetector;
defined('ABSPATH') || exit;
/** The BuilderDetector for Divi 5: tools exist while Divi 5 is loaded, a layout carries Divi's builder flag. */
final class DiviBuilderDetector implements BuilderDetector
{
public function isAvailable(): bool
{
return DiviModules::isAvailable();
}
public function usesBuilder(int $postId): bool
{
return DiviPages::usesBuilder($postId);
}
}
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi;
use LIT\MCP\Integrations\Core\EnvironmentComponent;
use LIT\MCP\Integrations\Divi\Release\DiviEnvironment;
use LIT\MCP\Integrations\Divi\Release\ReleaseGate;
defined('ABSPATH') || exit;
/**
* Divi in lit-site-status: version, the internals that are missing (DiviCompatibility) and the release status
* (spec §5.5); inactive without problems and release when Divi is not the template.
*/
final class DiviEnvironmentComponent implements EnvironmentComponent
{
public function __construct(private ?DiviCompatibility $compatibility = null)
{
}
public function describe(): array
{
$version = DiviEnvironment::version();
$active = $version !== null;
return [
'id' => 'divi',
'active' => $active,
'version' => $version,
'problems' => $active ? ($this->compatibility ?? new DiviCompatibility())->problems() : [],
'release' => $active ? ReleaseGate::status()->toArray() : null,
];
}
}
+42
View File
@@ -53,7 +53,10 @@ use LIT\MCP\Integrations\Divi\ThemeBuilder\DiviThemeBuilder;
use LIT\MCP\Integrations\Divi\ThemeBuilder\ThemeBuilderAccess;
use LIT\MCP\Integrations\Divi\ThemeBuilder\ThemeBuilderEdits;
use LIT\MCP\Integrations\Divi\ThemeBuilder\ThemeBuilderIntegration;
use LIT\MCP\Integrations\Core\EnvironmentComponent;
use LIT\MCP\Integrations\Integration;
use LIT\MCP\Integrations\Media\MediaUsageSource;
use LIT\MCP\Integrations\WordPress\BuilderDetector;
use LIT\MCP\Integrations\WordPress\Content\ContentComposer;
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
@@ -131,6 +134,45 @@ final class DiviIntegration implements Integration
return DiviModules::isAvailable();
}
/**
* Divi's own post types (library, Theme Builder, canvases, speculation), which the content tools leave alone:
* ContentSchema's excluded post types. Static because the schema is built before this integration (Plugin).
*
* @return list<string>
*/
public static function internalPostTypes(): array
{
return DiviModules::INTERNAL_POST_TYPES;
}
/** Whether Divi's builder is switched on for $postType: ContentSchema::diviEnabled() (static, like above). */
public static function builderEnabledFor(string $postType): bool
{
return DiviModules::builderEnabledFor($postType);
}
/** Port for the content tools: Divi's builder flag and availability (PostPresenter). */
public function builderDetector(): BuilderDetector
{
return new DiviBuilderDetector();
}
/**
* Port for the media tools: places outside the library where Divi stores an attachment (its logo).
*
* @return list<MediaUsageSource>
*/
public function mediaUsageSources(): array
{
return [new DiviLogoUsage()];
}
/** Port for lit-site-status: Divi's version, missing internals and release status. */
public function environmentComponent(): EnvironmentComponent
{
return new DiviEnvironmentComponent();
}
/**
* Divi short form for lit/content-create; available() reports whether Divi 5 is loaded,
* writable() asks $writable (the Tools-tab gate, security M2).
+35
View File
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi;
use LIT\MCP\Integrations\Divi\Design\DesignSystemReader;
use LIT\MCP\Integrations\Media\AttachmentFile;
use LIT\MCP\Integrations\Media\ContentMediaReferences;
use LIT\MCP\Integrations\Media\MediaUsageFinder;
use LIT\MCP\Integrations\Media\MediaUsageSource;
defined('ABSPATH') || exit;
/**
* The logo in Divi's theme options as a usage of an attachment: "possible", because only the file URL is stored
* (it may belong to another copy of the file); none without a file or a logo.
*/
final class DiviLogoUsage implements MediaUsageSource
{
public function usagesOf(int $attachmentId): array
{
$stem = AttachmentFile::stem($attachmentId);
$logo = DesignSystemReader::diviLogo();
if ($stem === '' || $logo === '') {
return [];
}
if (ContentMediaReferences::matches(ContentMediaReferences::fileRegex($stem), $logo) === false) {
return [];
}
return [MediaUsageFinder::siteUsage('Divi-Logo', 'option', 'divi_logo', MediaUsageFinder::POSSIBLE)];
}
}