I had this issue during when I create a custom Rest API in fresh magento 2.4.4p4
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