0

I made a custom attribute using this code in the Setup/Patch/Data, everything works just fine except when calling the API to get the customer object, it comes without the new custom attribute included, I made an extension_attribute.xml and a Plugin to retrieve it, but Im getting this error:

Error: Call to undefined method Magento\Customer\Api\Data\CustomerExtension::setCustomAttribute() in /var/www/html/app/code/Vendor/Brand/Plugin/AddCustomAttributeToCustomer.php:17

I don't know what im doing wrong

this is the setup code:

<?php

declare (strict_types = 1);

namespace Vendor\Brand\Setup\Patch\Data;

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

class Brands implements DataPatchInterface, PatchRevertableInterface
{
/**
 * @var ModuleDataSetupInterface
 */
private $moduleDataSetup;

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

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

/**
 * @var \Magento\Customer\Model\ResourceModel\Attribute
 */
private $attributeResource;

/**
 * Brand Constructor
 * @param EavSetupFactory $eavSetupFactory
 * @param Config $eavConfig
 * @param \Magento\Customer\Model\ResourceModel\Attribute $attributeResource
 * @param \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup
 */
public function __construct(
    EavSetupFactory $eavSetupFactory,
    Config $eavConfig,
    \Magento\Customer\Model\ResourceModel\Attribute $attributeResource,
    \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup
) {
    $this->eavSetupFactory = $eavSetupFactory;
    $this->eavConfig = $eavConfig;
    $this->attributeResource = $attributeResource;
    $this->moduleDataSetup = $moduleDataSetup;
}

/**
 * @return Brands|void
 * @throws \Magento\Framework\Exception\AlreadyExistsException
 * @throws \Magento\Framework\Exception\LocalizedException
 * @throws \Zend_Validate_Exception
 */
public function apply()
{
    $this->moduleDataSetup->getConnection()->startSetup();
    $this->addPhoneAttribute();
    $this->moduleDataSetup->getConnection()->endSetup();
}

/**
 * @return void
 * @throws \Magento\Framework\Exception\AlreadyExistsException
 * @throws \Magento\Framework\Exception\LocalizedException
 */
public function addPhoneAttribute()
{
    $eavSetup = $this->eavSetupFactory->create();
    $eavSetup->addAttribute(
        \Magento\Customer\Model\Customer::ENTITY,
        'brands',
        [
            'type' => 'varchar',
            'label' => 'Brands',
            'input' => 'multiselect',
            'source' => \Vendor\Brand\Model\Config\Brands::class,
            'required' => false,
            'sort_order' => 999,
            'system' => false,
            'position' => 999,
            'is_used_in_grid' => true,
            'is_visible_in_grid' => true,
            'is_filterable_in_grid' => true,
            'is_searchable_in_grid' => true,
        ]
    );

    $attributeSetId = $eavSetup->getDefaultAttributeSetId(Customer::ENTITY);
    $attributeGroupId = $eavSetup->getDefaultAttributeGroupId(Customer::ENTITY);

    $attribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'brands');
    $attribute->setData('attribute_set_id', $attributeSetId);
    $attribute->setData('attribute_group_id', $attributeGroupId);

    $attribute->setData('used_in_forms', [
        'adminhtml_customer',
        'adminhtml_customer_address',
        'customer_account_edit',
        'customer_address_edit',
        'customer_register_address',
        'customer_account_create'
    ]);

    $this->attributeResource->save($attribute);
}

/**
 * @return array|string[]
 */
public static function getDependencies()
{
    return [];
}

/**
 * @return string
 */
public static function getVersion()
{
    return '1.2.9';
}

/**
 * @return void
 */
public function revert()
{
}

/**
 * @return array|string[]
 */
public function getAliases()
{
    return [];
}
}

and this is the Plugin:

<?php
namespace Vendor\Brand\Plugin;

use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;

 class AddCustomAttributeToCustomer
{
public function afterGetById(
    CustomerRepositoryInterface $subject,
    CustomerInterface $customer
) {
    $customerExtension = $customer->getExtensionAttributes();
    if ($customerExtension === null) {
        $customerExtension = $this->customerExtensionFactory->create();
    }
    $customerExtension->setCustomAttribute('brands', $customer->getCustomAttribute('brands'));
    $customer->setExtensionAttributes($customerExtension);
    return $customer;
  }
}

Here is the extension_attribute.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Customer\Api\Data\CustomerInterface">
    <attribute code="brands" type="array"/>
</extension_attributes>
</config>

and the di.xml:

<?xml version="1.0"?>
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
 <type name="Magento\Customer\Api\CustomerRepositoryInterface">
    <plugin name="add_custom_attribute_to_customer" type="Vendor\Brand\Plugin\AddCustomAttributeToCustomer" sortOrder="10" />
 </type>

2 Answers 2

1

Hello Amjad Alarori you can try below code hope it's work for you.

<?php
namespace Vendor\Brand\Plugin;

use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;

class AddCustomAttributeToCustomer
{
    public function afterGetById(
        CustomerRepositoryInterface $subject,
        CustomerInterface $customer
    ) {
        $customerExtension = $customer->getExtensionAttributes();
        if ($customerExtension === null) {
            $customerExtension = $this->customerExtensionFactory->create();
        }
        //$customerExtension->setCustomAttribute('brands', $customer->getCustomAttribute('brands'));
        $customer->setExtensionAttributes('brands', $customerExtension);
        return $customer;
    }
}
0

It looks like the issue is that the setCustomattribute() method is not defined in the Magento\Customer\Api\Data\CustomerExtension class.

It's likely that you will need to create a custom extension attribute for the Customer object, which will allow you to add your custom attribute when calling the API.

You can do this by creating a new file in your module's Api/Data directory called CustomerExtension.php, and in that file, you should create a new class that extends Magento\Customer\Api\Data\CustomerExtension and add a new public function called setCustomattribute() that sets the value of your custom attribute.

Then you can use this new class in your plugin to set the value of the attribute when calling the API.

You should also update the plugin class so that it uses the new class you just created.

You need to make sure that the plugin class implements \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface and \Magento\Framework\Api\ExtensionAttribute\JoinProcessor\JoinProcessorInterface

Also need to add custom_attribute in extension_attributes.xml file.

Then you can use this new class in your plugin to set the value of the attribute when calling the API.

Hope this help you to resolve the issue.

Happy coding!

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.