I have a Symfony2 form field of type collection
, where the collection items are of the entity
type. I use Symfony 2.7.
So far it works, but in this case, I have to apply a model data transformer to those collection items as described in the Symfony Cookbook. I use this code snippet:
<?php
$builder
->add(
$builder
->create('items', 'collection', array(
'type' => 'entity',
'options' => array(
'class' => 'AppBundle:Item',
'property' => 'name',
'label' => 'Item',
),
'label' => 'Items',
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'prototype' => true,
'required' => false,
))
// $options['em'] is the entity manager
->addModelTransformer(new ItemToNumberTransformer($options['em']))
)
;
Unfortunately, this applies the model transformer to the whole collection and not one Item item of it. As a workaround, I modified the transformer to also work with arrays of items/ids instead of only a single item/id, but this kinda looks like the wrong place to handle this. Seems to me as if this is more of a syntactical problem.
Does anybody know how to apply model transformers to each item of a collection? Or ca anybody confirm this is simply not possible due to a limitaion in the Symfony framework?
I'd say instead of creating a collection
of entity
types, you need to make your own type.
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityManager;
/* Other use statements */
class ItemEntityType extends AbstractType
{
/**
* @var \Doctrine\ORM\EntityManager
*/
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addModelTransformer(new ItemToNumberTransformer($this->em));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'class' => 'AppBundle:Item',
'property' => 'name',
'label' => 'Item',
));
}
public function getParent()
{
return 'entity';
}
public function getName()
{
return 'appbundle_item_entity';
}
}
Then define this as a service
app/config/services.yml
services:
form.type.model.item_entity:
class: AppBundle\Form\Type\ItemEntityType
arguments: ["@doctrine.orm.entity_manager"]
tags:
- {name: form.type, alias: appbundle_item_entity}
And now you can specify this as the type for your collection
$builder
->create('items', 'collection', array(
'type' => 'appbundle_item_entity'
'label' => 'Items',
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'prototype' => true,
'required' => false,
))
Disclosure: I haven't tested this but it should work.
You should create a Type for your Item entity, apply the transformer to it, and then use it as a type for your collection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With