0

I'm creating a customer programmatically with a customer interface, and custom attributes are saving as expected, but I want those custom attributes value in the customer_entity table also.

My code is this

db_schema.xml

<table name="customer_entity">
   <column name="is_demo" xsi:type="boolean"  default="0" comment="Is Demo"/>
   <column name="sales_agent" xsi:type="varchar"   comment="Sales Agent"/>
</table>

My customer saving logic.

$customer = $this->customerInterfaceFactory->create();
                    $customer->setWebsiteId($websiteId);
                    $customer->setEmail($data['email']);
                    $customer->setFirstname($data['firstname']);
                    $customer->setLastname($data['lastname']);
                    $customer->setGroupId(1);
                    
                    // my custom fields in customer_entity table
                    $customer->setIsDemo($data['is_demo']);
                    $customer->setSalesAgent($data['sales_agent']);
                    
                    // saving custom attributes

                    if ($data['sales_agent']) {
                        $customer->setCustomAttribute('sales_agent', $data['sales_agent']);
                    }
                    if ($data['is_demo']) {
                        $customer->setCustomAttribute(
                            'is_demo',
                            isset($data['is_demo']) ? 1 : 0
                        );
                    }
                   
                    $hashedPassword = $this->encryptor->getHash($data['password'], true);
                    $this->customerRepository->save($customer, $hashedPassword);
                    $customer = $this->customerAccountManagement->authenticate($data['email'], $data['password']);
                    $this->customerSession->setCustomerDataAsLoggedIn($customer);
                    $this->customerSession->regenerateId();
                    // these variable for new trial approach
                    $this->checkoutSession->setIsTrial(true);
                    $this->customerSession->setIsTrial(true);

extension_attributes.xml

<extension_attributes for="Magento\Customer\Api\Data\CustomerInterface">
        <attribute code="is_demo" type="int"/>
        <attribute code="sales_agent" type="string"/>
</extension_attributes>

but when I do this in my code it says

Error: Call to undefined method Magento\Customer\Model\Data\Customer::setIsDemo()

How can I save those custom attribute values in the customer_entity table when saving customers programmatically?

1 Answer 1

0

Instead of creating a field using db_scheme.xml , i suggest that create a customer type eav attribute and defining the attribute type is static mean 'type' => 'static' in data [catch script.

Example:

<?php

namespace Medline\CustomerHello\Setup\Patch\Data;

use Magento\Customer\Api\CustomerMetadataInterface;
use Magento\Customer\Model\Customer;
use Magento\Customer\Model\ResourceModel\Attribute;
use Magento\Eav\Model\Config;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;

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

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

    /**
     * @var Config
     */
    private Config $eavConfig;

    /**
     * @var Attribute
     */
    private Attribute $attributeResource;

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

    /**
     * Run code inside patch
     * If code fails, patch must be reverted, in case when we are speaking about schema - then under revert
     * means run PatchInterface::revert()
     *
     * If we speak about data, under revert means: $transaction->rollback()
     *
     * @return $this
     */
    public function apply()
    {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);

        $eavSetup->addAttribute(
            Customer::ENTITY,
            'is_demo',
            [
                'input' => 'boolean',
                'is_visible_in_grid' => false,
                'visible' => true,
                'user_defined' => true,
                'is_filterable_in_grid' => false,
                'system' => false,
                'label' => 'IsDemo',
                'source' => null,
                'position' => 900,
                'type' => 'static',
                'is_used_in_grid' => false,
                'required' => false,
            ]
        );

        $eavSetup->addAttributeToSet(
            CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
            CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER,
            'Default',
            'is_demo'
        );

        $attribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'is_demo');
        $attribute->setData(
            'used_in_forms',
            ['adminhtml_customer', 'customer_account_edit']
        );
        $this->attributeResource->save($attribute);

        return $this;
    }

    /**
     * Get array of patches that have to be executed prior to this.
     *
     * Example of implementation:
     *
     * [
     *      \Vendor_Name\Module_Name\Setup\Patch\Patch1::class,
     *      \Vendor_Name\Module_Name\Setup\Patch\Patch2::class
     * ]
     *
     * @return string[]
     */
    public static function getDependencies()
    {
        return [];
    }

    /**
     * Get aliases (previous names) for the patch.
     *
     * @return string[]
     */
    public function getAliases()
    {
        return [];
    }
}

If you create an attribute as static then it will save data in the main entity type customer_entity.

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.