Magento – How to create text swatch programmatically

eavmagento2swatches

How to create text swatch programmatically?

If, I follow method from saving controller in the product-attribute module (admin) then, I got first and the third field saved but not actual text swatch.

Best Answer

Try to use my code, Basically you'd need to add a select type, then convert it to Text Swatch like SwatchesSampleData module this used some functions from this module

InstallData.php

<?php

namespace Vendor\Module\Setup;

use Magento\Framework\Setup;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Catalog\Model\Product\Type;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Catalog\Model\ResourceModel\Eav\Attribute as eavAttribute;

class InstallData implements InstallDataInterface
{
    /**
     * @var EavSetupFactory
     */
    protected $eavSetupFactory;

    protected $attrOptionCollectionFactory;
    protected $eavConfig;
    protected $logger;


    protected $optionCollection = [];


    public function __construct(
        EavSetupFactory $eavSetupFactory,
        \Magento\Eav\Model\Config $eavConfig,
        \Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\CollectionFactory $attrOptionCollectionFactory,
        \Psr\Log\LoggerInterface $logger
    )
    {
        $this->eavConfig = $eavConfig;
        $this->eavSetupFactory = $eavSetupFactory;
        $this->attrOptionCollectionFactory = $attrOptionCollectionFactory;
        $this->logger = $logger;
    }

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

        if (version_compare($context->getVersion(), '1.0.0', '<')) {
            /** @var \Magento\Eav\Setup\EavSetup $eavSetup */
            $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

            $this->installSwatches($eavSetup, $setup);
        }

        $setup->endSetup();
    }


    /**
     * @param EavSetup $eavSetup
     * @param ModuleDataSetupInterface $setup
     * @throws \Exception
     */
    private function installSwatches(
        \Magento\Eav\Setup\EavSetup $eavSetup,
        ModuleDataSetupInterface $setup
    ) {

        try {

            $productTypes = [
                \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
                \Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL,
                \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE,
                \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE,
            ];
            $productTypes = join(',', $productTypes);

            $eavSetup->addAttribute(
                \Magento\Catalog\Model\Product::ENTITY,
                'test_text_swatch',
                [
                    'type' => 'int',
                    'label' => 'Test Text Swatch',
                    'input' => 'select',
                    'required' => false,
                    'user_defined' => true,
                    'searchable' => true,
                    'filterable' => true,
                    'comparable' => true,
                    'visible_in_advanced_search' => true,
                    'apply_to' => $productTypes,
                    'is_used_in_grid' => true,
                    'is_visible_in_grid' => false,
                    'option' => [
                        'values' => [
                            'Test'
                        ]
                    ]
                ]
            );

            $this->eavConfig->clear();

            $this->convertAttributeToSwatches();

        } catch (\Exception $e) {
            $this->logger->critical($e);

        }

    }

    public function convertAttributeToSwatches() {
        $attribute = $this->eavConfig->getAttribute('catalog_product', 'test_text_swatch');
        if (!$attribute) {
            return;
        }

        $attributeData['option'] = $this->addExistingOptions($attribute);
        $attributeData['frontend_input'] = 'select';
        $attributeData['swatch_input_type'] = 'text';
        $attributeData['update_product_preview_image'] = 1;
        $attributeData['use_product_image_for_swatch'] = 0;
        $attributeData['optiontext'] = $this->getOptionSwatch($attributeData);
        $attributeData['defaulttext'] = $this->getOptionDefaultText($attributeData);
        $attributeData['swatchtext'] = $this->getOptionSwatchText($attributeData);
        $this->logger->log(100, print_r($attributeData, true));
        $attribute->addData($attributeData);
        $attribute->save();
    }

    protected function getOptionSwatch(array $attributeData)
    {
        $optionSwatch = ['order' => [], 'value' => [], 'delete' => []];
        $i = 0;
        foreach ($attributeData['option'] as $optionKey => $optionValue) {
            $optionSwatch['delete'][$optionKey] = '';
            $optionSwatch['order'][$optionKey] = (string)$i++;
            $optionSwatch['value']['option_' . $optionKey] = [$optionValue, ''];
        }
        return $optionSwatch;
    }

    /**
     * @param array $attributeData
     * @return array
     */
    private function getOptionSwatchText(array $attributeData)
    {
        $optionSwatch = ['value' => []];
        foreach ($attributeData['option'] as $optionKey => $optionValue) {
            $optionSwatch['value'][$optionKey] = [$optionValue, ''];
        }
        return $optionSwatch;
    }

    /**
     * @param array $attributeData
     * @return array
     */
    private function getOptionDefaultText(array $attributeData)
    {
        $optionSwatch = $this->getOptionSwatchText($attributeData);
        return [array_keys($optionSwatch['value'])[0]];
    }

    /**
     * @param $attributeId
     * @return void
     */
    private function loadOptionCollection($attributeId)
    {
        if (empty($this->optionCollection[$attributeId])) {
            $this->optionCollection[$attributeId] = $this->attrOptionCollectionFactory->create()
                ->setAttributeFilter($attributeId)
                ->setPositionOrder('asc', true)
                ->load();
        }
    }

    /**
     * @param eavAttribute $attribute
     * @return array
     */
    private function addExistingOptions(eavAttribute $attribute)
    {
        $options = [];
        $attributeId = $attribute->getId();
        if ($attributeId) {
            $this->loadOptionCollection($attributeId);
            /** @var \Magento\Eav\Model\Entity\Attribute\Option $option */
            foreach ($this->optionCollection[$attributeId] as $option) {
                $options[$option->getId()] = $option->getValue();
            }
        }
        return $options;
    }
}

Result

Result

Related Topic