Question

Hello everyone i would like to add an extension_attribute to quote item in magento 2. I create extension attribute:

<?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\Quote\Api\Data\CartItemInterface">
        <attribute code="image" type="string" />
    </extension_attributes>
</config>

Then i have created plugin that set an extension attribute "image" to every quote item in qoute, this plugin is running on afterGet magento rest endpoint

"V1/guest-carts/:cartId/totals":

/**
 * @var CartItemExtensionFactory
 */
protected $cartItemExtension;

/**
 * @param CartItemExtensionFactory $cartItemExtension
 * @param ProductRepositoryInterfaceFactory $productRepository
 */
public function __construct(
    CartItemExtensionFactory $cartItemExtension
) {
    $this->cartItemExtension = $cartItemExtension;
}

/**
 * Add attribute values
 *
 * @param CartRepositoryInterface $subject ,
 * @param   $quote
 * @return mixed $quoteData
 * @throws NoSuchEntityException
 */
public function afterGet(
    CartRepositoryInterface $subject,
    $quote
) {
    return $this->setAttributeValue($quote);
}

/**
 * set value of attributes
 *
 * @param $quote
 * @return mixed $extensionAttributes
 * @throws NoSuchEntityException
 */
private function setAttributeValue($quote)
{
    if ($quote->getItemsCount()) {
        foreach ($quote->getItems() as $item) {
            $extensionAttributes = $item->getExtensionAttributes();
            if ($extensionAttributes === null) {
                $extensionAttributes = $this->cartItemExtension->create();
            }
            $extensionAttributes->setImage('fooo');
            $item->setExtensionAttributes($extensionAttributes);
        }
    }

    return $quote;
}

But in response there is no extension_attributes in quote item. When i debug it in PHPSTORM i see that attribute is set in _data object but it is not returning in response.

My response in postman:

{
    "grand_total": 882.91,
    "base_grand_total": 1085.98,
    "subtotal": 882.91,
    "base_subtotal": 882.91,
    "discount_amount": 0,
    "base_discount_amount": 0,
    "subtotal_with_discount": 882.91,
    "base_subtotal_with_discount": 882.91,
    "shipping_amount": 0,
    "base_shipping_amount": 0,
    "shipping_discount_amount": 0,
    "base_shipping_discount_amount": 0,
    "tax_amount": 203.07,
    "base_tax_amount": 203.07,
    "weee_tax_applied_amount": null,
    "shipping_tax_amount": 0,
    "base_shipping_tax_amount": 0,
    "subtotal_incl_tax": 1085.98,
    "shipping_incl_tax": 0,
    "base_shipping_incl_tax": 0,
    "base_currency_code": "PLN",
    "quote_currency_code": "PLN",
    "items_qty": 2,
    "items": [
        {
            "item_id": 1324,
            "price": 21.13,
            "base_price": 21.13,
            "qty": 1,
            "row_total": 21.13,
            "base_row_total": 21.13,
            "row_total_with_discount": 0,
            "tax_amount": 4.86,
            "base_tax_amount": 4.86,
            "tax_percent": 23,
            "discount_amount": 0,
            "base_discount_amount": 0,
            "discount_percent": 0,
            "price_incl_tax": 25.99,
            "base_price_incl_tax": 25.99,
            "row_total_incl_tax": 25.99,
            "base_row_total_incl_tax": 25.99,
            "options": "[{\"value\":\"+30GB\",\"label\":\"Transfer Size\"}]",
            "weee_tax_applied_amount": null,
            "weee_tax_applied": null,
            "name": "Transfer"
        },
        {
            "item_id": 1325,
            "price": 861.78,
            "base_price": 861.78,
            "qty": 1,
            "row_total": 861.78,
            "base_row_total": 861.78,
            "row_total_with_discount": 0,
            "tax_amount": 198.21,
            "base_tax_amount": 198.21,
            "tax_percent": 23,
            "discount_amount": 0,
            "base_discount_amount": 0,
            "discount_percent": 0,
            "price_incl_tax": 1059.99,
            "base_price_incl_tax": 1059.99,
            "row_total_incl_tax": 1059.99,
            "base_row_total_incl_tax": 1059.99,
            "options": "[{\"value\":\"Unlimited\",\"label\":\"Variant\"}]",
            "weee_tax_applied_amount": null,
            "weee_tax_applied": null,
            "name": "foo"
        }
    ],
    "total_segments": [
        {
            "code": "subtotal",
            "title": "sum",
            "value": 1085.98
        },
        {
            "code": "shipping",
            "title": "shipping",
            "value": 0
        },
        {
            "code": "tax",
            "title": "Tax",
            "value": 203.07,
            "extension_attributes": {
                "tax_grandtotal_details": [
                    {
                        "amount": 203.07,
                        "rates": [
                            {
                                "percent": "23",
                                "title": "Poland (standard)"
                            }
                        ],
                        "group_id": 1
                    }
                ]
            }
        },
        {
            "code": "grand_total",
            "title": "Sub",
            "value": 1085.98,
            "area": "footer"
        }
    ]
}

Can anyone tell me why there is no my extension_attribute image in every single quote item ?

Was it helpful?

Solution

Not sure, but the first thing I noticed in your code is that you write plugin for \Magento\Quote\Api\CartRepositoryInterface but should be for \Magento\Quote\Api\GuestCartTotalRepositoryInterface

Upd #1: The following works for me:

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\Quote\Api\Data\TotalsItemInterface">
        <attribute code="some_super_cool_attribute" type="string" />
    </extension_attributes>
</config>

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="Underser_CartExtensionAttributes" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Quote"/>
        </sequence>
    </module>
</config>

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\Quote\Api\GuestCartTotalRepositoryInterface">
        <plugin name="underser_add_extension_attributes" type="Underser\CartExtensionAttributes\Plugin\Quote\TotalsPlugin"/>
    </type>
</config>

\Underser\CartExtensionAttributes\Plugin\Quote\TotalsPlugin

<?php

namespace Underser\CartExtensionAttributes\Plugin\Quote;

use Magento\Quote\Api\Data\TotalsInterface;
use Magento\Quote\Api\GuestCartTotalRepositoryInterface;
use Magento\Quote\Api\Data\TotalsItemInterface;
use Magento\Quote\Api\Data\TotalsItemExtensionInterfaceFactory;

class TotalsPlugin
{
    /**
     * @var TotalsItemExtensionInterfaceFactory
     */
    protected $totalsItemExtensionInterfaceFactory;

    /**
     * TotalsPlugin constructor.
     *
     * @param TotalsItemExtensionInterfaceFactory $totalsItemExtensionInterfaceFactory
     */
    public function __construct(TotalsItemExtensionInterfaceFactory $totalsItemExtensionInterfaceFactory)
    {
        $this->totalsItemExtensionInterfaceFactory = $totalsItemExtensionInterfaceFactory;
    }

    /**
     * After get items.
     *
     * @param GuestCartTotalRepositoryInterface $subject
     * @param TotalsInterface $result
     * @return TotalsInterface
     */
    public function afterGet(
        GuestCartTotalRepositoryInterface $subject,
        TotalsInterface $result
    ) {
        /** @var TotalsItemInterface $item */
        foreach ($result->getItems() as $item) {
            $extensionAttributes = $item->getExtensionAttributes();

            if (!$extensionAttributes) {
                $extensionAttributes = $this->totalsItemExtensionInterfaceFactory->create();
            }

            $extensionAttributes->setSomeSuperCoolAttribute('someSuperCoolAttributeValue');

            $item->setExtensionAttributes($extensionAttributes);
        }

        return $result;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top