Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Form] String is the preferred value type for TextType#41514

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation

peter-gribanov
Copy link
Contributor

@peter-gribanovpeter-gribanov commentedJun 2, 2021
edited
Loading

QA
Branch?7.0
Bug fix?yes
New feature?no
Deprecations?no
TicketsFix#5906
LicenseMIT
Doc PRsymfony/symfony-docs#15404

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 thestrict_types=1 is 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 usingNULL as 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.

useSymfony\Component\Validator\ConstraintsasAssert;finalclass RenameAuthor{/**     * @Assert\NotBlank     * @Assert\Length(max=128)     */publicstring$firstname ='';/**     * @Assert\Length(max=128)     */publicstring$lastname ='';/**     * @Assert\Length(max=128)     */publicstring$patronymic ='';}
useSymfony\Component\Form\AbstractType;useSymfony\Component\Form\Extension\Core\Type\TextType;useSymfony\Component\Form\FormBuilderInterface;useSymfony\Component\OptionsResolver\OptionsResolver;finalclass RenameAuthorFormTypeextends AbstractType{publicfunctionbuildForm(FormBuilderInterface$builder,array$options):void    {$builder            ->add('firstname', TextType::class)            ->add('lastname', TextType::class, ['required' =>false,            ])            ->add('patronymic', TextType::class, ['required' =>false,            ])        ;    }publicfunctionconfigureOptions(OptionsResolver$resolver):void    {$resolver->setDefault('data_class', RenameAuthor::class);    }}
class Questionnaire{// ...publicfunctionrenameAuthor(string$new_firstname,string$new_lastname,string$new_patronymic):void    {$this->author_name =newAuthorName($new_firstname,$new_lastname,$new_patronymic);    }
$command =newRenameAuthor();$form =$this->createForm(RenameAuthorFormType::class,$command)->handleRequest($request);if ($form->isSubmitted() &&$form->isValid()) {$questionnaire->renameAuthor($command->firstname,$command->lastname,$command->patronymic);// ...}

Actual implementation

Without hooks and specifying optionempty_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 astring, and to typecast to astring, you need to specify optionempty_data in 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);    }}

mmarton reacted with thumbs up emojiWarxcell reacted with thumbs down emoji
@stof
Copy link
Member

stof commentedJun 2, 2021

this change is a BC break for projects that rely on gettingnull. Doing that in 6.0 without an upgrade path is a no-go

@peter-gribanovpeter-gribanovforce-pushed theform_text_type_stringable branch 2 times, most recently from4217bfd to66fb803CompareJune 2, 2021 14:40
@peter-gribanov
Copy link
ContributorAuthor

@stof quite right. That is why i propose to introduce this in the major version, in which we can break BC. What do you think about this#41516 ?

@peter-gribanov
Copy link
ContributorAuthor

I would like to get some response. Is it a bad idea to give up the need to specify theempty_data option every time you useTextType and types inherited fromTextType?

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 ofNULL inTextType is justified when using strict types?

@fabpotfabpot modified the milestones:6.0,6.1Nov 21, 2021
@fabpotfabpot modified the milestones:6.1,6.2May 20, 2022
@nicolas-grekas
Copy link
Member

Changing the behavior in the next major is possible only if there is a deprecation in a previous minor.
In this case, I'm not sure it's worth it.
I'm closing here because it didn't get any traction apparently.
Thanks for submitting.

@peter-gribanov
Copy link
ContributorAuthor

Changing the behavior in the next major is possible only if there is a deprecation in a previous minor.

@nicolas-grekas see#41516

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@xabbuhxabbuhAwaiting requested review from xabbuhxabbuh is a code owner

@ycerutoycerutoAwaiting requested review from ycerutoyceruto is a code owner

Assignees
No one assigned
Projects
None yet
Milestone
6.2
Development

Successfully merging this pull request may close these issues.

5 participants
@peter-gribanov@stof@nicolas-grekas@fabpot@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp