refactor: one VariableRef per composition, design lookups in DesignSystem (H3)
- DiviComposition::references() builds the one VariableRef with the entry's
live map (S22/S31) and passes it to AttrWriter; Placeholders only needs the
design system now, Placeholders::references() is gone (no reach-through).
- DesignSystem::colorIdFor()/variableFor() replace the dead colorId()/variable()
and carry Placeholders' lookup incl. the S13a ambiguity check (byLabel moved,
messages unchanged); isColorVariable() decides color vs content for {{var:}}.
- DesignSystem::colorReferenceIds() (VariableRef color names) and
contentVariableIds() (DynamicContentRules design names) replace the two
inline computations; same lists, same order.
Tests: fixtures/tests get the VariableRef from ComposeFixture::references() or
build it with the map; DesignSystemTest uses the new lookups (+2 tests).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -12,7 +12,8 @@ use LIT\MCP\Integrations\Divi\Design\DesignSystem;
|
||||
* {{color:primary|<Name>|gcid-…}}, {{var:<Name>|gvid-…}}, {{font:heading|body}},
|
||||
* {{post:title|…}}, {{field:<meta_key>}}. A placeholder must be the whole value (D9); unknown
|
||||
* names fail with the list of existing ones, labels two entries share fail with their IDs
|
||||
* (ruling S13a). The result is still checked by VariableRef wherever it is written. Pure PHP.
|
||||
* (ruling S13a, DesignSystem::colorIdFor/variableFor). The result is still checked by VariableRef
|
||||
* wherever it is written. Pure PHP.
|
||||
*/
|
||||
final class Placeholders
|
||||
{
|
||||
@@ -36,21 +37,8 @@ final class Placeholders
|
||||
|
||||
private const PATTERN = '/^\{\{\s*(color|var|font|post|field)\s*:\s*([^{}]+?)\s*\}\}$/';
|
||||
|
||||
private VariableRef $references;
|
||||
|
||||
/**
|
||||
* @param array<string, array<string, string>>|null $dynamicContent Divi's dynamic content
|
||||
* options for VariableRef (ruling S22); null = DynamicContentRules::DEFAULT_DYNAMIC_CONTENT.
|
||||
*/
|
||||
public function __construct(private DesignSystem $design, ?array $dynamicContent = null)
|
||||
public function __construct(private DesignSystem $design)
|
||||
{
|
||||
$this->references = new VariableRef($design, $dynamicContent);
|
||||
}
|
||||
|
||||
/** The strict checker of $variable(…)$ values against this design system (ruling S1). */
|
||||
public function references(): VariableRef
|
||||
{
|
||||
return $this->references;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,18 +90,11 @@ final class Placeholders
|
||||
|
||||
private function color(string $name): string
|
||||
{
|
||||
$colors = $this->design->colors();
|
||||
$ids = array_column($colors, 'id');
|
||||
$alias = DesignSystem::COLOR_ALIASES[mb_strtolower($name)] ?? null;
|
||||
$id = match (true) {
|
||||
in_array($name, $ids, true) => $name,
|
||||
$alias !== null && in_array($alias, $ids, true) => $alias,
|
||||
default => self::byLabel($colors, $name, 'globale Farbe'),
|
||||
};
|
||||
|
||||
$id = $this->design->colorIdFor($name);
|
||||
if ($id === null) {
|
||||
$colors = $this->design->colors();
|
||||
$known = array_merge(
|
||||
array_keys(array_intersect(DesignSystem::COLOR_ALIASES, $ids)),
|
||||
array_keys(array_intersect(DesignSystem::COLOR_ALIASES, array_column($colors, 'id'))),
|
||||
array_column($colors, 'label')
|
||||
);
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
@@ -128,12 +109,9 @@ final class Placeholders
|
||||
|
||||
private function variable(string $name): string
|
||||
{
|
||||
$variables = $this->design->variables();
|
||||
$id = in_array($name, array_column($variables, 'id'), true)
|
||||
? $name
|
||||
: self::byLabel($variables, $name, 'globale Variable');
|
||||
$id = $this->design->variableFor($name);
|
||||
if ($id === null) {
|
||||
$labels = array_column($variables, 'label');
|
||||
$labels = array_column($this->design->variables(), 'label');
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Unbekannte globale Variable "%s". Vorhanden: %s.',
|
||||
$name,
|
||||
@@ -141,42 +119,7 @@ final class Placeholders
|
||||
));
|
||||
}
|
||||
|
||||
$type = 'content';
|
||||
foreach ($variables as $variable) {
|
||||
if ($variable['id'] === $id && $variable['type'] === 'colors') {
|
||||
$type = 'color';
|
||||
}
|
||||
}
|
||||
|
||||
return VariableRef::serialize($type, $id, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* ID of the one entry labelled $name (case-insensitive); null when none is.
|
||||
*
|
||||
* @param list<array{id: string, label: string}> $entries
|
||||
* @throws InvalidArgumentException When several entries share the label (ruling S13a).
|
||||
*/
|
||||
private static function byLabel(array $entries, string $name, string $what): ?string
|
||||
{
|
||||
$key = mb_strtolower($name);
|
||||
$ids = [];
|
||||
foreach ($entries as $entry) {
|
||||
if (mb_strtolower($entry['label']) === $key) {
|
||||
$ids[] = $entry['id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($ids) > 1) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Name der %s "%s" ist mehrdeutig; bitte die ID angeben: %s.',
|
||||
$what,
|
||||
$name,
|
||||
implode(', ', $ids)
|
||||
));
|
||||
}
|
||||
|
||||
return $ids[0] ?? null;
|
||||
return VariableRef::serialize($this->design->isColorVariable($id) ? 'color' : 'content', $id, []);
|
||||
}
|
||||
|
||||
private function font(string $name): string
|
||||
|
||||
Reference in New Issue
Block a user