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

Kozame
  • 964
  • 7
  • 24

3 Answers3

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-&gt;_categorySetupFactory-&gt;create(['setup' =&gt; $setup]);

$attributeSet = $this-&gt;_attributeSetFactory-&gt;create();
$entityTypeId = $categorySetup-&gt;getEntityTypeId(\Magento\Catalog\Model\Product::ENTITY);
$attributeSetId = $categorySetup-&gt;getDefaultAttributeSetId($entityTypeId);
$data = [
    'attribute_set_name' =&gt; 'YOUR_ATTRIBUTE_SET_NAME',
    'entity_type_id' =&gt; $entityTypeId,
    'sort_order' =&gt; 200,
];

try{

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

    $attributeSet-&gt;initFromSkeleton($attributeSetId);
    $this-&gt;_attribute-&gt;save($attributeSet);

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


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

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

$setup-&gt;endSetup();

} }

fmsthird
  • 4,592
  • 4
  • 17
  • 41
  • 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 Mar 07 '19 at 08:35
  • I have updated the answer please check – fmsthird Mar 07 '19 at 08:46
  • 1
    Work perfectly ! Thank you ! Can you just explain me why we use AttributeSetRepositoryInterface instead of Attribute ? – Kozame Mar 07 '19 at 08:49
  • can't really explain it but you can check it from the documentation https://devdocs.magento.com/guides/v2.3/extension-dev-guide/service-contracts/service-contracts.html#what-is-msc magento introduces and recommends to use module service contract to mitigate some issues with custom extension dependencies – fmsthird Mar 07 '19 at 09:04
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

Muhammad Hasham
  • 8,692
  • 11
  • 47
  • 105
  • 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 Mar 06 '19 at 15:43
1

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

You can read this.

PЯINCƎ
  • 11,669
  • 3
  • 25
  • 80
  • 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 Mar 06 '19 at 15:58