Skip to content

Commit

Permalink
Rewrote part of GA4 to support add/remove quantity from cart and cart…
Browse files Browse the repository at this point in the history
…_updates (OpenMage#3377)
  • Loading branch information
fballiano authored Jul 15, 2023
1 parent 9e17d42 commit a508ae5
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 95 deletions.
114 changes: 55 additions & 59 deletions app/code/core/Mage/GoogleAnalytics/Block/Ga.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,67 +131,57 @@ 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();
}

/**
* This event signifies that an item was added to a cart for purchase.
*
* @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();
}
}

Expand All @@ -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');
Expand Down Expand Up @@ -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');
Expand All @@ -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) . ");";
}

Expand All @@ -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) . ");";
}

Expand All @@ -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) . ");";
}
}
Expand All @@ -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;
}
Expand Down
9 changes: 9 additions & 0 deletions app/code/core/Mage/GoogleAnalytics/Helper/Data.php
Original file line number Diff line number Diff line change
Expand Up @@ -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, '.', '');
}
}
79 changes: 53 additions & 26 deletions app/code/core/Mage/GoogleAnalytics/Model/Observer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Loading

0 comments on commit a508ae5

Please sign in to comment.