0

I had this issue during when I create a custom Rest API in fresh magento 2.4.4p4

enter image description here

As you can see the error I get is "Class array does not exist"

Below are my code folder structure, which I found to be correct already

app/code/Wowshop/ApiFarhan/
├── Api/
│   └── CustomInterface.php
├── etc/
│   ├── di.xml
│   ├── webapi.xml
│   └── module.xml
├── Model/
│   └── Custom.php
├── composer.json
└── registration.php

Please find below content of the 7 file here

app/code/Wowshop/ApiFarhan/Api/CustomInterface.php


namespace Wowshop\ApiFarhan\Api;

interface CustomInterface
{
    /**
     * POST for update address API
     * @param int $address_id
     * @param string $address_data
     * @return array
     */
    public function updateAddress($address_id, array $address_data);
    /**
     * POST to add new address for a customer
     * @param int $customer_id
     * @param array $address_data
     * @return array
     */
    public function addAddress($customer_id, array $address_data);
}

app/code/Wowshop/ApiFarhan/etc/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">
    <preference for="Wowshop\ApiFarhan\Api\CustomInterface" type="Wowshop\ApiFarhan\Model\Custom"/>
</config>

app/code/Wowshop/ApiFarhan/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Wowshop_ApiFarhan" setup_version="1.0.0"/>
</config>

app/code/Wowshop/ApiFarhan/etc/webapi.xml

<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Webapi/etc/webapi.xsd">
    <route url="/V1/wowshop/address/add" method="POST">
        <service class="Wowshop\ApiFarhan\Api\CustomInterface" method="addAddress"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
    <route url="/V1/wowshop/address/update" method="POST">
        <service class="Wowshop\ApiFarhan\Api\CustomInterface" method="updateAddress"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

app/code/Wowshop/ApiFarhan/Model/Custom.php

<?php

namespace Wowshop\ApiFarhan\Model;

use Wowshop\ApiFarhan\Api\CustomInterface;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Customer\Api\Data\AddressInterface;
use Magento\Customer\Api\Data\AddressInterfaceFactory;
use Magento\Customer\Api\Data\RegionInterfaceFactory;
use Magento\Customer\Api\CustomerRepositoryInterface;

class Custom implements CustomInterface
{
    private $addressRepository;
    private $addressFactory;
    private $regionFactory;
    private $customerRepository;

    public function __construct(
        AddressRepositoryInterface $addressRepository,
        AddressInterfaceFactory $addressFactory,
        RegionInterfaceFactory $regionFactory,
        CustomerRepositoryInterface $customerRepository
    ) {
        $this->addressRepository = $addressRepository;
        $this->addressFactory = $addressFactory;
        $this->regionFactory = $regionFactory;
        $this->customerRepository = $customerRepository;
    }

     /**
     * Accept address_id and new address data and return the updated data to user
     * @author : Farhan
     *
     * @api
     * @param int $address_id Users address_id.
     * @param string $address_data Users address.
     * @return array Updated data to user
     */  
    public function updateAddress($address_id, array $address_data)
    {
        try {
            /** @var AddressInterface $address */
            $address = $this->addressRepository->getById($address_id);
            foreach ($address_data as $key => $value) {
                if (method_exists($address, 'set' . ucfirst($key))) {
                    $address->{'set' . ucfirst($key)}($value);
                }
            }
            $this->addressRepository->save($address);
            return ['address' => $this->convertAddressToArray($address)];
        } catch (\Exception $exception) {
            return ['error' => $exception->getMessage()];
        }
    }

    /**
     * Convert AddressInterface to array
     *
     * @param AddressInterface $address
     * @return array
     */
    private function convertAddressToArray(AddressInterface $address)
    {
        return [
            'id' => $address->getId(),
            'customer_id' => $address->getCustomerId(),
            // 'region' => [
            //     'region_code' => $address->getRegion()->getRegionCode(),
            //     'region' => $address->getRegion()->getRegion(),
            //     'region_id' => $address->getRegion()->getRegionId()
            // ],
            'firstname' => $address->getFirstname(),
            'lastname' => $address->getLastname(),
            'telephone' => $address->getTelephone(),
            'street' => $address->getStreet(),
            'city' => $address->getCity(),
            'region' => $address->getRegion(),
            'postcode' => $address->getPostcode(),
            'country_id' => $address->getCountryId()
            // 'custom_attributes' => $address->getCustomAttributes()
        ];
    }


