1

I'm trying to add custom extension_attribute to customer API (REST) in Magento 2. The logic is working for single record API V1/customers/{{CUSTOEMR_ID}} But it is not working for search API V1/customers/search?searchCriteria For search API I'm getting follwing error:

Fatal error: Uncaught TypeError: Argument 2 passed to Vendor\Extension\Plugin\Customer\MyCustomerRepository: :afterGetList() must be an instance of Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory, instance of Magento\Framework\Api\SearchResults given, called in /var/www/html/vendor/magento/framework/Interception/Interceptor.php on line 146 and defined in /var/www/html/app/code/Vendor/Extension/Plugin/Customer/MyCustomerRepository.php: 57
Stack trace:
#0 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(146): Vendor\Extension\Plugin\Customer\MyCustomerRepository->afterGetList(Object(Magento\Customer\Model\ResourceModel\CustomerRepository\Interceptor), Object(Magento\Framework\Api\SearchResults), Object(Magento\Framework\Api\SearchCriteria))
#1 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Customer\Model\ResourceModel\CustomerRepository\Interceptor->Magento\Framework\Int in /var/www/html/app/code/Vendor/Extension/Plugin/Customer/MyCustomerRepository.php on line 57

Following are the used files

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\Model\ResourceModel\CustomerRepository">       
        <plugin name="Vendor_Extension::MyCustomerRepository" type="\Vendor\Extension\Plugin\Customer\MyCustomerRepository"/>
    </type>
</config>

extension_attributes.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="reward_points_balance" type="float"/>
    </extension_attributes>
</config>

MyCustomerRepository.php

<?php

namespace Vendor\Extension\Plugin\Customer;

use Magento\Customer\Api\CustomerRepositoryInterface as CustomerRepository;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Customer\Api\Data\CustomerSearchResultsInterface;
use Magento\Framework\Api\ExtensionAttributesFactory;
use Magento\Customer\Api\Data\CustomerExtensionInterface;
use Magento\Framework\App\ObjectManager;

class MyCustomerRepository
{
    private $extensionFactory;

    public function __construct(
        ExtensionAttributesFactory $extensionFactory = null
    ) {
        $this->extensionFactory = $extensionFactory
            ?: ObjectManager::getInstance()->get(ExtensionAttributesFactory::class);
    }

    public function afterGetById(CustomerRepository $subject, CustomerInterface $customer)
    {
        $extensionAttributes = $customer->getExtensionAttributes();
        if ($extensionAttributes === null) {
            /** @var CustomerExtensionInterface $extensionAttributes */
            $extensionAttributes = $this->extensionFactory->create(CustomerInterface::class);
            $customer->setExtensionAttributes($extensionAttributes);
        }
        if ($extensionAttributes->getRewardPointsBalance() === null) {
            $fRewardPoints = $this->getRewardPoints($customer);
            $extensionAttributes->setRewardPointsBalance($fRewardPoints);
        }
        return $customer;
    }

    public function afterGetList(CustomerRepository $subject, CustomerSearchResultsInterface $searchResult)
    {
        $customers = $searchResult->getItems();

        foreach($customers as $customer)
        {
            $extensionAttributes = $customer->getExtensionAttributes();
            if ($extensionAttributes === null) {
                /** @var CustomerExtensionInterface $extensionAttributes */
                $extensionAttributes = $this->extensionFactory->create(CustomerInterface::class);
                $customer->setExtensionAttributes($extensionAttributes);
            }
            if ($extensionAttributes->getRewardPointsBalance() === null) {
                $fRewardPoints = $this->getRewardPoints($customer);
                $extensionAttributes->setRewardPointsBalance($fRewardPoints);
            }
        }


        return $searchResult;
    }

    private function getRewardPoints(CustomerInterface $customer)
    {
        $customerId = $customer->getId();

        $fCustomerRewardPoints = 10.00;

        return $fCustomerRewardPoints;
    }
}
0
+50

We need to pass the instance of CustomerSearchResultsInterface, not the interface. \Magento\Framework\Api\SearchResults is the instance of the interface. But, it's safe if you don't set the instance of $result.

Changes your plugin:

public function afterGetList(CustomerRepository $subject, \Magento\Framework\Api\SearchResults $results) {
    ......
}

Or

public function afterGetList(CustomerRepository $subject, $results) {
    ......
}
  • Thanks @Khoa, it worked! – Suyog Aug 1 at 8:48

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.