3

How can we create new product custom attribute of type boolean(yes/no) using db_schema.xml(of custom extension) as InstallData or InstallSchema file is not being used in Magento 2.3.0 ?

2
  • Have you try anything? Commented Dec 25, 2018 at 13:25
  • OK, I agree what Jisse told, anyway I think the right approach is that custom attributes are more used for situation where you also need some GUI for the attributes (like products) ... and extended attribute for somethig more complex data (quote, order).
    – emastyle
    Commented Feb 28, 2019 at 16:49

3 Answers 3

4

I think the goal is not to add EAV attributes in a scripted way anyway. For sure, the Declarative Schemas are not meant to add product attributes. Instead, consider using Extension Attributes instead (https://devdocs.magento.com/guides/v2.3/extension-dev-guide/attributes.html): Add a file extension_attributes.xml that defines your attribute. Next, create your own separate table using db_schema.xml. And then use Plugins (aka Interceptors) to mimic the old behaviour of JOINs by adding your own data to models and collections with methods like afterGetById or before saving the data with beforeSave. It's a lot of work, but allows for decoupling of your code.

1

Use a data patch: Develop data and schema patches

There you can use Magento\Eav\Setup\EavSetup::addAttribute to create your custom product attributes.

For Example:

<?php

namespace Test\Module\Setup\Patch\Data;

use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Catalog\Model\Product;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Catalog\Model\Product\Attribute\Source\Boolean as SourceBoolean;
use Magento\Catalog\Model\Product\Attribute\Backend\Boolean as BackendBoolean;

class CreateProductAttributes implements DataPatchInterface
{
    /**
     * @var EavSetupFactory
     */
    protected $eavSetupFactory;

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

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

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

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

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

        $eavSetup->addAttribute(
            Product::ENTITY,
            'custom_attribute_flag',
            [
                'type' => 'int',
                'frontend' => '',
                'label' => 'Custom Attribute Flag',
                'input' => 'boolean',
                'backend' => BackendBoolean::class,
                'source' => SourceBoolean::class,
                'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
                'visible' => false,
                'required' => false,
                'user_defined' => false,
                'default' => '',
                'searchable' => false,
                'filterable' => false,
                'comparable' => false,
                'visible_on_front' => false,
                'unique' => false,
                'apply_to' => ''
            ]
        );
    }
}
0
<?php

declare(strict_types=1);

namespace Vendor\Module\Setup\Patch\Data;

use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Catalog\Model\Product;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Catalog\Model\Product\Attribute\Source\Boolean as SourceBoolean;
use Magento\Catalog\Model\Product\Attribute\Backend\Boolean as BackendBoolean;

/**
 * Create the attribute for products
 *
 * Class AddAttribute
 */
class AddAttribute implements DataPatchInterface
{
    /**
     * ModuleDataSetupInterface
     *
     * @var ModuleDataSetupInterface
     */
    private ModuleDataSetupInterface $moduleDataSetup;
    /**
     * EavSetupFactory
     *
     * @var EavSetupFactory
     */
    private EavSetupFactory $eavSetupFactory;
    /**
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param EavSetupFactory          $eavSetupFactory
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        EavSetupFactory $eavSetupFactory
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->eavSetupFactory = $eavSetupFactory;
    }
    /**
     * {@inheritdoc}
     */
    public function apply()
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
        $eavSetup->addAttribute(Product::ENTITY, 'is_recycable', [
            'type' => 'int',
            'backend' => BackendBoolean::class,
            'frontend' => '',
            'label' => 'Enable Recyclable',
            'input' => 'boolean',
            'class' => '',
            'source' => SourceBoolean::class,
            'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
            'visible' => true,
            'required' => false,
            '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(): array
    {
        return [];
    }
    /**
     * {@inheritdoc}
     */
    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.