1

I am working on Magento 2 and want to add custom color in color swatch attribute option programmatically. I have gone through this post but unable to add options

Can anyone helps me to add custom attribute option with color = Black , color code = #000000 programmatically

Thanks in advance. Any help would be appreciated.

1

3 Answers 3

2

Step 1

Start by creating a basic setup script for it, if you don't already have one.

<?php
namespace Package\Module\Setup;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class UpgradeData implements UpgradeDataInterface
{
    const PRODUCT_GROUP = 'Product Details';

    /** @var \Magento\Framework\App\State */
    protected $state;

    /** @var \Magento\Catalog\Model\Product\Attribute\Repository $attributeRepository */
    protected $attributeRepository;

    /** @var \Magento\Framework\Filesystem  */
    protected $filesystem;

    /** @var \Magento\Swatches\Helper\Media */
    protected $swatchHelper;

    /** @var \Magento\Catalog\Model\Product\Media\Config */
    protected $productMediaConfig;

    /** @var \Magento\Framework\Filesystem\Driver\File */
    protected $driverFile;

    /** @var \Magento\Eav\Setup\EavSetupFactory */
    protected $eavSetupFactory;

    public function __construct(
        \Magento\Eav\Setup\EavSetupFactory $eavSetupFactory,
        \Magento\Framework\App\State $state,
        \Magento\Catalog\Model\Product\Attribute\Repository $attributeRepository,
        \Magento\Framework\Filesystem $filesystem,
        \Magento\Swatches\Helper\Media $swatchHelper,
        \Magento\Catalog\Model\Product\Media\Config $productMediaConfig,
        \Magento\Framework\Filesystem\Driver\File $driverFile
    ) {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->state = $state;
        $this->attributeRepository = $attributeRepository;
        $this->filesystem = $filesystem;
        $this->swatchHelper = $swatchHelper;
        $this->productMediaConfig = $productMediaConfig;
        $this->driverFile = $driverFile;
    }

    /**
     * {@inheritdoc}
     */
    public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        if (version_compare($context->getVersion(), '1.0.0', '<')) {
            $attributesData = [
               // to add in step 2
            ];

            $attributesOptionsData = [
                // to add in step 2
            ];

            $this->addProductAttributes($attributesData, $attributesOptionsData, $setup);
        }

        $setup->endSetup();
    }

    /**
     * Add product attributes.
     *
     * @param $attributesData
     * @param $attributesOptionsData
     * @param ModuleDataSetupInterface $setup
     *
     * @throws \Exception
     */
    public function addProductAttributes($attributesData, $attributesOptionsData, ModuleDataSetupInterface $setup)
    {
        // to implement in step 3
    }
}

Step 2

Secondly, prepare your data. Replace \\ to add in step 2 comments from Step 1 with something similar:

$attributesData = [
    'fit' => [
        'type' => 'int',
        'label' => 'Fit',
        'input' => 'select',
        'backend' => 'Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend',
        'source' => 'Magento\Eav\Model\Entity\Attribute\Source\Table',
        'required' => false,
        'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
        'group' => self::PRODUCT_GROUP,
        'used_in_product_listing' => true,
        'visible_on_front' => true,
        'user_defined' => true,
        'filterable' => 2,
        'filterable_in_search' => true,
        'used_for_promo_rules' => true,
        'is_html_allowed_on_front' => true,
        'used_for_sort_by' => true,
    ],
];
$attributesOptionsData = [
    'fit' => [
        \Magento\Swatches\Model\Swatch::SWATCH_INPUT_TYPE_KEY => \Magento\Swatches\Model\Swatch::SWATCH_INPUT_TYPE_VISUAL,
        'optionvisual' => [
            'value'     => [
                'option_0' => [
                    0 => 'FITTED'
                ],
                'option_1' => [
                    0 => 'RELAXED'
                ],
                'option_2' => [
                    0 => 'REGULAR'
                ],
            ],
        ],
        'swatchvisual' => [
            'value'     => [
                'option_0' => 'Fitted.png',
                'option_1' => 'Relaxed.png',
                'option_2' => 'Regular.png',
            ],
        ],
    ]
];

Step 3

Finally, finish implementation for addProductAttributes method:

/**
 * Add product attributes.
 *
 * @param $attributesData
 * @param $attributesOptionsData
 * @param ModuleDataSetupInterface $setup
 *
 * @throws \Exception
 */
