4

How to create a product attribute in Magento 2.3 via declarative schema. I have tried below code but the input element is not visible on the form.

<?php

namespace Rokanthemes\Updates\Setup\Patch\Data;

use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchVersionInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;
use Magento\Framework\DB\Ddl\Table;

class AddAttributes implements DataPatchInterface
{
    protected $_moduleDataSetup;
    protected $_customerSetupFactory;
    protected $_attributeSetFactory;

    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        CustomerSetupFactory $customerSetupFactory,
        AttributeSetFactory $attributeSetFactory
    )
    {
        $this->_moduleDataSetup = $moduleDataSetup;
        $this->_customerSetupFactory = $customerSetupFactory;
        $this->_attributeSetFactory = $attributeSetFactory;
    }

    public function apply()
    {
        $customerSetup = $this->_customerSetupFactory->create(['setup' => $this->_moduleDataSetup]);

        $customerEntity = $customerSetup->getEavConfig()->getEntityType(Customer::ENTITY);
        $attributeSetId = $customerEntity->getDefaultAttributeSetId();

        $attributeSet = $this->_attributeSetFactory->create();
        $attributeSet->getDefaultGroupId($attributeSetId);

        $customerSetup->addAttribute(Customer::ENTITY, 'news_from_date', array(
            'type' => Table::TYPE_DATE,
            'label' => 'New from date',
            'input' => 'date',
            'required' => 1,
            'type' => 'static',            
            'visible' => true
        ));
    }

    public function getAliases()
    {
        return [];
    }

    public static function getDependencies()
    {
        return [

        ];
    }
}

Thanks for the help.

3 Answers 3

16

I wrote an entire blog post about this. It is quite extensive and goes into detail about all of the intricacies: https://markshust.com/2019/02/19/create-product-attribute-data-patch-magento-2.3-declarative-schema/

That said, here is the final class of code you can work with:

<?php
namespace Acme\Foo\Setup\Patch\Data;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;

class AddAlternativeColorAttribute implements DataPatchInterface
{
    /** @var ModuleDataSetupInterface */
    private $moduleDataSetup;

    /** @var EavSetupFactory */
    private $eavSetupFactory;

    /**
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param EavSetupFactory $eavSetupFactory
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        EavSetupFactory $eavSetupFactory
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->eavSetupFactory = $eavSetupFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function apply()
    {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);

        $eavSetup->addAttribute('catalog_product', 'alternative_color', [
            'type' => 'int',
            'label' => 'Alternative Color',
            'input' => 'select',
            'used_in_product_listing' => true,
            'user_defined' => true,
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public static function getDependencies()
    {
        return [];
    }

    /**
     * {@inheritdoc}
     */
    public function getAliases()
    {
        return [];
    }
}
5
  • I'm getting an error when entering command bin\magento setup:upgrade, can you help? question => link
    – James
    Sep 7, 2019 at 0:29
  • how to create multiple attributes at a time? do we need to use different files for each attribute
    – Manjunath
    Mar 19, 2020 at 6:30
  • @Manjunath to add multiple attributes just keep adding addAttribute lines, as many as you need. You can keep them all in the same file/ I typically only separate installer scripts into multiple files if the install script is dealing with two or more completely different concepts. Mar 20, 2020 at 13:27
  • that post is far from being "quite extensive"
    – gabrieliri
    Feb 5, 2021 at 0:14
  • @gabrieliri if there is something you didn’t understand or felt was lacking, please do let me know what, and I’ll do my best to help you out. Feb 6, 2021 at 1:14
0

Data patch approch apply after Magento 2.3.x version. So, you can use data patch for add or update data in database table.

You need to create a CreateCustomAttr.php file inside app/code/VendorName/ModuleName/Setup/Patch/Data/

Add this below code inside CreateCustomAttr.php file

Reference : https://www.rohanhapani.com/magento-2-create-a-product-attribute-using-data-patches/

<?php

declare (strict_types = 1);

namespace VendorName\ModuleName\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 CreateCustomAttr implements DataPatchInterface {


    private $moduleDataSetup;


    private $eavSetupFactory;


    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        EavSetupFactory $eavSetupFactory
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->eavSetupFactory = $eavSetupFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function apply() {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);

        $eavSetup->addAttribute('catalog_product', 'news_from_date', [
            'type' => 'text',
            'backend' => '',
            'frontend' => '',
            'label' => 'News From Date',
            'input' => 'text',
            'class' => '',
            'source' => '',
            'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
            'visible' => true,
            'required' => true,
            'user_defined' => false,
            'default' => '',
            'searchable' => false,
            'filterable' => false,
            'comparable' => false,
            'visible_on_front' => false,
            'used_in_product_listing' => true,
            'unique' => false,
            'apply_to' => '',
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public static function getDependencies() {
        return [];
    }

    /**
     * {@inheritdoc}
     */
    public function getAliases() {
        return [];
    }
}
0
<?php

declare(strict_types=1);
namespace Moazzam\ProductSeriesAttr\Setup\Patch\Data;

use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;

/**
 * Create the product attribute for specfic attribute set
 *
 * Class ProductSeriesAttrbute
 */
class ProductSeriesAttrbute implements DataPatchInterface
{
    /**
     * @var EavSetup
     */
    protected EavSetup $eavSetup;

    /**
     * @var ModuleDataSetupInterface
     */
    protected ModuleDataSetupInterface $moduleDataSetup;

    /**
     * ProductSeriesAttr constructor.
     * @param EavSetup $eavSetup
     * @param ModuleDataSetupInterface $moduleDataSetup
     */
    public function __construct(EavSetup $eavSetup, ModuleDataSetupInterface
                                         $moduleDataSetup)
    {
        $this->eavSetup = $eavSetup;
        $this->moduleDataSetup = $moduleDataSetup;
    }

    /**
     * Apply the datapatch
     *
     * @return void
     * @throws LocalizedException|\Zend_Validate_Exception
     */
    public function apply()
    {
        $entityTypeId = $this->eavSetup->getEntityTypeId('catalog_product');
        $attributeSetId = $this->eavSetup->getAttributeSetId($entityTypeId, 'Bag');
        $attributeGroupId = $this->eavSetup->getAttributeGroupId(
            $entityTypeId,
            $attributeSetId,
            'Product Details'
        );
        $attributeCode = 'product_series';
        $properties = [
             'type' => 'varchar',
             'label' => 'Product Series',
             'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
             'user_defined' => 1,
            'required' => 0,
             'visible_on_front' => 1,
            'is_used_in_grid' => 1,
            'is_visible_in_grid' => 1,
            'is_filterable_in_grid' => 1
         ];

        $this->eavSetup->addAttribute($entityTypeId, $attributeCode, $properties);
        $this->eavSetup->addAttributeToGroup(
            $entityTypeId,
            $attributeSetId,
            $attributeGroupId,
            $attributeCode
        );
    }
    /**
     * Return the dependencies
     *
     * @return array|string[]
     */
    public static function getDependencies(): array
    {
        return [];
    }
    /**
     * Return the alisas
     *
     * @return array|string[]
     */
    public function getAliases(): array
    {
        return [];
    }
}

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.