Closed
Description
Since dynamic inheritance is inherently flawed (#3793), it should be replaced by proper PHP inheritance. This should make it much more intuitive for newcomers to extend a type. This change has been made possible by the recently added class DefaultOptions (#3789).
A BC layer should allow to use the old and new API side by side. Core types should be moved to the new API.
API before:
class MyType extends AbstractType
{
public function getName()
{
return 'my_type';
}
public function getParent()
{
return 'form';
}
public function buildForm(FormBuilder $builder, array $options)
{
// ...
}
public function buildView(FormView $view, FormInterface $form)
{
// ...
}
public function buildViewBottomUp(FormView $view, FormInterface $form)
{
// ...
}
public function getDefaultOptions()
{
return ...
}
}
API after:
class MyType extends FormType
{
public function getName()
{
return 'my_type';
}
public function buildForm(FormBuilder $builder, array $options)
{
// no parent::buildForm() call
// ...
}
public function buildView(FormView $view, FormInterface $form)
{
// no parent::buildView() call
// ...
}
public function finishView(FormView $view, FormInterface $form)
{
// no parent::finishView() call
// ...
}
public function setDefaultOptions(OptionsResolver $resolver)
{
// no parent::setDefaultOptions() call
$resolver->setDefaults(array(...));
}
}
As you can see, the type methods must not call their parent methods. This allows the factory to call each single method at the appropriate time and to interline the type extension methods in between.
Positive effects:
- Understandable inheritance
- Use of instanceof, e.g.
$form->getType() instanceof MyType
- Reuse of protected methods from the parent type
Negative effects:
- If you call
parent::..
in any of the interface methods, this will lead to strange side effects. I'm not sure if we can catch these situations and throw an exception.