1
1
<?php
2
2
/**
3
- * Copyright © Magento, Inc. All rights reserved.
4
- * See COPYING.txt for license details .
3
+ * Copyright 2013 Adobe
4
+ * All Rights Reserved .
5
5
*/
6
6
namespace Magento \ConfigurableProduct \Block \Adminhtml \Product \Edit \Tab \Variations \Config ;
7
7
8
8
use Magento \Catalog \Api \ProductRepositoryInterface ;
9
9
use Magento \Catalog \Model \Locator \LocatorInterface ;
10
10
use Magento \Catalog \Model \Product ;
11
+ use Magento \Eav \Model \Entity \Attribute \AbstractAttribute ;
11
12
use Magento \Framework \Exception \NoSuchEntityException ;
12
13
13
14
/**
@@ -88,7 +89,7 @@ public function __construct(
88
89
LocatorInterface $ locator ,
89
90
array $ data = []
90
91
) {
91
- parent ::__construct ($ context , $ data );
92
+ parent ::__construct ($ context , $ data, $ data [ ' jsonHelper ' ] ?? null , $ data [ ' directoryHelper ' ] ?? null );
92
93
$ this ->_configurableType = $ configurableType ;
93
94
$ this ->stockRegistry = $ stockRegistry ;
94
95
$ this ->variationMatrix = $ variationMatrix ;
@@ -242,6 +243,32 @@ protected function getAssociatedProducts()
242
243
return $ productByUsedAttributes ;
243
244
}
244
245
246
+ /**
247
+ * Retrieves attributes that are used for configurable product variations
248
+ *
249
+ * @return array
250
+ */
251
+ private function getVariantAttributeComposition (): array
252
+ {
253
+ $ variants = [];
254
+ foreach ($ this ->_getAssociatedProducts () as $ product ) {
255
+ /* @var $attribute AbstractAttribute */
256
+ foreach ($ this ->getUsedAttributes () as $ attribute ) {
257
+ $ variants [$ product ->getId ()][$ attribute ->getAttributeCode ()] =
258
+ [
259
+ 'value_id ' => $ product ->getData ($ attribute ->getAttributeCode ()),
260
+ 'label ' => $ this ->extractAttributeValueLabel (
261
+ $ attribute ,
262
+ $ product ->getData ($ attribute ->getAttributeCode ())
263
+ ),
264
+ 'attribute ' => $ attribute
265
+ ];
266
+ }
267
+ }
268
+
269
+ return $ variants ;
270
+ }
271
+
245
272
/**
246
273
* Retrieve actual list of associated products (i.e. if product contains variations matrix form data
247
274
* - previously saved in database relations are not considered)
@@ -251,7 +278,7 @@ protected function getAssociatedProducts()
251
278
protected function _getAssociatedProducts ()
252
279
{
253
280
$ product = $ this ->getProduct ();
254
- $ ids = $ this -> getProduct () ->getAssociatedProductIds ();
281
+ $ ids = $ product ->getAssociatedProductIds ();
255
282
if ($ ids === null ) {
256
283
// form data overrides any relations stored in database
257
284
return $ this ->_configurableType ->getUsedProducts ($ product );
@@ -332,6 +359,76 @@ public function getProductAttributes()
332
359
return $ this ->productAttributes ;
333
360
}
334
361
362
+ /**
363
+ * Prepare attribute details for child product configuration
364
+ *
365
+ * @param AbstractAttribute $attribute
366
+ * @return array
367
+ */
368
+ private function buildAttributeDetails (AbstractAttribute $ attribute ): array
369
+ {
370
+ $ configurableAttributes = $ this ->getAttributes ();
371
+ $ details = [
372
+ 'code ' => $ attribute ->getAttributeCode (),
373
+ 'label ' => $ attribute ->getStoreLabel (),
374
+ 'id ' => $ attribute ->getAttributeId (),
375
+ 'position ' => $ configurableAttributes [$ attribute ->getAttributeId ()]['position ' ],
376
+ 'chosen ' => [],
377
+ '__disableTmpl ' => true
378
+ ];
379
+
380
+ foreach ($ attribute ->getOptions () as $ option ) {
381
+ if ($ option ->getValue ()) {
382
+ $ details ['options ' ][] = [
383
+ 'attribute_code ' => $ attribute ->getAttributeCode (),
384
+ 'attribute_label ' => $ attribute ->getStoreLabel (0 ),
385
+ 'id ' => $ option ->getValue (),
386
+ 'label ' => $ option ->getLabel (),
387
+ 'value ' => $ option ->getValue (),
388
+ '__disableTmpl ' => true ,
389
+ ];
390
+ }
391
+ }
392
+
393
+ return $ details ;
394
+ }
395
+
396
+ /**
397
+ * Generate configurable product child option
398
+ *
399
+ * @param array $attributeDetails
400
+ * @return array
401
+ */
402
+ private function buildChildProductOption (array $ attributeDetails ): array
403
+ {
404
+ return [
405
+ 'attribute_code ' => $ attributeDetails ['attribute ' ]->getAttributeCode (),
406
+ 'attribute_label ' => $ attributeDetails ['attribute ' ]->getStoreLabel (0 ),
407
+ 'id ' => $ attributeDetails ['value_id ' ],
408
+ 'label ' => $ attributeDetails ['label ' ],
409
+ 'value ' => $ attributeDetails ['value_id ' ],
410
+ '__disableTmpl ' => true ,
411
+ ];
412
+ }
413
+
414
+ /**
415
+ * Get label for a specific value of an attribute.
416
+ *
417
+ * @param AbstractAttribute $attribute
418
+ * @param mixed $valueId
419
+ * @return string
420
+ */
421
+ private function extractAttributeValueLabel (AbstractAttribute $ attribute , mixed $ valueId ): string
422
+ {
423
+ foreach ($ attribute ->getOptions () as $ attributeOption ) {
424
+ if ($ attributeOption ->getValue () == $ valueId ) {
425
+ return $ attributeOption ->getLabel ();
426
+ }
427
+ }
428
+
429
+ return '' ;
430
+ }
431
+
335
432
/**
336
433
* Prepare product variations.
337
434
*
@@ -341,106 +438,57 @@ public function getProductAttributes()
341
438
*/
342
439
protected function prepareVariations ()
343
440
{
344
- $ variations = $ this ->getVariations ();
345
- $ productMatrix = [];
346
- $ attributes = [];
347
- if ($ variations ) {
348
- $ usedProductAttributes = $ this ->getUsedAttributes ();
349
- $ productByUsedAttributes = $ this ->getAssociatedProducts ();
350
- $ configurableAttributes = $ this ->getAttributes ();
351
- foreach ($ variations as $ variation ) {
352
- $ attributeValues = [];
353
- foreach ($ usedProductAttributes as $ attribute ) {
354
- $ attributeValues [$ attribute ->getAttributeCode ()] = $ variation [$ attribute ->getId ()]['value ' ];
355
- }
356
- $ key = implode ('- ' , $ attributeValues );
357
- if (isset ($ productByUsedAttributes [$ key ])) {
358
- $ product = $ productByUsedAttributes [$ key ];
359
- $ price = $ product ->getPrice ();
360
- $ variationOptions = [];
361
- foreach ($ usedProductAttributes as $ attribute ) {
362
- list ($ attributes , $ variationOptions ) = $ this ->prepareAttributes (
363
- $ attributes ,
364
- $ attribute ,
365
- $ configurableAttributes ,
366
- $ variation ,
367
- $ variationOptions
368
- );
369
- }
370
-
371
- $ productMatrix [] = [
372
- 'productId ' => $ product ->getId (),
373
- 'images ' => [
374
- 'preview ' => $ this ->image ->init ($ product , 'product_thumbnail_image ' )->getUrl ()
375
- ],
376
- 'sku ' => $ product ->getSku (),
377
- 'name ' => $ product ->getName (),
378
- 'quantity ' => $ this ->getProductStockQty ($ product ),
379
- 'price ' => $ price ,
380
- 'options ' => $ variationOptions ,
381
- 'weight ' => $ product ->getWeight (),
382
- 'status ' => $ product ->getStatus (),
383
- '__disableTmpl ' => true ,
384
- ];
441
+ $ productMatrix = $ attributes = [];
442
+ $ variants = $ this ->getVariantAttributeComposition ();
443
+ foreach (array_reverse ($ this ->getAssociatedProducts ()) as $ product ) {
444
+ $ childProductOptions = [];
445
+ foreach ($ variants [$ product ->getId ()] as $ attributeComposition ) {
446
+ $ childProductOptions [] = $ this ->buildChildProductOption ($ attributeComposition );
447
+
448
+ /** @var AbstractAttribute $attribute */
449
+ $ attribute = $ attributeComposition ['attribute ' ];
450
+ if (!isset ($ attributes [$ attribute ->getAttributeId ()])) {
451
+ $ attributes [$ attribute ->getAttributeId ()] = $ this ->buildAttributeDetails ($ attribute );
385
452
}
453
+ $ variationOption = [
454
+ 'attribute_code ' => $ attribute ->getAttributeCode (),
455
+ 'attribute_label ' => $ attribute ->getStoreLabel (0 ),
456
+ 'id ' => $ attributeComposition ['value_id ' ],
457
+ 'label ' => $ attributeComposition ['label ' ],
458
+ 'value ' => $ attributeComposition ['value_id ' ],
459
+ '__disableTmpl ' => true ,
460
+ ];
461
+ $ attributes [$ attribute ->getAttributeId ()]['chosen ' ][] = $ variationOption ;
386
462
}
463
+ $ productMatrix [] = $ this ->buildChildProductDetails ($ product , $ childProductOptions );
387
464
}
465
+
388
466
$ this ->productMatrix = $ productMatrix ;
389
467
$ this ->productAttributes = array_values ($ attributes );
390
468
}
391
469
392
470
/**
393
- * Prepare attributes.
471
+ * Create child product details
394
472
*
395
- * @param array $attributes
396
- * @param object $attribute
397
- * @param array $configurableAttributes
398
- * @param array $variation
399
- * @param array $variationOptions
473
+ * @param Product $product
474
+ * @param array $childProductOptions
400
475
* @return array
401
476
*/
402
- private function prepareAttributes (
403
- array $ attributes ,
404
- $ attribute ,
405
- array $ configurableAttributes ,
406
- array $ variation ,
407
- array $ variationOptions
408
- ): array {
409
- if (!isset ($ attributes [$ attribute ->getAttributeId ()])) {
410
- $ attributes [$ attribute ->getAttributeId ()] = [
411
- 'code ' => $ attribute ->getAttributeCode (),
412
- 'label ' => $ attribute ->getStoreLabel (),
413
- 'id ' => $ attribute ->getAttributeId (),
414
- 'position ' => $ configurableAttributes [$ attribute ->getAttributeId ()]['position ' ],
415
- 'chosen ' => [],
416
- '__disableTmpl ' => true
417
- ];
418
- $ options = $ attribute ->usesSource () ? $ attribute ->getSource ()->getAllOptions () : [];
419
- foreach ($ options as $ option ) {
420
- if (!empty ($ option ['value ' ])) {
421
- $ attributes [$ attribute ->getAttributeId ()]['options ' ][] = [
422
- 'attribute_code ' => $ attribute ->getAttributeCode (),
423
- 'attribute_label ' => $ attribute ->getStoreLabel (0 ),
424
- 'id ' => $ option ['value ' ],
425
- 'label ' => $ option ['label ' ],
426
- 'value ' => $ option ['value ' ],
427
- '__disableTmpl ' => true ,
428
- ];
429
- }
430
- }
431
- }
432
- $ optionId = $ variation [$ attribute ->getId ()]['value ' ];
433
- $ variationOption = [
434
- 'attribute_code ' => $ attribute ->getAttributeCode (),
435
- 'attribute_label ' => $ attribute ->getStoreLabel (0 ),
436
- 'id ' => $ optionId ,
437
- 'label ' => $ variation [$ attribute ->getId ()]['label ' ],
438
- 'value ' => $ optionId ,
477
+ private function buildChildProductDetails (Product $ product , array $ childProductOptions ): array
478
+ {
479
+ return [
480
+ 'productId ' => $ product ->getId (),
481
+ 'images ' => [
482
+ 'preview ' => $ this ->image ->init ($ product , 'product_thumbnail_image ' )->getUrl ()
483
+ ],
484
+ 'sku ' => $ product ->getSku (),
485
+ 'name ' => $ product ->getName (),
486
+ 'quantity ' => $ this ->getProductStockQty ($ product ),
487
+ 'price ' => $ product ->getPrice (),
488
+ 'options ' => $ childProductOptions ,
489
+ 'weight ' => $ product ->getWeight (),
490
+ 'status ' => $ product ->getStatus (),
439
491
'__disableTmpl ' => true ,
440
492
];
441
- $ variationOptions [] = $ variationOption ;
442
- $ attributes [$ attribute ->getAttributeId ()]['chosen ' ][] = $ variationOption ;
443
-
444
- return [$ attributes , $ variationOptions ];
445
493
}
446
494
}
0 commit comments