Last active
August 11, 2023 12:14
-
-
Save 0-Sony/402b89e385d5ad0b4129696c833c4057 to your computer and use it in GitHub Desktop.
Magento 2: change attribute type to Visual Swatch / Visual Text and add swatch options Ids
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace MyNamespace\Catalog\Model; | |
use Dnd\Catalog\Api\AttributeManagementInterface; | |
use Magento\Catalog\Api\Data\ProductAttributeInterface; | |
use Magento\Eav\Api\AttributeRepositoryInterface; | |
use Magento\Eav\Api\Data\AttributeInterface; | |
use Magento\Eav\Model\Entity\Attribute\Source\Table; | |
use Magento\Framework\App\ResourceConnection; | |
use Magento\Framework\Exception\NoSuchEntityException; | |
use Magento\Framework\Exception\StateException; | |
use Magento\Framework\DB\Adapter\AdapterInterface; | |
use Magento\Framework\DB\Select; | |
use Magento\Swatches\Model\Swatch; | |
use Psr\Log\LoggerInterface; | |
/** | |
* Class AttributeManagement | |
*/ | |
class AttributeManagement implements AttributeManagementInterface | |
{ | |
/** | |
* Description $attributeRepository | |
* | |
* @var AttributeRepositoryInterface $attributeRepository | |
*/ | |
protected AttributeRepositoryInterface $attributeRepository; | |
/** | |
* Description $resourceConnection | |
* | |
* @var ResourceConnection $resourceConnection | |
*/ | |
protected ResourceConnection $resourceConnection; | |
/** | |
* Description $logger | |
* | |
* @var LoggerInterface $logger | |
*/ | |
protected LoggerInterface $logger; | |
/** | |
* AttributeManagement constructor | |
* | |
* @param AttributeRepositoryInterface $attributeRepository | |
* @param ResourceConnection $resourceConnection | |
* @param LoggerInterface $logger | |
*/ | |
public function __construct( | |
AttributeRepositoryInterface $attributeRepository, | |
ResourceConnection $resourceConnection, | |
LoggerInterface $logger | |
) { | |
$this->attributeRepository = $attributeRepository; | |
$this->resourceConnection = $resourceConnection; | |
$this->logger = $logger; | |
} | |
/** | |
* Description updateProductAttributes function | |
* | |
* @param string[] $data | |
* | |
* @return void | |
* @throws NoSuchEntityException | |
* @throws StateException | |
*/ | |
public function updateProductAttributes(array $data): void | |
{ | |
foreach ($data as $attributeCode => $inputType) { | |
/** @var AttributeInterface $attribute */ | |
$attribute = $this->attributeRepository->get(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); | |
if (!$attribute) { | |
continue; | |
} | |
if ($inputType === Swatch::SWATCH_TYPE_VISUAL_ATTRIBUTE_FRONTEND_INPUT) { | |
$this->changeInputTypeToVisualSwatch($attribute, true); | |
} | |
if ($inputType === Swatch::SWATCH_TYPE_TEXTUAL_ATTRIBUTE_FRONTEND_INPUT) { | |
$this->changeInputTypeToTextSwatch($attribute, true); | |
} | |
$this->updateAttributeProperties($attribute); | |
} | |
} | |
/** | |
* Description changeInputTypeToVisualSwatch function | |
* | |
* @param AttributeInterface $attribute | |
* @param bool $createOptions | |
* | |
* @return void | |
* @throws StateException | |
*/ | |
public function changeInputTypeToVisualSwatch(AttributeInterface $attribute, bool $createOptions = false): void | |
{ | |
$attribute->setSourceModel(Table::class); | |
$attribute->setData(Swatch::SWATCH_INPUT_TYPE_KEY, Swatch::SWATCH_INPUT_TYPE_VISUAL); | |
$attribute->setData('update_product_preview_image', 1); | |
$this->attributeRepository->save($attribute); | |
} | |
/** | |
* Description changeInputTypeToTextSwatch function | |
* | |
* @param AttributeInterface $attribute | |
* @param bool $createOptions | |
* | |
* @return void | |
* @throws StateException | |
*/ | |
public function changeInputTypeToTextSwatch(AttributeInterface $attribute, bool $createOptions = false): void | |
{ | |
$attribute->setSourceModel(Table::class); | |
$attribute->setData(Swatch::SWATCH_INPUT_TYPE_KEY, Swatch::SWATCH_INPUT_TYPE_TEXT); | |
$attribute->setData('update_product_preview_image', 1); | |
$this->attributeRepository->save($attribute); | |
if ($createOptions) { | |
$this->createSwatchOptions($attribute); | |
} | |
} | |
/** | |
* Description createSwatchOptions function | |
* | |
* @param AttributeInterface $attribute | |
* | |
* @return AttributeManagement | |
*/ | |
private function createSwatchOptions(AttributeInterface $attribute): AttributeManagement | |
{ | |
/** @var string[] $optionIds */ | |
$optionIds = $this->getOptionsIds($attribute); | |
if (empty($optionIds)) { | |
return $this; | |
} | |
/** @var mixed[] $optionValues */ | |
$optionValues = $this->getOptionValues($optionIds); | |
if (empty($optionValues)) { | |
return $this; | |
} | |
$this->insertSwatchOptionValues($optionValues); | |
} | |
/** | |
* Description getOptionsIds function | |
* | |
* @param $attribute | |
* | |
* @return mixed[] | |
*/ | |
private function getOptionsIds(AttributeInterface $attribute): array | |
{ | |
/** @var AdapterInterface $connection */ | |
$connection = $this->getConnection(); | |
/** @var string[] $result */ | |
$optionIds = [] ; | |
try { | |
/** @var string $tableName */ | |
$tableName = $connection->getTableName('eav_attribute_option'); | |
/** @var Select $select */ | |
$select = $connection->select() | |
->from($tableName) | |
->where(AttributeInterface::ATTRIBUTE_ID . ' = ?', $attribute->getId()); | |
/** @var string[] $optionIds */ | |
$optionIds = $connection->fetchCol($select); | |
} catch (\Exception $exception) { | |
$this->logger->error($exception->getMessage()); | |
} | |
return $optionIds; | |
} | |
/** | |
* Description getOptionValues function | |
* | |
* @param string[] $optionIds | |
* | |
* @return mixed[] | |
*/ | |
private function getOptionValues(array $optionIds): array | |
{ | |
/** @var AdapterInterface $connection */ | |
$connection = $this->getConnection(); | |
/** @var mixed[] $optionValues */ | |
$optionValues = []; | |
try { | |
/** @var string $tableName */ | |
$tableName = $connection->getTableName('eav_attribute_option_value'); | |
/** @var Select $select */ | |
$select = $connection->select() | |
->from($tableName) | |
->where('option_id IN (?)', $optionIds); | |
/** @var mixed[] $optionValues */ | |
$optionValues = $connection->fetchAll($select); | |
} catch (\Exception $exception) { | |
$this->logger->error($exception->getMessage()); | |
} | |
return $optionValues; | |
} | |
/** | |
* Description insertSwatchOptionValues function | |
* | |
* @param mixed[] $optionValues | |
* | |
* @return void | |
*/ | |
private function insertSwatchOptionValues(array $optionValues): void | |
{ | |
/** @var AdapterInterface $connection */ | |
$connection = $this->getConnection(); | |
try { | |
$connection->beginTransaction(); | |
$connection->insertOnDuplicate( | |
'eav_attribute_option_swatch', | |
$optionValues, | |
['value'] | |
); | |
$connection->commit(); | |
} catch (\Exception $exception) { | |
$this->logger->error('Something went wrong while saving swatch option values'); | |
$this->logger->error($exception->getMessage()); | |
$connection->rollBack(); | |
} | |
} | |
/** | |
* Description updateAttributeProperties function | |
* | |
* @param AttributeInterface $attribute | |
* | |
* @return void | |
* @throws StateException | |
*/ | |
private function updateAttributeProperties(AttributeInterface $attribute): void | |
{ | |
$attribute->setData('used_in_product_listing', true); | |
$attribute->setData('is_filterable', '1'); | |
$this->attributeRepository->save($attribute); | |
} | |
/** | |
* Description getConnection function | |
* | |
* @return AdapterInterface | |
*/ | |
private function getConnection(): AdapterInterface | |
{ | |
return $this->resourceConnection->getConnection(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace MyNamespace\Catalog\Api; | |
use Magento\Eav\Api\Data\AttributeInterface; | |
/** | |
* Interface AttributeManagementInterface | |
*/ | |
interface AttributeManagementInterface | |
{ | |
/** | |
* Description updateProductAttributes function | |
* | |
* @param array $data | |
* | |
* @return void | |
*/ | |
public function updateProductAttributes(array $data): void; | |
/** | |
* Description changeInputTypeToVisualSwatch function | |
* | |
* @param AttributeInterface $attribute | |
* @param bool $createOptions | |
* | |
* @return void | |
*/ | |
public function changeInputTypeToVisualSwatch(AttributeInterface $attribute, bool $createOptions): void; | |
/** | |
* Description changeInputTypeToTextSwatch function | |
* | |
* @param AttributeInterface $attribute | |
* @param bool $createOptions | |
* | |
* @return void | |
*/ | |
public function changeInputTypeToTextSwatch(AttributeInterface $attribute, bool $createOptions): void; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" ?> | |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> | |
<preference for="\MyNamespace\Catalog\Api\AttributeManagementInterface" type="\MyNamespace\Catalog\Model\AttributeManagement" /> | |
</config> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment