Skip to content

Instantly share code, notes, and snippets.

@Alexander-Pop
Created June 27, 2022 02:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Alexander-Pop/c388d05a85463278f9ba5d07f2dbf822 to your computer and use it in GitHub Desktop.
Save Alexander-Pop/c388d05a85463278f9ba5d07f2dbf822 to your computer and use it in GitHub Desktop.
Magento 2 - change attribute type to Visual Swatch / Visual Text and add swatch options Ids #magento2 #attribute #interface
<?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();
}
}
<?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;
}
<?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