| Q | A
| ---------------- | -----
| Bug report? | yes
| Feature request? | no
| BC Break report? | no
| RFC? | no
| Symfony version | 3.2.6
Using the following entity as the model,
<?php
class Test
{
public function getName() : string
{
return $this->name;
}
public function setName(string $name) : void
{
$this->name = $name;
}
}
and the following form type,
<?php
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
class TestType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'name',
TextType::class,
[
'constraints' => [
new NotBlank(),
new Length(['max' => 255])
]
]
)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('data_class', Test::class);
}
}
will result with the following error message if the form data is not valid:
Expected argument of type "string", "NULL" given
It appears that validation occurs after the values are being set on the entity.
Might want to revisit #5480.
You should not be using strict types for data objects in your forms. Data set can in theory be null (though might not happen), but it's really easy to have your object break on returning null instead of a string in a getter.
It appears that validation occurs after the values are being set on the entity.
That's correct. That's also the reason your entity/model has to be allowed to be in an invalid state if you want to bind your entities/models to forms. If you want to get around this problem, please read: https://stovepipe.systems/post/rethinking-form-development
Hello @kherrera-ebsco, this is fixed since symfony 3.1 you can use:
class TestType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'name',
TextType::class,
[
'constraints' => [
new NotBlank(),
new Length(['max' => 255])
],
'empty_data' => '',
]
)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('data_class', Test::class);
}
}
The other solution is to add a model transformer yourself.
Thanks for the help, but it looks like my perspective on the matter is different.
If the form is not capable of supplying valid data to an object with strict requirements (passing an empty string is following the rule but not the spirit), then it should be documented that it is not supported. I can understand the need for a middle ground, using a builder for a new object, but I would argue that this workaround would need to be documented.
Given the history of this problem and the other issues that were opened and closed, I'll close this issue and consider it a "won't fix".
Most helpful comment
Thanks for the help, but it looks like my perspective on the matter is different.
If the form is not capable of supplying valid data to an object with strict requirements (passing an empty string is following the rule but not the spirit), then it should be documented that it is not supported. I can understand the need for a middle ground, using a builder for a new object, but I would argue that this workaround would need to be documented.
Given the history of this problem and the other issues that were opened and closed, I'll close this issue and consider it a "won't fix".