From 27c6ac8ada1fa3f4e3be27b8db7007ec0c9c748e Mon Sep 17 00:00:00 2001 From: Christian Bader Date: Thu, 21 Mar 2024 11:45:43 +0100 Subject: [PATCH] Added context to ChoiceOptionProvider for dynamic choices --- src/Form/Builder.php | 34 ++++++++++++++++-------------- src/Form/Type/AbstractChoices.php | 4 ++-- src/Form/Type/ChoicesInterface.php | 10 ++++++--- src/Service/FormService.php | 6 ++++-- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/Form/Builder.php b/src/Form/Builder.php index a9c478d..5edb05e 100644 --- a/src/Form/Builder.php +++ b/src/Form/Builder.php @@ -51,17 +51,17 @@ public function form(string $name, array $config): FormBuilderInterface * * @return array{string,array} */ - public function field(string $formName, array $definition, array $formConfig): array + public function field(string $formName, array $definition, ?array $options = []): array { - $options = $this->getOptions($formName, $definition, $formConfig); + $fieldOptions = $this->getOptions($formName, $definition, $options); - $constraints = $this->getConstraints($definition, $options); + $constraints = $this->getConstraints($definition, $fieldOptions); if (!empty($constraints)) { - $options['constraints'] = $constraints; + $fieldOptions['constraints'] = $constraints; } - return [$this->getType($definition['type']), $options]; + return [$this->getType($definition['type']), $fieldOptions]; } protected function getConstraintClass(string $name): string @@ -88,16 +88,17 @@ protected function getType(string $name): string * * @return array */ - protected function getOptions(string $formName, array $definition, array $formConfig): array + protected function getOptions(string $formName, array $definition, ?array $options = []): array { - $options = $definition['options']; + $fieldOptions = $definition['options']; + $formConfig = $options['config']; - if ($formConfig['translate']['field_labels'] && !empty($options['label'])) { - $options['label'] = $this->translator->trans($options['label']); + if ($formConfig['translate']['field_labels'] && !empty($fieldOptions['label'])) { + $fieldOptions['label'] = $this->translator->trans($fieldOptions['label']); } if (in_array($this->getType($definition['type']), [DateType::class, TimeType::class], true)) { - $options['widget'] ??= 'single_text'; + $fieldOptions['widget'] ??= 'single_text'; } if ($this->getType($definition['type']) === ChoiceType::class) { if ( @@ -111,7 +112,7 @@ protected function getOptions(string $formName, array $definition, array $formCo continue; } - $options[$key] = array_combine( + $fieldOptions[$key] = array_combine( array_map( fn (string $key): string => $this->translator->trans($key), array_keys($definition['options'][$key]) @@ -127,14 +128,15 @@ protected function getOptions(string $formName, array $definition, array $formCo $choices->setFieldConfig($formConfig); } - $options['choices'] = $choices->choices(); - $options['choice_value'] = fn ($a) => $a; - $options['choice_label'] = fn ($choice, $key, $value) => $choices->choiceLabel($choice, $key, $value); - $options['choice_attr'] = fn ($choice, $key, $value) => $choices->choiceAttribute($choice, $key, $value); + $context = $options['context'] ?? null; + $fieldOptions['choices'] = $choices->choices($context); + $fieldOptions['choice_value'] = fn ($a) => $a; + $fieldOptions['choice_label'] = fn ($choice, $key, $value) => $choices->choiceLabel($choice, $key, $value, $context); + $fieldOptions['choice_attr'] = fn ($choice, $key, $value) => $choices->choiceAttribute($choice, $key, $value, $context); } } - return $options; + return $fieldOptions; } /** diff --git a/src/Form/Type/AbstractChoices.php b/src/Form/Type/AbstractChoices.php index 4136649..a82728c 100644 --- a/src/Form/Type/AbstractChoices.php +++ b/src/Form/Type/AbstractChoices.php @@ -12,12 +12,12 @@ abstract class AbstractChoices implements ChoicesInterface, ConfigAwareInterface protected array $fieldConfig; protected string $formName; - public function choiceLabel(mixed $choice, mixed $key, mixed $value): ?string + public function choiceLabel(mixed $choice, mixed $key, mixed $value, mixed $context): ?string { return $key; } - public function choiceAttribute(mixed $choice, mixed $key, mixed $value): array + public function choiceAttribute(mixed $choice, mixed $key, mixed $value, mixed $context): array { return []; } diff --git a/src/Form/Type/ChoicesInterface.php b/src/Form/Type/ChoicesInterface.php index 619ec8b..a1549b0 100644 --- a/src/Form/Type/ChoicesInterface.php +++ b/src/Form/Type/ChoicesInterface.php @@ -7,25 +7,29 @@ interface ChoicesInterface { /** + * @param mixed $context + * * @return array */ - public function choices(): array; + public function choices(mixed $context): array; /** * @param mixed $choice * @param mixed $key * @param mixed $value + * @param mixed $context * * @return string|null */ - public function choiceLabel(mixed $choice, mixed $key, mixed $value): ?string; + public function choiceLabel(mixed $choice, mixed $key, mixed $value, mixed $context): ?string; /** * @param mixed $choice * @param mixed $key * @param mixed $value + * @param mixed $context * * @return array */ - public function choiceAttribute(mixed $choice, mixed $key, mixed $value): array; + public function choiceAttribute(mixed $choice, mixed $key, mixed $value, mixed $context): array; } diff --git a/src/Service/FormService.php b/src/Service/FormService.php index 125ceb9..86a6caa 100644 --- a/src/Service/FormService.php +++ b/src/Service/FormService.php @@ -58,13 +58,15 @@ public function __construct( $this->liform = $liform; } - public function build(string $name): FormBuilderInterface + public function build(string $name, mixed $context): FormBuilderInterface { $config = $this->getConfig($name); + $options['config'] = $config; + $options['context'] = $context; $form = $this->builder->form($name, $config); foreach ($config['fields'] as $fieldName => $definition) { - $form->add($fieldName, ...$this->builder->field($name, $definition, $config)); + $form->add($fieldName, ...$this->builder->field($name, $definition, $options)); } if ($form->getOption('csrf_protection') === true) {