I have created a Data patch file to create the product drop down attribute with options. used the following code in it.
<?php
declare(strict_types=1);
namespace Custom\Module\Setup\Patch\Data;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
class AddTestAttribute implements DataPatchInterface
{
private $moduleDataSetup;
private $eavSetupFactory;
public $_storeManager;
private $logger;
protected $_dir;
const TYPE_BOOLEAN = "boolean";
const TYPE_TEXT = "text";
const TYPE_SELECT = "select";
protected $_attributeFactory;
protected $_eavAttribute;
public function __construct(
ModuleDataSetupInterface $moduleDataSetup,
EavSetupFactory $eavSetupFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Filesystem\DirectoryList $dir,
\Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeFactory,
\Magento\Eav\Model\Entity\Attribute $eavAttribute
) {
$this->moduleDataSetup = $moduleDataSetup;
$this->eavSetupFactory = $eavSetupFactory;
$this->_storeManager = $storeManager;
$this->logger = $logger;
$this->_dir = $dir;
$this->_attributeFactory = $attributeFactory;
$this->_eavAttribute = $eavAttribute;
}
/**
* {@inheritdoc}
*/
public function apply()
{
/** @var EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$fileName = 'attributes_data.csv';
$pubPath = $this->_dir->getPath('pub');
$attributeFile = $pubPath.'/'.$fileName;
$arrResult = array();
if(($handle = fopen($attributeFile, 'r')) !== FALSE) {
$row = 1;
while(($data = fgetcsv($handle, 1000000, ',')) !== FALSE) {
$col_count = count($data);
$arrResult[] = $data;
$row++;
}
fclose($handle);
}
$i = 0;
foreach ($arrResult as $line) {
if($i > 0){
$attributeCode = $line[0];
$attributeName = $line[1];
$inputType = strtolower($line[2]);
$options = $line[3];
switch ($inputType) {
case ($inputType == self::TYPE_BOOLEAN && isset($attributeCode)):
$this->createBooleanAttribute($eavSetup,$attributeCode,$attributeName,$inputType);
break;
case ($inputType == self::TYPE_SELECT && isset($attributeCode)):
$this->createSelectAttribute($eavSetup,$attributeCode,$attributeName,$inputType);
if(isset($options) && $options != '' ){
$optionName = explode (",", $options);
if(count($optionName) > 0){
$this->createAttributeOptions($eavSetup,$attributeCode,$optionName);
}
}
case ($inputType == self::TYPE_TEXT && isset($attributeCode)):
$this->createTextAttribute($eavSetup,$attributeCode,$attributeName,$inputType);
break;
default:
$this->createTextAttribute($eavSetup,$attributeCode,$attributeName,$inputType);
}
}
$i++;
}
}
/**
* {@inheritdoc}
*/
public static function getDependencies()
{
return [];
}
/**
* {@inheritdoc}
*/
public function getAliases()
{
return [];
}
public function createSelectAttribute($eavSetup,$attributeCode,$attributeName,$inputType){ //,$options
$this->logger->info('-select Attribute---');
$type = 'int';
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
$attributeCode,
[
'type' => $type,
'group' => 'General',
'backend' => 'int',
'frontend' => '',
'label' => $attributeName,
'input' => $inputType,
'class' => '',
'source' => 'Magento\Eav\Model\Entity\Attribute\Source\Table',
'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
'visible' => true,
'required' => false,
'user_defined' => true,
'searchable' => false,
'filterable' => true,
"filterable_in_search" => 1,
'comparable' => false,
'visible_on_front' => true,
'used_in_product_listing' => true,
'unique' => false ,
'system' => 1
]
);
}
public function createTextAttribute($eavSetup,$attributeCode,$attributeName,$inputType){
$type = 'text';
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
$attributeCode,
[
'type' => $type,
'group' => 'Product Details',
'attribute_set' => 'Default',
'label' => $attributeName,
'backend' => '',
'input' => $inputType,
'wysiwyg_enabled' => false,
'source' => '',
'required' => false,
'sort_order' => 3,
'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
'used_in_product_listing' => true,
'visible_on_front' => true
]
);
}
public function createAttributeOptions($eavSetup,$attributeCode,$optionName){
$entityType = 'catalog_product';
$attributeInfo = $this->_eavAttribute->loadByCode($entityType, $attributeCode);
$attributeId = $attributeInfo->getAttributeId();
//$attribute_arr = ['aaa','bbb','ccc','ddd'];
$attribute_arr = $optionName;
$option = array();
$option['attribute_id'] = $attributeId;
foreach($attribute_arr as $key => $value){
$option['value'][$value][0]=$value;
foreach($this->_storeManager as $store){
$option['value'][$value][$store->getId()] = $value;
}
}
if ($option) {
$eavSetup->addAttributeOption($option);
}
}
}
In the above script, I have created a csv file inside pub directory, then reading data from the file and creating the attributes based on the file data.
File content will be like this.
In database its created like below.
The problem here is the "drop down" attribute is created well, but the "source_model" is created empty in database also the backend_type created as "text" instead of "int".
Due to this we are unable to see the drop down attribute in layered navigation. Can anyone advise me here please how can i create the drop down attribute with option by reading from the csv file. Thanks!!