refactor(form-builder): pre-publish check reads form_field_bindings; drop binding JSON columns
This commit is contained in:
@@ -36,11 +36,17 @@ final class FormFieldService
|
||||
$data['form_schema_id'] = $schema->id;
|
||||
$data['sort_order'] ??= $this->nextSortOrder($schema);
|
||||
|
||||
$bindingSpec = $this->extractBindingSpec($data);
|
||||
|
||||
$this->assertNoConditionalCycle($schema, null, $data['conditional_logic'] ?? null, $data['slug'] ?? null);
|
||||
|
||||
/** @var FormField $field */
|
||||
$field = FormField::create($data);
|
||||
|
||||
if ($bindingSpec !== null) {
|
||||
$this->bindingService->replaceBindings($field, [$bindingSpec]);
|
||||
}
|
||||
|
||||
$this->schemaService->bumpVersion($schema);
|
||||
$field->logFieldChange('field.created');
|
||||
|
||||
@@ -56,7 +62,13 @@ final class FormFieldService
|
||||
$schema = $field->schema;
|
||||
$this->assertNotFrozenForStructural($schema, $data);
|
||||
|
||||
if (array_key_exists('binding', $data) && $data['binding'] !== $field->binding) {
|
||||
$bindingProvided = array_key_exists('binding', $data);
|
||||
$rawBinding = $bindingProvided ? $data['binding'] : null;
|
||||
$bindingSpec = $bindingProvided ? $this->extractBindingSpec($data) : null;
|
||||
|
||||
$currentBindingShape = $this->bindingService->toJsonShape($field->bindings()->first());
|
||||
|
||||
if ($bindingProvided && $this->bindingChanged($currentBindingShape, $rawBinding)) {
|
||||
$this->assertBindingChangeAllowed($field, $forceBindingChange);
|
||||
}
|
||||
|
||||
@@ -65,7 +77,7 @@ final class FormFieldService
|
||||
}
|
||||
|
||||
$before = [
|
||||
'binding' => $field->binding,
|
||||
'binding' => $currentBindingShape,
|
||||
'is_filterable' => $field->is_filterable,
|
||||
'is_pii' => $field->is_pii,
|
||||
'field_type' => $field->field_type,
|
||||
@@ -74,12 +86,16 @@ final class FormFieldService
|
||||
$field->fill($data);
|
||||
$field->save();
|
||||
|
||||
if ($bindingProvided) {
|
||||
$this->bindingService->replaceBindings($field, $bindingSpec === null ? [] : [$bindingSpec]);
|
||||
}
|
||||
|
||||
$this->schemaService->bumpVersion($schema);
|
||||
|
||||
$field->logFieldChange('field.updated', [
|
||||
'old' => $before,
|
||||
'new' => [
|
||||
'binding' => $field->binding,
|
||||
'binding' => $this->bindingService->toJsonShape($field->bindings()->first()),
|
||||
'is_filterable' => $field->is_filterable,
|
||||
'is_pii' => $field->is_pii,
|
||||
'field_type' => $field->field_type,
|
||||
@@ -93,6 +109,51 @@ final class FormFieldService
|
||||
return $field->refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
* @return array{target_entity:string,target_attribute:string,mode:string,sync_direction?:?string}|null
|
||||
*/
|
||||
private function extractBindingSpec(array &$data): ?array
|
||||
{
|
||||
if (! array_key_exists('binding', $data)) {
|
||||
return null;
|
||||
}
|
||||
$raw = $data['binding'];
|
||||
unset($data['binding']);
|
||||
if (! is_array($raw) || $raw === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'target_entity' => (string) ($raw['entity'] ?? ''),
|
||||
'target_attribute' => (string) ($raw['column'] ?? ''),
|
||||
'mode' => (string) ($raw['mode'] ?? ''),
|
||||
'sync_direction' => isset($raw['sync_direction']) ? (string) $raw['sync_direction'] : null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed>|null $current Pre-WS-5a ARCH §6.3 shape
|
||||
* @param array<string, mixed>|null $next
|
||||
*/
|
||||
private function bindingChanged(?array $current, ?array $next): bool
|
||||
{
|
||||
$normalise = static function (?array $value): array {
|
||||
if ($value === null || $value === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'mode' => (string) ($value['mode'] ?? ''),
|
||||
'entity' => (string) ($value['entity'] ?? ''),
|
||||
'column' => (string) ($value['column'] ?? ''),
|
||||
'sync_direction' => (string) ($value['sync_direction'] ?? ''),
|
||||
];
|
||||
};
|
||||
|
||||
return $normalise($current) !== $normalise($next);
|
||||
}
|
||||
|
||||
public function delete(FormField $field, ?string $confirmedName = null): void
|
||||
{
|
||||
$schema = $field->schema;
|
||||
|
||||
Reference in New Issue
Block a user