Skip to content

How to include a custom attribute in the Customer object when calling through API

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 MagentoCustomerApiDataCustomerExtension::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 VendorBrandSetupPatchData;

use MagentoCustomerModelCustomer;
use MagentoEavModelConfig;
use MagentoEavSetupEavSetupFactory;
use MagentoFrameworkSetupModuleDataSetupInterface;
use MagentoFrameworkSetupPatchDataPatchInterface;
use MagentoFrameworkSetupPatchPatchRevertableInterface;

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

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

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

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

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

/**
 * @return Brands|void
 * @throws MagentoFrameworkExceptionAlreadyExistsException
 * @throws MagentoFrameworkExceptionLocalizedException
 * @throws Zend_Validate_Exception
 */
public function apply()
{
    $this->moduleDataSetup->getConnection()->startSetup();
    $this->addPhoneAttribute();
    $this->moduleDataSetup->getConnection()->endSetup();
}

/**
 * @return void
 * @throws MagentoFrameworkExceptionAlreadyExistsException
 * @throws MagentoFrameworkExceptionLocalizedException
 */
public function addPhoneAttribute()
{
    $eavSetup = $this->eavSetupFactory->create();
    $eavSetup->addAttribute(
        MagentoCustomerModelCustomer::ENTITY,
        'brands',
        [
            'type' => 'varchar',
            'label' => 'Brands',
            'input' => 'multiselect',
            'source' => VendorBrandModelConfigBrands::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 VendorBrandPlugin;

use MagentoCustomerApiDataCustomerInterface;
use MagentoCustomerApiCustomerRepositoryInterface;

 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="MagentoCustomerApiDataCustomerInterface">
    <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="MagentoCustomerApiCustomerRepositoryInterface">
    <plugin name="add_custom_attribute_to_customer" type="VendorBrandPluginAddCustomAttributeToCustomer" sortOrder="10" />
 </type>