Yep. The answer was nested CollectionType
forms and a custom query builder in the final form (for some reason it was calling all of the Variant
objects in the DB, rather than using the ones associated to the parsed VariantGroup
object:
Main product form
class ComplexProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Render the variant sets based on the parsed product
$builder
->add('variantSets', CollectionType::class, [
'entry_type' => VariantSetComplexProductType::class,
'label'=> false,
'by_reference' => true,
] );
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
"data_class" => Product::class,
));
}
}
Render the products Variant Sets: (to get the correct VariantGroups
associated to the main products VarianSet
objects)
class VariantSetComplexProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Render the groups based on the Variant sets
$builder
->add( 'label' )
->add( 'variantGroups', CollectionType::class, [
'entry_type' => VariantGroupComplexProductType::class,
'label'=> false,
'by_reference' => true
] )
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults( [
'data_class' => VariantSet::class,
] )
;
}
}
Render the Variant Sets VariantGroups
with its Variants
in a dropdown:
The drop down of Variant
objects needs to be done in a FromEvent
using the query_builder
options, as otherwise I had an issue where all the Variant
objects were being called in the DB.
There need to be a check to make sure only the correct Variant
objects were called based on the parsed VariantGroup
.
class VariantGroupComplexProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Render the drop downs based on the Parsed variant group
$builder
->add( 'label' )
// Rendering of the drop down must be done after the previous form data is available
->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'preSetData']);
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults( [
'data_class' => VariantGroup::class,
] );
}
public function preSetData(FormEvent $event)
{
$form = $event->getForm();
/** @var VariantGroup $child */
$child = $event->getData();
$form
->add('variants', EntityType::class, array(
'class' => Variant::class,
'by_reference' => true,
'query_builder' => function (EntityRepository $er) use ( $child ) {
return $er->createQueryBuilder('u')
->where('u.variant_group = :variant_group')
->setParameter('variant_group', $child )
->orderBy('u.label', 'DESC');
},
'choice_label' => 'label',
));
}
}