Categories
Magento 2

Fixing Quote Item Extension Attributes (Magento 2.3.5)

Do you know that feeling as a developer when you do things the Right Way(tm) according to a framework’s best practices only to get tripped up by a half-baked implementation? Welcome to Magento 2’s extension attributes!

Magento 2.3.5 doesn’t appear to pass cart item extension attributes to the javascript checkoutConfig object on the cart and checkout pages. This issue appears to be similar to this bug which stopped extension attributes from permeating to the checkoutConfig.quoteData object. Unfortunately, the bug has only been fixed for quote objects, not quote items.

The Fix

Add a plugin to the Checkout module’s DefaultConfigProvider in di.xml;

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Model\DefaultConfigProvider">
        <plugin name="vendor_module_checkout_model_defaultconfigprovider" type="Vendor\Module\Plugin\Checkout\Model\DefaultConfigProvider" />
    </type>
</config>

Now we can manipulate the data in the plugin to make it do the thing it was intended to do when Magento 2 launched in 2015. Snark.

<?php
namespace Vendor\Namespace\Plugin\Checkout\Model;

class DefaultConfigProvider
{ 
    /** @var \Vendor\Namespace\Helper\Quote */
    protected $quoteHelper;

    /**
     *
     * @param \Magento\Checkout\Model\DefaultConfigProvider $subject
     * @param array $result
     * @return void
     */
    public function afterGetConfig(
        \Magento\Checkout\Model\DefaultConfigProvider $subject,
        $result
    ) {
        if(isset($result['quoteItemData'])) {
            foreach($result['quoteItemData'] as $itemKey => $quoteItem) {
                if(isset($quoteItem['extension_attributes']) && !is_array($quoteItem['extension_attributes'])) {
                    $extensionAttributes = $quoteItem['extension_attributes'];
                    $data = [];
                    foreach ($extensionAttributes->__toArray() as $key => $value) {
                        if (!is_object($value)) {
                            $data[$key] = $value;
                        }
                    }
                    $result['quoteItemData'][$itemKey]['extension_attributes'] = $data;
                }
            }
        }
        return $result;
    }
}

Next half baked implementation bug, please!