refactor(form-field): extract legacy conditional_logic shape normaliser

Three byte-identical copies of `normaliseLegacyGroupShape` lived in
FormFieldService, StoreFormFieldRequest, and UpdateFormFieldRequest.
WS-5d (form_fields.options) would have been the fourth copy. Hoist
the helper to a single public static on FormFieldConditionalLogicService
and have all three call sites delegate.

Implementation:

  - `FormFieldConditionalLogicService::normaliseLegacyShape(array)` —
    pure recursive passthrough. Translates the ARCH §8 JSON group shape
    (`{"all": [...]}` / `{"any": [...]}`) into the service's internal
    `{"operator", "children"}` form. Does NOT validate; malformed shapes
    return as-is and surface downstream as
    `InvalidConditionalLogicSpecException` from `assertSpecsValid`.
  - Group operator catalogue sourced from
    `FormFieldConditionalLogicGroupOperator::values()` instead of an
    `['all', 'any']` literal — single source of truth for future
    operator additions.
  - All three call sites switched to the static method. The two
    FormRequests reach it via the existing `use` import; FormFieldService
    sits in the same namespace.

Behaviour preserved exactly:

  - Existing FormFieldApiTest (cyclic logic rejection),
    FormFieldStrictConditionalLogicRequestTest (strict-validator
    rejection paths), and FormFieldConditionalLogicServiceTest
    (service-level paths) all green without modification.

New unit tests pin the passthrough contract (8 tests):

  - Valid ALL / ANY translations
  - Recursive nested-group translation (depth 2)
  - Internal shape unchanged
  - Condition leaf passthrough
  - Unknown group key (`xor`) returned unchanged for downstream
    `assertSpecsValid` to reject
  - Empty array unchanged
  - Non-array children stripped silently

Tests: 1150 → 1158 green (3110 → 3124 assertions).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-25 00:57:06 +02:00
parent 64f5855fdb
commit 2656818c35
6 changed files with 205 additions and 115 deletions

View File

@@ -367,44 +367,7 @@ final class FormFieldService
$rootGroup = $raw;
}
return [$this->normaliseLegacyGroupShape($rootGroup), true];
}
/**
* @param array<string, mixed> $node
* @return array<string, mixed>
*/
private function normaliseLegacyGroupShape(array $node): array
{
if (isset($node['field_slug'])) {
return $node;
}
if (isset($node['operator'], $node['children']) && is_array($node['children'])) {
$children = [];
foreach ($node['children'] as $child) {
if (is_array($child)) {
$children[] = $this->normaliseLegacyGroupShape($child);
}
}
return ['operator' => $node['operator'], 'children' => $children];
}
foreach (['all', 'any'] as $candidate) {
if (isset($node[$candidate]) && is_array($node[$candidate])) {
$children = [];
foreach ($node[$candidate] as $child) {
if (is_array($child)) {
$children[] = $this->normaliseLegacyGroupShape($child);
}
}
return ['operator' => $candidate, 'children' => $children];
}
}
return $node;
return [FormFieldConditionalLogicService::normaliseLegacyShape($rootGroup), true];
}
/**