How does symfony 2 find custom form types?

I read Data Transformations. I changed it a bit in my code. I get

Failed to load type "csv2tags"

I have my own type of form

class CSV2TagsType extends AbstractType { public function buildForm(FormBuilder $builder, array $opts) { $builder->appendClientTransformer(new CSV2TagsTransformer()); } public function getParent() { return 'text'; } public function getName() { return 'csv2tags'; } } 

Transformer use:

 class CSV2TagsTransformer implements DataTransformerInterface { /** * @var EntityManager */ protected $em; public function __construct(EntityManager $em) { $this->em = $em; } // ... } 

In services.yml

 services: jm.blog.csv2tagsTransformer: class: JM\BlogBundle\Form\DataTransformer\CSV2TagsTransformer arguments: ["@doctrine.orm.entity_manager"] 

A few questions:

  • I moved the EntityManager to a transformer instead of a form type, is this normal?
  • I did not declare an alias for the transformer service, as in the docs. I thought the alias for the form type was from the AbstractType::getName() function? Do I have to declare my own type of form as a service?
  • I moved the EntityManager to a transformer. Am I doing new CSV2TagsTransformer() without EntityManager ?
0
source share
2 answers

I will just end the answer received by @ greg0ire, which is almost right.

First, the service you specify should be your form type ( CSV2TagsType ), not your transformer ( CSV2TagsTransformer ), because it is the form type that is used by the form builder. Since the form builder expects AbstractType , it will not work with your service definition, since the data converter is not AbstractType . As @ greg0ire said, you should tag your own form type with the form.type tag.

 services: jm.blog.csv2tagsType: class: JM\BlogBundle\Form\Type\CSV2TagsType arguments: ["@doctrine.orm.entity_manager"] tags: - { name: form.type, alias: csv2tags } 

The value returned by the getName function in your custom form view must match the nickname you specified ( cvs2tags ) or the specified service identifier ( jm.blog.csv2tagsType ). In this way, Symfony can find your own type. It tries to find the service identifier specified by the getName() method.

For you data converter, there is a problem. You are executing new CSV2TagsTransformer() , but you are not passing an object manager. This will result in an error. You cannot do it this way because there is no way to introduce a data transformer into the service path.

What you need to do is enter the object manager in your own form type, and then pass it to the data converter when you create it.

 class CSV2TagsType extends AbstractType { protected $em; public function __construct(EntityManager $em) { $this->em = $em; } public function buildForm(FormBuilder $builder, array $opts) { $builder->appendClientTransformer(new CSV2TagsTransformer($this->em)); } // Rest of class } 

Thus, you enter the object manager into your form type, which is possible because the form type is defined as a service. And in the form type, you create an instance of the data transformer and pass the constructor the object manager that was entered into the form type.

Another way is to declare you the data converter as a service, and then type it into the form type. Thus, you yourself do not create a data transformer, but use the one that is entered in the form type constructor. So, if you do not need an object manager in the form type, you can omit it. Here is an example of this alternative:

 services: jm.blog.csv2tagsTransformer: class: JM\BlogBundle\Form\DataTransformer\CSV2TagsTransformer arguments: ["@doctrine.orm.entity_manager"] jm.blog.csv2tagsType: class: JM\BlogBundle\Form\Type\CSV2TagsType arguments: ["@jm.blog.csv2tagsTransformer"] tags: - { name: form.type, alias: csv2tags } class CSV2TagsType extends AbstractType { protected $transformer; public function __construct(CSV2TagsTransformer $transformer) { $this->transformer= $transformer; } public function buildForm(FormBuilder $builder, array $opts) { $builder->appendClientTransformer($this->transformer); } // Rest of class } 

Here's a short summary of the answers to your question:

  • It is right.
  • There is no alias for the transformer service. But, as @ greg0ire said, you need to define a service for your form type. The getName() function should return the identifier that should be used. This can be a specific alias or service identifier. Usually people use an alias as the value returned by getName .
  • It is wrong to do new CSV2TagsTransformer() , because in this way you do not send the entity manager to your class, and since it cannot be null, it will not work in PHP.

Hope this helps.

Respectfully,
Matt

+3
source

As for your main problem, in your services.yml file you should mark your service as form.type , for example:

 services: jm.blog.csv2tagsTransformer: class: JM\BlogBundle\Form\DataTransformer\CSV2TagsTransformer arguments: ["@doctrine.orm.entity_manager"] tags: - { name: form.type, alias: csv2tags } 

For other problems, I have no idea.

+1
source

Source: https://habr.com/ru/post/1210013/


All Articles