3

Magento 2 product rest API provided custom_attributes and details provided attribute_code and value in /V1/products/:sku API. But V1/products rest API not included custom_attributes details attributes label in products.

I want to need custom_attributes in to the selected attribute value label

Method: GET

URL: http://localhost/magentosample230/rest/V1/products/sku

Actual Response:

    "custom_attributes": [
        {
            "attribute_code": "color",
            "value": "59"
        }
   ]

Expected Response:

"custom_attributes": [
    {
        "attribute_code": "color",
        "value": "59",
        "label": "white"  
    }
]

Any have idea how to get in rest API product selected attribute value "label"

Any help would be appropriated. Thanks.

1
  • I would suggest here to create a new extension attribute of product interface and defined getter setter of all needed index (attribute_code, label and value) or you can try to extend Magento\Framework\Api\AttributeInterface and define your own method with getLabel() and setLabel() Sep 8, 2019 at 6:58

2 Answers 2

3

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));
    }
}
0

Just in case anyone needs this to be purely using the rest API, without a custom module, you can see my answer here: https://magento.stackexchange.com/a/313072/88690

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.