1

I added a custom attribute to Customer and it shows on admin forms as expected. But values not getting saved upon saving the form. Bellow is patch file I used to create the attribute.

<?php
namespace Vendor\Module\Setup\Patch\Data;

use Magento\Customer\Model\Customer;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\SchemaPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Setup\EavSetupFactory;

/**
* Patch is mechanism, that allows to do atomic upgrade data changes
*/
class CustomerDataPatch implements
    DataPatchInterface
{
    /**
     * @var ModuleDataSetupInterface $moduleDataSetup
     */
    private $moduleDataSetup;

    private $eavSetupFactory;

    private $eavConfig;

    /**
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param EavSetupFactory $eavSetupFactory
     * @param \Magento\Eav\Model\Config $eavConfig
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        EavSetupFactory $eavSetupFactory,
        \Magento\Eav\Model\Config $eavConfig
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->eavSetupFactory = $eavSetupFactory;
        $this->eavConfig = $eavConfig;
    }

    /**
     * Do Upgrade
     *
     * @return void
     */
    public function apply()
    {
        $eavSetup = $this->eavSetupFactory->create();

        $eavSetup->addAttribute(
            Customer::ENTITY,
            'customer_agreement_end_date',
            [
                'type' => 'static',
                'label' => 'Aggrement End Date',
                'input' => 'date',
                'sort_order'   => 20,
                'frontend' => \Magento\Eav\Model\Entity\Attribute\Frontend\Datetime::class,
                'backend' => \Magento\Eav\Model\Entity\Attribute\Backend\Datetime::class,
                'global' => 1,
                'visible' => true,
                'required' => false,
                'system' => false,
                'visible_on_front' => true,
                'unique' => false,
                'group' => 'General',
                'input_filter' => 'date',
                'position' => 20,
                'validate_rules' => '{"input_validation":"date"}',
                'note' => 'End date of the aggrement',
            ]
        );

        $customAttribute = $this->eavConfig->getAttribute(Customer::ENTITY,'customer_agreement_end_date');
        $customAttribute->setData(
            'used_in_forms',
            [
                'adminhtml_customer_address',
                'customer_address_edit'
            ]
        );

        $customAttribute->save();
    }

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

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

        ];
    }
}

Bellow is the database record created in eav_attribute table. I have got dob field (which comes from default Magento) as well for comparison.

enter image description here

The element is visible in Customer edit form in magento admin. But for some reason, values are not getting saved when I saving the customer. I expect the attribute value be saved upon saving the customer, without any observer or plugin code and Magento handles it itself. Please correct me if I'm wrong or please show me what I have done wrong. Thanks in advance.

1
  • Any advice is highly appreciated. Please share your experience if you had similar issue and got the solution for that
    – Ajith
    Commented Feb 25, 2020 at 9:41

2 Answers 2

3
+50

As you want to add a static attribute. An entity can have some static attributes, whose values are stored in entity main table. So you have to create a column inside the entity main table, here is customer_entity

Vendor/Module/etc/db_schema.xml

<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
    <table name="customer_entity">
        <column xsi:type="date" name="customer_agreement_end_date" comment="End date of the agreement"/>
    </table>
</schema>

Or even a Schema Update Vendor/Module/Setup/Patch/Schema/AddCustomerAgreementEndDateColumn.php

<?php

namespace Vendor\Module\Setup\Patch\Schema;

use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\Patch\SchemaPatchInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class AddCustomerAgreementEndDateColumn implements SchemaPatchInterface
{
    /**
     * @var ModuleDataSetupInterface
     */
    private $moduleDataSetup;

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


    public static function getDependencies()
    {
        return [];
    }

    public function getAliases()
    {
        return [];
    }


    public function apply()
    {
        $this->moduleDataSetup->startSetup();
        $this->moduleDataSetup->getConnection()->addColumn(
            $this->moduleDataSetup->getTable('customer_entity'),
            'customer_agreement_end_date',
            [
                'type' => Table::TYPE_DATE,
                'nullable' => true,
                'comment' => 'End date of the agreement',
            ]
        );
        $this->moduleDataSetup->endSetup();
    }
}

