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] Deprecated FormTypeInterface::getName() and passing of type instances#15079

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

Merged
fabpot merged 1 commit intosymfony:2.8fromwebmozart:issue15008
Aug 1, 2015

Conversation

@webmozart
Copy link
Contributor

QA
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?yes
Tests pass?yes
Fixed tickets#5321,#15008
LicenseMIT
Doc PRTODO

Type Names

This PR deprecates the definition of thegetName() method of form types. See#15008 for a more detailed description.

Before:

class MyTypeextends AbstractType{publicfunctiongetName()    {return'mytype';    }// ...}

After:

class MyTypeextends AbstractType{// ...}

You should always reference other types by their fully-qualified class names. Thanks to PHP 5.5, that's easy:

Before:

$form =$this->createFormBuilder()    ->add('name','text')    ->add('age','integer')    ->getForm();

After:

$form =$this->createFormBuilder()    ->add('name', TextType::class)    ->add('age', IntegerType::class)    ->getForm();

Type Instances

Furthermore, passing of type instances is deprecated.

Before:

$form =$this->createForm(newAuthorType());

After:

$form =$this->createForm(AuthorType::class);

DIC Aliases

When registering a type in the DIC, you should omit the "alias" attribute now.

Before:

<serviceid="my.type"class="Vendor\Type\MyType">    <tagname="form.type"alias="mytype" />    <argumenttype="service"id="some.service.id" /></service>

After:

<serviceid="my.type"class="Vendor\Type\MyType">    <tagname="form.type" />    <argumenttype="service"id="some.service.id" /></service>

Types without dependencies don't need to be registered in the DIC as they can be instantiated right away.

Template Block Prefixes

By default, the class name of the type in underscore notation minus "Type" suffix is used as Twig template block prefix (e.g.UserProfileType =>user_profile_*). If you want to customize that, overwrite the newgetBlockPrefix() method in your type:

class UserProfileTypeextends AbstractType{publicfunctiongetBlockPrefix()    {return'profile';    }// ...}

@webmozartwebmozart added Form DXDX = Developer eXperience (anything that improves the experience of using Symfony) labelsJun 23, 2015
@Tobion
Copy link
Contributor

I think you can simply add the service id to the$types additionally to the class name. This way both work as alias and there is no BC break.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

are we going to remove that in 3.0? Then we could also remove theFormType::getName completely, or?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Good idea!

@webmozartwebmozartforce-pushed theissue15008 branch 2 times, most recently fromde9a855 tof516801CompareJune 24, 2015 13:25
@webmozartwebmozart changed the title[Form] Added default implementation of AbstractType::getName()[Form] Deprecated FormTypeInterface::getName() and passing of type instancesJun 24, 2015
@webmozart
Copy link
ContributorAuthor

Updated. Ping @symfony/deciders

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

this was more likely to return an alias though

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ah sorry, I misread the deprecation message. I confused with the deprecation of type names (which is the main goal of this PR even though this other change went in)

Returning an instance ingetParent was indeed a bad idea by forcing to resolve types again and again.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think stof missed that this is describing the deprecated way.

@javiereguiluz
Copy link
Member

@webmozart I have a question. You say that when using PHP 5.5, the needed changes are minimal:

Before:

$form =$this->createFormBuilder()    ->add('name','text')    ->add('age','integer')    ->getForm();$form =$this->createForm(newAuthorType());

After:

useSymfony\Component\Form\Extension\Core\Type\TextType;useSymfony\Component\Form\Extension\Core\Type\IntegerType;useAppBundle\Form\Type\AuthorType;$form =$this->createFormBuilder()    ->add('name', TextType::class)    ->add('age', IntegerType::class)    ->getForm();$form =$this->createForm(AuthorType::class);

My question is: if you use PHP 5.3 or PHP 5.4, you should use the following?

$form =$this->createFormBuilder()    ->add('name','Symfony\Component\Form\Extension\Core\Type\TextType')    ->add('age','Symfony\Component\Form\Extension\Core\Type\IntegerType')    ->getForm();$form =$this->createForm('AppBundle\Form\Type\AuthorType');

@stof
Copy link
Member

@javiereguiluz yes

@webmozart
Copy link
ContributorAuthor

@javiereguiluz Exactly. However, passing "text" or similar type names is still supported until Symfony 3.0 (although you'll get deprecation notes). Symfony 3.0 has a higher minimum PHP version anyway so there this is not a problem anymore.

@javiereguiluz
Copy link
Member

@webmozart the original idea of this change was to improve DX by getting rid of thegetName(). However, I find this change anti-DX because you now have to type a lot more.

@stof
Copy link
Member

@webmozart can you fix the SecurityBundle form login test failures ? These tests are passing on the current 2.8 branch

@Koc
Copy link
Contributor

Koc commentedJun 24, 2015

Does it possible use dynamic form names? Currently we are using inline editing for cities in grid:

$form =$this->container->get('form.factory')->createNamed(            CityInlineEditType::getNameForCity($city),newCityInlineEditType(),$city        );

Is this code still walid after this PR?

@webmozart
Copy link
ContributorAuthor

@Koc Sure, you can use any form name you like. However, thetype needs to be passed as FQCN, i.e.

$form =$this->container->get('form.factory')->createNamed(    CityInlineEditType::getNameForCity($city),    CityInlineEditType::class,$city);

@stof
Copy link
Member

@Koc this PR is abouttype names, not aboutforms names.

@webmozart how does this impact the block names in form themes ?

@DavidBadura
Copy link
Contributor

Is it still possible to use alias? What if you have a type and you want then use this with various dependencies? I have to extend my class to solve this problem?

@webmozart
Copy link
ContributorAuthor

@javiereguiluz That's FUD. As I've shown above, you are writing less code than before. As of using types in forms, instead of typing'text' (6 chars) you now typeTextT + ENTER and let the IDE do the rest. That's one character less + type safety.

@dosten
Copy link
Contributor

@DavidBadura you should add the type as a service

<serviceid="my.type"class="Vendor\Type\MyType">    <tagname="form.type" />    <argumenttype="service"id="some.service.id" /></service>

and do something like this

$form =$this->createFormBuilder()    ->add('name', MyType::class)¿    ->getForm();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

the null part is not relevant anymore

@Tobion
Copy link
Contributor

I think the old way of forcing people to implementgetName was NOT good for three reasons:

  1. there is already a class name to identify it, meaning getName is redundant
  2. as we know, naming things is hard. thus forcing people to invent a name just creates a burden
  3. easily creates conflicting names

This is why I proposed to remove/deprecate this concept completely instead of just making it optional.
The new way also has another advantage: It makes codeself-documenting.
Writing/seeing code like$formBuilder->add('property', 'entity') is not expressive (what options are available, what doesentity do?), but$formBuilder->add('property', EntityType::class) is. It allows you to easily open the EntityType class to look at documention and exposed options.
So I think it is DX-friendly. IDEs could even go futher now and propose/autocomplete all classes in your project that implement FormTypeInterface when building a form. Such things wouldn't be easily possible to automate when using abstract names which are resolved at runtime.

The only disadvantage I see is that using the class name does not correspond to type extensions. Using a class name as reference (in contrast to an abstract name) makes people assume it's really just this class. But type extensions can do anything on top of it which somehow clashes with the object-oriented way of using a class name. But I think type extensions are not so common anyway (esp. in user-defined ones).

All in all, I'm 👍

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This code needs to deal with FQCNs.

@stof
Copy link
Member

stof commentedJul 1, 2015

The only disadvantage I see is that using the class name does not correspond to type extensions. Using a class name as reference (in contrast to an abstract name) makes people assume it's really just this class. But type extensions can do anything on top of it which somehow clashes with the object-oriented way of using a class name. But I think type extensions are not so common anyway (esp. in user-defined ones).

not only type extension but also type inheritance. but this is just a documentation thing IMO.

@aderuwe
Copy link
Contributor

This looks really good. Thanks@webmozart.

@webmozart
Copy link
ContributorAuthor

Updated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

typo: default without s

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

fixed in8d049c5

@fabpot
Copy link
Member

Thank you@webmozart.

@fabpotfabpot merged commit3d9e5de intosymfony:2.8Aug 1, 2015
fabpot added a commit that referenced this pull requestAug 1, 2015
…sing of type instances (webmozart)This PR was merged into the 2.8 branch.Discussion----------[Form] Deprecated FormTypeInterface::getName() and passing of type instances| Q             | A| ------------- | ---| Bug fix?      | no| New feature?  | yes| BC breaks?    | no| Deprecations? | yes| Tests pass?   | yes| Fixed tickets |#5321,#15008| License       | MIT| Doc PR        | TODO#### Type NamesThis PR deprecates the definition of the `getName()` method of form types. See#15008 for a more detailed description.Before:```phpclass MyType extends AbstractType{    public function getName()    {        return 'mytype';    }    // ...}```After:```phpclass MyType extends AbstractType{    // ...}```You should always reference other types by their fully-qualified class names. Thanks to PHP 5.5, that's easy:Before:```php$form = $this->createFormBuilder()    ->add('name', 'text')    ->add('age', 'integer')    ->getForm();```After:```php$form = $this->createFormBuilder()    ->add('name', TextType::class)    ->add('age', IntegerType::class)    ->getForm();```#### Type InstancesFurthermore, passing of type instances is deprecated.Before:```php$form = $this->createForm(new AuthorType());```After:```php$form = $this->createForm(AuthorType::class);```#### DIC AliasesWhen registering a type in the DIC, you should omit the "alias" attribute now.Before:```xml<service>    <tag name="form.type" alias="mytype" />    <argument type="service" /></service>```After:```xml<service>    <tag name="form.type" />    <argument type="service" /></service>```Types without dependencies don't need to be registered in the DIC as they can be instantiated right away.#### Template Block PrefixesBy default, the class name of the type in underscore notation minus "Type" suffix is used as Twig template block prefix (e.g. `UserProfileType` => `user_profile_*`). If you want to customize that, overwrite the new `getBlockPrefix()` method in your type:```phpclass UserProfileType extends AbstractType{    public function getBlockPrefix()    {        return 'profile';    }    // ...}```Commits-------3d9e5de [Form] Deprecated FormTypeInterface::getName() and passing of type instances
@fabpotfabpot mentioned this pull requestNov 16, 2015
@Hanmac
Copy link
Contributor

with this change how will i do now that my Type has some dependency injection stuff as constructor or otherwise?

before i did this in service.yml:

mybundle.form.type.address:class:%mybundle.form.type.address.class%arguments:[ @mybundle.service.transformator_factory ]tags:            -{ name: form.type, alias: address }

the transformator_factory did return a DataTransformerInterface i did use for addModelTransformer
(i need that because ParamConverter did had problems with my Object because i need an object inside a object)

now does the FormBuilder respect my service definition, and if not how can i get that working again in future symfony 2.8+ or 3.0?

@nicolas-grekas
Copy link
Member

@Hanmac please open an issue, comments in closed PRs are hard to track

@stof
Copy link
Member

@Hanmac this works exactly as before (except that you don't need the alias anymore in the tag if you use only the 2.8+ API)

fabpot added a commit that referenced this pull requestMar 31, 2016
…eahDude)This PR was merged into the 3.1-dev branch.Discussion----------[FrameworkBundle] Deprecated form types as services| Q             | A| ------------- | ---| Branch?       | master| Bug fix?      | no| New feature?  | no| BC breaks?    | no| Deprecations? | yes| Tests pass?   | yes| Fixed tickets | ~| License       | MIT| Doc PR        | ~These services are needless in regard of#15079.If they have no dependencies, whatever are the registered extensions, `FormTypeInterface` instances will be autoloaded by their FQCN.Commits-------dfe4f53 [FrameworkBundle] Deprecated form types as services
from your form types.

If you want to customize the block prefix of a type in Twig, you should now
implement`FormTypeInterface::getBlockPrefix()` instead:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

What exactly does "block prefix of a type in Twig" mean?

I'm upgrading old Symfony projects and this line is a mystery for me. Can I remove thegetName() or not?
I'd appreciated some Twig snippet example what exactly is meant here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This refers to how form fragment names are generated. By default, the value is derived from the class name (see e.g.https://symfony.com/doc/current/form/form_themes.html#form-fragment-naming wheretextarea is derived fromTextareaType class). If you have your ownTextareaType class, you will maybe want to override thegetBlockPrefix() method to not reuse the blocks used by the coreTextareaType.

Copy link
Contributor

@TomasVotrubaTomasVotrubaJul 13, 2020
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I never used such fragments and docs is very confusing for me. I don't see any twig sample fortextarea_widget keyword. I also checked PRs referecing this PR when upgrading, but it seems nobody ever used it on custom types.

I look for 3 lines of twig sample, so I canjust scan twig templates with regualar expression. There are no Twig tests that could tell us what broke.

{{ form_widget(form.age) }}{{ textarea_widget(form.age) }}

So for custom:

class SomeTypeextends FormType{publicfunctiongetName()    {return'yolo';}}

{{ yolo_widget(form.age) }}

Like this?

So it's string fromgetName() + somehow_widget magically added?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

If you just looking for a way to automatically update the code of the form type class, I would compare the value returned ingetName() with what the automatically computed name would be (see

return StringUtil::fqcnToBlockPrefix(static::class) ?:'';
). Only if both values differ, you will need to rename thegetName() method togetBlockPrefix(). Otherwise it can be removed.

Copy link
Contributor

@TomasVotrubaTomasVotrubaJul 13, 2020
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

That's what I already do withrectorphp/rector#3705 I made it just before reading your comment :D

I want to take it further and remove all thegetBlockPrefix() that:

  • don't have standard name
  • are never used in the twig templates

That's why I ask how can I find it in the twig templates.

Any example for that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The special block names are*_row,*_label,*_widget and*_errors (nowadays there is also*_help, but I guess you are addressing 2.8 applications here). But you need to be careful as the block prefix is also used to build block names forCollectionType entries (seehttps://symfony.com/doc/2.8/form/form_customization.html#form-custom-prototype).

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

Reviewers

@xabbuhxabbuhxabbuh left review comments

+1 more reviewer

@TomasVotrubaTomasVotrubaTomasVotruba left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

DXDX = Developer eXperience (anything that improves the experience of using Symfony)FormReady

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

16 participants

@webmozart@Tobion@javiereguiluz@stof@Koc@DavidBadura@dosten@fabpot@csarrazi@harikt@aderuwe@Hanmac@nicolas-grekas@TomasVotruba@OskarStark@xabbuh

[8]ページ先頭

©2009-2025 Movatter.jp