2

I've a little problem with an override of google tag manager in Magento 2 enterprise.

google-analytics-universals.js have some function that trigger the events: addToCart, removeFromCart.

To get the products details in addtocart function google tag manager(google-analytics-universals.js) use:

 'Magento_Customer/js/customer-data'

with the method:

   items = customerData.get('cart')().items;

Unfortunately this method don't retrieve product custom-attribute.

The question is: which is the best way to retrieve the custom attributes?

The js of google tag manager and the customer-data.js seems to haven't a phtml associated that I can use and however I have to get custom attributes only of the product triggered by addtocart event in js.

Any idea?

1 Answer 1

0

You should modify the existing section Magento\Checkout\CustomerData\Cart.

The cart data comes from it each time when data should be updated:

/**
 * @inheritdoc
 */
public function getSectionData()
{
    $totals = $this->getQuote()->getTotals();
    $subtotalAmount = $totals['subtotal']->getValue();
    return [
        'summary_count' => $this->getSummaryCount(),
        'subtotalAmount' => $subtotalAmount,
        'subtotal' => isset($totals['subtotal'])
            ? $this->checkoutHelper->formatPrice($subtotalAmount)
            : 0,
        'possible_onepage_checkout' => $this->isPossibleOnepageCheckout(),
        'items' => $this->getRecentItems(),
        'extra_actions' => $this->layout->createBlock(\Magento\Catalog\Block\ShortcutButtons::class)->toHtml(),
        'isGuestCheckoutAllowed' => $this->isGuestCheckoutAllowed(),
        'website_id' => $this->getQuote()->getStore()->getWebsiteId(),
        'storeId' => $this->getQuote()->getStore()->getStoreId()
    ];
}

Pay attention at the 'items' property. Data about cart items comes from the getRecentItems method:

/**
 * Get array of last added items
 *
 * @return \Magento\Quote\Model\Quote\Item[]
 */
protected function getRecentItems()
{
    $items = [];
    if (!$this->getSummaryCount()) {
        return $items;
    }

    foreach (array_reverse($this->getAllQuoteItems()) as $item) {
        /* @var $item \Magento\Quote\Model\Quote\Item */
        if (!$item->getProduct()->isVisibleInSiteVisibility()) {
            $product =  $item->getOptionByCode('product_type') !== null
                ? $item->getOptionByCode('product_type')->getProduct()
                : $item->getProduct();

            $products = $this->catalogUrl->getRewriteByProductStore([$product->getId() => $item->getStoreId()]);
            if (isset($products[$product->getId()])) {
                $urlDataObject = new \Magento\Framework\DataObject($products[$product->getId()]);
                $item->getProduct()->setUrlDataObject($urlDataObject);
            }
        }
        $items[] = $this->itemPoolInterface->getItemData($item);
    }
    return $items;
}

So you can create a plugin for the Magento\Checkout\CustomerData\ItemPool (or interface) for the method getItemData, which has access to the original QuoteItem (in arguments).

Here how it will be looking, when you add some custom attribute:

Here is example:

Define the plugin:

app/code/MageWorx/ShippingCalculator/etc/di.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © MageWorx. All rights reserved.
 * See LICENSE.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\CustomerData\ItemPoolInterface">
        <plugin name="add_custom_attributes_plugin"
                type="MageWorx\ShippingCalculator\Plugin\ItemCustomAttributes"
                sortOrder="10"
                disabled="false" />
    </type>
</config>

Create plugin class (you should add own logic here):

app/code/MageWorx/ShippingCalculator/Plugin/ItemCustomAttributes.php

<?php
/**
 * Copyright © MageWorx. All rights reserved.
 * See LICENSE.txt for license details.
 */

namespace MageWorx\ShippingCalculator\Plugin;

use Magento\Quote\Model\Quote\Item;

/**
 * Class ItemCustomAttributes
 */
class ItemCustomAttributes
{
    /**
     * @param \Magento\Checkout\CustomerData\ItemInterface $subject
     * @param array $result
     * @param Item $item
     * @return array
     */
    public function afterGetItemData($subject, $result, Item $item)
    {
        $result['custom_attribute_1'] = 121;

        return $result;
    }
}

Run setup:di:compile, clean cache and see a result.

Note: you can trigger an update of corresponding section from the browsers console using require('Magento_Customer/js/customer-data').reload('cart') command.

Example result with plugin

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.