[Form] String is the preferred value type for TextType#41514
[Form] String is the preferred value type for TextType#41514peter-gribanov wants to merge 1 commit into
Conversation
|
this change is a BC break for projects that rely on getting |
4217bfd to
66fb803
Compare
66fb803 to
e20148a
Compare
|
I would like to get some response. Is it a bad idea to give up the need to specify the I agree that an unsubmitted value is not equivalent to empty value and it is correct to provide the user of Form component with the ability to handle these cases differently, but do users need to handle them separately? Is it possible to give some example in which the use of |
|
Changing the behavior in the next major is possible only if there is a deprecation in a previous minor. |
|
I want to return to an old and very painful topic #5906. I wanted to revisit this topic before the release 4.0 and 5.0, but didn't find the time for this. Now, when everyone already has PHP 7 or 8, and the
strict_types=1is the defect standard, it is probably time to abandon the hook when the text may not be astring.We've been using hooks for many years, even before #18357. We want string values to always be strings. Under strict typing conditions, i consider using
NULLas a value valid only in cases where the expected value is not a scalar type and cannot be correctly transformed from the submitted data. In such cases, we use custom transformers.Expected implementation
A very crude example.
Actual implementation
Without hooks and specifying option
empty_data.use Symfony\Component\Validator\Constraints as Assert; final class RenameAuthor { /** * @Assert\NotBlank * @Assert\Length(max=128) */ - public string $firstname = ''; + private string $firstname = ''; /** * @Assert\Length(max=128) */ - public string $lastname = ''; + private string $lastname = ''; /** * @Assert\Length(max=128) */ - public string $patronymic = ''; + private string $patronymic = ''; + + public function getFirstname(): string + { + return $this->firstname; + } + + public function setFirstname(?string $firstname): void + { + $this->firstname = $firstname ?? ''; + } + + public function getLastname(): string + { + return $this->lastname; + } + + public function setLastname(?string $lastname): void + { + $this->lastname = $lastname ?? ''; + } + + public function getPatronymic(): string + { + return $this->patronymic; + } + + public function setPatronymic(?string $patronymic): void + { + $this->patronymic = $patronymic ?? ''; + } }$command = new RenameAuthor(); $form = $this->createForm(RenameAuthorFormType::class, $command)->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $questionnaire->renameAuthor($command->firstname, $command->lastname, $command->patronymic); + $questionnaire->renameAuthor($command->getFirstname(), $command->getLastname(), $command->getPatronymic()); // ... }Implementation with empty_data option
It seems that specifying one option is not a problem. But you should always remember that the text may not be a
string, and to typecast to astring, you need to specify optionempty_datain each field, each form. There may be hundreds and thousands of such places per project, and the probability of errors increases with the growth of the project.use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; final class RenameAuthorFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder - ->add('firstname', TextType::class) + ->add('firstname', TextType::class, [ + 'empty_data' => '', + ]) ->add('lastname', TextType::class, [ + 'empty_data' => '', 'required' => false, ]) ->add('patronymic', TextType::class, [ + 'empty_data' => '', 'required' => false, ]) ; } public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefault('data_class', RenameAuthor::class); } }