I would like to create attributes with swatch option programatically in Magento 2.
- By programmatically, do you mean using the API or using PHP coding?Steve Johnson– Steve Johnson2016-08-27 13:26:58 +00:00Commented Aug 27, 2016 at 13:26
- @SteveJohnson I mean by PHP codingGideon– Gideon2016-08-30 05:06:58 +00:00Commented Aug 30, 2016 at 5:06
- I also want solution for this. Have you found any solution then please post here.Magecode– Magecode2017-12-06 12:20:56 +00:00Commented Dec 6, 2017 at 12:20
2 Answers
This is similar to Magento 1, with a few differences.
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); } } - Mimarcel, it is always best to post your entire answer so people don't link out to an outside site.brentwpeterson– brentwpeterson2016-09-22 21:45:04 +00:00Commented Sep 22, 2016 at 21:45
- I have to import attribute option with visual swatch and swatch value is colorcode. I am following this link for upload attribute options but not getting solution to add visual swatch value. Please help me. pearlbells.co.uk/…Magecode– Magecode2017-12-06 12:19:02 +00:00Commented Dec 6, 2017 at 12:19
Recently tried below code for creating visual swatch attribute options pro-grammatically. Created file within root "import-visual-swatch.php" with below code:
Place your all image into "magentoRoot\images" directory and then run below Script
<?php use Magento\Framework\App\Bootstrap; require __DIR__ . '/app/bootstrap.php'; $bootstraps = Bootstrap::create(BP, $_SERVER); $object_Manager = $bootstraps->getObjectManager(); $app_state = $object_Manager->get('\Magento\Framework\App\State'); $app_state->setAreaCode('frontend'); // Visual Swatch option values array containing name, unique code as key and image url for swatch // Swatch image are to be placed within "project_root\images" directory // After code execution swatch images will be uploaded to "project_root\pub\media\attribute\swatch" directory /* You can create your color name with color image array here replace with your color name and Image name */ $finalProductData = array( 'BLKV' => array("label" => "Black", "url" => "p2.jpeg"), 'BLKV1' => array("label" => "Black1", "url" => "p2.jpeg"), ); $eavConfig = $object_Manager->get('\Magento\Eav\Model\Config'); $attribute = $eavConfig->getAttribute('catalog_product', 'color'); // Generating options as we are creating Visual Swatch hence passing 'visual' as parameter $data = generateOptions($finalProductData, 'visual'); $filesystem = $object_Manager->create('\Magento\Framework\Filesystem'); // Prepare visual swatches files. $mediaDirectory = $filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); $productMediaConfig = $object_Manager->create('\Magento\Catalog\Model\Product\Media\Config'); $tmpMediaPath = $productMediaConfig->getBaseTmpMediaPath(); $fullTmpMediaPath = $mediaDirectory->getAbsolutePath($tmpMediaPath); $driverFile = $object_Manager->create('\Magento\Framework\Filesystem\Driver\File'); $driverFile->createDirectory($fullTmpMediaPath); $swatchHelper = $object_Manager->create('\Magento\Swatches\Helper\Media'); foreach ($data as $key => $attributeOptionsData) { if ($key == "swatchvisual") { $swatchVisualFiles = isset($attributeOptionsData['value']) ? $attributeOptionsData['value'] : []; foreach ($swatchVisualFiles as $index => $swatchVisualFile) { if (!empty($swatchVisualFile)) { if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . $swatchVisualFile)) { $driverFile->copy( __DIR__ . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . $swatchVisualFile, $fullTmpMediaPath . '/' . $swatchVisualFile ); $newFile = $swatchHelper->moveImageFromTmp($swatchVisualFile); if (substr($newFile, 0, 1) == '.') { $newFile = substr($newFile, 1); // Fix generating swatch variations for files beginning with ".". } $swatchHelper->generateSwatchVariations($newFile); $data[$key]['value'][$index] = $newFile; } else { $data[$key]['value'][$index] = ""; } } } } } function generateOptions($values, $swatchType = 'visual') { $i = 0; foreach ($values as $key => $value) { $order["option_{$i}"] = $i; $optionsStore["option_{$i}"] = array( 0 => $key, // admin 1 => $value['label'], // default store view ); $textSwatch["option_{$i}"] = array( 1 => $value['label'], ); $visualSwatch["option_{$i}"] = $value['url']; $delete["option_{$i}"] = ''; $i++; } switch ($swatchType) { case 'text': return [ 'optiontext' => [ 'order' => $order, 'value' => $optionsStore, 'delete' => $delete, ], 'swatchtext' => [ 'value' => $textSwatch, ], ]; break; case 'visual': return [ 'optionvisual' => [ 'order' => $order, 'value' => $optionsStore, 'delete' => $delete, ], 'swatchvisual' => [ 'value' => $visualSwatch, ], ]; break; default: return [ 'option' => [ 'order' => $order, 'value' => $optionsStore, 'delete' => $delete, ], ]; } } $attribute->addData($data)->save(); - Thank for answer buddyPraveen Chelumalla– Praveen Chelumalla2019-12-16 12:29:22 +00:00Commented Dec 16, 2019 at 12:29
- Thank you buddy. :) +10Ronak Rathod– Ronak Rathod2021-12-21 15:55:20 +00:00Commented Dec 21, 2021 at 15:55