     /**
     * Accept customer_data and new address data and return the updated data to user
     * @author : Farhan
     *
     * @api
     * @param int $customer_id Users customer_id.
     * @param array $address_data Users address.
     * @return array Updated data to user
     */  
    public function addAddress($customer_id, array $address_data)
    {
        try {
            $customer = $this->customerRepository->getById($customer_id);

            /** @var AddressInterface $address */
            $address = $this->addressFactory->create();
            $address->setCustomerId($customer_id);

            // Set default values for required fields if not provided
            if (!isset($address_data['street'])) {
                throw new \Exception("Street is a required field.");
            }
            if (!isset($address_data['country_id'])) {
                throw new \Exception("Country ID is a required field.");
            }
            if (!isset($address_data['region']) || !isset($address_data['region']['region_code']) || !isset($address_data['region']['region_id'])) {
                throw new \Exception("Region details are required fields.");
            }

            foreach ($address_data as $key => $value) {
                if (method_exists($address, 'set' . ucfirst($key))) {
                    $address->{'set' . ucfirst($key)}($value);
                }
            }

            // Manually set region data if provided
            if (isset($address_data['region'])) {
                $region = $this->regionFactory->create();
                $region->setRegionCode($address_data['region']['region_code']);
                $region->setRegion($address_data['region']['region']);
                $region->setRegionId($address_data['region']['region_id']);
                $address->setRegion($region);
            }

            $this->addressRepository->save($address);

            return ['address' => $this->convertAddressToArray($address)];
        } catch (\Exception $exception) {
            return ['error' => $exception->getMessage()];
        }
    }

}

app/code/Wowshop/ApiFarhan/composer.json

{
    "name": "wowshop/api-farhan",
    "description": "Custom API module",
    "require": {
        "php": "~7.4.0||~8.0.0||~8.1.0"
    },
    "type": "magento2-module",
    "version": "1.0.0",
    "license": [
        "OSL-3.0",
        "AFL-3.0"
    ],
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Wowshop\\ApiFarhan\\": ""
        }
    }
}

app/code/Wowshop/ApiFarhan/registration.php

<?php
use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
    ComponentRegistrar::MODULE,
    'Wowshop_ApiFarhan',
    __DIR__
);

I am unable to figure out how to resolve this isssue, from my checking the docblock I put already correct and same as per the CustomInterface.php and Custom.php

I have tried changing the @param array $address_data in both file to @param string[] $address_data or @param string $address_data but none helps as it gives out other error : Notice: Array to string conversion

Please help me understand how this error occur and how to fix this

1 Answer 1

1

Here is the corrected code for your Magento module

app/code/Wowshop/ApiFarhan/Api/CustomInterface.php

<?php

namespace Wowshop\ApiFarhan\Api;

interface CustomInterface
{
    /**
     * POST for update address API
     * @param int $address_id
     * @param mixed $address_data
     * @return array
     */
    public function updateAddress($address_id,$address_data);
    /**
     * POST to add new address for a customer
     * @param int $customer_id
     * @param mixed $address_data
     * @return array
     */
    public function addAddress($customer_id,$address_data);
}

app/code/Wowshop/ApiFarhan/Model/Custom.php

<?php

namespace Wowshop\ApiFarhan\Model;

use Wowshop\ApiFarhan\Api\CustomInterface;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Customer\Api\Data\AddressInterface;
use Magento\Customer\Api\Data\AddressInterfaceFactory;
use Magento\Customer\Api\Data\RegionInterfaceFactory;
use Magento\Customer\Api\CustomerRepositoryInterface;

class Custom implements CustomInterface
{
    private $addressRepository;
    private $addressFactory;
    private $regionFactory;
    private $customerRepository;

    public function __construct(
        AddressRepositoryInterface $addressRepository,
        AddressInterfaceFactory $addressFactory,
        RegionInterfaceFactory $regionFactory,
        CustomerRepositoryInterface $customerRepository
    ) {
        $this->addressRepository = $addressRepository;
        $this->addressFactory = $addressFactory;
        $this->regionFactory = $regionFactory;
        $this->customerRepository = $customerRepository;
    }

    /**
     * Accept address_id and new address data and return the updated data to user
     *
     * @api
     * @param int $address_id Users address_id.
     * @param mixed $address_data Users address.
     * @return array
     */  
    public function updateAddress($address_id, $address_data)
    {
        // Code 
    }

    /**
     * Convert AddressInterface to array
     *
     * @param AddressInterface $address
     * @return array
     */
    private function convertAddressToArray(AddressInterface $address)
    {
        //code
    }

    /**
     * Accept customer_data and new address data and return the updated data to user
     *
     * @api
     * @param int $customer_id Users customer_id.
     * @param mixed $address_data Users address.
     * @return array
     */  
    public function addAddress($customer_id, $address_data)
    {
        //code
    }
}
4
  • Thank you soo much, I don't know what you changed, but suddenly it works, tqvm Commented Jun 27 at 6:36
  • Please accept this solution and upvote Commented Jun 27 at 6:38
  • Hi, @Devang, I encounter this same issue again on a Custom API that I created, can you please help explain what do you change, this issue really struck my nerve as I have look clearly and cannot find any abnormalities in my code Commented Jul 1 at 8:24
  • Hi @Devang, hope you can help me to fix this ya, I posted other question here magento.stackexchange.com/questions/374076/… Commented Jul 1 at 8:45

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.