refactor: Divi pages adapter replaces DiviFlags
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,7 +20,7 @@ defined('ABSPATH') || exit;
|
||||
/**
|
||||
* Divi short form for lit/content-create (spec §6.2): the sections become a Divi 5 layout in
|
||||
* exactly one divi/placeholder – inserted by TreeEditor like the first section of an empty page
|
||||
* (ruling S9) – stored through DiviSaver's kses window, with the builder flags (DiviFlags, S11).
|
||||
* (ruling S9) – stored through DiviSaver's kses window, with the builder flags (DiviPages, S11).
|
||||
*
|
||||
* Allow map (ruling S22) for an entry that does not exist yet: check() runs before the insert
|
||||
* with the composition bound to post ID 0 – Divi's own registry for "no entry" (get_options(0)
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\Divi\Pages;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Marks an entry as a Divi 5 builder layout, like the Visual Builder's own save does
|
||||
* (Divi 5.2.1 SyncToServerController.php:382-387: _et_pb_use_divi_5 = "on", legacy
|
||||
* _et_pb_use_builder = "on", and _et_pb_show_page_creation = "off" so the builder does not show
|
||||
* its page creation flow on the first open). Ruling S11: update_post_meta() returns false for
|
||||
* an unchanged value too, so success is checked by reading the flags back. Used by DiviSaver
|
||||
* (inside FollowUp) and the Divi content creation.
|
||||
*/
|
||||
final class DiviFlags
|
||||
{
|
||||
public const FLAGS = [
|
||||
'_et_pb_use_divi_5' => 'on',
|
||||
'_et_pb_use_builder' => 'on',
|
||||
'_et_pb_show_page_creation' => 'off',
|
||||
];
|
||||
|
||||
/** @throws RuntimeException When a flag does not read back as set. */
|
||||
public static function set(int $postId): void
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,6 +74,6 @@ final class DiviPage
|
||||
/** The entry opened in the Divi Visual Builder – the edit_url of every Divi write (review I-1). */
|
||||
public static function builderUrl(WP_Post|int $post): string
|
||||
{
|
||||
return (string) add_query_arg('et_fb', '1', (string) get_permalink($post));
|
||||
return DiviPages::builderUrl($post);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<?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\Manifest;
|
||||
use LIT\MCP\Integrations\Divi\Release\Mirror;
|
||||
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. */
|
||||
public static function setFlags(int $postId): void
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Save pipeline of spec §5.6, steps 3–5: restore point and wp_update_post() with wp_slash() (the
|
||||
* status stays), Divi 5 flags (DiviFlags), Divi's static CSS cache. A failure after saving is
|
||||
* status stays), Divi 5 flags and the page's static CSS (DiviPages). A failure after saving is
|
||||
* only a warning (FollowUp); a filter that changed the stored content is reported as well.
|
||||
*
|
||||
* kses (spec D7): for users without unfiltered_html WordPress' kses would run
|
||||
@@ -45,7 +45,7 @@ defined('ABSPATH') || exit;
|
||||
* for its single wp_update_post().
|
||||
*
|
||||
* Divi's own save filters are NOT kses and are never removed (ruling S7, defense in depth):
|
||||
* Security::initialize() (Divi 5.2.1 Security.php:74-81) registers on wp_insert_post_data
|
||||
* Security::initialize() (Divi's Security.php) registers on wp_insert_post_data
|
||||
* AttributeSecurity (priority 5, always), HtmlSecurity (priority 6, by capability) and
|
||||
* DynamicContentFixes (priority 10: strips enable_html for users without unfiltered_html). The first
|
||||
* two re-serialize the whole page when it holds custom attributes or htmlBefore/htmlAfter/elementType, so on such
|
||||
@@ -98,7 +98,7 @@ class DiviSaver
|
||||
$warnings = [];
|
||||
if ($scope->setsFlags()) {
|
||||
FollowUp::run(
|
||||
static fn () => DiviFlags::set($postId),
|
||||
static fn () => DiviPages::setFlags($postId),
|
||||
'divi builder flags',
|
||||
'Die Divi-Kennzeichen der Seite konnten nicht gesetzt werden; der Inhalt ist gespeichert – die Seite '
|
||||
. 'einmal im Divi-Builder öffnen und speichern.',
|
||||
@@ -107,9 +107,7 @@ class DiviSaver
|
||||
}
|
||||
FollowUp::run(
|
||||
static function () use ($postId, $scope): void {
|
||||
if (class_exists('ET_Core_PageResource')) {
|
||||
\ET_Core_PageResource::remove_static_resources($postId, 'all', true);
|
||||
}
|
||||
DiviPages::clearPageCss($postId);
|
||||
// A global library entry is part of every page that shows it (spec §5.6 step 5).
|
||||
if ($scope->clearsSiteCss()) {
|
||||
DiviThemeBuilder::clearSiteCaches();
|
||||
@@ -149,7 +147,7 @@ class DiviSaver
|
||||
}
|
||||
|
||||
if ($scope->setsFlags()) {
|
||||
DiviFlags::set($postId);
|
||||
DiviPages::setFlags($postId);
|
||||
}
|
||||
|
||||
$stored = get_post($postId);
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace LIT\MCP\Integrations\Divi\Pages;
|
||||
|
||||
use Closure;
|
||||
use LIT\MCP\Integrations\Divi\Compose\LinkTargets;
|
||||
use LIT\MCP\Integrations\Divi\Library\DiviLibraryStore;
|
||||
use WP_Post;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
@@ -22,18 +23,19 @@ final class WpLinkTargets implements LinkTargets
|
||||
private const DEAD = ['trash', 'auto-draft', 'inherit'];
|
||||
|
||||
/** Never link targets, whatever Divi lists: attachments and the Divi Library (ruling Q14). */
|
||||
private const NEVER = ['attachment', 'et_pb_layout'];
|
||||
private const NEVER = ['attachment', DiviLibraryStore::POST_TYPE];
|
||||
|
||||
/** @var Closure(string): bool */
|
||||
private Closure $linkable;
|
||||
|
||||
/**
|
||||
* @param (Closure(string): bool)|null $linkable Whether Divi offers post_link_url_<type> (tests);
|
||||
* null = Divi's et_builder_get_public_post_types(), the list its link option uses.
|
||||
* null = DiviPages::isLinkable() (Divi's et_builder_get_public_post_types(), the list its
|
||||
* link option uses).
|
||||
*/
|
||||
public function __construct(?Closure $linkable = null)
|
||||
{
|
||||
$this->linkable = $linkable ?? self::diviLinkable(...);
|
||||
$this->linkable = $linkable ?? DiviPages::isLinkable(...);
|
||||
}
|
||||
|
||||
public function postTypeOf(int $id): ?string
|
||||
@@ -50,16 +52,4 @@ final class WpLinkTargets implements LinkTargets
|
||||
|
||||
return current_user_can('read_post', $id) ? $type : null;
|
||||
}
|
||||
|
||||
/** Fail closed: without Divi's list no type has a link option. */
|
||||
private static function diviLinkable(string $type): 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($type, $types);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\Divi\Release;
|
||||
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviPages;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DynamicContentMap;
|
||||
use LIT\MCP\Integrations\Divi\Schema\DiviModules;
|
||||
|
||||
@@ -14,6 +15,7 @@ final class DiviAdapters
|
||||
{
|
||||
/** @var list<class-string<DiviAdapter>> */
|
||||
public const CLASSES = [
|
||||
DiviPages::class,
|
||||
DiviModules::class,
|
||||
DynamicContentMap::class,
|
||||
];
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace LIT\MCP\Integrations\WordPress\Content;
|
||||
|
||||
use LIT\MCP\Abilities\JsonMap;
|
||||
use LIT\MCP\Abilities\Rev;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviPages;
|
||||
use LIT\MCP\Integrations\Divi\Schema\DiviModules;
|
||||
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use LIT\MCP\Integrations\WordPress\Schema\FieldDefinition;
|
||||
@@ -95,7 +96,7 @@ class PostPresenter
|
||||
|
||||
public static function usesDivi(WP_Post $post): bool
|
||||
{
|
||||
return get_post_meta((int) $post->ID, '_et_pb_use_builder', true) === 'on'
|
||||
return DiviPages::usesBuilder((int) $post->ID)
|
||||
|| str_contains((string) $post->post_content, '<!-- wp:divi/');
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ final class GlobalEditsTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testPlainLibraryItemIsSavedWithoutConfirmAndWithoutDiviFlags(): void
|
||||
public function testPlainLibraryItemIsSavedWithoutConfirmAndWithoutPageFlags(): void
|
||||
{
|
||||
LibraryFixtures::given([LibraryFixtures::item(1057)]);
|
||||
|
||||
@@ -563,7 +563,7 @@ final class GlobalEditsTest extends TestCase
|
||||
}
|
||||
|
||||
/** Ruling P1: lit-divi-replace-text saves library entries through DiviWriter::commit(). */
|
||||
public function testReplaceTextSavesAPlainLibraryItemWithoutDiviFlags(): void
|
||||
public function testReplaceTextSavesAPlainLibraryItemWithoutPageFlags(): void
|
||||
{
|
||||
LibraryFixtures::given([LibraryFixtures::item(1057)]);
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Pages;
|
||||
|
||||
use Brain\Monkey\Functions;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviFlags;
|
||||
use LIT\MCP\Tests\Unit\TestCase;
|
||||
use RuntimeException;
|
||||
|
||||
final class DiviFlagsTest extends TestCase
|
||||
{
|
||||
public function testSetsBothFlagsAndAcceptsAnUnchangedValue(): void
|
||||
{
|
||||
$written = [];
|
||||
// update_post_meta() is false when the value is already "on" – no failure (ruling S11).
|
||||
Functions\when('update_post_meta')->alias(static function (int $id, string $key, string $value) use (&$written): bool {
|
||||
$written[] = "$id:$key=$value";
|
||||
|
||||
return false;
|
||||
});
|
||||
Functions\when('get_post_meta')->alias(
|
||||
static fn (int $id, string $key): string => $key === '_et_pb_show_page_creation' ? 'off' : 'on'
|
||||
);
|
||||
|
||||
DiviFlags::set(7);
|
||||
|
||||
// Like Divi's own save (SyncToServerController.php:382-387), incl. the page creation flow flag.
|
||||
self::assertSame(
|
||||
['7:_et_pb_use_divi_5=on', '7:_et_pb_use_builder=on', '7:_et_pb_show_page_creation=off'],
|
||||
$written
|
||||
);
|
||||
}
|
||||
|
||||
public function testThrowsWhenAFlagDoesNotReadBack(): void
|
||||
{
|
||||
Functions\when('update_post_meta')->justReturn(true);
|
||||
Functions\when('get_post_meta')->alias(
|
||||
static fn (int $id, string $key): string => $key === '_et_pb_use_builder' ? 'off' : 'on'
|
||||
);
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage('_et_pb_use_builder');
|
||||
DiviFlags::set(7);
|
||||
}
|
||||
|
||||
public function testThrowsWhenThePageCreationFlagDoesNotReadBack(): void
|
||||
{
|
||||
Functions\when('update_post_meta')->justReturn(true);
|
||||
Functions\when('get_post_meta')->justReturn('on');
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage('_et_pb_show_page_creation');
|
||||
DiviFlags::set(7);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Pages;
|
||||
|
||||
use Brain\Monkey\Functions;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviPages;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviAdapters;
|
||||
use LIT\MCP\Integrations\Divi\Release\Manifest;
|
||||
use LIT\MCP\Tests\Unit\TestCase;
|
||||
use RuntimeException;
|
||||
use WP_Post;
|
||||
|
||||
final class DiviPagesTest extends TestCase
|
||||
{
|
||||
public function testSetsBothFlagsAndAcceptsAnUnchangedValue(): void
|
||||
{
|
||||
$written = [];
|
||||
// update_post_meta() is false when the value is already "on" – no failure (ruling S11).
|
||||
Functions\when('update_post_meta')->alias(static function (int $id, string $key, string $value) use (&$written): bool {
|
||||
$written[] = "$id:$key=$value";
|
||||
|
||||
return false;
|
||||
});
|
||||
Functions\when('get_post_meta')->alias(
|
||||
static fn (int $id, string $key): string => $key === '_et_pb_show_page_creation' ? 'off' : 'on'
|
||||
);
|
||||
|
||||
DiviPages::setFlags(7);
|
||||
|
||||
// Like Divi's own save (SyncToServerController::update, Mirror vb-sync-flags), incl. the page creation flag.
|
||||
self::assertSame(
|
||||
['7:_et_pb_use_divi_5=on', '7:_et_pb_use_builder=on', '7:_et_pb_show_page_creation=off'],
|
||||
$written
|
||||
);
|
||||
}
|
||||
|
||||
public function testThrowsWhenAFlagDoesNotReadBack(): void
|
||||
{
|
||||
Functions\when('update_post_meta')->justReturn(true);
|
||||
Functions\when('get_post_meta')->alias(
|
||||
static fn (int $id, string $key): string => $key === '_et_pb_use_builder' ? 'off' : 'on'
|
||||
);
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage('_et_pb_use_builder');
|
||||
DiviPages::setFlags(7);
|
||||
}
|
||||
|
||||
public function testThrowsWhenThePageCreationFlagDoesNotReadBack(): void
|
||||
{
|
||||
Functions\when('update_post_meta')->justReturn(true);
|
||||
Functions\when('get_post_meta')->justReturn('on');
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage('_et_pb_show_page_creation');
|
||||
DiviPages::setFlags(7);
|
||||
}
|
||||
|
||||
public function testIsTheRegisteredPagesAdapterWithTheFlagMirror(): void
|
||||
{
|
||||
$manifest = DiviPages::manifest();
|
||||
|
||||
self::assertContains(DiviPages::class, DiviAdapters::CLASSES);
|
||||
self::assertSame(Manifest::PAGES, $manifest->area);
|
||||
self::assertSame(['vb-sync-flags'], array_map(static fn ($mirror): string => $mirror->id, $manifest->mirrors));
|
||||
self::assertSame('SyncToServerController::update()', $manifest->mirrors[0]->label());
|
||||
}
|
||||
|
||||
public function testUsesBuilderReadsDivisFlag(): void
|
||||
{
|
||||
Functions\when('get_post_meta')->alias(
|
||||
static fn (int $id, string $key): string => $id === 7 && $key === '_et_pb_use_builder' ? 'on' : ''
|
||||
);
|
||||
|
||||
self::assertTrue(DiviPages::usesBuilder(7));
|
||||
self::assertFalse(DiviPages::usesBuilder(8));
|
||||
}
|
||||
|
||||
public function testBuilderUrlOpensTheVisualBuilder(): void
|
||||
{
|
||||
Functions\when('get_permalink')->justReturn('https://k.de/start/');
|
||||
Functions\when('add_query_arg')->alias(
|
||||
static fn (string $key, string $value, string $url): string => $url . '?' . $key . '=' . $value
|
||||
);
|
||||
|
||||
self::assertSame('https://k.de/start/?et_fb=1', DiviPages::builderUrl(new WP_Post(['ID' => 7])));
|
||||
}
|
||||
|
||||
public function testClearPageCssRemovesThePagesStaticFiles(): void
|
||||
{
|
||||
\ET_Core_PageResource::$removed = [];
|
||||
|
||||
DiviPages::clearPageCss(7);
|
||||
|
||||
self::assertSame([[7, 'all', true]], \ET_Core_PageResource::$removed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Own process (Brain Monkey's FunctionStub eval's a real global function the first time a name is
|
||||
* stubbed – function_exists() would report it as permanently defined for the rest of the run
|
||||
* otherwise, breaking WpLinkTargetsTest's "without Divi" case).
|
||||
*
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testIsLinkableFollowsDivisPublicPostTypes(): void
|
||||
{
|
||||
Functions\when('et_builder_get_public_post_types')->justReturn(['page' => 'Seiten', 'post' => 'Beiträge']);
|
||||
|
||||
self::assertTrue(DiviPages::isLinkable('page'));
|
||||
self::assertFalse(DiviPages::isLinkable('product'));
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ final class DiviSaverTest extends TestCase
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testSavesWithoutKsesForFilteredUsersAndSetsDiviFlags(): void
|
||||
public function testSavesWithoutKsesForFilteredUsersAndSetsThePageFlags(): void
|
||||
{
|
||||
Functions\when('current_user_can')->justReturn(false);
|
||||
Functions\when('has_filter')->justReturn(10);
|
||||
@@ -269,7 +269,7 @@ final class DiviSaverTest extends TestCase
|
||||
(new DiviSaver())->saveNew(42, 'NEU');
|
||||
}
|
||||
|
||||
public function testLibraryItemsGetNoDiviFlagsAndGlobalOnesClearEveryPage(): void
|
||||
public function testLibraryItemsGetNoPageFlagsAndGlobalOnesClearEveryPage(): void
|
||||
{
|
||||
\ET_Core_PageResource::$removed = [];
|
||||
Functions\when('current_user_can')->justReturn(true);
|
||||
|
||||
@@ -30,13 +30,8 @@ final class DiviBoundaryTest extends TestCase
|
||||
'Integrations/Divi/Library/DiviRoles.php',
|
||||
'Integrations/Divi/Library/LibraryItemSpec.php',
|
||||
'Integrations/Divi/Library/NewLibraryEntry.php',
|
||||
'Integrations/Divi/Pages/DiviFlags.php',
|
||||
'Integrations/Divi/Pages/DiviPage.php',
|
||||
'Integrations/Divi/Pages/DiviSaver.php',
|
||||
'Integrations/Divi/Pages/WpLinkTargets.php',
|
||||
'Integrations/Divi/ThemeBuilder/DiviThemeBuilder.php',
|
||||
'Integrations/Media/MediaUsageFinder.php',
|
||||
'Integrations/WordPress/Content/PostPresenter.php',
|
||||
];
|
||||
|
||||
public function testOnlyAdaptersTouchDivi(): void
|
||||
|
||||
Reference in New Issue
Block a user