I'm developing a e-commerce system with customizable products. Each product may have some options that, for its part, may have one or many values selected by consumer. I can't use the variant approach due the high level of customization of my users (some products could have more than 1M of variants), so I need persist the option combination chosen by costumer.
The form options are assembled dynamically once each product may have distinct options. This form should transform the user choice into a storable structure for a relational database.
Basically, it's my scenario (my attempt):
- Product
- Option
- OptionValue
- ProductOption
- Order
- OrderItem
- OrderItemOption
Fixture:
- Option: 1#Salad
- Values: 1#Tomato, 2#Lettuce, 3#Pickles, 3#Carrot
- Product: Hamburger
- ProductOption: 1#Salad
- Values: 1#Tomato, 2#Lettuce, Picles
My target is something like:
class OrderItemType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$field = $builder->create('options', new OptionPickerType(), ['options' => $options['product']->getOptions()]);
$field->addModelTransformation(new FixOptionIndexTransformer());
$builder->add($field);
}
}
class OptionPickerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
foreach ($options['options'] as $productOption) {
$name = $productOption->getId();
$builder->add($name, 'choice', array(
'choice_list' => new ObjectChoiceList($productOption->getValues(), 'label', array(), null, 'id'),
'multiple' => true,
'cascade_validation' => true,
'property_path' => '['.$name.']'
));
}
}
}
$form = $factory->create(new OrderItemType(), ['product' => $product]);
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()) {
$item = $form->getItem(); // A collection of ItemOption filled with the OptionValue picked out from Choice field
}
}
This configuration will return a collection of arrays of OptionValue as expected. In fact it isn't enough for my purposes. What I really need is a flatten collection with all chosen values more some extra data:
class ItemOption
{
protected $item;
protected $productOption;
protected $option; // $productOption->getName()
protected $optionValue;
protected $value; // / $optionValue->getLabel()
}
As you can see, the value of Choice field in fact is inside the ItemOption.
After some days trying, I could not figure out how to do this or even think in other approach.
Can you help me?