5

I try to create programmatically some attributes set.

I find this code :

    $setup = $this->moduleDataSetup->getConnection();
    $setup->startSetup();
    $categorySetup = $this->categorySetupFactory->create(['setup' => $this->moduleDataSetup]);

    $attributeSet = $this->attributeSetFactory->create();
    $entityTypeId = $categorySetup->getEntityTypeId(\Magento\Catalog\Model\Product::ENTITY);
    $attributeSetId = $categorySetup->getDefaultAttributeSetId($entityTypeId);

    try {

        foreach ($attributeSetNameArray as $attributeSetName) {
            $data = [
                'attribute_set_name' => $attributeSetName,
                'entity_type_id' => $entityTypeId
            ];
            $attributeSet->setData($data);
            $attributeSet->validate();
            $attributeSet->save();
            $attributeSet->initFromSkeleton($attributeSetId);
            $attributeSet->save();
        }
    } catch (\Exception $exception) {
        throw new InputException(__($exception->getMessage()));
    }

    $setup->endSetup();

It's work perfectly, but my PhpStorm say that the Method "save" in

$attributeSet->save();

$attributeSet->initFromSkeleton($attributeSetId)->save();

is deprecated.

Do you know why is deprecated ? How can I fix this ?

Thank you

2
  • it would be easier to help you if your code is complete
    – fmsthird
    Commented Mar 6, 2019 at 12:31
  • I used this example : magecomp.com/blog/…
    – Kozame
    Commented Mar 6, 2019 at 15:45

3 Answers 3

3

You can use the Magento\Eav\Api\AttributeSetRepositoryInterface; to handle the save attribute
Check this:

<?php

namespace Vendor\CustomModule\Setup;

use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Catalog\Setup\CategorySetupFactory;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;
use Magento\Eav\Api\AttributeSetRepositoryInterface;

class InstallData implements InstallDataInterface
{
private $_eavSetupFactory;
private $_attributeSetFactory;
private $_categorySetupFactory;
private $_attribute;

/**
 * InstallData constructor.
 * @param AttributeSetRepositoryInterface $attribute
 * @param EavSetupFactory $eavSetupFactory
 * @param AttributeSetFactory $attributeSetFactory
 * @param CategorySetupFactory $categorySetupFactory
 */
public function __construct(AttributeSetRepositoryInterface $attribute, EavSetupFactory $eavSetupFactory, AttributeSetFactory $attributeSetFactory, CategorySetupFactory $categorySetupFactory )
{
    $this->_eavSetupFactory = $eavSetupFactory;
    $this->_attributeSetFactory = $attributeSetFactory;
    $this->_categorySetupFactory = $categorySetupFactory;
    $this->_attribute = $attribute;
}

/**
 * @param ModuleDataSetupInterface $setup
 * @param ModuleContextInterface $context
 * @throws \Magento\Framework\Exception\LocalizedException
 */
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
    $setup->startSetup();

    $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' => 'YOUR_ATTRIBUTE_SET_NAME',
        'entity_type_id' => $entityTypeId,
        'sort_order' => 200,
    ];

    try{

        $attributeSet->setData($data);
        $attributeSet->validate();
        $this->_attribute->save($attributeSet);

        $attributeSet->initFromSkeleton($attributeSetId);
        $this->_attribute->save($attributeSet);

    } catch (\Exception $exception) {
        throw new InputException(__($exception->getMessage()));
    }


    // CREATE PRODUCT ATTRIBUTE
    $eavSetup = $this->_eavSetupFactory->create(['setup' => $setup]);

    $eavSetup->addAttribute(
        \Magento\Catalog\Model\Product::ENTITY,
        'attribute_id',
        [
            'type' => 'varchar',
            'label' => 'YOUR ATTRIBUTE LABEL',
            'backend' => '',
            'input' => 'text',
            'wysiwyg_enabled'   => false,
            'source' => '',
            'required' => false,
            'sort_order' => 5,
            'global' => \Magento\Catalog\Model\ResourceModel\Eav\Attribute::SCOPE_STORE,
            'used_in_product_listing' => true,
            'visible_on_front' => true,
            'attribute_set_id' => 'TESTING ATTRIBUTE',
        ]
    );

    $setup->endSetup();
}
}
4
  • 1
    When I try your code, I get : Fatal error: Class Magento\Eav\Model\ResourceModel\Attribute\Interceptor contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (Magento\Eav\Model\ResourceModel\Attribute::_getEavWebsiteTable, Magento\Eav\Model\ResourceModel\Attribute::_getFormAttributeTable) in /var/www/magento/generated/code/Magento/Eav/Model/ResourceModel/Attribute/Interceptor.php on line 7. I'm not sure to understand why I need to implement theses functions because I not extends this class
    – Kozame
    Commented Mar 7, 2019 at 8:35
  • I have updated the answer please check
    – fmsthird
    Commented Mar 7, 2019 at 8:46
  • 1
    Work perfectly ! Thank you ! Can you just explain me why we use AttributeSetRepositoryInterface instead of Attribute ?
    – Kozame
    Commented Mar 7, 2019 at 8:49
  • can't really explain it but you can check it from the documentation devdocs.magento.com/guides/v2.3/extension-dev-guide/… magento introduces and recommends to use module service contract to mitigate some issues with custom extension dependencies
    – fmsthird
    Commented Mar 7, 2019 at 9:04
1

Yes of course, as save(), delete(), load() are deprecated now, you have to use a service contract or resourceModel

You can read this.

1
  • Can you please share an ewample of service contract or resourceModel ? I'm not sur to understand how to apply this in my code
    – Kozame
    Commented Mar 6, 2019 at 15:58
1

Magento 2 repo contains load and save methods from Magento\Framework\Model\AbstractModel that are deprecated. If you follow the guidelines that the core module does, you may face a problem: it is necessary to use something instead of them or extend something else. One of the possible most obvious solution is to use Module Service Contract – ProductRepositoryInterface for products. Alternatively, you can save entities via ResourceModel if Module Service Contract is unavailable.

ProductRepositoryInterface Example and Usage Reference link:

  1. https://hotexamples.com/examples/magento.catalog.api/ProductRepositoryInterface/-/php-productrepositoryinterface-class-examples.html

  2. https://mage2.pro/t/topic/1297

I hope this will help

1
  • Thank you for your explanation. But can you please show me some example ? I'm not sure to really understand how to use ProductRepositoryInterface..
    – Kozame
    Commented Mar 6, 2019 at 15:43

Your Answer

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

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