-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,7 @@ Form | |
Before: | ||
|
||
```php | ||
$form = $this->createForm('form', $article, array('cascade_validation' => true)) | ||
$form = $this->createFormBuilder($article, array('cascade_validation' => true)) | ||
->add('author', new AuthorType()) | ||
->getForm(); | ||
``` | ||
|
@@ -22,7 +22,7 @@ Form | |
```php | ||
use Symfony\Component\Validator\Constraints\Valid; | ||
|
||
$form = $this->createForm('form', $article) | ||
$form = $this->createFormBuilder($article) | ||
->add('author', new AuthorType(), array( | ||
'constraints' => new Valid(), | ||
)) | ||
|
@@ -42,6 +42,194 @@ Form | |
private $author; | ||
} | ||
``` | ||
|
||
* Type names were deprecated and will be removed in Symfony 3.0. Instead of | ||
referencing types by name, you should reference them by their | ||
fully-qualified class name (FQCN) instead. With PHP 5.5 or later, you can | ||
use the "class" constant for that: | ||
|
||
Before: | ||
|
||
```php | ||
$form = $this->createFormBuilder() | ||
->add('name', 'text') | ||
->add('age', 'integer') | ||
->getForm(); | ||
``` | ||
|
||
After: | ||
|
||
```php | ||
use Symfony\Component\Form\Extension\Core\Type\IntegerType; | ||
use Symfony\Component\Form\Extension\Core\Type\TextType; | ||
|
||
$form = $this->createFormBuilder() | ||
->add('name', TextType::class) | ||
->add('age', IntegerType::class) | ||
->getForm(); | ||
``` | ||
|
||
As a further consequence, the method `FormTypeInterface::getName()` was | ||
deprecated and will be removed in Symfony 3.0. You should remove this method | ||
from your form types. | ||
|
||
If you want to customize the block prefix of a type in Twig, you should now | ||
implement `FormTypeInterface::getBlockPrefix()` instead: | ||
|
||
Before: | ||
|
||
```php | ||
class UserProfileType extends AbstractType | ||
{ | ||
public function getName() | ||
{ | ||
return 'profile'; | ||
} | ||
} | ||
``` | ||
|
||
After: | ||
|
||
```php | ||
class UserProfileType extends AbstractType | ||
{ | ||
public function getBlockPrefix() | ||
{ | ||
return 'profile'; | ||
} | ||
} | ||
``` | ||
|
||
If you don't customize `getBlockPrefix()`, it defaults to the class name | ||
without "Type" suffix in underscore notation (here: "user_profile"). | ||
|
||
If you want to create types that are compatible with Symfony 2.3 up to 2.8 | ||
and don't trigger deprecation errors, implement *both* `getName()` and | ||
`getBlockPrefix()`: | ||
|
||
```php | ||
class ProfileType extends AbstractType | ||
{ | ||
public function getName() | ||
{ | ||
return $this->getBlockPrefix(); | ||
} | ||
|
||
public function getBlockPrefix() | ||
{ | ||
return 'profile'; | ||
} | ||
} | ||
``` | ||
|
||
If you define your form types in the Dependency Injection configuration, you | ||
should further remove the "alias" attribute: | ||
|
||
Before: | ||
|
||
```xml | ||
<service id="my.type" class="Vendor\Type\MyType"> | ||
<tag name="form.type" alias="mytype" /> | ||
</service> | ||
``` | ||
|
||
After: | ||
|
||
```xml | ||
<service id="my.type" class="Vendor\Type\MyType"> | ||
<tag name="form.type" /> | ||
</service> | ||
``` | ||
|
||
Type extension should return the fully-qualified class name of the extended | ||
type from `FormTypeExtensionInterface::getExtendedType()` now. | ||
|
||
Before: | ||
|
||
```php | ||
class MyTypeExtension extends AbstractTypeExtension | ||
{ | ||
public function getExtendedType() | ||
{ | ||
return 'form'; | ||
} | ||
} | ||
``` | ||
|
||
After: | ||
|
||
```php | ||
use Symfony\Component\Form\Extension\Core\Type\FormType; | ||
|
||
class MyTypeExtension extends AbstractTypeExtension | ||
{ | ||
public function getExtendedType() | ||
{ | ||
return FormType::class; | ||
} | ||
} | ||
``` | ||
|
||
If your extension has to be compatible with Symfony 2.3-2.8, use the | ||
following statement: | ||
|
||
```php | ||
use Symfony\Component\Form\AbstractType; | ||
use Symfony\Component\Form\Extension\Core\Type\FormType; | ||
|
||
class MyTypeExtension extends AbstractTypeExtension | ||
{ | ||
public function getExtendedType() | ||
{ | ||
method_exists(AbstractType::class, 'getBlockPrefix') ? FormType::class : 'form'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed in 8d049c5 |
||
} | ||
} | ||
``` | ||
|
||
* Returning type instances from `FormTypeInterface::getParent()` is deprecated | ||
and will not be supported anymore in Symfony 3.0. Return the fully-qualified | ||
class name of the parent type class instead. | ||
|
||
Before: | ||
|
||
```php | ||
class MyType | ||
{ | ||
public function getParent() | ||
{ | ||
return new ParentType(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this was more likely to return an alias though There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think stof missed that this is describing the deprecated way. |
||
} | ||
} | ||
``` | ||
|
||
After: | ||
|
||
```php | ||
class MyType | ||
{ | ||
public function getParent() | ||
{ | ||
return ParentType::class; | ||
} | ||
} | ||
``` | ||
|
||
* Passing type instances to `Form::add()`, `FormBuilder::add()` and the | ||
`FormFactory::create*()` methods is deprecated and will not be supported | ||
anymore in Symfony 3.0. Pass the fully-qualified class name of the type | ||
instead. | ||
|
||
Before: | ||
|
||
```php | ||
$form = $this->createForm(new MyType()); | ||
``` | ||
|
||
After: | ||
|
||
```php | ||
$form = $this->createForm(MyType::class); | ||
``` | ||
|
||
Translator | ||
---------- | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,12 +94,12 @@ public static function createChoiceName($choice, $key, $value) | |
* Gets important parts from QueryBuilder that will allow to cache its results. | ||
* For instance in ORM two query builders with an equal SQL string and | ||
* equal parameters are considered to be equal. | ||
* | ||
* | ||
* @param object $queryBuilder | ||
* | ||
* | ||
* @return array|false Array with important QueryBuilder parts or false if | ||
* they can't be determined | ||
* | ||
* | ||
* @internal This method is public to be usable as callback. It should not | ||
* be used in user code. | ||
*/ | ||
|
@@ -335,6 +335,6 @@ abstract public function getLoader(ObjectManager $manager, $queryBuilder, $class | |
|
||
public function getParent() | ||
{ | ||
return 'choice'; | ||
return 'Symfony\Component\Form\Extension\Core\Type\ChoiceType'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This requires bumping the min version of the component in the bridge There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
} | ||
} |
There was a problem hiding this comment.
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 the
getName()
or not?I'd appreciated some Twig snippet example what exactly is meant here.
There was a problem hiding this comment.
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 where
textarea
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
.There was a problem hiding this comment.
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 for
textarea_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 can just scan twig templates with regualar expression. There are no Twig tests that could tell us what broke.
So for custom:
↓
Like this?
So it's string from
getName()
+ somehow_widget
magically added?There was a problem hiding this comment.
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 in
getName()
with what the automatically computed name would be (seesymfony/src/Symfony/Component/Form/AbstractType.php
Line 55 in ba4d57b
getName()
method togetBlockPrefix()
. Otherwise it can be removed.There was a problem hiding this comment.
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 with rectorphp/rector#3705 I made it just before reading your comment :D
I want to take it further and remove all the
getBlockPrefix()
that:That's why I ask how can I find it in the twig templates.
Any example for that?
There was a problem hiding this comment.
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 (see https://symfony.com/doc/2.8/form/form_customization.html#form-custom-prototype).