Behebt die fünf Befunde der Abschlussprüfung von divi-absicherung: Divi-Reiter ohne aktives Divi zeigt nur noch einen Hinweis (kein Status, keine Prüfung, kein Aufräumen), Zustandstexte werden erst beim Rendern übersetzt, DiviPages::setFlags() und DiviThemeBuilder::liveId(true) prüfen jetzt selbst die Freigabesperre, WriteProbe::removeOrphans() löscht nur noch Entwürfe mit passendem Titel, und wp lit-mcp divi-check --update-reference verweigert sich ohne Entwicklungskopie, bevor irgendetwas geschrieben wird. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
105 lines
3.9 KiB
PHP
105 lines
3.9 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace LIT\MCP\Integrations\Divi\Pages;
|
||
|
||
use LIT\MCP\Integrations\Divi\Release\Call;
|
||
use LIT\MCP\Integrations\Divi\Release\DiviAdapter;
|
||
use LIT\MCP\Integrations\Divi\Release\DiviLocked;
|
||
use LIT\MCP\Integrations\Divi\Release\Manifest;
|
||
use LIT\MCP\Integrations\Divi\Release\Mirror;
|
||
use LIT\MCP\Integrations\Divi\Release\ReleaseGate;
|
||
use RuntimeException;
|
||
use WP_Post;
|
||
|
||
defined('ABSPATH') || exit;
|
||
|
||
/**
|
||
* Adapter "Seiten" (spec §3): the Divi 5 builder flags of an entry as the Visual Builder's own save sets them
|
||
* (mirror vb-sync-flags: _et_pb_use_divi_5 = "on", legacy _et_pb_use_builder = "on", _et_pb_show_page_creation =
|
||
* "off" so the builder skips its page creation flow), whether an entry uses the builder, its builder URL, the
|
||
* static CSS of one page and Divi's list of linkable post types. Ruling S11: update_post_meta() returns false for an
|
||
* unchanged value too, so setFlags() checks by reading the flags back. Used by DiviSaver, the Divi content creation,
|
||
* WpLinkTargets and PostPresenter.
|
||
*/
|
||
final class DiviPages implements DiviAdapter
|
||
{
|
||
public const FLAGS = [
|
||
'_et_pb_use_divi_5' => 'on',
|
||
'_et_pb_use_builder' => 'on',
|
||
'_et_pb_show_page_creation' => 'off',
|
||
];
|
||
|
||
public static function manifest(): Manifest
|
||
{
|
||
return new Manifest(
|
||
Manifest::PAGES,
|
||
calls: [
|
||
new Call('ET_Core_PageResource::remove_static_resources', 3),
|
||
new Call('et_builder_get_public_post_types', 0),
|
||
],
|
||
keys: ['_et_pb_use_divi_5', '_et_pb_use_builder', '_et_pb_show_page_creation', 'et_fb'],
|
||
mirrors: [
|
||
new Mirror(
|
||
'vb-sync-flags',
|
||
'includes/builder-5/server/VisualBuilder/REST/SyncToServer/SyncToServerController.php',
|
||
'update',
|
||
'SyncToServerController',
|
||
'Builder-Kennzeichen einer Seite (_et_pb_use_divi_5, _et_pb_use_builder, _et_pb_show_page_creation)'
|
||
),
|
||
]
|
||
);
|
||
}
|
||
|
||
/**
|
||
* @throws RuntimeException When a flag does not read back as set.
|
||
* @throws DiviLocked When Divi is not released (spec §5.5) – before anything is written.
|
||
*/
|
||
public static function setFlags(int $postId): void
|
||
{
|
||
ReleaseGate::assertWritable($postId);
|
||
foreach (self::FLAGS as $key => $value) {
|
||
update_post_meta($postId, $key, $value);
|
||
}
|
||
|
||
foreach (self::FLAGS as $key => $value) {
|
||
if (get_post_meta($postId, $key, true) !== $value) {
|
||
throw new RuntimeException(sprintf('Divi flag %s of post %d is not "%s".', $key, $postId, $value));
|
||
}
|
||
}
|
||
}
|
||
|
||
/** Whether Divi's builder flag marks $postId as a builder layout. */
|
||
public static function usesBuilder(int $postId): bool
|
||
{
|
||
return get_post_meta($postId, '_et_pb_use_builder', true) === 'on';
|
||
}
|
||
|
||
/** The entry opened in the Divi Visual Builder: its permalink with et_fb=1. */
|
||
public static function builderUrl(WP_Post|int $post): string
|
||
{
|
||
return (string) add_query_arg('et_fb', '1', (string) get_permalink($post));
|
||
}
|
||
|
||
/** Removes the static CSS files Divi generated for $postId (spec §5.6 step 5). */
|
||
public static function clearPageCss(int $postId): void
|
||
{
|
||
if (class_exists('ET_Core_PageResource')) {
|
||
\ET_Core_PageResource::remove_static_resources($postId, 'all', true);
|
||
}
|
||
}
|
||
|
||
/** Whether Divi offers a post_link_url_<type> option for $postType. Fail closed: without Divi's list, none. */
|
||
public static function isLinkable(string $postType): bool
|
||
{
|
||
if (! function_exists('et_builder_get_public_post_types')) {
|
||
return false;
|
||
}
|
||
|
||
$types = et_builder_get_public_post_types();
|
||
|
||
return is_array($types) && array_key_exists($postType, $types);
|
||
}
|
||
}
|