public function addProductAttributes($attributesData, $attributesOptionsData, ModuleDataSetupInterface $setup)
{
    try {
        // Make sure we don't get error "Area code is not set".
        $this->state->setAreaCode('admin');
    } catch (\Exception $ignored) {}
    try {
        /** @var \Magento\Eav\Setup\EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        // Add attributes.
        foreach ($attributesData as $code => $attributeData) {
            $eavSetup->addAttribute(\Magento\Catalog\Model\Product::ENTITY, $code, $attributeData);
        }

        // Add order if it doesn't exist. This is an important step to make sure everything will be created correctly.
        foreach ($attributesOptionsData as &$attributeOptionsData) {
            $order = 0;
            $swatchVisualFiles = isset($attributeOptionsData['optionvisual']['value'])
                ? $attributeOptionsData['optionvisual']['value']
                : [];
            foreach ($swatchVisualFiles as $index => $swatchVisualFile) {
                if (!isset($attributeOptionsData['optionvisual']['order'][$index])) {
                    $attributeOptionsData['optionvisual']['order'][$index] = ++$order;
                }
            }
        }

        // Prepare visual swatches files.
        $mediaDirectory = $this->filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
        $tmpMediaPath = $this->productMediaConfig->getBaseTmpMediaPath();
        $fullTmpMediaPath = $mediaDirectory->getAbsolutePath($tmpMediaPath);
        $this->driverFile->createDirectory($fullTmpMediaPath);
        foreach ($attributesOptionsData as &$attributeOptionsData) {
            $swatchVisualFiles = $attributeOptionsData['swatchvisual']['value'] ?? [];
            foreach ($swatchVisualFiles as $index => $swatchVisualFile) {
                $this->driverFile->copy(
                    __DIR__ . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . $swatchVisualFile,
                    $fullTmpMediaPath . DIRECTORY_SEPARATOR . $swatchVisualFile
                );
                $newFile = $this->swatchHelper->moveImageFromTmp($swatchVisualFile);
                if (substr($newFile, 0, 1) == '.') {
                    $newFile = substr($newFile, 1); // Fix generating swatch variations for files beginning with ".".
                }
                $this->swatchHelper->generateSwatchVariations($newFile);
                $attributeOptionsData['swatchvisual']['value'][$index] = $newFile;
            }
        }

        // Add attribute options.
        foreach ($attributesOptionsData as $code => $attributeOptionsData) {
            /* @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */
            $attribute = $this->attributeRepository->get($code);
            $attribute->addData($attributeOptionsData);
            $attribute->save();
        }
    } catch (\Exception $ex) {
        throw new \Exception(__('There was an error adding product attributes.'), 0, $ex);
    }
}
0

Sorry, one year before here is the answer:

<?php
namespace Hello\Boy\Model;

class Attribute extends \Magento\Framework\Model\AbstractModel
{
    protected $eavConfig;
    protected $attributeOptionInterfaceFactory;
    protected $attributeOptionManagement;

    public function __construct(
        \Magento\Eav\Model\Config $eavConfig,
        \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $attributeOptionInterfaceFactory,
        \Magento\Catalog\Api\ProductAttributeOptionManagementInterface $attributeOptionManagement
    )
    {
        $this->eavConfig = $eavConfig;
        $this->attributeOptionInterfaceFactory = $attributeOptionInterfaceFactory;;
        $this->attributeOptionManagement = $attributeOptionManagement;
    }

    public function processAttributes()
    {
        $attribute = $this->eavConfig->getAttribute('catalog_product', 'color');
        $this->registerOption($attribute->getId(), 'red');
    }

    private function registerOption($attributeCode, $label)
    {
        $option = $this->attributeOptionInterfaceFactory->create();
        $option->setLabel($label);

        return $this->attributeOptionManagement->add(
            $attributeCode,
            $option
        );
    }
}
0

You can add one color option this way:

<?php

namespace Vendor\Module\Model;

use Magento\Catalog\Api\Data\ProductAttributeInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory;

class ColorsImporter
{
    private AttributeFactory $attributeFactory;
    
    public function __construct(AttributeFactory $attributeFactory)
    {
        $this->attributeFactory = $attributeFactory;
    }

    public function execute()
    {
        /** @var ProductAttributeInterface $model */
        $model = $this->attributeFactory->create();
        $model->loadByCode(Product::ENTITY,'color');
        $data = [];
        $data['optionvisual']['value'] = ['option_0' => ['Black', 'Black']];
        $data['swatchvisual']['value'] = ['option_0' => '#000000'];
        $model->addData($data);
        $model->save();
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.