Disclaimer: Parts of this code were taken from Magento_SwatchesSampleData
core module. Also you might not need colorMap
but I just put it there.
This code was tested on Magento 2.1.4.
I assume you have an extension called Goivvy_Custom
. I also assume you know how to install the extension and have magento run install scripts.
The code below will create new_swatch_attribute
Visual Swatch.
Here is Goivvy/Custom/Setup/InstallData.php
:
<?php
namespace Goivvy\Custom\Setup;
use Magento\Framework\Setup;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Catalog\Model\Product\Type;
use Magento\Catalog\Model\ResourceModel\Eav\Attribute as eavAttribute;
class InstallData implements Setup\InstallDataInterface
{
private $attrOptionCollectionFactory;
private $eavSetupFactory;
private $eavConfig;
protected $colorMap = [
'Black' => '#000000',
'Blue' => '#1857f7',
'Brown' => '#945454',
'Gray' => '#8f8f8f',
'Green' => '#53a828',
'Lavender' => '#ce64d4',
'Multi' => '#ffffff',
'Orange' => '#eb6703',
'Purple' => '#ef3dff',
'Red' => '#ff0000',
'White' => '#ffffff',
'Yellow' => '#ffd500',
];
public function __construct(EavSetupFactory $eavSetupFactory,
\Magento\Eav\Model\Config $eavConfig,
\Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\CollectionFactory $attrOptionCollectionFactory
)
{
$this->eavConfig = $eavConfig;
$this->eavSetupFactory = $eavSetupFactory;
$this->attrOptionCollectionFactory = $attrOptionCollectionFactory;
}
public function install(Setup\ModuleDataSetupInterface $setup, Setup\ModuleContextInterface $moduleContext)
{
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
if(version_compare($moduleContext->getVersion(),'1.0.0') < 0){
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'new_swatch_attribute',
[
'type' => 'int',
'label' => 'New Swatch Attribute',
'input' => 'select',
'required' => false,
'user_defined' => true,
'searchable' => true,
'filterable' => true,
'comparable' => true,
'visible_in_advanced_search' => true,
'apply_to' => implode(',', [Type::TYPE_SIMPLE, Type::TYPE_VIRTUAL]),
'is_used_in_grid' => true,
'is_visible_in_grid' => false,
'option' => [
'values' => [
'Black',
'Blue',
'Brown',
'Gray',
'Green',
'Lavender',
'Multi',
'Orange',
'Purple',
'Red',
'White',
'Yellow'
]
]
]
);
$this->eavConfig->clear();
$attribute = $this->eavConfig->getAttribute('catalog_product', 'new_swatch_attribute');
if (!$attribute) {
return;
}
$attributeData['option'] = $this->addExistingOptions($attribute);
$attributeData['frontend_input'] = 'select';
$attributeData['swatch_input_type'] = 'visual';
$attributeData['update_product_preview_image'] = 1;
$attributeData['use_product_image_for_swatch'] = 0;
$attributeData['optionvisual'] = $this->getOptionSwatch($attributeData);
$attributeData['defaultvisual'] = $this->getOptionDefaultVisual($attributeData);
$attributeData['swatchvisual'] = $this->getOptionSwatchVisual($attributeData);
$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'][$optionKey] = [$optionValue, ''];
}
return $optionSwatch;
}
private function getOptionSwatchVisual(array $attributeData)
{
$optionSwatch = ['value' => []];
foreach ($attributeData['option'] as $optionKey => $optionValue) {
if (substr($optionValue, 0, 1) == '#' && strlen($optionValue) == 7) {
$optionSwatch['value'][$optionKey] = $optionValue;
} else if ($this->colorMap[$optionValue]) {
$optionSwatch['value'][$optionKey] = $this->colorMap[$optionValue];
} else {
$optionSwatch['value'][$optionKey] = $this->colorMap['White'];
}
}
return $optionSwatch;
}
private function getOptionDefaultVisual(array $attributeData)
{
$optionSwatch = $this->getOptionSwatchVisual($attributeData);
if(isset(array_keys($optionSwatch['value'])[0]))
return [array_keys($optionSwatch['value'])[0]];
else
return [''];
}
private function addExistingOptions(eavAttribute $attribute)
{
$options = [];
$attributeId = $attribute->getId();
if ($attributeId) {
$this->loadOptionCollection($attributeId);
foreach ($this->optionCollection[$attributeId] as $option) {
$options[$option->getId()] = $option->getValue();
}
}
return $options;
}
private function loadOptionCollection($attributeId)
{
if (empty($this->optionCollection[$attributeId])) {
$this->optionCollection[$attributeId] = $this->attrOptionCollectionFactory->create()
->setAttributeFilter($attributeId)
->setPositionOrder('asc', true)
->load();
}
}
}
Here is how it looks in Magento 2.1.4:
Any questions - let me know.