diff --git a/app/code/core/Mage/GoogleAnalytics/Block/Ga.php b/app/code/core/Mage/GoogleAnalytics/Block/Ga.php
index b706fd83b53..01d210f0d17 100644
--- a/app/code/core/Mage/GoogleAnalytics/Block/Ga.php
+++ b/app/code/core/Mage/GoogleAnalytics/Block/Ga.php
@@ -131,36 +131,32 @@ protected function _getEnhancedEcommerceDataForAnalytics4()
$request = $this->getRequest();
$moduleName = $request->getModuleName();
$controllerName = $request->getControllerName();
+ $helper = Mage::helper('googleanalytics');
/**
* This event signifies that an item was removed from a cart.
*
* @link https://developers.google.com/tag-platform/gtagjs/reference/events#remove_from_cart
*/
- $removedProducts = Mage::getSingleton('core/session')->getRemovedProductsCart();
+ $removedProducts = Mage::getSingleton('core/session')->getRemovedProductsForAnalytics();
if ($removedProducts) {
foreach ($removedProducts as $removedProduct) {
- $_removedProduct = Mage::getModel('catalog/product')->load($removedProduct);
$eventData = [];
$eventData['currency'] = Mage::app()->getStore()->getCurrentCurrencyCode();
- $eventData['value'] = number_format($_removedProduct->getFinalPrice(), 2, '.', '');
+ $eventData['value'] = $helper->formatPrice($removedProduct['price'] * $removedProduct['qty']);
$eventData['items'] = [];
$_item = [
- 'item_id' => $_removedProduct->getSku(),
- 'item_name' => $_removedProduct->getName(),
- 'price' => number_format($_removedProduct->getFinalPrice(), 2, '.', ''),
+ 'item_id' => $removedProduct['sku'],
+ 'item_name' => $removedProduct['name'],
+ 'price' => $helper->formatPrice($removedProduct['price']),
+ 'quantity' => (int) $removedProduct['qty'],
+ 'item_brand' => $removedProduct['manufacturer'],
+ 'item_category' => $removedProduct['category'],
];
- if ($_removedProduct->getAttributeText('manufacturer')) {
- $_item['item_brand'] = $_removedProduct->getAttributeText('manufacturer');
- }
- $itemCategory = Mage::helper('googleanalytics')->getLastCategoryName($_removedProduct);
- if ($itemCategory) {
- $_item['item_category'] = $itemCategory;
- }
- array_push($eventData['items'], $_item);
+ $eventData['items'][] = $_item;
$result[] = "gtag('event', 'remove_from_cart', " . json_encode($eventData, JSON_THROW_ON_ERROR) . ");";
}
- Mage::getSingleton('core/session')->unsRemovedProductsCart();
+ Mage::getSingleton('core/session')->unsRemovedProductsForAnalytics();
}
/**
@@ -168,30 +164,24 @@ protected function _getEnhancedEcommerceDataForAnalytics4()
*
* @link https://developers.google.com/tag-platform/gtagjs/reference/events#add_to_cart
*/
- $addedProducts = Mage::getSingleton('core/session')->getAddedProductsCart();
+ $addedProducts = Mage::getSingleton('core/session')->getAddedProductsForAnalytics();
if ($addedProducts) {
- foreach ($addedProducts as $addedProduct) {
- $_addedProduct = Mage::getModel('catalog/product')->load($addedProduct);
+ foreach ($addedProducts as $_addedProduct) {
$eventData = [];
$eventData['currency'] = Mage::app()->getStore()->getCurrentCurrencyCode();
- $eventData['value'] = number_format($_addedProduct->getFinalPrice(), 2, '.', '');
+ $eventData['value'] = $helper->formatPrice($_addedProduct['price'] * $_addedProduct['qty']);
$eventData['items'] = [];
$_item = [
- 'item_id' => $_addedProduct->getSku(),
- 'item_name' => $_addedProduct->getName(),
- 'price' => number_format($_addedProduct->getFinalPrice(), 2, '.', ''),
+ 'item_id' => $_addedProduct['sku'],
+ 'item_name' => $_addedProduct['name'],
+ 'price' => $helper->formatPrice($_addedProduct['price']),
+ 'quantity' => (int) $_addedProduct['qty'],
+ 'item_brand' => $_addedProduct['manufacturer'],
+ 'item_category' => $_addedProduct['category'],
];
- if ($_addedProduct->getAttributeText('manufacturer')) {
- $_item['item_brand'] = $_addedProduct->getAttributeText('manufacturer');
- }
-
- $itemCategory = Mage::helper('googleanalytics')->getLastCategoryName($_addedProduct);
- if ($itemCategory) {
- $_item['item_category'] = $itemCategory;
- }
- array_push($eventData['items'], $_item);
+ $eventData['items'][] = $_item;
$result[] = "gtag('event', 'add_to_cart', " . json_encode($eventData, JSON_THROW_ON_ERROR) . ");";
- Mage::getSingleton('core/session')->unsAddedProductsCart();
+ Mage::getSingleton('core/session')->unsAddedProductsForAnalytics();
}
}
@@ -205,14 +195,14 @@ protected function _getEnhancedEcommerceDataForAnalytics4()
$category = Mage::registry('current_category') ? Mage::registry('current_category')->getName() : false;
$eventData = [];
$eventData['currency'] = Mage::app()->getStore()->getCurrentCurrencyCode();
- $eventData['value'] = number_format($productViewed->getFinalPrice(), 2, '.', '');
+ $eventData['value'] = $helper->formatPrice($productViewed->getFinalPrice());
$eventData['items'] = [];
$_item = [
'item_id' => $productViewed->getSku(),
'item_name' => $productViewed->getName(),
'list_name' => 'Product Detail Page',
'item_category' => $category,
- 'price' => number_format($productViewed->getFinalPrice(), 2, '.', ''),
+ 'price' => $helper->formatPrice($productViewed->getFinalPrice()),
];
if ($productViewed->getAttributeText('manufacturer')) {
$_item['item_brand'] = $productViewed->getAttributeText('manufacturer');
@@ -251,7 +241,7 @@ protected function _getEnhancedEcommerceDataForAnalytics4()
'item_id' => $productViewed->getSku(),
'index' => $index,
'item_name' => $productViewed->getName(),
- 'price' => number_format($productViewed->getFinalPrice(), 2, '.', ''),
+ 'price' => $helper->formatPrice($productViewed->getFinalPrice()),
];
if ($productViewed->getAttributeText('manufacturer')) {
$_item['item_brand'] = $productViewed->getAttributeText('manufacturer');
@@ -263,7 +253,7 @@ protected function _getEnhancedEcommerceDataForAnalytics4()
$index++;
$eventData['value'] += $productViewed->getFinalPrice();
}
- $eventData['value'] = number_format($eventData['value'], 2, '.', '');
+ $eventData['value'] = $helper->formatPrice($eventData['value']);
$result[] = "gtag('event', 'view_item_list', " . json_encode($eventData, JSON_THROW_ON_ERROR) . ");";
}
@@ -273,32 +263,34 @@ protected function _getEnhancedEcommerceDataForAnalytics4()
* @link https://developers.google.com/tag-platform/gtagjs/reference/events#view_cart
*/
elseif ($moduleName == 'checkout' && $controllerName == 'cart') {
- $productCollection = Mage::getSingleton('checkout/session')->getQuote()->getAllVisibleItems();
+ $productCollection = Mage::getSingleton('checkout/session')->getQuote()->getAllItems();
$eventData = [];
$eventData['currency'] = Mage::app()->getStore()->getCurrentCurrencyCode();
$eventData['value'] = 0.00;
$eventData['items'] = [];
foreach ($productCollection as $productInCart) {
- $_product = Mage::getModel('catalog/product')->load($productInCart->getProductId());
+ if ($productInCart->getParentItem()) {
+ continue;
+ }
+ $_product = $productInCart->getProduct();
$_item = [
'item_id' => $_product->getSku(),
'item_name' => $_product->getName(),
- 'price' => number_format($_product->getFinalPrice(), 2, '.', ''),
+ 'price' => $helper->formatPrice($_product->getFinalPrice()),
'quantity' => (int) $productInCart->getQty(),
];
if ($_product->getAttributeText('manufacturer')) {
$_item['item_brand'] = $_product->getAttributeText('manufacturer');
}
-
- $itemCategory = Mage::helper('googleanalytics')->getLastCategoryName($_product);
+ $itemCategory = $helper->getLastCategoryName($_product);
if ($itemCategory) {
$_item['item_category'] = $itemCategory;
}
array_push($eventData['items'], $_item);
- $eventData['value'] += $_product->getFinalPrice();
+ $eventData['value'] += $_product->getFinalPrice() * $productInCart->getQty();
}
- $eventData['value'] = number_format($eventData['value'], 2, '.', '');
+ $eventData['value'] = $helper->formatPrice($eventData['value']);
$result[] = "gtag('event', 'view_cart', " . json_encode($eventData, JSON_THROW_ON_ERROR) . ");";
}
@@ -308,32 +300,34 @@ protected function _getEnhancedEcommerceDataForAnalytics4()
* @link https://developers.google.com/tag-platform/gtagjs/reference/events#begin_checkout
*/
elseif ($moduleName == static::CHECKOUT_MODULE_NAME && $controllerName == static::CHECKOUT_CONTROLLER_NAME) {
- $productCollection = Mage::getSingleton('checkout/session')->getQuote()->getAllVisibleItems();
+ $productCollection = Mage::getSingleton('checkout/session')->getQuote()->getAllItems();
if ($productCollection) {
$eventData = [];
$eventData['currency'] = Mage::app()->getStore()->getCurrentCurrencyCode();
$eventData['value'] = 0.00;
$eventData['items'] = [];
foreach ($productCollection as $productInCart) {
- $_product = Mage::getModel('catalog/product')->load($productInCart->getProductId());
+ if ($productInCart->getParentItem()) {
+ continue;
+ }
+ $_product = $productInCart->getProduct();
$_item = [
'item_id' => $_product->getSku(),
'item_name' => $_product->getName(),
- 'price' => number_format($_product->getFinalPrice(), 2, '.', ''),
+ 'price' => $helper->formatPrice($_product->getFinalPrice()),
'quantity' => (int) $productInCart->getQty(),
];
if ($_product->getAttributeText('manufacturer')) {
$_item['item_brand'] = $_product->getAttributeText('manufacturer');
}
-
- $itemCategory = Mage::helper('googleanalytics')->getLastCategoryName($_product);
+ $itemCategory = $helper->getLastCategoryName($_product);
if ($itemCategory) {
$_item['item_category'] = $itemCategory;
}
array_push($eventData['items'], $_item);
$eventData['value'] += $_product->getFinalPrice();
}
- $eventData['value'] = number_format($eventData['value'], 2, '.', '');
+ $eventData['value'] = $helper->formatPrice($eventData['value']);
$result[] = "gtag('event', 'begin_checkout', " . json_encode($eventData, JSON_THROW_ON_ERROR) . ");";
}
}
@@ -352,28 +346,30 @@ protected function _getEnhancedEcommerceDataForAnalytics4()
$orderData = [
'currency' => $order->getBaseCurrencyCode(),
'transaction_id' => $order->getIncrementId(),
- 'value' => number_format($order->getBaseGrandTotal(), 2, '.', ''),
- 'coupon' => strtoupper($order->getCouponCode()),
- 'shipping' => number_format($order->getBaseShippingAmount(), 2, '.', ''),
- 'tax' => number_format($order->getBaseTaxAmount(), 2, '.', ''),
+ 'value' => $helper->formatPrice($order->getBaseGrandTotal()),
+ 'coupon' => strtoupper((string)$order->getCouponCode()),
+ 'shipping' => $helper->formatPrice($order->getBaseShippingAmount()),
+ 'tax' => $helper->formatPrice($order->getBaseTaxAmount()),
'items' => []
];
/** @var Mage_Sales_Model_Order_Item $item */
- foreach ($order->getAllVisibleItems() as $item) {
+ foreach ($order->getAllItems() as $item) {
+ if ($item->getParentItem()) {
+ continue;
+ }
+ $_product = $item->getProduct();
$_item = [
'item_id' => $item->getSku(),
'item_name' => $item->getName(),
'quantity' => (int) $item->getQtyOrdered(),
- 'price' => number_format($item->getBasePrice(), 2, '.', ''),
- 'discount' => number_format($item->getBaseDiscountAmount(), 2, '.', '')
+ 'price' => $helper->formatPrice($item->getBasePrice()),
+ 'discount' => $helper->formatPrice($item->getBaseDiscountAmount())
];
- $_product = Mage::getModel('catalog/product')->load($item->getProductId());
if ($_product->getAttributeText('manufacturer')) {
$_item['item_brand'] = $_product->getAttributeText('manufacturer');
}
-
- $itemCategory = Mage::helper('googleanalytics')->getLastCategoryName($_product);
+ $itemCategory = $helper->getLastCategoryName($_product);
if ($itemCategory) {
$_item['item_category'] = $itemCategory;
}
diff --git a/app/code/core/Mage/GoogleAnalytics/Helper/Data.php b/app/code/core/Mage/GoogleAnalytics/Helper/Data.php
index 49b4b098987..5079f00e022 100644
--- a/app/code/core/Mage/GoogleAnalytics/Helper/Data.php
+++ b/app/code/core/Mage/GoogleAnalytics/Helper/Data.php
@@ -184,4 +184,13 @@ public function getLastCategoryName($product): string
}
return '';
}
+
+ /**
+ * @param int|float|string $price
+ * @return string
+ */
+ public function formatPrice($price): string
+ {
+ return number_format($price, 2, '.', '');
+ }
}
diff --git a/app/code/core/Mage/GoogleAnalytics/Model/Observer.php b/app/code/core/Mage/GoogleAnalytics/Model/Observer.php
index 728a0ae2fe6..411b6941ee6 100644
--- a/app/code/core/Mage/GoogleAnalytics/Model/Observer.php
+++ b/app/code/core/Mage/GoogleAnalytics/Model/Observer.php
@@ -39,38 +39,65 @@ public function setGoogleAnalyticsOnOrderSuccessPageView(Varien_Event_Observer $
}
/**
- * Add 'removed item' from cart into session for GA4 block to render event on cart view
- *
+ * Process items added or removed from cart for GA4 block to render event on cart view
* @param Varien_Event_Observer $observer
+ * @return void
*/
- public function removeItemFromCartGoogleAnalytics(Varien_Event_Observer $observer)
+ public function processItemsAddedOrRemovedFromCart(Varien_Event_Observer $observer): void
{
- $productRemoved = $observer->getEvent()->getQuoteItem()->getProduct();
- if ($productRemoved) {
- $_removedProducts = Mage::getSingleton('core/session')->getRemovedProductsCart() ?: [];
- $_removedProducts[] = $productRemoved->getId();
- $_removedProducts = array_unique($_removedProducts);
- Mage::getSingleton('core/session')->setRemovedProductsCart($_removedProducts);
+ /** @var Mage_Sales_Model_Quote_Item $item */
+ $item = $observer->getEvent()->getItem();
+ if ($item->getParentItem()) {
+ return;
}
- }
- /**
- * Add 'added item' to cart into session for GA4 block to render event on cart view
- *
- * @param Varien_Event_Observer $observer
- */
- public function addItemToCartGoogleAnalytics(Varien_Event_Observer $observer)
- {
- $productAdded = $observer->getEvent()->getQuoteItem()->getProduct();
- if ($productAdded) {
- // Fix double add to cart for configurable products, skip child product
- if ($productAdded->getParentProductId()) {
- return;
+ // avoid to process the same quote_item more than once
+ // this could happen in case of double save of the same quote_item
+ $processedProductsRegistry = Mage::registry('processed_quote_items_for_analytics') ?? new ArrayObject();
+ if ($processedProductsRegistry->offsetExists($item->getId())) {
+ return;
+ }
+ $processedProductsRegistry[$item->getId()] = true;
+ Mage::register('processed_quote_items_for_analytics', $processedProductsRegistry, true);
+
+ $addedQty = 0;
+ $removedQty = 0;
+ if ($item->isObjectNew()) {
+ $addedQty = $item->getQty();
+ } elseif ($item->isDeleted()) {
+ $removedQty = $item->getQty();
+ } elseif ($item->hasDataChanges()) {
+ $newQty = $item->getQty();
+ $oldQty = $item->getOrigData('qty');
+ if ($newQty > $oldQty) {
+ $addedQty = $newQty - $oldQty;
+ } elseif ($newQty < $oldQty) {
+ $removedQty = $oldQty - $newQty;
+ }
+ }
+
+ if ($addedQty || $removedQty) {
+ $product = $item->getProduct();
+ $dataForAnalytics = [
+ 'id' => $product->getId(),
+ 'sku' => $product->getSku(),
+ 'name' => $product->getName(),
+ 'qty' => $addedQty ?: $removedQty,
+ 'price' => $product->getFinalPrice(),
+ 'manufacturer' => $product->getAttributeText('manufacturer') ?: '',
+ 'category' => Mage::helper('googleanalytics')->getLastCategoryName($product)
+ ];
+
+ $session = Mage::getSingleton('core/session');
+ if ($addedQty) {
+ $addedProducts = $session->getAddedProductsForAnalytics() ?: [];
+ $addedProducts[] = $dataForAnalytics;
+ $session->setAddedProductsForAnalytics($addedProducts);
+ } else {
+ $removedProducts = $session->getRemovedProductsForAnalytics() ?: [];
+ $removedProducts[] = $dataForAnalytics;
+ $session->setRemovedProductsForAnalytics($removedProducts);
}
- $_addedProducts = Mage::getSingleton('core/session')->getAddedProductsCart() ?: [];
- $_addedProducts[] = $productAdded->getParentItem() ? $productAdded->getParentItem()->getId() : $productAdded->getId();
- $_addedProducts = array_unique($_addedProducts);
- Mage::getSingleton('core/session')->setAddedProductsCart($_addedProducts);
}
}
}
diff --git a/app/code/core/Mage/GoogleAnalytics/etc/config.xml b/app/code/core/Mage/GoogleAnalytics/etc/config.xml
index 8f7750a93b9..d4e605dde6e 100644
--- a/app/code/core/Mage/GoogleAnalytics/etc/config.xml
+++ b/app/code/core/Mage/GoogleAnalytics/etc/config.xml
@@ -72,22 +72,22 @@
-
+
-
+
googleanalytics/observer
- removeItemFromCartGoogleAnalytics
-
+ processItemsAddedOrRemovedFromCart
+
-
-
+
+
-
+
googleanalytics/observer
- addItemToCartGoogleAnalytics
-
+ processItemsAddedOrRemovedFromCart
+
-
+