I have added attribute value with label
in custom_attributes
products Rest API.
Also with added attribute visible_on_storefront
Follow below file path to create cusotm module and fix the requirement.
File path: magento/app/code/Vendor/AttributelabelApi/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Vendor_AttributelabelApi',
__DIR__
);
File path: magento/app/code/Vendor/AttributelabelApi/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="Vendor_AttributelabelApi" setup_version="1.0.0">
<sequence>
<module name="Magento_Webapi" />
</sequence>
</module>
</config>
File path: magento/app/code/Vendor/AttributelabelApi/etc/webapi.xml
<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<route url="/V1/products/:sku" method="GET">
<service class="Vendor\AttributelabelApi\Api\ProductsInterface" method="getAdditional"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
</routes>
File path: magento/app/code/Vendor/AttributelabelApi/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="Vendor\AttributelabelApi\Api\ProductsInterface" type="Vendor\AttributelabelApi\Model\Products" />
</config>
File path:
magento/app/code/Vendor/AttributelabelApi/Api/ProductsInterface.php
<?php
namespace Vendor\AttributelabelApi\Api;
interface ProductsInterface
{
/**
* Get info about product by product SKU
*
* @param string $sku
* @param bool $editMode
* @param int|null $storeId
* @param bool $forceReload
* @return \Magento\Catalog\Api\Data\ProductInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getAdditional($sku, $editMode = false, $storeId = null, $forceReload = false);
}
File path:
magento/app/code/Vendor/AttributelabelApi/Model/Products.php
<?php
namespace Vendor\AttributelabelApi\Model;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Vendor\AttributelabelApi\Api\ProductsInterface;
class Products implements ProductsInterface
{
/**
* @var \Magento\Catalog\Model\ProductFactory
*/
protected $productFactory;
/**
* @var Product[]
*/
protected $instances = [];
/**
* @var \Magento\Catalog\Model\ResourceModel\Product
*/
protected $resourceModel;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $storeManager;
/**
* @var \Magento\Catalog\Helper\ImageFactory
*/
protected $helperFactory;
/**
* @var \Magento\Store\Model\App\Emulation
*/
protected $appEmulation;
/**
* Review model
*
* @var \Magento\Review\Model\ReviewFactory
*/
protected $_reviewFactory;
/**
* Review resource model
*
* @var \Magento\Review\Model\ResourceModel\Review\CollectionFactory
*/
protected $_reviewsColFactory;
/**
* @var PriceCurrencyInterface
*/
protected $priceCurrency;
protected $_attributeLoading;
/**
* ProductRepository constructor.
* @param \Magento\Catalog\Model\ProductFactory $productFactory
* @param \Magento\Catalog\Model\ResourceModel\Product $resourceModel
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Review\Model\ReviewFactory $reviewFactory
* @param \Magento\Review\Model\ResourceModel\Review\CollectionFactory $collectionFactory
* @param PriceCurrencyInterface $priceCurrency
*/
public function __construct(
\Magento\Catalog\Model\ProductFactory $productFactory,
\Magento\Catalog\Model\ResourceModel\Product $resourceModel,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Store\Model\App\Emulation $appEmulation,
\Magento\Catalog\Helper\ImageFactory $helperFactory,
\Magento\Review\Model\ReviewFactory $reviewFactory,
\Magento\Review\Model\ResourceModel\Review\CollectionFactory $collectionFactory,
PriceCurrencyInterface $priceCurrency,
\Magento\Catalog\Model\ResourceModel\ProductFactory $attributeLoading
) {
$this->productFactory = $productFactory;
$this->storeManager = $storeManager;
$this->resourceModel = $resourceModel;
$this->helperFactory = $helperFactory;
$this->appEmulation = $appEmulation;
$this->_reviewFactory = $reviewFactory;
$this->_reviewsColFactory = $collectionFactory;
$this->priceCurrency = $priceCurrency;
$this->_attributeLoading = $attributeLoading;
}
public function getAdditional($sku, $editMode = false, $storeId = null, $forceReload = false)
{
$cacheKey = $this->getCacheKey([$editMode, $storeId]);
if (!isset($this->instances[$sku][$cacheKey]) || $forceReload) {
$product = $this->productFactory->create();
$productId = $this->resourceModel->getIdBySku($sku);
if (!$productId) {
throw new NoSuchEntityException(__('Requested product doesn\'t exist'));
}
if ($editMode) {
$product->setData('_edit_mode', true);
}
if ($storeId !== null) {
$product->setData('store_id', $storeId);
} else {
$storeId = $this->storeManager->getStore()->getId();
}
$product->load($productId);
$excludeAttr = [];
$attributes = $product->getAttributes();
foreach ($attributes as $attribute) {
$data = [];
if ($this->isVisibleOnFrontend($attribute, $excludeAttr))
{
$code = $attribute->getAttributeCode();
$value = $product->getResource()->getAttributeRawValue($product->getId(), $code, '1');
if ($value instanceof Phrase) {
$value = (string)$value;
} elseif ($attribute->getFrontendInput() == 'price' && is_string($value)) {
$value = $this->priceCurrency->convertAndFormat($value);
} elseif ($attribute->getFrontendInput() == 'select') {
$value = $attribute->getSource()->getOptionText($value);
$attr = $product->getResource()->getAttribute($code);
if ($attr->usesSource()) {
$optionId = $attr->getSource()->getOptionId($value);
}
} elseif ($attribute->getFrontendInput() == 'multiselect') {
// added if condition in order or resolve the explode issue if value is empty.
if($value) {
$multiselectOptionsArray = explode(',', $value);
foreach ($multiselectOptionsArray as $k => $optionKey) {
$multiselectOptionsArray[$k] = $attribute->getSource()->getOptionText($optionKey);
}
$value = implode(', ', $multiselectOptionsArray);
$multiSelectValue = explode(', ', $value);
foreach ($multiSelectValue as $a => $attValue) {
$attr = $product->getResource()->getAttribute($code);
if ($attr->usesSource()) {
$optionIdInfo = $attr->getSource()->getOptionId($attValue);
$attArray[$a] = $optionIdInfo;
$optionId = implode(', ', $attArray);
}
}
}
}
if (is_string($value) && strlen($value)) {
$data[$attribute->getAttributeCode()] = [
'title' => $attribute->getFrontendLabel(),
'label' => __($value),
'code' => $optionId,
'visible_on_storefront' => $attribute->getIsVisibleOnFront()
];
}
$product->setCustomAttribute($attribute->getAttributeCode(), $data);
}
}
$this->instances[$sku][$cacheKey] = $product;
$this->instancesById[$product->getId()][$cacheKey] = $product;
}
return $this->instancesById[$product->getId()][$cacheKey];
}
/**
* Get key for cache
*
* @param array $data
* @return string
*/
protected function getCacheKey($data)
{
$serializeData = [];
foreach ($data as $key => $value) {
if (is_object($value)) {
$serializeData[$key] = $value->getId();
} else {
$serializeData[$key] = $value;
}
}
return md5(serialize($serializeData));
}
protected function isVisibleOnFrontend(
\Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute,
array $excludeAttr
) {
return ($attribute->getIsVisibleOnFront() && !in_array($attribute->getAttributeCode(), $excludeAttr));
}
}