0

I add EAV attribute to a customer address. I can use \Magento\Customer\Model\ResourceModel\Attribute $attributeResource to save the attribute.

According to Magento DevDocs https://devdocs.magento.com/guides/v2.3/extension-dev-guide/attributes.html

/** @var \Magento\Eav\Api\Data\AttributeInterface $attribute */
$attribute->setData('used_in_forms', ['adminhtml_customer']);
$attributeResource->save($attribute);

It works.

I'm trying to use Magento\Eav\Model\AttributeRepository to save the attribute.

The repository contains a method

    public function save(\Magento\Eav\Api\Data\AttributeInterface $attribute)
    {
        try {
            /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute */
            $this->eavResource->save($attribute);
        } catch (\Exception $e) {
        ...
    }

and I see the attribute in eav_attribute database table but there are no records in the table customer_form_attribute.

Maybe someone can explain why?

Code example:

use Magento\Customer\Api\AddressMetadataInterface;
use Magento\Eav\Api\AttributeRepositoryInterface;
use Magento\Eav\Model\Config as EavConfig;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;

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

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

        $attributeCode = 'test_attribute';

        $entityTypeId = AddressMetadataInterface::ENTITY_TYPE_ADDRESS;
        $setId = AddressMetadataInterface::ATTRIBUTE_SET_ID_ADDRESS;
        $eavSetup->addAttribute($entityTypeId, $attributeCode, [
            'type' => 'int',
            'input' => 'boolean',
            'label' => 'Test attribute',
            'required' => 0,
            'user_defined' => 1,
            'default' => 0,
            'system' => 0,
            'position' => 60,
        ]);

        $eavSetup->addAttributeToSet($entityTypeId, $setId, null, $attributeCode);

        $attribute = $this->eavConfig->getAttribute($entityTypeId, $attributeCode);
        $attribute->setData('used_in_forms', [
            'adminhtml_customer_address',
            'customer_address_edit',
            'customer_register_address'
        ]);

        // works. deprecated, I remember
        // $attribute->getResource()->save($attribute);

        // the attribute is saved, but the information on the forms in which the attribute is added is not saved
        $this->attributeRepository->save($attribute);
    }
0

AttributeResource (\Magento\Customer\Model\ResourceModel\Attribute) extends \Magento\Eav\Model\ResourceModel\Attribute which extends \Magento\Eav\Model\ResourceModel\Entity\Attribute

\Magento\Eav\Model\ResourceModel\Attribute contains _afterSave method. This method saves data to the table customer_form_attribute.

\Magento\Eav\Model\AttributeRepository uses \Magento\Eav\Model\ResourceModel\Entity\Attribute $eavResource directly:

$this->eavResource->save($attribute);

without _afterSave. For this reason, the information about adding an attribute to forms is not saved.

Is that how it should work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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