Skip to content

Instantly share code, notes, and snippets.

@khusseini
Created May 21, 2020 17:16
Show Gist options
  • Save khusseini/e0eaddc1cf2c709252621e2f11054c95 to your computer and use it in GitHub Desktop.
Save khusseini/e0eaddc1cf2c709252621e2f11054c95 to your computer and use it in GitHub Desktop.
<?php
namespace App\Form\Extension;
use CoreShop\Bundle\OrderBundle\Form\Type\CartItemType;
use CoreShop\Component\Core\Model\CartItemInterface;
use Pimcore\Model\DataObject\AbstractObject;
use Pimcore\Model\DataObject\CoreShopProduct;
use Pimcore\Model\DataObject\Objectbrick\Data\AbstractData;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
class CartItemTypeExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$data = $event->getData();
if (!$data instanceof CartItemInterface) {
return;
}
$product = $data->getProduct();
if (!$product instanceof CoreShopProduct) {
return;
}
/** @var CoreShopProduct[] $variants */
$variants = $product->getChildren([AbstractObject::OBJECT_TYPE_VARIANT]);
if (!\count($variants)) {
return;
}
$fields = [];
$getters = $product->getOptions()->getBrickGetters();
foreach ($variants as $variant) {
$onHand = $variant->getOnHand();
if (!$onHand) {
continue;
}
$variantOptions = $variant->getOptions();
if (!$variantOptions) {
continue;
}
$variantOptionDefinitions = $variantOptions->getItemDefinitions();
foreach ($getters as $getter) {
$call = [$variantOptions, $getter];
/** @var AbstractData $variantObjectBrick */
$variantObjectBrick = \call_user_func($call);
if (!$variantObjectBrick) {
continue;
}
$childFields = $variantOptionDefinitions[
$variantObjectBrick->getType()
]->getFieldDefinitions();
foreach ($childFields as $fieldDefinition) {
$fieldName = $fieldDefinition->getName();
$label = $fieldDefinition->getTitle();
if (!isset($fields[$fieldName])) {
$fields[$fieldName] = [
'options' => [],
'fieldname' => $variantObjectBrick->getType().'_'.$fieldName,
'has_options' => false,
'label' => $label,
];
}
$value = $variantObjectBrick->getValueForFieldName($fieldName);
if ($value) {
$fields[$fieldName]['options'][$value] = $value;
$fields[$fieldName]['has_options'] = true;
}
}
}
}
$builder = $event->getForm();
foreach ($fields as $field) {
if (!$field['has_options']) {
continue;
}
$builder->add($product->getOptions()->getFieldname().'_'.strtolower($field['fieldname']), ChoiceType::class, [
'choices' => $field['options'],
'multiple' => false,
'expanded' => false,
'mapped' => false,
'label' => $field['label'],
]);
}
});
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
$data = $event->getData();
if (!$data instanceof CartItemInterface) {
return;
}
$product = $data->getProduct();
if (!$product instanceof CoreShopProduct) {
return;
}
/** @var CoreShopProduct[] $variants */
$variants = $product->getChildren([AbstractObject::OBJECT_TYPE_VARIANT]);
if (!\count($variants)) {
return;
}
$options = $product->getOptions();
$fields = $event->getForm()->all();
$formData = [];
foreach ($fields as $name => $field) {
if (0 !== strpos($name, $options->getFieldname())) {
continue;
}
$n = substr($name, \strlen($options->getFieldname()) + 1);
$n = explode('_', $n);
if (!isset($formData[$n[0]])) {
$formData[$n[0]] = [];
}
$formData[$n[0]][$n[1]] = $field->getData();
}
if (!\count($formData)) {
return;
}
$getters = $options->getBrickGetters();
$types = $options->getAllowedBrickTypes();
$map = array_combine($types, $getters);
$foundVariant = null;
foreach ($variants as $variant) {
if ($foundVariant) {
break;
}
$variantOptions = $variant->getOptions();
$defs = $variantOptions->getItemDefinitions();
foreach ($defs as $name => $definition) {
if (!isset($formData[$name])) {
continue;
}
$obdata = $formData[$name];
foreach ($obdata as $key => $value) {
$getter = $map[$name];
$valueGetter = 'get'.ucfirst($key);
$variantValue = $variantOptions->$getter();
$variantValue = $variantValue->$valueGetter();
if (!$foundVariant && $variantValue == $value) {
$foundVariant = $variant;
}
if ($foundVariant
&& $variantValue != $value
) {
$foundVariant = null;
}
}
}
}
if ($foundVariant) {
$data->setProduct($foundVariant);
}
});
}
public static function getExtendedTypes()
{
return [CartItemType::class];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment