feat: explain the type collision on contact fields (trial)

A contact-field item whose type is no allowed child now gets a hint that
type is the node type, with the attrs path (fieldItem.advanced.type) and
the lit-divi-update set alternative, instead of "unbekanntes Modul
divi/email". The metadata fixture gains contact-form/contact-field
(regenerated from Divi 5.2.1, additions only).

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:
2026-09-26 19:22:13 +02:00
co-authored by Claude Opus 5.5
parent 26108bc9a9
commit cda8b025cc
4 changed files with 975 additions and 2 deletions
+37 -1
View File
@@ -256,7 +256,7 @@ final class Composer
$violation = $this->rules->violation($parent, $type);
if ($violation !== null) {
$this->errors[$path . '.type'] = $violation;
$this->errors[$path . '.type'] = $this->typeFieldCollision($spec, $parent) ?? $violation;
return null;
}
@@ -268,6 +268,42 @@ final class Composer
};
}
/**
* Trial feedback: an item whose only possible type has a short-form field named "type" (the
* contact field's field type) – a `type` that is no allowed child was almost certainly meant as
* that field. Explains the collision instead of "unbekanntes Modul divi/<value>".
*
* @param array<array-key, mixed> $spec
*/
private function typeFieldCollision(array $spec, ?Block $parent): ?string
{
$children = $parent === null ? [] : $this->catalog->childrenOf($parent->name());
if (count($children) !== 1 || ! is_string($spec['type'] ?? null)) {
return null;
}
$child = ModuleCatalog::shortName($children[0]);
$field = ShortformMap::fields($child)['type'] ?? null;
if ($field === null) {
return null;
}
// phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode -- pure PHP (spec §4.4).
$value = json_encode(
$spec['type'],
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE
);
return sprintf(
'`type` ist hier der Knotentyp (%1$s, darf fehlen); das Feldtyp-Feld über attrs setzen: '
. '{"attrs": {"%2$s": {"desktop": %3$s}}} – oder type weglassen und danach mit lit-divi-update '
. '{"set": {"type": %3$s}} setzen.',
$child,
(string) $field['path'],
(string) $value
);
}
/** @param array<array-key, mixed> $spec */
private function typeOf(array $spec, ?Block $parent): ?string
{