Vendor/Module/Setup/Patch/Data/AddCustomerAgreementEndDateCustomerAttribute.php

<?php

namespace Vendor\Module\Setup\Patch\Data;

use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetup;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Eav\Model\Entity\Attribute\Set;
use Magento\Eav\Model\Entity\Attribute\SetFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;

/**
 * Class AddCustomerAgreementEndDateCustomerAttribute add attribute
 */
class AddCustomerAgreementEndDateCustomerAttribute implements DataPatchInterface, PatchRevertableInterface
{

    /**
     * @var ModuleDataSetupInterface
     */
    private $moduleDataSetup;
    /**
     * @var CustomerSetup
     */
    private $customerSetupFactory;
    /**
     * @var SetFactory
     */
    private $attributeSetFactory;

    /**
     * Constructor
     *
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param CustomerSetupFactory $customerSetupFactory
     * @param SetFactory $attributeSetFactory
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        CustomerSetupFactory $customerSetupFactory,
        SetFactory $attributeSetFactory
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->customerSetupFactory = $customerSetupFactory;
        $this->attributeSetFactory = $attributeSetFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function apply()
    {
        $this->moduleDataSetup->getConnection()->startSetup();
        /** @var CustomerSetup $customerSetup */
        $customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
        $customerEntity = $customerSetup->getEavConfig()->getEntityType(Customer::ENTITY);
        $attributeSetId = $customerEntity->getDefaultAttributeSetId();

        /** @var $attributeSet Set */
        $attributeSet = $this->attributeSetFactory->create();
        $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);

        $customerSetup->addAttribute(
            Customer::ENTITY,
            'customer_agreement_end_date',
            [
                'type' => 'static',
                'label' => 'Agreement End Date',
                'input' => 'date',
                'frontend' => \Magento\Eav\Model\Entity\Attribute\Frontend\Datetime::class,
                'backend' => \Magento\Eav\Model\Entity\Attribute\Backend\Datetime::class,
                'required' => false,
                'sort_order' => 100,
                'global' => 1,
                'visible' => true,
                'visible_on_front' => true,
                'unique' => false,
                'group' => 'General',
                'system' => false,
                'input_filter' => 'date',
                'position' => 100,
                'validate_rules' => '{"input_validation":"date"}',
                'admin_checkout' => 1
            ]
        );

        $attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'customer_agreement_end_date');
        $attribute->addData([
            'used_in_forms' => [
                'adminhtml_customer',
                'customer_account_edit'
            ]
        ]);
        $attribute->addData([
            'attribute_set_id' => $attributeSetId,
            'attribute_group_id' => $attributeGroupId

        ]);
        $attribute->save();

        $this->moduleDataSetup->getConnection()->endSetup();
    }

    public function revert()
    {
        $this->moduleDataSetup->getConnection()->startSetup();
        /** @var CustomerSetup $customerSetup */
        $customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
        $customerSetup->removeAttribute(\Magento\Customer\Model\Customer::ENTITY, 'customer_agreement_end_date');

        $this->moduleDataSetup->getConnection()->endSetup();
    }

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

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

        ];
    }
}

enter image description here

1
  • Yes this worked for me. And this is what I was expecting. Thank you very much
    – Ajith
    Commented Mar 17, 2020 at 2:29
1

There are two things that need to be updated to resolve your issue.

First, change the type value from static to datetime

Second, change used_in_forms value from adminhtml_customer_address to adminhtml_customer because you want to add your attribute in customer edit form.

Remove the patch from database and delete existing attribute from eav_attribute table. Execute setup:upgrade command and check. It should work.

1
  • 1
    Sutaria, what you explain is correct. But I needed to add a static attribute. Thank you very much for your support.
    – Ajith
    Commented Mar 17, 2020 at 2:28

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.