I have never been too fond of DataTransformers
and therefore I would not use them here, but they can be useful.
In this particular case, I would go for FormEvents
and build the form dynamically, based on the data your entity contains.
WebShopItemType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
.....
->add('prices', 'collection', array(
'type' => new WebshopPricesType()
));
}
WebshopPricesType
class WebshopPricesType extends AbstractType{
.....
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Dynamically build form fields, **after** the data has been set
$builder->addEventListener(FormEvents::POST_SET_DATA, function(FormEvent $event) use ($builder){
/** @var $data WebshopItemPrice **/
$data = $event->getData();
$builder->add('price', 'money', array('currency' => $data->getCurrency()));
});
}
public function setDefaults(OptionsResolverInterface $resolver){
$resolver->setDefault(array(
'data_class' => 'bundlePath\Entity\WebshopItemPrice'
));
}
.....
}
Given that, let's glue it altogether:
public class SomeController extends Controller{
public function insertAction(){
$item = new WebshopItem();
// be sure to initialize the $prices with new `ArrayCollection`
// in order to avoid NullPointerException
// Also, be sure to bind WebshopItemPrice::$item
$item
->addPrice(new WebshopItemPrice('EUR', 0))
->addPrice(new WebshopItemPrice('USD', 0))
->addPrice(new WebshopItemPrice('GBP', 0));
// this is where POST_SET_DATA gets fired
$form = $this->createForm(new WebShopItemType(), $item);
// form is ready
}
public function editAction(){
$item = ... // fetch or whatever, be sure to fetch prices as well
// this is where POST_SET_DATA gets fired
$form = $this->createForm(new WebShopItemType(), $item);
// form is ready
}
}
I have put this together in Notepad++ and I not sure if I did some typos but as far as logic is concerned - it should work ;)