1

I wish to do the following during a module install;

  • Create a new Attribute Set based upon the Default Attribute Set
  • Create multiple new Product Attributes that are assigned into the Product Details Group in the new Attribute Set

I have found the following link which seems quite close StackExchange Link

Can somebody please confirm that this code will do as I wish before I write the module, or suggest a modification to this code so that it will execute as required please?

Edit; I have it partly working, however it adds the Product Attribute to every Attribute Set.

    <?php

namespace Challenge\Multiselect\Setup;

use Magento\Eav\Setup\EavSetup; 
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Catalog\Setup\CategorySetupFactory;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;

class UpgradeData implements UpgradeDataInterface
{
    /**
     * EAV setup factory
     *
     * @var EavSetupFactory
     */
    private $eavSetupFactory;
    private $attributeSetFactory;
    private $attributeSet;
    private $categorySetupFactory;

    /**
     * Init
     *
     * @param EavSetupFactory $eavSetupFactory
     */
    public function __construct(EavSetupFactory $eavSetupFactory, AttributeSetFactory $attributeSetFactory, CategorySetupFactory $categorySetupFactory )    
    {
            $this->eavSetupFactory = $eavSetupFactory; 
            $this->attributeSetFactory = $attributeSetFactory; 
            $this->categorySetupFactory = $categorySetupFactory; 
    }

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

        $setup->startSetup();   

            // CREATE ATTRIBUTE SET 
            $categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);

            $attributeSet = $this->attributeSetFactory->create();
            $entityTypeId = $categorySetup->getEntityTypeId(\Magento\Catalog\Model\Product::ENTITY);
            $attributeSetId = $categorySetup->getDefaultAttributeSetId($entityTypeId);
            $data = [
                'attribute_set_name' => 'TEST_SET22', 
                'entity_type_id' => $entityTypeId,
                'sort_order' => 200,
            ];
            $attributeSet->setData($data);
            $attributeSet->validate();
            $attributeSet->save();
            $attributeSet->initFromSkeleton($attributeSetId);
            $attributeSet->save();      

        $setup->endSetup();


        $setup->startSetup();

        /** @var \Magento\Eav\Setup\EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);


        $eavSetup->addAttribute(
            \Magento\Catalog\Model\Product::ENTITY,
            'custom_test22',
        [

                'label' => 'test22',
                'type' => 'varchar',
                'input' => 'multiselect',

                'user_defined' => true,                 

                'option' => ['values' => [
                    'Option 2',
                    'Option 3',
                    'Option 4',         
                    ],
                ],
                'backend' => 'Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend',
                'required' => false,
                'visible' => true,
                'visible_on_front' => true,
                'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
                'searchable' => true,
                'filterable' => true,
                'used_for_promo_rule' => true,
                'comparable' => true,
                'wysiwyg_enabled' => false,
                'used_in_product_listing' => true,
                'used_for_sort_by' => false, 
                'filterable' => '1',
                'filterable_in_search' => true,

                'is_filterable_in_grid' => '1',
                'is_used_in_grid' => '1',               
                'wp_show_quantity' => '1',


                'attribute_set_id' => 'TEST_SET22',
                'group' => 'Product Details',           


        ]
        );


        $setup->endSetup();


    }
}
Anthony
  • 431
  • 2
  • 9

2 Answers2

1

You need to add the the attribute to specific attribute sets in a separate call addAttributeToSet(). Details why this must be that way are in my answer to your related question https://magento.stackexchange.com/a/263819/76597

Here is how your method upgrade() should look like:

public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {

        $setup->startSetup();   

            // CREATE ATTRIBUTE SET 
            $categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);

            $attributeSet = $this->attributeSetFactory->create();
            $entityTypeId = $categorySetup->getEntityTypeId(\Magento\Catalog\Model\Product::ENTITY);
            $attributeSetId = $categorySetup->getDefaultAttributeSetId($entityTypeId);
            $data = [
                'attribute_set_name' => 'TEST_SET22', 
                'entity_type_id' => $entityTypeId,
                'sort_order' => 200,
            ];
            $attributeSet->setData($data);
            $attributeSet->validate();
            $attributeSet->save();
            $attributeSet->initFromSkeleton($attributeSetId);
            $attributeSet->save();      

        $setup->endSetup();


        $setup->startSetup();

        /** @var \Magento\Eav\Setup\EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);


        $eavSetup->addAttribute(
            \Magento\Catalog\Model\Product::ENTITY,
            'custom_test22',
        [

                'label' => 'test22',
                'type' => 'varchar',
                'input' => 'multiselect',

                'user_defined' => true,                 

                'option' => ['values' => [
                    'Option 2',
                    'Option 3',
                    'Option 4',         
                    ],
                ],
                'backend' => 'Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend',
                'required' => false,
                'visible' => true,
                'visible_on_front' => true,
                'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
                'searchable' => true,
                'filterable' => true,
                'used_for_promo_rule' => true,
                'comparable' => true,
                'wysiwyg_enabled' => false,
                'used_in_product_listing' => true,
                'used_for_sort_by' => false, 
                'filterable' => '1',
                'filterable_in_search' => true,

                'is_filterable_in_grid' => '1',
                'is_used_in_grid' => '1',               
                'wp_show_quantity' => '1'

        ]
        );

        $attributeSetName = 'TEST_SET22';
        $groupName = 'Product Details';
        $attributeCode = 'custom_test22';
        $attributeSetId = $eavSetup->getAttributeSetId($entityTypeId, $attributeSetName);
        $attributeId = $eavSetup->getAttributeId($entityTypeId, $attributeCode);
        $attributeGroupId = $eavSetup->getAttributeGroupId($entityTypeId, $attributeSetId, $groupName);
        $eavSetup->addAttributeToSet($entityTypeId,$attributeSetId, $attributeGroupId, $attributeId);

        $setup->endSetup();
    }
}
HelgeB
  • 4,511
  • 2
  • 10
  • 27
  • Yes! This works perfectly, finally. I really appreciate your help. I can sort of see why it has been done this way but i was swayed by so many people saying you do it through the options array. Again thank you very much! – Anthony Mar 01 '19 at 00:54
0

Simply change the below line

'attribute_set_id' => 'TEST_SET22',

to

'attribute_set' => 'TEST_SET22',

Now, your attribute gets assigned to the above-mentioned attribute name.

Bilal Usean
  • 9,977
  • 14
  • 75
  • 122
  • I tried this, including changing TEST_SET22 to an actual ID and I still get the new product attribute in EVERY product attribute set – Anthony Feb 28 '19 at 07:58