1919use Magento \Framework \Json \Helper \Data as JsonHelper ;
2020use Magento \Framework \Locale \CurrencyInterface ;
2121use Magento \Framework \UrlInterface ;
22+ use Magento \ConfigurableProduct \Model \Product \Type \VariationMatrix ;
2223
2324/**
2425 * Associated products helper
@@ -62,6 +63,11 @@ class AssociatedProducts
6263 */
6364 protected $ productIds = [];
6465
66+ /**
67+ * @var VariationMatrix
68+ */
69+ protected $ variationMatrix ;
70+
6571 /**
6672 * @var UrlInterface
6773 */
@@ -93,6 +99,7 @@ class AssociatedProducts
9399 * @param ConfigurableType $configurableType
94100 * @param ProductRepositoryInterface $productRepository
95101 * @param StockRegistryInterface $stockRegistry
102+ * @param VariationMatrix $variationMatrix
96103 * @param CurrencyInterface $localeCurrency
97104 * @param JsonHelper $jsonHelper
98105 * @param ImageHelper $imageHelper
@@ -105,6 +112,7 @@ public function __construct(
105112 ConfigurableType $ configurableType ,
106113 ProductRepositoryInterface $ productRepository ,
107114 StockRegistryInterface $ stockRegistry ,
115+ VariationMatrix $ variationMatrix ,
108116 CurrencyInterface $ localeCurrency ,
109117 JsonHelper $ jsonHelper ,
110118 ImageHelper $ imageHelper ,
@@ -115,6 +123,7 @@ public function __construct(
115123 $ this ->configurableType = $ configurableType ;
116124 $ this ->productRepository = $ productRepository ;
117125 $ this ->stockRegistry = $ stockRegistry ;
126+ $ this ->variationMatrix = $ variationMatrix ;
118127 $ this ->localeCurrency = $ localeCurrency ;
119128 $ this ->jsonHelper = $ jsonHelper ;
120129 $ this ->imageHelper = $ imageHelper ;
@@ -219,20 +228,104 @@ public function getConfigurableAttributesData()
219228 return $ result ;
220229 }
221230
231+ protected function prepareVariations2 (): array
232+ {
233+ $ variations = $ this ->getVariations ();
234+ $ productMatrix = [];
235+ $ attributes = [];
236+ $ productIds = [];
237+ if ($ variations ) {
238+ $ usedProductAttributes = $ this ->getUsedAttributes ();
239+ $ productByUsedAttributes = $ this ->getAssociatedProducts ();
240+ $ currency = $ this ->localeCurrency ->getCurrency ($ this ->locator ->getBaseCurrencyCode ());
241+ $ configurableAttributes = $ this ->getAttributes ();
242+ foreach ($ variations as $ variation ) {
243+ $ attributeValues = [];
244+ foreach ($ usedProductAttributes as $ attribute ) {
245+ $ attributeValues [$ attribute ->getAttributeCode ()] = $ variation [$ attribute ->getId ()]['value ' ];
246+ }
247+ $ key = implode ('- ' , $ attributeValues );
248+ if (isset ($ productByUsedAttributes [$ key ])) {
249+ $ product = $ productByUsedAttributes [$ key ];
250+ $ price = $ product ->getPrice ();
251+ $ variationOptions = [];
252+ foreach ($ usedProductAttributes as $ attribute ) {
253+ if (!isset ($ attributes [$ attribute ->getAttributeId ()])) {
254+ $ attributes [$ attribute ->getAttributeId ()] = [
255+ 'code ' => $ attribute ->getAttributeCode (),
256+ 'label ' => $ attribute ->getStoreLabel (),
257+ 'id ' => $ attribute ->getAttributeId (),
258+ 'position ' => $ configurableAttributes [$ attribute ->getAttributeId ()]['position ' ],
259+ 'chosen ' => [],
260+ ];
261+ $ options = $ attribute ->usesSource () ? $ attribute ->getSource ()->getAllOptions () : [];
262+ foreach ($ options as $ option ) {
263+ if (!empty ($ option ['value ' ])) {
264+ $ attributes [$ attribute ->getAttributeId ()]['options ' ][$ option ['value ' ]] = [
265+ 'attribute_code ' => $ attribute ->getAttributeCode (),
266+ 'attribute_label ' => $ attribute ->getStoreLabel (0 ),
267+ 'id ' => $ option ['value ' ],
268+ 'label ' => $ option ['label ' ],
269+ 'value ' => $ option ['value ' ],
270+ ];
271+ }
272+ }
273+ }
274+ $ optionId = $ variation [$ attribute ->getId ()]['value ' ];
275+ $ variationOption = [
276+ 'attribute_code ' => $ attribute ->getAttributeCode (),
277+ 'attribute_label ' => $ attribute ->getStoreLabel (0 ),
278+ 'id ' => $ optionId ,
279+ 'label ' => $ variation [$ attribute ->getId ()]['label ' ],
280+ 'value ' => $ optionId ,
281+ ];
282+ $ variationOptions [] = $ variationOption ;
283+ $ attributes [$ attribute ->getAttributeId ()]['chosen ' ][$ optionId ] = $ variationOption ;
284+ }
285+
286+ $ productMatrix [] = [
287+ 'id ' => $ product ->getId (),
288+ 'product_link ' => '<a href=" ' . $ this ->urlBuilder ->getUrl (
289+ 'catalog/product/edit ' ,
290+ ['id ' => $ product ->getId ()]
291+ ) . '" target="_blank"> ' . $ this ->escaper ->escapeHtml ($ product ->getName ()) . '</a> ' ,
292+ 'sku ' => $ product ->getSku (),
293+ 'name ' => $ product ->getName (),
294+ 'qty ' => $ this ->getProductStockQty ($ product ),
295+ 'price ' => $ price ,
296+ 'price_string ' => $ currency ->toCurrency (sprintf ("%f " , $ price )),
297+ 'price_currency ' => $ this ->locator ->getStore ()->getBaseCurrency ()->getCurrencySymbol (),
298+ 'configurable_attribute ' => $ this ->getJsonConfigurableAttributes ($ variationOptions ),
299+ 'weight ' => $ product ->getWeight (),
300+ 'status ' => $ product ->getStatus (),
301+ 'variationKey ' => $ this ->getVariationKey ($ variationOptions ),
302+ 'canEdit ' => 0 ,
303+ 'newProduct ' => 0 ,
304+ 'attributes ' => $ this ->getTextAttributes ($ variationOptions ),
305+ 'thumbnail_image ' => $ this ->imageHelper ->init ($ product , 'product_thumbnail_image ' )->getUrl (),
306+ ];
307+ $ productIds [] = $ product ->getId ();
308+ }
309+ }
310+ }
311+
312+ return $ productMatrix ;
313+ //$this->productMatrix = $productMatrix;
314+ //$this->productIds = $productIds;
315+ }
316+
222317 /**
223318 * Prepare variations
224319 *
225320 * @return void
226321 * @throws CurrencyException
227- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
228- * phpcs:disable Generic.Metrics.NestingLevel.TooHigh
229322 */
230- protected function prepareVariations ()
323+ protected function prepareVariations (): void
231324 {
232325 $ productMatrix = $ attributes = [];
233326 $ variants = $ this ->getVariantAttributeComposition ();
234327 $ productIds = [];
235- foreach ($ this ->getAssociatedProducts () as $ product ) {
328+ foreach (array_reverse ( $ this ->getAssociatedProducts () ) as $ product ) {
236329 $ childProductOptions = [];
237330 $ productIds [] = $ product ->getId ();
238331 foreach ($ variants [$ product ->getId ()] as $ attributeComposition ) {
@@ -250,12 +343,13 @@ protected function prepareVariations()
250343 'label ' => $ attributeComposition ['label ' ],
251344 'value ' => $ attributeComposition ['value_id ' ]
252345 ];
253- $ attributes [$ attribute ->getAttributeId ()]['chosen ' ][] = $ variationOption ;
346+ $ attributes [$ attribute ->getAttributeId ()]['chosen ' ][$ attributeComposition ['value_id ' ]] =
347+ $ variationOption ;
254348 }
255349 $ productMatrix [] = $ this ->buildChildProductDetails ($ product , $ childProductOptions );
256350 }
257351
258- $ this ->productMatrix = $ productMatrix ;
352+ $ this ->productMatrix = $ this -> prepareVariations2 () ;
259353 $ this ->productIds = $ productIds ;
260354 $ this ->productAttributes = array_values ($ attributes );
261355 }
@@ -408,9 +502,10 @@ private function buildAttributeDetails(AbstractAttribute $attribute): array
408502 'chosen ' => []
409503 ];
410504
411- foreach ($ attribute ->getOptions () as $ option ) {
505+ $ options = $ attribute ->usesSource () ? $ attribute ->getSource ()->getAllOptions () : [];
506+ foreach ($ options as $ option ) {
412507 if (!empty ($ option ['value ' ])) {
413- $ details ['options ' ][] = [
508+ $ details ['options ' ][$ option [ ' value ' ] ] = [
414509 'attribute_code ' => $ attribute ->getAttributeCode (),
415510 'attribute_label ' => $ attribute ->getStoreLabel (0 ),
416511 'id ' => $ option ['value ' ],
@@ -435,7 +530,7 @@ private function buildChildProductOption(array $attributeDetails): array
435530 'attribute_code ' => $ attributeDetails ['attribute ' ]->getAttributeCode (),
436531 'attribute_label ' => $ attributeDetails ['attribute ' ]->getStoreLabel (0 ),
437532 'id ' => $ attributeDetails ['value_id ' ],
438- 'label ' => $ attributeDetails ['value_id ' ],
533+ 'label ' => $ attributeDetails ['label ' ],
439534 'value ' => $ attributeDetails ['value_id ' ]
440535 ];
441536 }
@@ -486,7 +581,7 @@ private function buildChildProductDetails(Product $product, array $childProductO
486581 'variationKey ' => $ this ->getVariationKey ($ childProductOptions ),
487582 'canEdit ' => 0 ,
488583 'newProduct ' => 0 ,
489- 'attributes ' => $ this ->getTextAttributes ($ childProductOptions ),
584+ 'attributes ' => $ this ->getTextAttributes ($ childProductOptions ), //here be the problem
490585 'thumbnail_image ' => $ this ->imageHelper ->init ($ product , 'product_thumbnail_image ' )->getUrl (),
491586 ];
492587 }
@@ -516,4 +611,14 @@ private function getVariantAttributeComposition(): array
516611
517612 return $ variants ;
518613 }
614+
615+ /**
616+ * Retrieve all possible attribute values combinations
617+ *
618+ * @return array
619+ */
620+ protected function getVariations ()
621+ {
622+ return $ this ->variationMatrix ->getVariations ($ this ->getAttributes ());
623+ }
519624}
0 commit comments