custom/plugins/HuebertAddOrderAttributes/src/Subscriber/ProductSubscriber.php line 186

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace HuebertAddOrderAttributes\Subscriber;
  3. use HuebertAddOrderAttributes\Core\Content\Attribute\AttributeEntity;
  4. use Shopware\Core\Checkout\Cart\Cart;
  5. use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
  6. use Shopware\Core\Checkout\Cart\Event\BeforeLineItemRemovedEvent;
  7. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  8. use Shopware\Core\Content\Media\MediaEntity;
  9. use Shopware\Core\Content\Product\ProductEntity;
  10. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  11. use Shopware\Core\Framework\Context;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  14. use Shopware\Core\System\SystemConfig\SystemConfigService;
  15. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPage;
  16. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
  17. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  18. use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
  19. use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPage;
  20. use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
  21. use Symfony\Component\HttpFoundation\ParameterBag;
  22. use Symfony\Component\HttpFoundation\Session\Session;
  23. use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
  24. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  25. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  26. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  27. use Shopware\Core\Framework\Uuid\Uuid;
  28. use Shopware\Storefront\Page\Product\ProductPage;
  29. use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
  30. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  31. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  32. use Symfony\Component\HttpFoundation\RequestStack;
  33. class ProductSubscriber implements EventSubscriberInterface
  34. {
  35.     /**
  36.      * @var EntityRepositoryInterface
  37.      */
  38.     private $categoryRepository;
  39.     /**
  40.      * @var RequestStack
  41.      */
  42.     private $requestStack;
  43.     /**
  44.      * @var SystemConfigService
  45.      */
  46.     private $pluginConfig;
  47.     /**
  48.      * @var Session
  49.      */
  50.     private $session;
  51.     /**
  52.      * @var EntityRepositoryInterface
  53.      */
  54.     private $attributeRepository;
  55.     /**
  56.      * @var EntityRepositoryInterface
  57.      */
  58.     private $productRepository;
  59.     /**
  60.      * @var EntityRepositoryInterface
  61.      */
  62.     private $dependencyepository;
  63.     /**
  64.      * @var EntityRepositoryInterface
  65.      */
  66.     private $mediaEntity;
  67.     /**
  68.      * @var EntityRepositoryInterface
  69.      */
  70.     private $productStreamRepository;
  71.     /**
  72.      * @param EntityRepositoryInterface $categoryRepository
  73.      * @param RequestStack $requestStack
  74.      * @param SystemConfigService $pluginConfig
  75.      * @param Session $session
  76.      * @param EntityRepositoryInterface $attributeRepository
  77.      * @param EntityRepositoryInterface $productRepository
  78.      * @param EntityRepositoryInterface $mediaEntity
  79.      * @param EntityRepositoryInterface $dependencyepository
  80.      * @param EntityRepositoryInterface $productStreamRepository
  81.      */
  82.     public function __construct(
  83.         EntityRepositoryInterface $categoryRepository,
  84.         RequestStack $requestStack,
  85.         SystemConfigService $pluginConfig,
  86.         Session $session,
  87.         EntityRepositoryInterface $attributeRepository,
  88.         EntityRepositoryInterface $productRepository,
  89.         EntityRepositoryInterface $mediaEntity,
  90.         EntityRepositoryInterface $dependencyepository,
  91.         EntityRepositoryInterface $productStreamRepository
  92.     )
  93.     {
  94.         $this->categoryRepository $categoryRepository;
  95.         $this->requestStack $requestStack;
  96.         $this->pluginConfig $pluginConfig;
  97.         $this->session $session;
  98.         $this->attributeRepository $attributeRepository;
  99.         $this->productRepository $productRepository;
  100.         $this->mediaEntity $mediaEntity;
  101.         $this->dependencyepository $dependencyepository;
  102.         $this->productStreamRepository $productStreamRepository;
  103.     }
  104.     /**
  105.      * @inheritDoc
  106.      */
  107.     public static function getSubscribedEvents()
  108.     {
  109.         return [
  110.             ProductPageCriteriaEvent::class => 'onProductCriteria',
  111.             ProductPageLoadedEvent::class => 'onProductPageLoaded',
  112.             CheckoutFinishPageLoadedEvent::class => 'onCheckoutFinish',
  113.             BeforeLineItemAddedEvent::class => 'onLineItemAdded',
  114.             BeforeLineItemRemovedEvent::class => 'beforeLineItemRemoved',
  115.             CheckoutCartPageLoadedEvent::class => 'onCartPage',
  116.             OffcanvasCartPageLoadedEvent::class => 'onOffcanvasCartPage',
  117.             CheckoutConfirmPageLoadedEvent::class => 'onCheckoutPage'
  118.         ];
  119.     }
  120.     /**
  121.      * @param ProductPageCriteriaEvent $event
  122.      * @return void
  123.      */
  124.     public function onProductCriteria(ProductPageCriteriaEvent $event): void
  125.     {
  126.         $event->getCriteria()->addAssociations(['attributes''categories''streams''streams.extensions.attributes']);
  127.     }
  128.     /**
  129.      * @param CheckoutFinishPageLoadedEvent $event
  130.      * @return void
  131.      */
  132.     public function onCheckoutFinish(CheckoutFinishPageLoadedEvent $event)
  133.     {
  134.         $session $this->session->all();
  135.         unset($session['huebert_attributes']);
  136.         $this->session->replace($session);
  137.         /**
  138.          * @var CheckoutCartPage $page
  139.          */
  140.         $page $event->getPage();
  141.         $salesChannelId $event->getSalesChannelContext()->getSalesChannelId();
  142.         $enablePrices $this->pluginConfig->get('HuebertAddOrderAttributes.config.enablePrices'$salesChannelId);
  143.         $separatedQuantity $this->pluginConfig->get('HuebertAddOrderAttributes.config.separatedQuantity'$salesChannelId);
  144.         $page->assign([
  145.             'enabledPrices' => $enablePrices,
  146.             'separatedQuantity' => $separatedQuantity
  147.         ]);
  148.     }
  149.     /**
  150.      * @param ProductPageLoadedEvent $event
  151.      * @return void
  152.      */
  153.     public function onProductPageLoaded(ProductPageLoadedEvent $event): void
  154.     {
  155.         /**
  156.          * @var ProductPage $page
  157.          */
  158.         $page $event->getPage();
  159.         $salesChannelId $event->getSalesChannelContext()->getSalesChannelId();
  160.         $enablePrices $this->pluginConfig->get('HuebertAddOrderAttributes.config.enablePrices'$salesChannelId);
  161.         $separatedQuantity $this->pluginConfig->get('HuebertAddOrderAttributes.config.separatedQuantity'$salesChannelId);
  162.         $previewImage $this->pluginConfig->get('HuebertAddOrderAttributes.config.previewImage'$salesChannelId);
  163.         $widthImage $this->pluginConfig->get('HuebertAddOrderAttributes.config.imageWidth'$salesChannelId);
  164.         $page->assign([
  165.             'session' => $this->session->all(),
  166.             'enabledPrices' => $enablePrices,
  167.             'separatedQuantity' => $separatedQuantity,
  168.             'previewImage' => $previewImage,
  169.             'imageWidth' => $widthImage
  170.         ]);
  171.         $product $page->getProduct();
  172.         $extensions $product->getExtensions();
  173.         $attributesFromCategories = new EntityCollection();
  174. //        $categoryDependecyAttributes = new EntityCollection();
  175.         $attributeIds = [];
  176.         $attributeExists = (!empty($extensions['attributes']));
  177.         $attributeHasEntry false;
  178. //        if(array_key_exists('attributes', $extensions))  {
  179.         $attributesFromCategories $this->checkIfCategoriesHaveAttributes($product$event->getContext(), $salesChannelId);
  180.         $attributesChild $this->applyAttributesOnSubcategories($product$event->getContext(), $event->getSalesChannelContext()->getSalesChannelId());
  181.         if($attributeExists) {
  182.             if(count($extensions['attributes']->getElements())) {
  183. //                $attributeHasEntry = true;
  184.                 $attributesFromProduct $extensions['attributes'];
  185. //                $attributesFromCategories = $this->sortAttributeEntities($attributesFromCategories);
  186. //                $product->assign([
  187. //                    'attributesFromProduct' => $attributesFromProduct
  188. //                ]);
  189.                 if($attributesFromProduct) {
  190.                     foreach ($attributesFromProduct as $child) {
  191.                         $attributesFromCategories->add($child);
  192.                     }
  193.                 }
  194.             }
  195.         }
  196.         if($attributesChild != null) {
  197.             foreach ($attributesChild as $child) {
  198.                 $attributesFromCategories->add($child);
  199.             }
  200.         }
  201.         $attributesFromDynamic $this->getAttributesByProductStream($product$event->getContext(), $attributesFromCategories);
  202.         if($attributesFromDynamic != null) {
  203.             foreach ($attributesFromDynamic as $child) {
  204.                 $attributesFromCategories->add($child);
  205.             }
  206.         }
  207.         $productStreamDependencies = new EntityCollection();
  208.         $productStreamDependencies $this->getProductStreamDependecnies($product$event->getContext(), $attributesFromDynamic);
  209.         if($productStreamDependencies->count() > 0) {
  210.             foreach ($productStreamDependencies as $attribute) {
  211.                 if ($attribute->hasExtension('dependencies')) {
  212.                     foreach ($attribute->getExtension('dependencies') as $key => $value) {
  213.                         if ($attributesFromCategories->has($key)) {
  214.                             $attributesFromCategories->remove($key);
  215.                         }
  216.                     }
  217.                 }
  218.             }
  219.         }
  220. //                }
  221. //        }
  222.         if($attributesFromCategories->count() > || $productStreamDependencies->count() > 0) {
  223.             $categoryDependecyAttributes $this->getCategoryAttributes($product->getCategories(), $event->getContext(), $attributesFromCategories);
  224.             $applyDependencyOnSubcategories $this->applyDependencyOnSubcategories($product$event->getContext(), $salesChannelId);
  225.             if($applyDependencyOnSubcategories != null) {
  226.                 foreach ($applyDependencyOnSubcategories as $dependency) {
  227.                     $categoryDependecyAttributes->add($dependency);
  228.                 }
  229.             }
  230.             $applyDependencyOnParent $this->applyDependencyOnParentCategories($product$event->getContext(),$salesChannelId);
  231.             if($applyDependencyOnParent != null) {
  232.                 foreach ($applyDependencyOnParent as $dependency) {
  233.                     $categoryDependecyAttributes->add($dependency);
  234.                 }
  235.             }
  236.             if($categoryDependecyAttributes) {
  237.                 foreach ($categoryDependecyAttributes as $attribute) {
  238.                     if ($attribute->hasExtension('dependencies')) {
  239.                         foreach ($attribute->getExtension('dependencies') as $key => $value) {
  240.                             if ($attributesFromCategories->has($key)) {
  241.                                 $attributesFromCategories->remove($key);
  242.                             }
  243.                         }
  244.                     }
  245.                 }
  246.             }
  247.             $criteria = new Criteria();
  248.             $productId $product->getId();
  249.             if($product->getParentId()){
  250.                 $productId $product->getParentId();
  251.             }
  252.             $criteria->addFilter(new EqualsFilter('productId'$productId));
  253.             $productDependencies $this->dependencyepository->search($criteria$event->getContext())->getEntities();
  254.             $dependenciesAttributes = new EntityCollection();
  255.             foreach ($productDependencies as $dependency ){
  256.                 $dependencies = new EntityCollection();
  257.                 $dependenciesAttributes->add($dependency);
  258.                     foreach ($dependency['attributes'] as $attr) {
  259.                         if ( $attributesFromCategories->has($attr)) {
  260.                             $dependencies->add($attributesFromCategories->get($attr));
  261.                             $attributesFromCategories->remove($attr);
  262.                         }
  263.                     }
  264.                     $dependenciesAttributes->get($dependency->getId())->addExtension('dependencies'$dependencies);
  265.             }
  266.             $attributesFromCategories $this->sortAttributeEntities($attributesFromCategories);
  267.             $product->assign([
  268.                 'attributesFromCategories' => $attributesFromCategories,
  269.                 'dependenciesAttributes' => $dependenciesAttributes,
  270.                 'categoryAttributes' => $categoryDependecyAttributes,
  271.                 'productStreamDependencies' => $productStreamDependencies
  272.             ]);
  273.         }
  274.     }
  275.     /**
  276.      * @param BeforeLineItemAddedEvent $event
  277.      * @return void
  278.      */
  279.     public function onLineItemAdded(BeforeLineItemAddedEvent $event)
  280.     {
  281.         $salesChannelId $event->getSalesChannelContext()->getSalesChannelId();
  282.         $lineItem $event->getLineItem();
  283.         $lineItemId $lineItem->getId();
  284.         $cart $event->getCart();
  285.         $attributes = [];
  286.         $session $this->session;
  287.         $sessionVars $this->session->all();
  288.         $request $this->requestStack->getCurrentRequest();
  289.         /**
  290.          * @var ParameterBag $requestBag
  291.          */
  292.         $requestBag $request->request;
  293.         $requestValues $requestBag->all();
  294.         if(!empty($requestValues['lineItems'])) {
  295.             $enablePrices $this->pluginConfig->get('HuebertAddOrderAttributes.config.enablePrices'$salesChannelId);
  296.             $separatedQuantity $this->pluginConfig->get('HuebertAddOrderAttributes.config.separatedQuantity'$salesChannelId);
  297.             $lineItem $requestValues['lineItems'];
  298.             foreach ($lineItem as $item) {
  299.                 $firstItem $item;
  300.                 break;
  301.             }
  302.             $addedQuantity $firstItem['quantity'];
  303.             if ((isset($requestValues['attributes']) && array_key_first($requestValues['attributes']) === $lineItemId) || (isset($requestValues['dependencies']) && array_key_first($requestValues['dependencies']) === $lineItemId)) {
  304.                 $uuid Uuid::randomHex();
  305.                 $attributesInRequest array_shift($requestValues['attributes']);
  306.                 $attributeEntities $this->getEntiesOfAttributes($attributesInRequest$event->getContext());
  307.                 $dependenciesEntitiesFormat = [];
  308.                 if (isset($requestValues['dependencies'])) {
  309.                     $dependenciesEntitiesFormat $this->formatDependencies($requestValues['dependencies'], $lineItemId);
  310.                 }
  311.                 //IF QUANTITY IS NOT SEPARATED
  312.                 if($enablePrices && !$separatedQuantity) {
  313.                     $arryAttributes = [];
  314.                     foreach ($attributeEntities as $key => $attribute) {
  315.                         $lineItemParam $this->requestStack->getCurrentRequest()->get('lineItems');
  316.                         $this->updateLineItem($lineItemParam$event->getLineItem());
  317.                         $arryAttributes[$lineItemId][$uuid][$key] = [
  318.                             'name' => $attribute['name'],
  319.                             'order' => $attribute['entity']->getOrder()
  320.                         ];
  321.                         if (isset($attribute['value']['attributes_with_prices'])) {
  322.                             foreach ($attribute['value']['attributes_with_prices'] as $key => $value) {
  323.                                 $attributeName $key;
  324.                                 $payloadAttribute = [];
  325.                                 if (is_array($value)) {
  326.                                     foreach ($value as $k => $v) {
  327.                                         $payloadAttribute[$attributeName][$k]['price'] = $v;
  328.                                     }
  329.                                 } else {
  330.                                     $array explode('--'$value);
  331.                                     $payloadAttribute[$attributeName][$array[0]]['price'] = $array[1];
  332.                                 }
  333.                                 $arryAttributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value']['attributes_with_prices'] = $payloadAttribute;
  334.                             }
  335.                         } else {
  336.                             //FIELD WITHOUT PRICES
  337.                             if(isset($attribute['value']['media'])){
  338.                                 if($attribute['value']['media'] == "" || $attribute['value']['media'] == null){
  339.                                     unset($arryAttributes[$lineItemId][$uuid][$attribute['entity']->getId()]);
  340.                                 }
  341.                                 if($attribute['value']['media']!=null){
  342.                                     $criteria = new Criteria();
  343.                                     $criteria->addFilter(new EqualsFilter('id'$attribute['value']['media']));
  344.                                     $mediaEntityVar $this->mediaEntity->search($criteria$event->getContext())->first();
  345.                                     $arryAttributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value']['media'] = $mediaEntityVar;
  346.                                 }
  347.                             }else {
  348.                                 $arryAttributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value'] = $attribute['value'];
  349.                                 if(isset($attribute['value'])) {
  350.                                     if($attribute['value']== "" || $attribute['value'] == null){
  351.                                         unset($arryAttributes[$lineItemId][$uuid][$attribute['entity']->getId()]);
  352.                                     }
  353.                                 }
  354.                             }
  355.                         }
  356.                         $event->getLineItem()->setPayloadValue('huebert_attributes'$arryAttributes);
  357.                         $event->getLineItem()->setPayloadValue('dependencies'$dependenciesEntitiesFormat);
  358.                     }
  359.                 } else {
  360.                     if ($this->checkSessionForExistingAttributes($sessionVars)) {
  361.                         $attributes $sessionVars['huebert_attributes'];
  362.                         if ($uuidOfSame $this->checkForSameAttributePair($attributeEntities$attributes$lineItemId$salesChannelId)) {
  363.                             if (!empty($attributes[$lineItemId][$uuidOfSame]['quantity'])) {
  364.                                 if (count($attributes[$lineItemId][$uuidOfSame]) > 1) {
  365.                                     $attributes[$lineItemId][$uuidOfSame]['quantity'] = ((int)$attributes[$lineItemId][$uuidOfSame]['quantity'] + (int)$addedQuantity);
  366.                                 }
  367.                             } else {
  368.                                 $attributes[$lineItemId][$uuidOfSame]['quantity'] = $addedQuantity;
  369.                             }
  370.                             $this->session->set('huebert_attributes'$attributes);
  371.                         } else {
  372.                             foreach ($attributeEntities as $key => $attribute) {
  373.                                 if (!empty($attribute)) {
  374.                                     $attributes[$lineItemId][$uuid][$key] = [
  375.                                         'name' => $attribute['name'],
  376.                                         'order' => $attribute['entity']->getOrder(),
  377.                                         'value' => $attribute['value']
  378.                                     ];
  379.                                     if (is_array($attribute['value'])) {
  380.                                         //IF QUANTITY IS NOT SEPARATED
  381.                                         if ($enablePrices && !$separatedQuantity) {
  382.                                             if (isset($attribute['value']['attributes_with_prices'])) {
  383.                                                 foreach ($attribute['value']['attributes_with_prices'] as $key => $value) {
  384.                                                     $attributeName $key;
  385.                                                     $payloadAttribute = [];
  386.                                                     if (is_array($value)) {
  387.                                                         foreach ($value as $k => $v) {
  388.                                                             $payloadAttribute[$attributeName][$k]['price'] = $v;
  389.                                                         }
  390.                                                     } else {
  391.                                                         $array explode('--'$value);
  392.                                                         $payloadAttribute[$attributeName][$array[0]]['price'] = $array[1];
  393.                                                     }
  394.                                                     $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value']['attributes_with_prices'] = $payloadAttribute;
  395.                                                 }
  396.                                             } else {
  397.                                                 //IF QUANTITY IS NOT SEPARATED AND NOT WITH PRICES
  398.                                                 if(isset($attribute['value']['media'])){
  399.                                                     if($attribute['value']['media'] == "" || $attribute['value']['media'] == null){
  400.                                                         unset( $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]);
  401.                                                     }                                                    if($attribute['value']['media']!=null){
  402.                                                         $criteria = new Criteria();
  403.                                                         $criteria->addFilter(new EqualsFilter('id'$attribute['value']['media']));
  404.                                                         /**
  405.                                                          * @var MediaEntity
  406.                                                          */
  407.                                                         $mediaEntityVar $this->mediaEntity->search($criteria$event->getContext())->first();
  408.                                                         $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value']['media'] = $mediaEntityVar;
  409.                                                     }
  410.                                                 }else{
  411.                                                     $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value'] = implode(","$attribute['value']);
  412.                                                 }
  413.                                             }
  414.                                         } else {
  415.                                             //IF QUANTITY IS SEPARATED
  416.                                             if(isset($attribute['value']['media'])){
  417.                                                 if($attribute['value']['media'] == "" || $attribute['value']['media'] == null){
  418.                                                     unset( $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]);
  419.                                                 }
  420.                                                 if($attribute['value']['media']!=null){
  421.                                                     $criteria = new Criteria();
  422.                                                     $criteria->addFilter(new EqualsFilter('id'$attribute['value']['media']));
  423.                                                     /**
  424.                                                      * @var MediaEntity
  425.                                                      */
  426.                                                     $mediaEntityVar $this->mediaEntity->search($criteria$event->getContext())->first();
  427.                                                     $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value']['media'] = $mediaEntityVar;
  428.                                                 }
  429.                                             }else{
  430.                                                 $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value'] = implode(","$attribute['value']);
  431.                                             }
  432.                                         }
  433.                                     }
  434.                                 }
  435.                             }
  436.                             if (!empty($attributes[$lineItemId][$uuid])) {
  437.                                 $attributes[$lineItemId][$uuid]['quantity'] = $addedQuantity;
  438.                                 $this->session->set('huebert_attributes'$attributes);
  439.                             }
  440.                         }
  441.                     } else {
  442.                         $isEmpty true;
  443.                         foreach ($attributeEntities as $attribute) {
  444.                             if (!empty($attribute['value'])) {
  445.                                 $attributes[$lineItemId][$uuid][$attribute['entity']->getId()] = [
  446.                                     'name' => $attribute['name'],
  447.                                     'order' => $attribute['entity']->getOrder(),
  448.                                     'value' => $attribute['value']
  449.                                 ];
  450.                                 if (is_array($attribute['value'])) {
  451.                                     //IF QUANTITY IS NOT SEPARATED
  452.                                     if ($enablePrices && !$separatedQuantity) {
  453.                                         if (isset($attribute['value']['attributes_with_prices'])) {
  454.                                             $lineItemParam $this->requestStack->getCurrentRequest()->get('lineItems');
  455.                                             $product $this->getProduct($event$event->getLineItem());
  456.                                             $this->updateLineItem($lineItemParam$event->getLineItem(), $product);
  457.                                             foreach ($attribute['value']['attributes_with_prices'] as $key => $value) {
  458.                                                 $attributeName $key;
  459.                                                 $payloadAttribute = [];
  460.                                                 if (is_array($value)) {
  461.                                                     foreach ($value as $k => $v) {
  462.                                                         $payloadAttribute[$attributeName][$k]['price'] = $v;
  463.                                                     }
  464.                                                 } else {
  465.                                                     $array explode('--'$value);
  466.                                                     $payloadAttribute[$attributeName][$array[0]]['price'] = $array[1];
  467.                                                 }
  468.                                                 $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value']['attributes_with_prices'] = $payloadAttribute;
  469.                                             }
  470.                                         } else {
  471.                                             //IF QUANTITY IS NOT SEPARATED AND NOT WITH PRICES
  472.                                             if(isset($attribute['value']['media'])){
  473.                                                 if($attribute['value']['media'] == "" || $attribute['value']['media'] == null){
  474.                                                     unset( $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]);
  475.                                                 }
  476.                                                 if($attribute['value']['media']!=null){
  477.                                                     $criteria = new Criteria();
  478.                                                     $criteria->addFilter(new EqualsFilter('id'$attribute['value']['media']));
  479.                                                     /**
  480.                                                      * @var MediaEntity
  481.                                                      */
  482.                                                     $mediaEntityVar $this->mediaEntity->search($criteria$event->getContext())->first();
  483.                                                     $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value']['media'] = $mediaEntityVar;
  484.                                                 }
  485.                                             }else{
  486.                                                 $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value'] = implode(","$attribute['value']);
  487.                                             }
  488.                                         }
  489.                                     } else {
  490.                                         //IF QUANTITY IS SEPARATED
  491.                                         if(isset($attribute['value']['media'])){
  492.                                             if($attribute['value']['media'] == "" || $attribute['value']['media'] == null){
  493.                                                 unset( $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]);
  494.                                             }
  495.                                             if($attribute['value']['media']!=null){
  496.                                                 $criteria = new Criteria();
  497.                                                 $criteria->addFilter(new EqualsFilter('id'$attribute['value']['media']));
  498.                                                 /**
  499.                                                  * @var MediaEntity
  500.                                                  */
  501.                                                 $mediaEntityVar $this->mediaEntity->search($criteria$event->getContext())->first();
  502.                                                 $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value']['media'] = $mediaEntityVar;
  503.                                             }
  504.                                     }else{
  505.                                             $attributes[$lineItemId][$uuid][$attribute['entity']->getId()]['value'] = implode(","$attribute['value']);
  506.                                         }
  507.                                     }
  508.                                 }
  509.                                 $isEmpty false;
  510.                             }
  511.                         }
  512.                         if (!$isEmpty) {
  513.                             $attributes[$lineItemId][$uuid]['quantity'] = $addedQuantity;
  514.                             $this->session->set('huebert_attributes'$attributes);
  515.                         }
  516.                     }
  517.                 }
  518.             }
  519.             if (!empty($attributes)) {
  520.                 if($enablePrices && !$separatedQuantity) {
  521.                 } else {
  522.                     $this->assignAttributesToLineItems($cart$attributes$dependenciesEntitiesFormat);
  523.                 }
  524.             }
  525. //            if($enablePrices && !$separatedQuantity) {
  526.             if($enablePrices && $separatedQuantity) {
  527.                 //WITH PRICES
  528.                 $lineItem $event->getLineItem();
  529.                 $lineItemParam $this->requestStack->getCurrentRequest()->get('lineItems');
  530.                 $attributesWithPrices null;
  531.                 if($lineItemParam) {
  532.                     if (array_key_exists($lineItem->getId(), $lineItemParam)) {
  533.                         foreach ($lineItemParam[$lineItem->getId()] as $key => $value) {
  534.                             if ($key == 'attributes_with_prices'$attributesWithPrices $value;
  535.                         }
  536.                     }
  537.                     if ($attributesWithPrices) {
  538.                         $product $this->getProduct($event$lineItem);
  539.                         $this->updateLineItem($lineItemParam$lineItem$product);
  540.                         $payloadAttribute = [];
  541.                         foreach ($attributesWithPrices as $key => $value) {
  542.                             $attributeName $key;
  543.                             if(is_array($value)) {
  544.                                 foreach ($value as $k => $v) {
  545.                                     $payloadAttribute[$attributeName][$k]['price'] = $v;
  546.                                     $payloadAttribute[$attributeName][$k]['quantity'] = 1;
  547.                                 }
  548.                             } else {
  549.                                 $array explode('--'$value);
  550.                                 $payloadAttribute[$attributeName][$array[0]]['price'] = $array[1];
  551.                                 $payloadAttribute[$attributeName][$array[0]]['quantity'] = 1;
  552.                             }
  553.                         }
  554.                         $lineItem->setPayloadValue('attributes_with_prices'$payloadAttribute);
  555.                     }
  556.                 }
  557.             }
  558.         }
  559.     }
  560.     /**
  561.      * @param BeforeLineItemAddedEvent $event
  562.      * @param LineItem $lineItem
  563.      * @return ProductEntity
  564.      * @throws InconsistentCriteriaIdsException
  565.      */
  566.     private function getProduct(BeforeLineItemAddedEvent $eventLineItem $lineItem): ProductEntity
  567.     {
  568.         $productCollection $this->productRepository->search(new Criteria([
  569.             $lineItem->getReferencedId()
  570.         ]), $event->getContext());
  571.         if ($productCollection->count() === 1) {
  572.             /** @var ProductEntity $product */
  573.             $product $productCollection->first();
  574.         }
  575.         return $product;
  576.     }
  577.     /**
  578.      * @param array $lineItemParam
  579.      * @param LineItem $lineItem
  580.      * @param ProductEntity $product
  581.      * @return array
  582.      */
  583.     private function updateLineItem(array $lineItemParamLineItem $lineItemProductEntity $product null): array
  584.     {
  585.         //set new ID
  586.         $newId Uuid::randomHex();
  587.         if(isset($lineItemParam[$lineItem->getId()])) {
  588.             $lineItemParam[$newId] = $lineItemParam[$lineItem->getId()];
  589.             $lineItem->setId($newId);
  590.         }
  591.         return $lineItemParam;
  592.     }
  593.     /**
  594.      * @param BeforeLineItemRemovedEvent $event
  595.      * @return void
  596.      */
  597.     public function beforeLineItemRemoved(BeforeLineItemRemovedEvent $event)
  598.     {
  599.         $lineItem $event->getLineItem();
  600.         $lineItemId $lineItem->getId();
  601.         if(!empty($this->session->get('huebert_attributes'))) {
  602.             $attributes $this->session->all();
  603.             unset($attributes['huebert_attributes'][$lineItemId]);
  604.             $this->session->replace($attributes);
  605.         }
  606.     }
  607.     /**
  608.      * @param $session
  609.      * @return bool
  610.      */
  611.     private function checkSessionForExistingAttributes($session): bool
  612.     {
  613.         if(!empty($session['huebert_attributes'])) {
  614.             return true;
  615.         }
  616.         return false;
  617.     }
  618.     /**
  619.      * @param $cart
  620.      * @param $attributes
  621.      * @param $dependenciesEntitiesFormat
  622.      * @return void
  623.      */
  624.     private function assignAttributesToLineItems($cart$attributes$dependenciesEntitiesFormat)
  625.     {
  626.         /**
  627.          * @var Cart $cart
  628.          */
  629.         $lineItems $cart->getLineItems();
  630.         foreach($lineItems as $lineItem) {
  631.             if(!empty($attributes[$lineItem->getId()])) {
  632.                 $payload $lineItem->getPayload();
  633.                 foreach($attributes[$lineItem->getId()] as $key => $attributeContainer) {
  634.                     foreach($attributeContainer as $_key => $attribute) {
  635.                         if(is_array($attribute)) {
  636.                             $attributes[$lineItem->getId()][$key][$_key] = $attribute;
  637.                         }
  638.                     }
  639.                 }
  640.                 $payload['huebert_attributes'] = $attributes[$lineItem->getId()];
  641.                 $lineItem->setPayload($payload);
  642.                 $lineItem->setPayloadValue('dependencies'$dependenciesEntitiesFormat);
  643.             }
  644.         }
  645.     }
  646.     /**
  647.      * @param $product
  648.      * @param $context
  649.      * @param $salesChannelId
  650.      * @return EntityCollection|null
  651.      */
  652.     private function checkIfCategoriesHaveAttributes($product$context$salesChannelId): ?EntityCollection
  653.     {
  654.         $includeParent $this->pluginConfig->get('HuebertAddOrderAttributes.config.includeParentCategory'$salesChannelId);
  655.         $categories $product->getCategories();
  656.         $categoriesCollection = new EntityCollection();
  657.         if(empty($categories)) {
  658.             return $categoriesCollection;
  659.         }
  660.         if(empty($categories->getIds())) {
  661.             return $categoriesCollection;
  662.         }
  663.         $criteria = new Criteria();
  664.         $criteria->addAssociations(['categorys']);
  665.         $criteria->addFilter(new EqualsAnyFilter('categorys.id'$categories->getIds()));
  666.         $categoryResult $this->attributeRepository->search($criteria$context);
  667.         foreach ($categoryResult as $category){
  668.             $categoriesCollection->add($category);
  669.         }
  670.         if($includeParent) {
  671. //            $parentCategoryIds = [];
  672. //            /**
  673. //             * @var CategoryEntity $category
  674. //             */
  675. //            foreach($categoryResult->getEntities() as $category) {
  676. //                $categories->add($category);
  677. //                if(!is_null($category->getParentId())) {
  678. //                    $parentCategoryIds[] = $category->getParentId();
  679. //                }
  680. //            }
  681. //            if(!empty($parentCategoryIds)) {
  682.                 $criteria = new Criteria();
  683.                 $criteria->addFilter(new EqualsAnyFilter('parentId'$categories->getIds()));
  684.                 $result $this->categoryRepository->search($criteria$context)->getIds();
  685.             $criteria = new Criteria();
  686.                 $criteria->addAssociations(['categorys']);
  687.                 $criteria->addFilter(new EqualsAnyFilter('categorys.id'$result));
  688.                 $categoryResults $this->attributeRepository->search($criteria$context);
  689.             foreach ($categoryResults as $category){
  690.                 $categoriesCollection->add($category);
  691.             }
  692. //            }
  693.         }
  694.         return $categoriesCollection;
  695.     }
  696.     /**
  697.      * @param SalesChannelProductEntity $product
  698.      * @param $context
  699.      * @param EntityCollection $attributes
  700.      * @return EntityCollection|null
  701.      */
  702.     private function getAttributesByProductStream(SalesChannelProductEntity $product$contextEntityCollection $attributes): ?EntityCollection
  703.     {
  704.         $attributeIds = [];
  705.         $productId $product->getId();
  706.         if($product->getParentId()) {
  707.             $productId $product->getParentId();
  708.         }
  709.         if($productId){
  710.             $mappingCriteria = new Criteria();
  711.             $mappingCriteria->addFilter(new EqualsFilter('id'$productId));
  712.             $mappingCriteria->addAssociation('productStreams');
  713.             $mappingCriteria->addAssociation('productStreams.attributes');
  714.             $mappingCriteria->addAssociation('productStreams.mapping');
  715.             $product $this->productRepository->search($mappingCriteria$context)->getElements();
  716.             $productStreamsIds = [];
  717.             foreach ($product as $item) {
  718.                 $productStreamsIds $item->getStreamIds();
  719.             }
  720.             if($productStreamsIds) {
  721.                 $criteria = new Criteria();
  722.                 $criteria->addFilter(new EqualsAnyFilter('id'$productStreamsIds));
  723.                 $criteria->addAssociation('attributes');
  724.                 $productStreams $this->productStreamRepository->search($criteria$context);
  725.                 if(!empty($productStreams)) {
  726.                     foreach($productStreams as $productStream) {
  727.                         $attributesExtension $productStream->getExtension('attributes');
  728.                         if($attributesExtension) {
  729.                             /**
  730.                              * @var AttributeEntity $attribute
  731.                              */
  732.                             foreach ($attributesExtension as $attribute) {
  733.                                 if(!in_array($attribute->getId(), $attributeIds)) {
  734.                                     $attributes->add($attribute);
  735.                                     $attributeIds[] = $attribute->getId();
  736.                                 }
  737.                             }
  738.                         }
  739.                     }
  740.                 }
  741.             }
  742.         }
  743.         return $attributes;
  744.     }
  745.     /**
  746.      * @param $attributes
  747.      * @param $context
  748.      * @return array
  749.      */
  750.     private function getEntiesOfAttributes($attributes$context)
  751.     {
  752.         $returnData = [];
  753.         foreach ($attributes as $id => $attribute) {
  754.             /** @var AttributeEntity $entity */
  755.             $entity $this->attributeRepository->search(new Criteria([$id]), $context)->first();
  756.             $returnData[$id] = [
  757.                 'value' => $attribute,
  758.                 'name' => $entity->getName(),
  759.                 'entity' => $entity
  760.             ];
  761.         }
  762.         return $returnData;
  763.     }
  764.     /**
  765.      * @param $attributesInRequest
  766.      * @param $attributes
  767.      * @param $lineItemIdAdded
  768.      * @param $salesChannelId
  769.      * @return false|int|string
  770.      */
  771.     private function checkForSameAttributePair($attributesInRequest$attributes$lineItemIdAdded$salesChannelId)
  772.     {
  773.         if(empty($attributesInRequest) || empty($attributes))  {
  774.             return false;
  775.         }
  776.         foreach($attributes as $key => $lineItem) {
  777.             foreach($lineItem as $_key => $lineItemAttributes) {
  778.                 foreach ($lineItemAttributes as $__key => $attribute) {
  779.                     if ($__key === 'quantity') {
  780.                         continue;
  781.                     }
  782.                     if(is_array($attribute['value'])) {
  783.                         $attributes[$key][$_key][$__key] = $attribute;
  784.                     }
  785.                 }
  786.             }
  787.         }
  788.         foreach ($attributesInRequest as $key => $attribute) {
  789.             if ($key === 'quantity') {
  790.                 continue;
  791.             }
  792.             $attributesInRequest[$key] = [
  793.                 'name' => $attribute['name'],
  794.                 'order' => $attribute['entity']->getOrder(),
  795.                 'value' => $attribute['value']
  796.             ];
  797.             if(is_array($attribute['value'])) {
  798.                 //IF QUANTITY IS NOT SEPARATED
  799.                 $enablePrices $this->pluginConfig->get('HuebertAddOrderAttributes.config.enablePrices'$salesChannelId);
  800.                 $separatedQuantity $this->pluginConfig->get('HuebertAddOrderAttributes.config.separatedQuantity'$salesChannelId);
  801.                 if($enablePrices && !$separatedQuantity) {
  802.                     if (isset($attribute['value']['attributes_with_prices'])) {
  803.                         foreach ($attribute['value']['attributes_with_prices'] as $key1 => $value1) {
  804.                             $attributeName $key1;
  805.                             $payloadAttribute = [];
  806.                             if (is_array($value1)) {
  807.                                 foreach ($value1 as $k => $v) {
  808.                                     $payloadAttribute[$attributeName][$k]['price'] = $v;
  809.                                 }
  810.                             } else {
  811.                                 $array explode('--'$value1);
  812.                                 $payloadAttribute[$attributeName][$array[0]]['price'] = $array[1];
  813.                             }
  814.                             $attributesInRequest[$key]['value']['attributes_with_prices'] = $payloadAttribute;
  815.                         }
  816.                     } else {
  817.                         //IF QUANTITY IS NOT SEPARATED AND NOT WITH PRICES
  818.                         $attributesInRequest[$key]['value'] = implode(","$attribute['value']);
  819.                     }
  820.                 } else {
  821.                     //IF QUANTITY IS SEPARATED
  822.                     $attributesInRequest[$key]['value'] = implode(","$attribute['value']);
  823.                 }
  824. //                $attributesInRequest[$key]['value'] = implode(",", $attribute['value']);
  825.             }
  826.         }
  827.         foreach($attributes as $lineItemId => $lineItem) {
  828.             if(!empty($lineItem) && $lineItemId === $lineItemIdAdded) {
  829.                 foreach($lineItem as $key => $lineItemAttributes) {
  830.                     $diffResult $this->array_multi_diff($lineItemAttributes$attributesInRequest);
  831.                     unset($diffResult['quantity']);
  832.                     if(count($diffResult) == 0) {
  833.                         return $key;
  834.                     }
  835.                 }
  836.             }
  837.         }
  838.         return false;
  839.     }
  840.     /**
  841.      * @param $array1
  842.      * @param $array2
  843.      * @return array
  844.      */
  845.     private function array_multi_diff$array1$array2 )
  846.     {
  847.         $result = array();
  848.         foreach( $array1 as $key => $a1 ) {
  849.             if( !is_array($array2) || !array_key_exists$key$array2 ) ) {
  850.                 $result$key ] = $a1;
  851.                 continue;
  852.             }
  853.             $a2 $array2$key ];
  854.             if( is_array$a1 ) ) {
  855.                 $recc_array $this->array_multi_diff$a1$a2 );
  856.                 if( !empty( $recc_array ) ) {
  857.                     $result$key ] = $recc_array;
  858.                 }
  859.             }
  860.             else if( $a1 != $a2 ) {
  861.                 $result$key ] = $a1;
  862.             }
  863.         }
  864.         return $result;
  865.     }
  866.     /**
  867.      * @param EntityCollection $attributeEntities
  868.      */
  869.     private function sortAttributeEntities(EntityCollection $attributeEntities) {
  870.         $switchCollection = new EntityCollection();
  871.         $attributeEntitiesCount count($attributeEntities->getElements());
  872.         $i 0;
  873.         while(count($switchCollection->getElements()) != $attributeEntitiesCount) {
  874.             foreach($attributeEntities as $attributeEntity) {
  875.                 if($attributeEntity->getOrder() == $i) {
  876.                     $switchCollection->add($attributeEntity);
  877.                 }
  878.             }
  879.             $i++;
  880.         }
  881.         return $switchCollection;
  882.     }
  883.     public function onOffcanvasCartPage(OffcanvasCartPageLoadedEvent $event): void
  884.     {
  885.         /**
  886.          * @var OffcanvasCartPage $page
  887.          */
  888.         $salesChannelId $event->getSalesChannelContext()->getSalesChannelId();
  889.         $page $event->getPage();
  890.         $enablePrices $this->pluginConfig->get('HuebertAddOrderAttributes.config.enablePrices'$salesChannelId);
  891.         $separatedQuantity $this->pluginConfig->get('HuebertAddOrderAttributes.config.separatedQuantity'$salesChannelId);
  892.         $page->assign([
  893.             'enabledPrices' => $enablePrices,
  894.             'separatedQuantity' => $separatedQuantity
  895.         ]);
  896.     }
  897.     public function onCartPage(CheckoutCartPageLoadedEvent $event): void
  898.     {
  899.         /**
  900.          * @var CheckoutCartPage $page
  901.          */
  902.         $page $event->getPage();
  903.         $salesChannelId $event->getSalesChannelContext()->getSalesChannelId();
  904.         $enablePrices $this->pluginConfig->get('HuebertAddOrderAttributes.config.enablePrices'$salesChannelId);
  905.         $separatedQuantity $this->pluginConfig->get('HuebertAddOrderAttributes.config.separatedQuantity'$salesChannelId);
  906.         $page->assign([
  907.             'enabledPrices' => $enablePrices,
  908.             'separatedQuantity' => $separatedQuantity
  909.         ]);
  910.     }
  911.     public function onCheckoutPage(CheckoutConfirmPageLoadedEvent $event): void
  912.     {
  913.         /**
  914.          * @var CheckoutCartPage $page
  915.          */
  916.         $page $event->getPage();
  917.         $salesChannelId $event->getSalesChannelContext()->getSalesChannelId();
  918.         $enablePrices $this->pluginConfig->get('HuebertAddOrderAttributes.config.enablePrices'$salesChannelId);
  919.         $separatedQuantity $this->pluginConfig->get('HuebertAddOrderAttributes.config.separatedQuantity'$salesChannelId);
  920.         $page->assign([
  921.             'enabledPrices' => $enablePrices,
  922.             'separatedQuantity' => $separatedQuantity
  923.         ]);
  924.     }
  925.     public function getCategoryAttributes($categories$context$attributes): EntityCollection
  926.     {
  927.         $attributesFromCategories = new EntityCollection();
  928.            $criteria = new Criteria();
  929.            $criteria->addFilter(new EqualsAnyFilter('categoryId'$categories->getIds()));
  930.            $categoryAttributes $this->dependencyepository->search($criteria$context)->getEntities();
  931.            foreach ($categoryAttributes as $categoryAttribute){
  932.                $dependecies = new EntityCollection();
  933.                $attributesFromCategories->add($categoryAttribute);
  934.                foreach ($categoryAttribute['categoryAttributes'] as $attr){
  935.                    if($attributes->has($attr)) {
  936.                        $dependecies->add($attributes->get($attr));
  937.                }
  938.                }
  939.                $attributesFromCategories->get($categoryAttribute->getId())->addExtension('dependencies'$dependecies);
  940.            }
  941.            return $attributesFromCategories;
  942.     }
  943.     public function applyAttributesOnSubcategories($product$context$salesChannelId): ?EntityCollection{
  944.         $includeChildren $this->pluginConfig->get('HuebertAddOrderAttributes.config.includeChildCategories'$salesChannelId);
  945.         if($includeChildren) {
  946.             $categories $product->getCategories();
  947.             if (empty($categories)) {
  948.                 return null;
  949.             }
  950.             $breadCrumb = [];
  951.             foreach ($product->getCategoryTree() as $k) {
  952.                 $breadCrumb[$k] = $k;
  953.             }
  954.             $criteria = new Criteria();
  955.             $criteria->addAssociations(['categorys']);
  956.             $criteria->addFilter(new EqualsAnyFilter('categorys.id'$breadCrumb));
  957.             $categoriess $this->attributeRepository->search($criteria$context);
  958.             $attributes = new EntityCollection();
  959.             foreach ($categoriess->getEntities() as $attr) {
  960.                 $attributes->add($attr);
  961.             }
  962.             return $attributes;
  963.         }
  964.         return null;
  965.     }
  966.     public function applyDependencyOnSubcategories($product$context$salesChannelId): ?EntityCollection{
  967.         $includeChildren $this->pluginConfig->get('HuebertAddOrderAttributes.config.includeChildCategories'$salesChannelId);
  968.         $attributesFromCategories = new EntityCollection();
  969.         if($includeChildren) {
  970.             $categories $product->getCategories();
  971.             if (empty($categories)) {
  972.                 return null;
  973.             }
  974.             $breadCrumb = [];
  975.             foreach ($product->getCategoryTree() as $k) {
  976.                 $breadCrumb[$k] = $k;
  977.             }
  978.             $criteria = new Criteria();
  979.             $criteria->addFilter(new EqualsAnyFilter('categoryId'$breadCrumb));
  980.             $categoryAttributes $this->dependencyepository->search($criteria$context)->getEntities();
  981.             $criteria1 = new Criteria();
  982.             $criteria1->addAssociations(['categorys']);
  983.             $criteria1->addFilter(new EqualsAnyFilter('categorys.id'$breadCrumb));
  984.             $attributes $this->attributeRepository->search($criteria1$context)->getEntities();
  985.             foreach ($categoryAttributes as $categoryAttribute){
  986.                 $dependecies = new EntityCollection();
  987.                 $attributesFromCategories->add($categoryAttribute);
  988.                 foreach ($categoryAttribute['categoryAttributes'] as $attr){
  989.                     if($attributes->has($attr)) {
  990.                         $dependecies->add($attributes->get($attr));
  991.                     }
  992.                 }
  993.                 $attributesFromCategories->get($categoryAttribute->getId())->addExtension('dependencies'$dependecies);
  994.             }
  995.             return $attributesFromCategories;
  996.             }
  997.         return null;
  998. }
  999.     private function applyDependencyOnParentCategories($product$context$salesChannelId): ?EntityCollection {
  1000.         $includeParent $this->pluginConfig->get('HuebertAddOrderAttributes.config.includeParentCategory'$salesChannelId);
  1001.         $categories $product->getCategories();
  1002.         $categoriesCollection = new EntityCollection();
  1003.         if(empty($categories)) {
  1004.             return null;
  1005.         }
  1006.         if(empty($categories->getIds())) {
  1007.             return null;
  1008.         }
  1009.         if($includeParent) {
  1010.             $criteria = new Criteria();
  1011.             $criteria->addFilter(new EqualsAnyFilter('parentId'$categories->getIds()));
  1012.             $result $this->categoryRepository->search($criteria$context)->getIds();
  1013.             $criteria2 = new Criteria();
  1014.             $criteria2->addFilter(new EqualsAnyFilter('categoryId',$result));
  1015.             $categoryAttributes $this->dependencyepository->search($criteria2$context)->getEntities();
  1016.             $criteria1 = new Criteria();
  1017.             $criteria1->addAssociations(['categorys']);
  1018.             $criteria1->addFilter(new EqualsAnyFilter('categorys.id'$result));
  1019.             $categoryResults $this->attributeRepository->search($criteria1$context)->getEntities();
  1020.             foreach ($categoryAttributes as $categoryAttribute){
  1021.                 $dependecies = new EntityCollection();
  1022.                 $categoriesCollection->add($categoryAttribute);
  1023.                     foreach ($categoryAttribute['categoryAttributes'] as $attr) {
  1024.                         if($categoryResults->has($attr)) {
  1025.                             $dependecies->add($categoryResults->get($attr));
  1026.                         }
  1027.                 }
  1028.                 $categoriesCollection->get($categoryAttribute->getId())->addExtension('dependencies'$dependecies);
  1029.             }
  1030.             return $categoriesCollection;
  1031.         }
  1032.         return null;
  1033.     }
  1034.     private function formatDependencies($dependencies$lineItemId): array{
  1035.         $dependenciesArray = [];
  1036.         foreach ($dependencies[$lineItemId] as $key => $value) {
  1037.                 if ($value !== "") {
  1038.                     $data explode("--"$value);
  1039.                     if($data[1] !== "0") {
  1040.                         $dependenciesArray[$key] = [
  1041.                             'name' => $data[0],
  1042.                             'price' => (float)$data[1]
  1043.                         ];
  1044.                     }
  1045.                 }
  1046.             }
  1047.         return $dependenciesArray;
  1048.     }
  1049.     private function getProductStreamDependecnies($productContext $context, ?EntityCollection $attributes)
  1050.     {
  1051.         $attributesFromStream= new EntityCollection();
  1052.         $productId $product->getId();
  1053.         if($product->getParentId()) {
  1054.             $productId $product->getParentId();
  1055.         }
  1056.         if($productId) {
  1057.             $mappingCriteria = new Criteria();
  1058.             $mappingCriteria->addFilter(new EqualsFilter('id'$productId));
  1059.             $mappingCriteria->addAssociation('productStreams');
  1060.             $mappingCriteria->addAssociation('productStreams.attributes');
  1061.             $mappingCriteria->addAssociation('productStreams.mapping');
  1062.             $product $this->productRepository->search($mappingCriteria$context)->getElements();
  1063.             $productStreamsIds = [];
  1064.             foreach ($product as $item) {
  1065.                 $productStreamsIds $item->getStreamIds();
  1066.             }
  1067.             if ($productStreamsIds) {
  1068.                 $criteria = new Criteria();
  1069.                 $criteria->addFilter(new EqualsAnyFilter('productStreamId'$productStreamsIds));
  1070.                 $productStreamAttribues $this->dependencyepository->search($criteria$context)->getEntities();
  1071.                 foreach ($productStreamAttribues as $streamAttribute) {
  1072.                     $dependecies = new EntityCollection();
  1073.                     $attributesFromStream->add($streamAttribute);
  1074.                     foreach ($streamAttribute['productStreamAttributes'] as $attr) {
  1075.                         if ($attributes->has($attr)) {
  1076.                             $dependecies->add($attributes->get($attr));
  1077.                         }
  1078.                     }
  1079.                     $attributesFromStream->get($streamAttribute->getId())->addExtension('dependencies'$dependecies);
  1080.                 }
  1081.             }
  1082.         }
  1083.         return $attributesFromStream;
  1084.     }
  1085. }