-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix some issues in Choice field with PHP Enums #5620
Conversation
When you plan to merge it? |
Hi,
The error:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On 42 line should set CLASS option -> $field->setFormTypeOption('class', $enumTypeClass);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choices should be ENUM not STRING.
foreach ($choices as $choice) {
$processedEnumChoices[$choice->name] = $choice;
}
My work with Enum with the current 4.x branch looks like this: enum Nds: string
{
case RATE_NONE = 'rate_none';
case RATE_ZERO = 'rate_0';
case RATE_10 = 'rate_10';
case RATE_20 = 'rate_20';
public static function choices(): array
{
return [
self::RATE_NONE->getLabel() => self::RATE_NONE->name,
self::RATE_ZERO->getLabel() => self::RATE_ZERO->name,
self::RATE_10->getLabel() => self::RATE_10->name,
self::RATE_20->getLabel() => self::RATE_20->name,
];
}
public function trans(TranslatorInterface $translator, string $locale = null): string
{
return $translator->trans($this->getLabel(), locale: $locale);
}
public function getLabel(): string
{
return 'admin_label.enum.nds.'.$this->value;
}
public function getRate(): int
{
return (int) (substr($this->value, 5));
}
} # messages.en.yaml
admin_label:
enum:
nds:
rate_none: Without VAT
rate_0: 0%
rate_10: 10%
rate_20: 20% class MyEnumType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->addModelTransformer(
new CallbackTransformer(
static fn (mixed $value): mixed => $value, // no convertion
static fn (?string $value): ?\BackedEnum => call_user_func([$options['class'], 'tryFrom'], $value)
)
);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setNormalizer('choice_label', static fn (Options $options, ?\Closure $value): \Closure => static fn ($choice): ?string => self::getTranslatableLabel($options, $choice));
$resolver->setNormalizer('choice_value', static fn (Options $options, ?\Closure $value): \Closure => static fn ($choice): ?string => $choice instanceof \BackedEnum ? $choice->value : $choice);
$resolver->setRequired('label_prefix');
$resolver->setAllowedTypes('label_prefix', 'string');
$resolver->setDefault('label_prefix', 'admin_label.enum.');
$resolver->setRequired('class');
$resolver->setAllowedTypes('class', 'string');
}
public static function getTranslatableLabel(Options $options, string $value) {
return $options['label_prefix'] . lcfirst(self::classShortName($options['class'])) . '.' . $value;
}
public static function classShortName(string $class): string
{
return (false === $pos = strrpos($class, '\\')) ? $class : substr($class, $pos + 1);
}
public function getParent(): string
{
return EnumType::class;
}
} class DocCrudController extends AbstractCrudController
{
...
public function configureFields(string $pageName): iterable
{
...
yield Fields\ChoiceField::new('nds', 'admin_label.doc.field.nds')->setRequired(true)
->setPermission(DocAccessVoter::SHOW_NDS)
->renderAsNativeWidget()
->addCssClass('col-md-6 col-xxl-5')
->setFormType(MyEnumType::class)
->setFormTypeOption('placeholder', false)
->setFormTypeOption('class', Nds::class)
->setChoices(in_array($pageName, [Crud::PAGE_INDEX, Crud::PAGE_DETAIL], true) ? Nds::choices() : Nds::cases())
;
...
}
...
} |
This is my PR -> #5640 |
@javiereguiluz |
Closing in favor of #5740. |
Fixes the issues reported in #4988.