STARTING SITUATION
I'm trying to create, with Symfony 6, a FormTypeExtension to extend my custom types.
Class hierarchy is the following:
AbstractType <-- indeed this class is abstract
--MyBaseType
| --MySubType1
| --MySubType2
--MyOtherType
My FormTypeExtension:
class TranslatableTypeExtension extends AbstractTypeExtension
{
/**
* Should apply to MyBaseType plus MySubType1 and
* MySubType2 by inheritance
*/
public static function getExtendedTypes(): iterable
{
return [
MyBaseType::class,
];
}
/**
* Special option for these custom form types
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'translate_only' => false,
]);
$resolver->setDefined(['translate_only']);
}
}
My custom type classes:
class MyBaseType extends AbstractType
{
}
class MySubType1 extends MyBaseType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('blahblahblah', TextType::class, [
'label' => 'blahblahblah',
])
(etc.)
;
}
}
(same for MySubType2)
In my controller:
class MySub1Controller extends AbstractController
{
#[Route('/MySub1/{id}/translate', name: 'app_mysub1_translate')]
public function translateMuSub1(MySub1Repository $mySub1Repository, EntityManagerInterface $entityManager, Request $request, int $id): Response
{
$mySub1 = $mySub1Repository->find($id);
$form = $this->createForm(MySubType1Type::class, $mySub1, [
'translate_only' => true,
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$mySub1 = $form->getData();
$entityManager->persist($mySub1);
$entityManager->flush();
return $this->redirectToRoute('app_mysub1', ['id' => $id]);
}
return $this->renderForm('public/form/mysub1.html.twig', [
'form' => $form,
]);
}
}
This results is:
An error has occurred resolving the options of the form "App\Form\Type\MySub1Type": The option "translate_only" does not exist. Defined options are: (...)
CONCLUSION
This error message means that the FormTypeExtension does not apply to MySubType1: the option translate_only is not reckognized as allowed.
QUESTIONS
I see in the Symfony Form Type Extension doc that Form Extensions can be used for the classic Form Types inheriting FormType. But I see nowhere written that we cannot use it the same way for customer types inheriting AbstractType.
- Is it possible or not?
- If possible, what am I doing wrong?
Thanks in advance for your help, buddies.
CodePudding user response:
FormType inheritance is built on method getParent(). Probably, you should not extend MyBaseType
but return it in getParent()
getParent() When returning a (fully-qualified) class name here, Symfony will call each method of that type (i.e. buildForm(), buildView(), etc.) and all its type extensions, before calling the corresponding method of your custom type.
class MyBaseType extends AbstractType
{
}
class MySubType1 extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('blahblahblah', TextType::class, [
'label' => 'blahblahblah',
])
(etc.)
;
}
public function getParent()
{
return MyBaseType::class;
}
}