refactor: DesignRights::themeOptions() ohne ungenutzten DesignSystemWriter

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-19 18:27:52 +02:00
co-authored by Claude Sonnet 5.5
parent 0a24753b4d
commit bfe6623fe8
8 changed files with 13 additions and 27 deletions
@@ -79,10 +79,10 @@ final class DesignRights
} }
/** /**
* Theme options (writing and restoring): edit_theme_options and Divi's role right "Theme-Anpassung". $writer is * Theme options (writing and restoring): edit_theme_options and Divi's role right "Theme-Anpassung". Divi's
* not asked – Divi's customizer needs no Visual Builder; it keeps the signature of the other design rights. * customizer needs no Visual Builder, so no DesignSystemWriter is asked.
*/ */
public static function themeOptions(DesignSystemWriter $writer, ThemeOptionsAdapter $options): ?WP_Error public static function themeOptions(ThemeOptionsAdapter $options): ?WP_Error
{ {
$refusal = self::themeRight('Theme-Optionen ändern'); $refusal = self::themeRight('Theme-Optionen ändern');
if ($refusal !== null || $options->canCustomize()) { if ($refusal !== null || $options->canCustomize()) {
@@ -29,7 +29,6 @@ final class DiviThemeOptionsUpdateAbility implements Ability, RequiresDiviFeatur
private const BUILDER = 'Geänderte Schriften wirken auch im Divi-Builder (Standardschrift der Module).'; private const BUILDER = 'Geänderte Schriften wirken auch im Divi-Builder (Standardschrift der Module).';
public function __construct( public function __construct(
private DesignSystemWriter $writer,
private ThemeOptionsAdapter $options, private ThemeOptionsAdapter $options,
private FontCatalog $fonts, private FontCatalog $fonts,
private DesignChange $change private DesignChange $change
@@ -102,12 +101,12 @@ final class DiviThemeOptionsUpdateAbility implements Ability, RequiresDiviFeatur
public function permission(array $input): bool|WP_Error public function permission(array $input): bool|WP_Error
{ {
return DesignRights::themeOptions($this->writer, $this->options) ?? true; return DesignRights::themeOptions($this->options) ?? true;
} }
public function execute(array $input): mixed public function execute(array $input): mixed
{ {
$refusal = DesignRights::themeOptions($this->writer, $this->options); $refusal = DesignRights::themeOptions($this->options);
if ($refusal !== null) { if ($refusal !== null) {
return $refusal; return $refusal;
} }
@@ -18,7 +18,7 @@ final class ThemeOptionsRestorePlanner implements RestorePlanner
{ {
private const RESET = 'Theme-Optionen, die im Snapshot nicht gesetzt sind, kehren zum Divi-Standard zurück (%s).'; private const RESET = 'Theme-Optionen, die im Snapshot nicht gesetzt sind, kehren zum Divi-Standard zurück (%s).';
public function __construct(private DesignSystemWriter $writer, private ThemeOptionsAdapter $options) public function __construct(private ThemeOptionsAdapter $options)
{ {
} }
@@ -34,7 +34,7 @@ final class ThemeOptionsRestorePlanner implements RestorePlanner
public function rights(): ?WP_Error public function rights(): ?WP_Error
{ {
return DesignRights::themeOptions($this->writer, $this->options); return DesignRights::themeOptions($this->options);
} }
/** Like lit/divi-theme-options-update: reads et_divi (ThemeOptionRead), writes it (ThemeOptionWrite). */ /** Like lit/divi-theme-options-update: reads et_divi (ThemeOptionRead), writes it (ThemeOptionWrite). */
+1 -2
View File
@@ -299,7 +299,7 @@ final class DiviIntegration implements Integration, Bootable
new PresetRestorePlanner($this->designWriter, DesignRights::unfilteredHtml()), new PresetRestorePlanner($this->designWriter, DesignRights::unfilteredHtml()),
new ColorRestorePlanner($this->designWriter, $this->colorsAdapter), new ColorRestorePlanner($this->designWriter, $this->colorsAdapter),
new VariableRestorePlanner($this->designWriter, $this->variablesAdapter), new VariableRestorePlanner($this->designWriter, $this->variablesAdapter),
new ThemeOptionsRestorePlanner($this->designWriter, $this->themeOptionsAdapter) new ThemeOptionsRestorePlanner($this->themeOptionsAdapter)
), ),
new DiviPresetsAssignAbility( new DiviPresetsAssignAbility(
$this->designWriter, $this->designWriter,
@@ -329,7 +329,6 @@ final class DiviIntegration implements Integration, Bootable
), ),
new DiviThemeOptionsGetAbility($this->themeOptionsAdapter), new DiviThemeOptionsGetAbility($this->themeOptionsAdapter),
new DiviThemeOptionsUpdateAbility( new DiviThemeOptionsUpdateAbility(
$this->designWriter,
$this->themeOptionsAdapter, $this->themeOptionsAdapter,
$this->fontCatalog, $this->fontCatalog,
$this->designChange() $this->designChange()
@@ -78,21 +78,18 @@ final class DesignRightsTest extends TestCase
public function testThemeOptionsNeedEditThemeOptionsAndTheThemeCustomizerRight(): void public function testThemeOptionsNeedEditThemeOptionsAndTheThemeCustomizerRight(): void
{ {
$writer = Mockery::mock(DesignSystemWriter::class);
// Divi's customizer does not need the Visual Builder (plan 4d, rights).
$writer->expects('canUseVisualBuilder')->never();
$options = Mockery::mock(ThemeOptionsAdapter::class); $options = Mockery::mock(ThemeOptionsAdapter::class);
$options->allows('canCustomize')->andReturn(true, false); $options->allows('canCustomize')->andReturn(true, false);
Functions\when('current_user_can')->alias(static fn (string $cap): bool => $cap === 'edit_theme_options'); Functions\when('current_user_can')->alias(static fn (string $cap): bool => $cap === 'edit_theme_options');
self::assertNull(DesignRights::themeOptions($writer, $options)); self::assertNull(DesignRights::themeOptions($options));
$refusal = self::assertToolError(DesignRights::themeOptions($writer, $options), 'forbidden'); $refusal = self::assertToolError(DesignRights::themeOptions($options), 'forbidden');
self::assertStringContainsString('Theme-Anpassung', $refusal['message']); self::assertStringContainsString('Theme-Anpassung', $refusal['message']);
self::assertStringContainsString('keine Theme-Optionen', $refusal['message']); self::assertStringContainsString('keine Theme-Optionen', $refusal['message']);
self::assertStringContainsString('Rollen-Editor', $refusal['hint']); self::assertStringContainsString('Rollen-Editor', $refusal['hint']);
Functions\when('current_user_can')->justReturn(false); Functions\when('current_user_can')->justReturn(false);
$refusal = self::assertToolError(DesignRights::themeOptions($writer, $options), 'forbidden'); $refusal = self::assertToolError(DesignRights::themeOptions($options), 'forbidden');
self::assertStringContainsString('Theme-Optionen ändern erfordert', $refusal['message']); self::assertStringContainsString('Theme-Optionen ändern erfordert', $refusal['message']);
self::assertStringContainsString('edit_theme_options', $refusal['message']); self::assertStringContainsString('edit_theme_options', $refusal['message']);
} }
@@ -179,7 +179,7 @@ final class DiviDesignRestoreAbilityTest extends TestCase
new PresetRestorePlanner($writer), new PresetRestorePlanner($writer),
new ColorRestorePlanner($writer, $colors), new ColorRestorePlanner($writer, $colors),
new VariableRestorePlanner($writer, $variables), new VariableRestorePlanner($writer, $variables),
new ThemeOptionsRestorePlanner($writer, $options ?? self::optionStore($noOptions)) new ThemeOptionsRestorePlanner($options ?? self::optionStore($noOptions))
); );
} }
@@ -49,11 +49,7 @@ final class DiviThemeOptionsUpdateAbilityTest extends TestCase
bool $customize = true, bool $customize = true,
?ThemeOptionsAdapter $options = null ?ThemeOptionsAdapter $options = null
): DiviThemeOptionsUpdateAbility { ): DiviThemeOptionsUpdateAbility {
$writer = Mockery::mock(DesignSystemWriter::class);
$writer->allows('canUseVisualBuilder')->andReturn(true);
return new DiviThemeOptionsUpdateAbility( return new DiviThemeOptionsUpdateAbility(
$writer,
$options ?? ThemeOptionsAreaTest::adapter($this->stored, $this->writes, $sanitize, $customize), $options ?? ThemeOptionsAreaTest::adapter($this->stored, $this->writes, $sanitize, $customize),
FontCheckTest::catalog(), FontCheckTest::catalog(),
new DesignChange($snapshots ?? Mockery::mock(SnapshotStore::class), new FakeChangeLog(3)) new DesignChange($snapshots ?? Mockery::mock(SnapshotStore::class), new FakeChangeLog(3))
@@ -36,13 +36,8 @@ final class ThemeOptionsRestorePlannerTest extends TestCase
{ {
$stored = []; $stored = [];
$writes = []; $writes = [];
$writer = Mockery::mock(DesignSystemWriter::class);
$writer->allows('canUseVisualBuilder')->andReturn(true);
return new ThemeOptionsRestorePlanner( return new ThemeOptionsRestorePlanner(ThemeOptionsAreaTest::adapter($stored, $writes, null, $customize));
$writer,
ThemeOptionsAreaTest::adapter($stored, $writes, null, $customize)
);
} }
public function testAreaFeaturesAndDesignArea(): void public function testAreaFeaturesAndDesignArea(): void