Skip to content

Commit 1963fd0

Browse files
committed
MC-19739: Add swatch value via API to existing text swatch or visual swatch
- Fix empty swatch option value created through API
1 parent 0a390bb commit 1963fd0

File tree

5 files changed

+859
-561
lines changed

5 files changed

+859
-561
lines changed

app/code/Magento/Swatches/Model/Plugin/EavAttribute.php

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
/**
1616
* Plugin model for Catalog Resource Attribute
17+
*
18+
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
1719
*/
1820
class EavAttribute
1921
{
@@ -29,6 +31,11 @@ class EavAttribute
2931
*/
3032
const BASE_OPTION_TITLE = 'option';
3133

34+
/**
35+
* Prefix added to option value added through API
36+
*/
37+
private const API_OPTION_PREFIX = 'id_';
38+
3239
/**
3340
* @var \Magento\Swatches\Model\ResourceModel\Swatch\CollectionFactory
3441
*/
@@ -189,7 +196,9 @@ protected function processSwatchOptions(Attribute $attribute)
189196

190197
if (!empty($optionsArray) && is_array($optionsArray)) {
191198
$optionsArray = $this->prepareOptionIds($optionsArray);
192-
$attributeSavedOptions = $attribute->getSource()->getAllOptions();
199+
$adminStoreAttribute = clone $attribute;
200+
$adminStoreAttribute->setStoreId(self::DEFAULT_STORE_ID);
201+
$attributeSavedOptions = $adminStoreAttribute->getSource()->getAllOptions();
193202
$this->prepareOptionLinks($optionsArray, $attributeSavedOptions);
194203
}
195204

@@ -227,10 +236,9 @@ protected function prepareOptionLinks(array $optionsArray, array $attributeSaved
227236
{
228237
$dependencyArray = [];
229238
if (is_array($optionsArray['value'])) {
230-
$optionCounter = 1;
231-
foreach (array_keys($optionsArray['value']) as $baseOptionId) {
232-
$dependencyArray[$baseOptionId] = $attributeSavedOptions[$optionCounter]['value'];
233-
$optionCounter++;
239+
$options = array_column($attributeSavedOptions, 'value', 'label');
240+
foreach ($optionsArray['value'] as $id => $labels) {
241+
$dependencyArray[$id] = $options[$labels[self::DEFAULT_STORE_ID]];
234242
}
235243
}
236244

@@ -285,7 +293,7 @@ protected function processVisualSwatch(Attribute $attribute)
285293
* Clean swatch option values after switching to the dropdown type.
286294
*
287295
* @param array $attributeOptions
288-
* @param int|null $swatchType
296+
* @param int|null $swatchType
289297
* @throws \Magento\Framework\Exception\LocalizedException
290298
*/
291299
private function cleanEavAttributeOptionSwatchValues(array $attributeOptions, int $swatchType = null)
@@ -309,6 +317,8 @@ private function cleanTextSwatchValuesAfterSwitch(array $attributeOptions)
309317
}
310318

311319
/**
320+
* Get the visual swatch type based on its value
321+
*
312322
* @param string $value
313323
* @return int
314324
*/
@@ -368,7 +378,7 @@ protected function processTextualSwatch(Attribute $attribute)
368378
*/
369379
protected function getAttributeOptionId($optionId)
370380
{
371-
if (substr($optionId, 0, 6) == self::BASE_OPTION_TITLE) {
381+
if (substr($optionId, 0, 6) == self::BASE_OPTION_TITLE || substr($optionId, 0, 3) == self::API_OPTION_PREFIX) {
372382
$optionId = isset($this->dependencyArray[$optionId]) ? $this->dependencyArray[$optionId] : null;
373383
}
374384
return $optionId;
@@ -447,13 +457,10 @@ protected function saveDefaultSwatchOptionValue(Attribute $attribute)
447457
if (!empty($defaultValue)) {
448458
/** @var \Magento\Swatches\Model\Swatch $swatch */
449459
$swatch = $this->swatchFactory->create();
450-
// created and removed on frontend option not exists in dependency array
451-
if (substr($defaultValue, 0, 6) == self::BASE_OPTION_TITLE &&
452-
isset($this->dependencyArray[$defaultValue])
453-
) {
454-
$defaultValue = $this->dependencyArray[$defaultValue];
455-
}
456-
$swatch->getResource()->saveDefaultSwatchOption($attribute->getId(), $defaultValue);
460+
$swatch->getResource()->saveDefaultSwatchOption(
461+
$attribute->getId(),
462+
$this->getAttributeOptionId($defaultValue)
463+
);
457464
}
458465
}
459466

@@ -503,6 +510,10 @@ protected function isOptionsValid(array $options, Attribute $attribute)
503510
}
504511

505512
/**
513+
* Modifies Attribute::usesSource() response
514+
*
515+
* Returns true if attribute type is swatch
516+
*
506517
* @param Attribute $attribute
507518
* @param bool $result
508519
* @return bool
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types = 1);
7+
8+
namespace Magento\Swatches\Plugin\Eav\Model\Entity\Attribute;
9+
10+
use Magento\Catalog\Api\Data\ProductAttributeInterface;
11+
use Magento\Eav\Model\AttributeRepository;
12+
use Magento\Store\Model\Store;
13+
use Magento\Swatches\Helper\Data;
14+
15+
/**
16+
* OptionManagement Plugin
17+
*/
18+
class OptionManagement
19+
{
20+
/**
21+
* @var AttributeRepository
22+
*/
23+
private $attributeRepository;
24+
/**
25+
* @var Data
26+
*/
27+
private $swatchHelper;
28+
29+
/**
30+
* @param AttributeRepository $attributeRepository
31+
* @param Data $swatchHelper
32+
*/
33+
public function __construct(
34+
AttributeRepository $attributeRepository,
35+
Data $swatchHelper
36+
) {
37+
$this->attributeRepository = $attributeRepository;
38+
$this->swatchHelper = $swatchHelper;
39+
}
40+
41+
/**
42+
* Add swatch value to the attribute option
43+
*
44+
* @param \Magento\Catalog\Model\Product\Attribute\OptionManagement $subject
45+
* @param string $attributeCode
46+
* @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
47+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
48+
*/
49+
public function beforeAdd(
50+
\Magento\Catalog\Model\Product\Attribute\OptionManagement $subject,
51+
?string $attributeCode,
52+
\Magento\Eav\Api\Data\AttributeOptionInterface $option
53+
) {
54+
if (empty($attributeCode)) {
55+
return;
56+
}
57+
$attribute = $this->attributeRepository->get(
58+
ProductAttributeInterface::ENTITY_TYPE_CODE,
59+
$attributeCode
60+
);
61+
if (!$attribute || !$this->swatchHelper->isSwatchAttribute($attribute)) {
62+
return;
63+
}
64+
$optionId = $this->getOptionId($option);
65+
$optionsValue = $option->getValue();
66+
if ($this->swatchHelper->isVisualSwatch($attribute)) {
67+
$attribute->setData('swatchvisual', ['value' => [$optionId => $optionsValue]]);
68+
} else {
69+
$options = [];
70+
$options['value'][$optionId][Store::DEFAULT_STORE_ID] = $optionsValue;
71+
if (is_array($option->getStoreLabels())) {
72+
foreach ($option->getStoreLabels() as $label) {
73+
if (!isset($options['value'][$optionId][$label->getStoreId()])) {
74+
$options['value'][$optionId][$label->getStoreId()] = null;
75+
}
76+
}
77+
}
78+
$attribute->setData('swatchtext', $options);
79+
}
80+
}
81+
82+
/**
83+
* Returns option id
84+
*
85+
* @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
86+
* @return string
87+
*/
88+
private function getOptionId(\Magento\Eav\Api\Data\AttributeOptionInterface $option) : string
89+
{
90+
return 'id_' . ($option->getValue() ?: 'new_option');
91+
}
92+
}

0 commit comments

Comments
 (0)