feat: Fähigkeiten theme-option-read/-write und font-upload; ThemeOptionsAdapter und FontCatalog (Manifest, Nachbau customizer-typography, Signatur-Referenzen) und DesignRights::themeOptions()/fonts()
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
8379c55c89
commit
a90cd7f5bd
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\Divi\Design;
|
||||
|
||||
use LIT\MCP\Integrations\Divi\Release\Call;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviAdapter;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||||
use LIT\MCP\Integrations\Divi\Release\Manifest;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Adapter "Designsystem" (spec §3) for Divi's font lists (plan 4d W5, W9): the families Divi's customizer sanitizer
|
||||
* accepts (uploaded fonts + et_builder_get_fonts(), exact names), the uploaded ones, and every reserved name for an
|
||||
* upload, plus Divi's role right "Eigene Schriften verwalten". et_builder_get_google_fonts() parses about 1.3 MB and
|
||||
* may fetch from Google once a day, so names() is loaded once per instance – DiviIntegration builds one per request;
|
||||
* uploaded() and reserved() are read fresh (an upload changes them). Not final so the tools can be tested with a mock.
|
||||
*/
|
||||
class FontCatalog implements DiviAdapter
|
||||
{
|
||||
/** @var list<string>|null */
|
||||
private ?array $names = null;
|
||||
|
||||
public static function manifest(): Manifest
|
||||
{
|
||||
return new Manifest(
|
||||
Manifest::DESIGN,
|
||||
calls: [
|
||||
new Call('et_builder_get_fonts', 0),
|
||||
new Call('et_builder_get_custom_fonts', 0),
|
||||
new Call('et_builder_get_google_fonts', 0),
|
||||
new Call('et_builder_get_websafe_fonts', 0),
|
||||
new Call('et_pb_is_allowed', 1, [DiviFeature::FontUpload]),
|
||||
],
|
||||
// The options behind Divi's lists; read only through the functions above.
|
||||
keys: ['et_uploaded_fonts', 'et_google_fonts_cache', 'et_google_api_settings'],
|
||||
// Plan 4d W1: font variables are checked against the same list, so a break locks all three on purpose.
|
||||
features: [DiviFeature::ThemeOptionWrite, DiviFeature::FontUpload, DiviFeature::VariableWrite]
|
||||
);
|
||||
}
|
||||
|
||||
/** @return list<string> Exact family names Divi's sanitizer accepts: uploaded, then web-safe and Google. */
|
||||
public function names(): array
|
||||
{
|
||||
return $this->names ??= self::namesOf(et_builder_get_custom_fonts(), et_builder_get_fonts());
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
public function uploaded(): array
|
||||
{
|
||||
return self::namesOf(et_builder_get_custom_fonts());
|
||||
}
|
||||
|
||||
/** @return list<string> Google, web-safe and uploaded names – an upload must not reuse one (W9). */
|
||||
public function reserved(): array
|
||||
{
|
||||
return self::namesOf(
|
||||
et_builder_get_google_fonts(),
|
||||
et_builder_get_websafe_fonts(),
|
||||
et_builder_get_custom_fonts()
|
||||
);
|
||||
}
|
||||
|
||||
public function has(string $name): bool
|
||||
{
|
||||
return in_array($name, $this->names(), true);
|
||||
}
|
||||
|
||||
/** Divi's role right "Eigene Schriften verwalten" (custom_fonts_management); fail closed without Divi. */
|
||||
public function canManage(): bool
|
||||
{
|
||||
return function_exists('et_pb_is_allowed') && (bool) et_pb_is_allowed('custom_fonts_management');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed ...$lists Divi's lists (family => settings); anything else (a broken filter) is skipped.
|
||||
* @return list<string>
|
||||
*/
|
||||
private static function namesOf(mixed ...$lists): array
|
||||
{
|
||||
$names = [];
|
||||
foreach ($lists as $list) {
|
||||
if (! is_array($list)) {
|
||||
continue;
|
||||
}
|
||||
foreach (array_keys($list) as $name) {
|
||||
$names[] = (string) $name;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values(array_unique($names));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user