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();


    }
}
1
  • Can anybody help on this please?
    – Anthony
    Feb 25, 2019 at 7:23

2 Answers 2

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();
    }
}
1
  • 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 1, 2019 at 0: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.

1
  • 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, 2019 at 7:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.