Files
wyczarujprezent.pl/modules/ecsgtmpro/classes/gtm/EcsGtmProDataLayerManager.php
2024-10-28 22:14:22 +01:00

1078 lines
39 KiB
PHP

<?php
/**
* 2022 ECSoft
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to dev.ecsoft@gmail.com so we can send you a copy immediately.
*
* @author ECSoft <dev.ecsoft@gmail.com>
* @copyright 2022 ECSoft
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of ECSoft
*/
require_once dirname(__FILE__) . '/ua/EcsGtmProGtmParams.php';
require_once dirname(__FILE__) . '/ua/EcsGtmProRefund.php';
require_once dirname(__FILE__) . '/../EcsGtmProTools.php';
require_once dirname(__FILE__) . '/EcsGtmProProduct.php';
require_once dirname(__FILE__) . '/EcsGtmProDataLayer.php';
require_once dirname(__FILE__) . '/ga4/EcsGtmProDataLayerItem.php';
/**
* @property EcsGtmPro $module
*/
class EcsGtmProDataLayerManager
{
public $module;
protected $dlGenerated;
protected $remarketingGenerated;
protected $dataLayer;
protected $format;
protected $context;
protected $idLang;
protected $categoryTree;
protected $rootCategory;
protected $opc;
public function __construct($module, $format)
{
$this->module = $module;
$this->format = $format;
$this->context = Context::getContext();
$this->dataLayer = new EcsGtmProDataLayer($this);
}
public function isEE()
{
return in_array($this->format, array('gau', 'all'));
}
public function isGA4()
{
return in_array($this->format, array('ga4', 'all'));
}
public function toJson()
{
return $this->dataLayer->toJson();
}
public function addProductList($products, $list = null, $maxProducts = null, $type = null)
{
$i = 1;
if (is_array($products) && !empty($products)) {
foreach ($products as $p) {
if (is_array($list)) {
$list['index'] = $i++;
}
$this->dataLayer->addItem($p, $type, $list);
if ($maxProducts && $i > $maxProducts) {
break;
}
}
}
}
public function generateDataLayer()
{
if (!$this->dlGenerated) {
$controller = Tools::getValue('controller');
$this->dataLayer->pageCategory = $controller;
if (!$this->module->gtmConfig->userIdConfig->async) {
$this->addUserInfo($this->dataLayer);
}
if ($this->module->isOrderValidationPage()) {
$this->orderConfirmation();
} else {
if ($this->module->isOPC()) {
$controller = 'orderopc';
}
if ($this->module->isHomePage()) {
$this->homeDataLayer();
} elseif ($this->module->isProductPage()) {
$this->productDataLayer();
} elseif ($this->module->isCategoryPage()) {
$this->categoryDataLayer();
} elseif ($this->module->isSearchPage()) {
$this->searchResultDataLayer();
} elseif ($this->module->isCartPage() || $this->module->isOrderPage() || $this->module->isPaymentPage() || $this->module->isOPC()) {
$this->checkoutDataLayer($controller);
}
}
$this->dlGenerated = true;
return true;
}
return false;
}
protected function checkoutDataLayer($controller)
{
$step = $this->getCheckoutStep();
$cartProducts = $this->getCartProducts();
$this->addProductList($cartProducts, null, $this->module->gtmConfig->generalConfig->max_category, 'begin_checkout');
$this->dataLayer->setSubtotalsFromCart($this->context->cart);
$this->getCartRulesFromCart($this->context->cart);
if ($this->isEE()) {
$actionField = new stdClass();
$actionField->step = $step;
$this->dataLayer->event = "checkout";
if (!isset($this->dataLayer->ecommerce->checkout)) {
$this->dataLayer->ecommerce->checkout = new stdClass();
}
$this->dataLayer->ecommerce->checkout->actionField = $actionField;
}
if ($this->isGA4()) {
if ($this->module->isCartPage() || ($this->module->is16() && $step == 1)) {
$this->dataLayer->event = 'view_cart';
} else {
switch ($step) {
case 1:
$this->dataLayer->event = 'begin_checkout';
Context::getContext()->cookie->begin_checkout_triggered = 1;
break;
case 2:
$this->dataLayer->event = 'checkout_address';
if (empty(Context::getContext()->cookie->begin_checkout_triggered)) {
$this->preDataLayer = new self($this->module, $this->module->gtmConfig->generalConfig->format);
$this->preDataLayer->addProductList($cartProducts, null, $this->module->gtmConfig->generalConfig->max_category);
$this->preDataLayer->event = 'begin_checkout';
} else {
unset(Context::getContext()->cookie->begin_checkout_triggered);
}
break;
case 3:
$this->dataLayer->event = 'checkout_shipping';
break;
case 4:
$this->dataLayer->event = 'checkout_payment';
break;
default:
$this->dataLayer->event = 'checkout_step'.$step;
break;
}
}
}
}
protected function getCheckoutStep()
{
$step = 0;
if ($this->module->is17() || $this->module->is8x()) {
$checkoutProcess = $this->context->smarty->getTemplateVars('checkout_process');
if ($checkoutProcess) {
$checkoutProcessClass = new ReflectionObject($checkoutProcess);
$renderable = $checkoutProcessClass->getProperty('renderable');
$renderable->setAccessible(true);
$checkoutProcessAccess = $renderable->getValue($checkoutProcess);
$reflectionMethod = new ReflectionMethod('CheckoutProcess', 'getSteps');
$steps = $reflectionMethod->invoke($checkoutProcessAccess);
foreach ($steps as $k => $v) {
if ($v->isCurrent()) {
$step = $k;
break;
}
}
}
} else {
if (!$this->module->isOPC()) {
$step = Tools::getValue('controller') == 'payment' ? 4 : Tools::getValue('step', 0);
}
}
$step++;
if ($step > 4) {
$step = 4;
}
return $step;
}
public function getUserPostcodeFromCart()
{
$cart = $this->context->cart;
if (!Validate::isLoadedObject($cart) && Tools::getIsset('id_cart')) {
$cart = new Cart((int) Tools::getValue('id_cart'));
}
$cart_id = $cart->id;
// select id_customer from ps_orders where id_cart = $cart_id
$sql = 'SELECT id_customer FROM '._DB_PREFIX_.'orders WHERE id_cart = '.(int)$cart_id;
$id_customer = Db::getInstance()->getValue($sql);
// select postcode from ps_address where id_customer = $id_customer
$sql = 'SELECT postcode FROM '._DB_PREFIX_.'address WHERE id_customer = '.(int)$id_customer;
$postcode = Db::getInstance()->getValue($sql);
return $postcode;
}
public function getUserCountryFromCart()
{
$cart = $this->context->cart;
if (!Validate::isLoadedObject($cart) && Tools::getIsset('id_cart')) {
$cart = new Cart((int) Tools::getValue('id_cart'));
}
$cart_id = $cart->id;
// select id_customer from ps_orders where id_cart = $cart_id
$sql = 'SELECT id_customer FROM '._DB_PREFIX_.'orders WHERE id_cart = '.(int)$cart_id;
$id_customer = Db::getInstance()->getValue($sql);
// select id_country from ps_address where id_customer = $id_customer
$sql = 'SELECT id_country FROM '._DB_PREFIX_.'address WHERE id_customer = '.(int)$id_customer;
$id_country = Db::getInstance()->getValue($sql);
// select name from ps_country where id_country = $id_country
$sql = 'SELECT name FROM '._DB_PREFIX_.'country_lang WHERE id_country = '.(int)$id_country . ' AND id_lang = 1';
$country = Db::getInstance()->getValue($sql);
return $country;
}
public function getUserCityFromCart()
{
$cart = $this->context->cart;
if (!Validate::isLoadedObject($cart) && Tools::getIsset('id_cart')) {
$cart = new Cart((int) Tools::getValue('id_cart'));
}
$cart_id = $cart->id;
// select id_customer from ps_orders where id_cart = $cart_id
$sql = 'SELECT id_customer FROM '._DB_PREFIX_.'orders WHERE id_cart = '.(int)$cart_id;
$id_customer = Db::getInstance()->getValue($sql);
// select city from ps_address where id_customer = $id_customer
$sql = 'SELECT city FROM '._DB_PREFIX_.'address WHERE id_customer = '.(int)$id_customer;
$city = Db::getInstance()->getValue($sql);
return $city;
}
public function getUserAddress1FromCart()
{
$cart = $this->context->cart;
if (!Validate::isLoadedObject($cart) && Tools::getIsset('id_cart')) {
$cart = new Cart((int) Tools::getValue('id_cart'));
}
$cart_id = $cart->id;
// select id_customer from ps_orders where id_cart = $cart_id
$sql = 'SELECT id_customer FROM '._DB_PREFIX_.'orders WHERE id_cart = '.(int)$cart_id;
$id_customer = Db::getInstance()->getValue($sql);
// select address1 from ps_address where id_customer = $id_customer
$sql = 'SELECT address1 FROM '._DB_PREFIX_.'address WHERE id_customer = '.(int)$id_customer;
$address1 = Db::getInstance()->getValue($sql);
return $address1;
}
public function getUserLastNameFromCart()
{
$cart = $this->context->cart;
if (!Validate::isLoadedObject($cart) && Tools::getIsset('id_cart')) {
$cart = new Cart((int) Tools::getValue('id_cart'));
}
$cart_id = $cart->id;
// select id_customer from ps_orders where id_cart = $cart_id
$sql = 'SELECT id_customer FROM '._DB_PREFIX_.'orders WHERE id_cart = '.(int)$cart_id;
$id_customer = Db::getInstance()->getValue($sql);
// select lastname from ps_address where id_customer = $id_customer
$sql = 'SELECT lastname FROM '._DB_PREFIX_.'address WHERE id_customer = '.(int)$id_customer;
$lastname = Db::getInstance()->getValue($sql);
return $lastname;
}
public function getUserFirstNameFromCart()
{
$cart = $this->context->cart;
if (!Validate::isLoadedObject($cart) && Tools::getIsset('id_cart')) {
$cart = new Cart((int) Tools::getValue('id_cart'));
}
$cart_id = $cart->id;
// select id_customer from ps_orders where id_cart = $cart_id
$sql = 'SELECT id_customer FROM '._DB_PREFIX_.'orders WHERE id_cart = '.(int)$cart_id;
$id_customer = Db::getInstance()->getValue($sql);
// select firstname from ps_address where id_customer = $id_customer
$sql = 'SELECT firstname FROM '._DB_PREFIX_.'address WHERE id_customer = '.(int)$id_customer;
$firstname = Db::getInstance()->getValue($sql);
return $firstname;
}
public function getUserPhoneFromCart()
{
$cart = $this->context->cart;
if (!Validate::isLoadedObject($cart) && Tools::getIsset('id_cart')) {
$cart = new Cart((int) Tools::getValue('id_cart'));
}
$cart_id = $cart->id;
// select id_customer from ps_orders where id_cart = $cart_id
$sql = 'SELECT id_customer FROM '._DB_PREFIX_.'orders WHERE id_cart = '.(int)$cart_id;
$id_customer = Db::getInstance()->getValue($sql);
// select phone from ps_address where id_customer = $id_customer
$sql = 'SELECT phone FROM '._DB_PREFIX_.'address WHERE id_customer = '.(int)$id_customer;
$phone = Db::getInstance()->getValue($sql);
return $phone;
}
public function getUserEmailFromCart()
{
$cart = $this->context->cart;
if (!Validate::isLoadedObject($cart) && Tools::getIsset('id_cart')) {
$cart = new Cart((int) Tools::getValue('id_cart'));
}
$cart_id = $cart->id;
// select id_customer from ps_orders where id_cart = $cart_id
$sql = 'SELECT id_customer FROM '._DB_PREFIX_.'orders WHERE id_cart = '.(int)$cart_id;
$id_customer = Db::getInstance()->getValue($sql);
// select email from ps_address where id_customer = $id_customer
$sql = 'SELECT email FROM '._DB_PREFIX_.'customer WHERE id_customer = '.(int)$id_customer;
$email = Db::getInstance()->getValue($sql);
return $email;
}
protected function getCartProducts()
{
$products = array();
$cart = $this->context->cart;
if (!Validate::isLoadedObject($cart) && Tools::getIsset('id_cart')) {
$cart = new Cart((int) Tools::getValue('id_cart'));
}
if (Validate::isLoadedObject($cart)) {
$products = $cart->getProducts();
}
return $products;
}
public function homeDataLayer()
{
$this->dataLayer->pageCategory = false;
}
public function categoryDataLayer()
{
$list = array(
'name' => $this->getCategoryName((int) Tools::getValue('id_category')),
'id' => 'cat_'.(int) Tools::getValue('id_category')
);
$products = $this->getProductsFromSmarty();
$this->addProductList($products, $list, $this->module->gtmConfig->generalConfig->max_category, 'view_item_list');
}
public function productDataLayer()
{
$this->dataLayer->addItem($this->getDisplayedProduct(), 'view_item');
}
public function searchResultDataLayer()
{
$list = array(
'name' => 'Search Results',
'id' => 'search'
);
$products = $this->getProductsFromSmarty();
$this->addProductList($products, $list, $this->module->gtmConfig->generalConfig->max_category, 'search_results');
if ($this->module->is17() || $this->module->is8x()) {
$term = $this->context->smarty->getTemplateVars('search_string');
} else {
$term = $this->context->smarty->getTemplateVars('search_query');
}
$this->dataLayer->search_term = EcsGtmProTools::cleanString(htmlspecialchars($term));
$this->dataLayer->event = 'search';
}
public function productClick($id_product, $id_product_attribute)
{
$product = new Product($id_product);
$product->id_product_attribute = $id_product_attribute;
$dataLayer = new EcsGtmProDataLayer($this, $this->module->gtmConfig->generalConfig->format);
$dataLayer->addItem($product, 'view_item');
$dataLayer->event = 'select_item';
return $dataLayer;
}
public function orderConfirmation($id_cart = null, $force_resend = false)
{
if (!$id_cart) {
$id_cart = $this->getCartFromOrderConfirmation();
}
$this->generateOrderConfirmationFromCart($id_cart, $force_resend);
}
protected function getCartFromOrderConfirmation()
{
$id_cart = null;
if (isset($this->displayOrderConfirmationOrderObj['id_cart'])) {
$id_cart = (int) $this->displayOrderConfirmationOrderObj['id_cart'];
}
if (!$id_cart) {
$id_cart = (int)(Tools::getValue('id_cart'));
}
if (!$id_cart) {
$order_id = (int) Tools::getValue('id_order', Tools::getValue('order'));
$order = new Order($order_id);
if (Validate::isLoadedObject($order)) {
$id_cart = $order->id_cart;
}
}
return $id_cart;
}
public function addUserInfo($dataLayer = null)
{
if ($dataLayer == null) {
$dataLayer = $this->dataLayer;
}
if ($this->module->gtmConfig->userIdConfig->add_user_id) {
if (!empty($this->context->cookie->id_customer)) {
$dataLayer->userLogged = 1;
$dataLayer->userId = (string) $this->context->cookie->id_customer;
$customer = new Customer($dataLayer->userId);
if (Validate::isLoadedObject($customer)) {
$groups = $customer->getGroups();
$groupsName = array();
foreach ($groups as $id) {
$group = new Group($id);
if (Validate::isLoadedObject($group)) {
$groupsName[] = $group->name[(int)(Configuration::get('PS_LANG_DEFAULT'))];
}
}
$dataLayer->userGroups = $groupsName;
}
} elseif ($this->module->gtmConfig->userIdConfig->add_guest_id) {
$dataLayer->userLogged = 0;
if (!empty($this->context->cookie->id_guest)) {
$dataLayer->userId = "guest_".$this->context->cookie->id_guest;
} else {
if (empty($this->context->cookie->user_rand_id)) {
$this->context->cookie->user_rand_id = rand(100000, 999999);
}
$dataLayer->userId = "guest_".$this->context->cookie->user_rand_id;
}
}
}
return $dataLayer;
}
protected function getProductsFromSmarty()
{
$products = $this->context->smarty->getTemplateVars('products');
if ($this->module->is17() || $this->module->is8x()) {
if (!$products || !is_array($products)) {
$listing = $this->context->smarty->getTemplateVars('listing');
if (isset($listing['products'])) {
$products = $listing['products'];
}
}
if (!$products || !is_array($products)) {
$cart = $this->context->smarty->getTemplateVars('cart');
if (isset($cart['products'])) {
$products = $cart['products'];
}
}
}
return $products;
}
public function getCategoryNameHierarchy($category, $level)
{
if (!$this->rootCategory) {
$this->rootCategory = new Category($this->context->shop->id_category);
}
$depth = $level + (int)$this->rootCategory->level_depth;
if ($category->level_depth >= $depth) {
return $this->getCategoryName($category, $depth);
}
return null;
}
public function generateRemarketingParams()
{
if (!$this->remarketingGenerated) {
$controller = Tools::getValue('controller');
$this->dataLayer->google_tag_params = new EcsGtmProGtmParams();
$pagetype = $controller;
if ($this->module->isOrderValidationPage()) {
$pagetype = 'purchase';
$this->dataLayer->google_tag_params->ecomm_prodid = $this->remarketingGetProductIdsFromCart();
$this->dataLayer->google_tag_params->ecomm_totalvalue = (float) round($this->getTotalProductPriceFromCart(), _ECSGTMPRO_PRICE_DECIMAL_);
$this->dataLayer->google_tag_params->ecomm_totalvalue_tax_exc = (float) round($this->getTotalProductPriceFromCart(false), _ECSGTMPRO_PRICE_DECIMAL_);
// ecommerce user
$this -> dataLayer -> orderData -> userEmail = $this -> getUserEmailFromCart();
$this -> dataLayer -> orderData -> userPhone = $this -> getUserPhoneFromCart();
$this -> dataLayer -> orderData -> userFirstName = $this -> getUserFirstNameFromCart();
$this -> dataLayer -> orderData -> userLastName = $this -> getUserLastNameFromCart();
// address1
$this -> dataLayer -> orderData -> userAddress1 = $this -> getUserAddress1FromCart();
// city
$this -> dataLayer -> orderData -> userCity = $this -> getUserCityFromCart();
$this -> dataLayer -> orderData -> userRegion = '';
// country
$this -> dataLayer -> orderData -> userCountry = $this -> getUserCountryFromCart();
// postcode
$this -> dataLayer -> orderData -> userPostcode = $this -> getUserPostcodeFromCart();
} else {
if ($this->module->isOPC()) {
$controller = 'orderopc';
}
if ($this->module->isHomePage()) {
$pagetype = 'home';
} elseif ($this->module->isProductPage()) {
$product = $this->getDisplayedProduct();
if (Validate::isLoadedObject($product)) {
$this->dataLayer->google_tag_params->ecomm_prodid = EcsGtmProProduct::getInstance()->remarketingGetProductIdentifier($product);
$this->dataLayer->google_tag_params->ecomm_totalvalue = (float) round((float) Product::getPriceStatic($product->id, true, $product->id_product_attribute), _ECSGTMPRO_PRICE_DECIMAL_);
$this->dataLayer->google_tag_params->ecomm_totalvalue_tax_exc = (float) round((float) Product::getPriceStatic($product->id, false, $product->id_product_attribute), _ECSGTMPRO_PRICE_DECIMAL_);
$this->dataLayer->google_tag_params->ecomm_category = $this->getCategoryName($product->id_category_default);
}
} elseif ($this->module->isPaymentPage() || $this->module->isCartPage() || $this->module->isOPC()) {
$pagetype = 'cart';
$this->dataLayer->google_tag_params->ecomm_prodid = $this->remarketingGetProductIdsFromCart();
$this->dataLayer->google_tag_params->ecomm_totalvalue = (float) round($this->getTotalProductPriceFromCart(), _ECSGTMPRO_PRICE_DECIMAL_);
$this->dataLayer->google_tag_params->ecomm_totalvalue_tax_exc = (float) round($this->getTotalProductPriceFromCart(false), _ECSGTMPRO_PRICE_DECIMAL_);
} elseif ($this->module->isCategoryPage()) {
$this->dataLayer->google_tag_params->ecomm_category = $this->getCategoryName((int) Tools::getValue('id_category'));
} elseif ($this->module->isSearchPage()) {
$pagetype = 'searchresults';
} else {
$pagetype = 'other';
}
}
$this->dataLayer->google_tag_params->ecomm_pagetype = $pagetype;
$this->dataLayer->google_tag_params->removeNull();
$this->remarketingGenerated = true;
}
}
public function getCartActionDataLayer($idProduct, $ipa, $action, $qty)
{
if (!in_array($action, array('add', 'remove'))) {
return null;
}
$product = new Product($idProduct);
$product->id_product_attribute = $ipa;
$product->quantity = (int)$qty;
$dataLayer = new self($this->module, $this->module->gtmConfig->generalConfig->format);
$dataLayer->dataLayer->addItem($product, ($action == 'add') ? 'add_to_cart' : 'remove_from_cart');
return $dataLayer;
}
protected function getTotalProductPriceFromCart($includeTax = true, $mod = 'total')
{
$productTotal = 0.0;
$priceField = 'price';
if ($includeTax) {
$priceField = 'price_wt';
}
$products = $this->getCartProducts();
if (is_array($products) && count($products)) {
foreach ($products as $p) {
if (isset($p[$priceField])) {
$qty = 1;
if ($mod == 'total' && !empty($p['quantity'])) {
$qty = $p['quantity'];
}
$productTotal += $qty * ((float) $p[$priceField]);
}
}
}
return $productTotal;
}
protected function remarketingGetProductIdsFromCart()
{
$productsList = array();
$products = $this->getCartProducts();
if (is_array($products) && count($products)) {
foreach ($products as $product) {
$productID = EcsGtmProProduct::getInstance()->remarketingGetProductIdentifier($product);
if ($productID) {
$productsList[] = $productID;
}
}
}
return $productsList;
}
public function getCategoryName($category, $level = null)
{
$categoryName = '';
$categoryId = null;
$id_lang = $this->getDataLanguage();
if (!Validate::isLoadedObject($category)) {
$categoryId = (int) $category;
if ($categoryId) {
$category = new Category($categoryId);
}
}
if (!Validate::isLoadedObject($category)) {
return 'category not found ('.$categoryId.')';
}
if (!is_null($level)) {
while ($category->level_depth > $level) {
$category = new Category($category->id_parent);
}
}
switch ($this->module->gtmConfig->dataConfig->category_name) {
case 'link_rewrite':
$categoryName = !empty($category->link_rewrite) ? $category->link_rewrite : null;
break;
case 'id':
$categoryName = $category->id;
break;
default:
if (Validate::isLoadedObject($category)) {
if ($this->categoryTree && is_null($level)) {
$c_parents = $category->getParentsCategories($id_lang);
$c_parents_names = array();
foreach ($c_parents as $c_parent) {
if (!$c_parent['is_root_category']) {
$c_parents_names[] = $this->cleanString($c_parent['name']);
}
}
$c_parents_names = array_reverse($c_parents_names);
$categoryName = implode('/', $c_parents_names);
} else {
$categoryName = EcsGtmProTools::cleanString($category->getName());
}
}
break;
}
$categoryName = trim($categoryName);
if (empty($categoryName)) {
$categoryName = 'Unknown category name';
}
return $categoryName;
}
public function getDataLanguage()
{
return $this->idLang ? $this->idLang : (int) $this->context->language->id;
}
public function generateGtmTag()
{
if (!$this->module->isAllowed()) {
return '';
}
$dataLayerJs = $this->toJson();
$preDataLayerJs = null;
if (is_object($this->module->preDataLayer)) {
$preDataLayerJs = $this->module->preDataLayer->toJson();
} else {
if (isset($this->context->cookie->preDataLayerJs)) {
$preDataLayerJs = Context::getContext()->cookie->preDataLayerJs;
unset($this->context->cookie->preDataLayerJs);
}
}
if ($this->module->isDebugMode()) {
if ($preDataLayerJs) {
$this->module->addDebug($preDataLayerJs);
}
$this->module->addDebug($dataLayerJs);
if ($this->module->gtmConfig->userIdConfig->async) {
$this->module->addDebug('<div>[ASYNC USER INFO]</div><div id="ecsgtmpro_debug_ajax">Loading user info datalayer...</div>');
}
}
if ($this->module->isOrderValidationPage()) {
$this->module->saveDataLayerInLog($dataLayerJs);
}
$params = array(
'generalConfig' => $this->module->gtmConfig->generalConfig,
'userIdConfig' => $this->module->gtmConfig->userIdConfig,
'preDataLayer' => $preDataLayerJs,
'dataLayer' => $dataLayerJs,
'asyncUrl' => $this->context->link->getModuleLink('ecsgtmpro', 'async', array('action' => 'user'), null, null, null, true),
'eventDlReady' => $this->module->eventDatalayerReady,
'debug' => $this->module->isDebugMode()
);
$this->context->smarty->assign($params);
return $params;
}
public function getDataLayer()
{
return $this->dataLayer;
}
public function generateOrderConfirmationCode()
{
$id_cart = (int)(Tools::getValue('id_cart'));
$orders = EcsGtmProTools::getOrdersByCartId((int)($id_cart));
if ($this->module->isDebugMode()) {
$this->module->addDebug("[greviewsGenerateOrderConfirmationCode]");
}
$gcrOrderParams = array();
$gcrOrderParams['merchant_id'] = $this->module->gcrConfig->merchant_id;
$gcrOrderParams['order_id'] = '';
$gcrOrderParams['customer_email'] = '';
$gcrOrderParams['delivery_country'] = '';
$deliveryDelay = (int) $this->module->gcrConfig->delivery_delay;
$gcrOrderParams['estimated_delivery_date'] = date('Y-m-d', strtotime($deliveryDelay . ' weekdays'));
$ordersList = array();
foreach ($orders as $id_order) {
$order = new Order($id_order);
if (Validate::isLoadedObject($order)) {
if ($order->current_state != Configuration::get('PS_OS_ERROR')) {
$ordersList[] = $id_order;
if (count($ordersList) == 1) {
$customer = $order->getCustomer();
if (Validate::isLoadedObject($customer)) {
$gcrOrderParams['customer_email'] = $customer->email;
}
$delivery_address = new Address($order->id_address_delivery);
if (Validate::isLoadedObject($delivery_address)) {
$gcrOrderParams['delivery_country'] = Country::getIsoById($delivery_address->id_country);
}
}
$ref = $order->reference;
if (empty($gcrOrderParams['order_id'])) {
$gcrOrderParams['order_id'] = $ref;
} else {
$ids = explode(',', $gcrOrderParams['order_id']);
if (!in_array($ref, $ids)) {
$ids[] = $ref;
$gcrOrderParams['order_id'] = implode(',', $ids);
}
}
}
}
}
$this->context->smarty->assign(array(
'ecsGtmProGcr' => $gcrOrderParams
));
}
public function getCartAction($id_product, $id_product_attribute, $action, $qty)
{
if ($action != 'add' && $action != 'remove') {
return null;
}
$product = new Product($id_product);
$product->id_product_attribute = $id_product_attribute;
$product->quantity = (int) $qty;
$dataLayer = new self($this->module, $this->module->gtmConfig->generalConfig->format);
$dataLayer->dataLayer->addItem($product, ($action == 'add') ? 'add_to_cart' : 'remove_from_cart');
return $dataLayer;
}
public function addSubtotalsFromOrder($ecommerce, $order)
{
$revenue = (float) round($order->total_paid_tax_incl, _ECSGTMPRO_PRICE_DECIMAL_);
$tax = (float) round($order->total_paid_tax_incl - $order->total_paid_tax_excl, _ECSGTMPRO_PRICE_DECIMAL_);
$shipping = (float) round($order->total_shipping_tax_incl, _ECSGTMPRO_PRICE_DECIMAL_);
$discounts = (float) round($order->total_discounts_tax_incl, _ECSGTMPRO_PRICE_DECIMAL_);
if ($this->isEE()) {
$ecommerce->revenue = empty($ecommerce->revenue) ? $revenue : $ecommerce->revenue + $revenue;
}
if ($this->isGA4()) {
$ecommerce->value = empty($ecommerce->value) ? $revenue : $ecommerce->value + $revenue;
}
$ecommerce->tax = empty($ecommerce->tax) ? $tax : $ecommerce->tax + $tax;
$ecommerce->shipping = empty($ecommerce->shipping) ? $shipping : $ecommerce->shipping + $shipping;
$ecommerce->discounts = empty($ecommerce->discounts) ? $discounts : $ecommerce->discounts + $discounts;
if (empty($ecommerce->coupon)) {
$discounts = $order->getCartRules();
if (is_array($discounts) && count($discounts) > 0) {
$ecommerce->coupon = $discounts[0]['id_cart_rule'].'-'.$discounts[0]['name'];
}
}
}
public function getCartRulesFromCart($cart)
{
if (Validate::isLoadedObject($cart)) {
$cartRules = $cart->getCartRules();
if (is_array($cartRules) && count($cartRules) > 0) {
$this->dataLayer->coupon = $cartRules[0]['id_cart_rule'].'-'.$cartRules[0]['name'];
}
}
}
public function generateOrderConfirmationFromCart($idCart, $forceResend = false)
{
$orders = EcsGtmProTools::getOrdersByCartId($idCart);
$ecommerce = new stdClass();
$tx = null;
$lastOrder = null;
$ordersList = array();
foreach ($orders as $id_order) {
$order = new Order($id_order);
if (Validate::isLoadedObject($order)) {
if ($order->current_state != Configuration::get('PS_OS_ERROR') && ($forceResend || !EcsGtmProOrder::isSent($id_order, $order->id_shop))) {
$lastOrder = $order;
$ordersList[] = $id_order;
$this->module->createGtmOrder($id_order, $order->id_shop);
$this->module->orderValidationDetails[] = array('id_order' => $id_order);
$orderIdField = $this->module->orderIdField;
$currentRefOrder = $order->$orderIdField;
if (empty($tx)) {
$tx = (string) $currentRefOrder;
} else {
$ids = explode(',', $tx);
if (!in_array($currentRefOrder, $ids)) {
$ids[] = $currentRefOrder;
$tx = implode(',', $ids);
}
}
$this->addSubtotalsFromOrder($ecommerce, $order);
$products = $order->getProducts();
$this->addProductList($products, null, $this->module->gtmConfig->generalConfig->max_category, 'purchase');
}
}
}
if (Validate::isLoadedObject($lastOrder)) {
$pastOrders = EcsGtmProTools::countCustomerOtherOrders($lastOrder->id_customer, $lastOrder->reference);
$userInfo = new stdClass();
$userInfo->new = $pastOrders > 0 ? 0 : 1;
$userInfo->past_orders = $pastOrders;
$this->customer = $userInfo;
}
if (count($ordersList) > 0) {
if ($this->isEE()) {
$ecommerce->id = $tx;
$this->dataLayer->ecommerce->purchase->actionField = $ecommerce;
$this->dataLayer->event = "order_confirmation";
}
if ($this->isGA4()) {
$ecommerce->transaction_id = $tx;
$this->dataLayer->ecommerce->mergeObject($ecommerce);
$this->dataLayer->event = "purchase";
}
$callbackName = $forceResend ? 'orderresend' : 'orderconfirmation';
$this->dataLayer->eventCallback = $this->getCallback($callbackName, array(
'orders' => $ordersList,
'id_shop' => Context::getContext()->shop->id
));
}
}
public function getCallback($type, $params = array())
{
$callback = '';
$baseurl = $this->context->shop->getBaseURL(true);
if (empty($baseurl) || Tools::substr($baseurl, -1) != '/') {
$baseurl = $baseurl.'/';
}
$callbackUrl = $baseurl.'index.php?fc=module&module=ecsgtmpro&controller=callback';
$callbackParams = array();
$callbackParams['type'] = $type;
if (!is_null($params) && is_array($params) && count($params)) {
$callbackParams['params'] = $params;
}
if (count($callbackParams)) {
$callbackParams = urlencode(base64_encode(EcsGtmProTools::jsonEncode($callbackParams)));
$callbackUrl .= '&p='.$callbackParams;
$callback = 'function() {
var ajax = new XMLHttpRequest();
ajax.open("GET", "'.$callbackUrl.'", true);
ajax.send();
}';
$callback = preg_replace("/\r|\n/", "", $callback);
$callback = preg_replace('/\s+/', ' ', $callback);
}
return $callback;
}
protected function getDisplayedProduct()
{
$id = (int)Tools::getValue('id_product');
if (!$id) {
$smartyProduct = $this->context->smarty->getTemplateVars('product');
if (Validate::isLoadedObject($smartyProduct)) {
$id = (int)$smartyProduct->id;
}
}
$product = new Product($id);
if (Tools::getValue('id_product_attribute')) {
$product->id_product_attribute = (int) Tools::getValue('id_product_attribute');
} elseif (!isset($product->id_product_attribute)) {
$product->id_product_attribute = 0;
}
return $product;
}
public function generateRefund($order_id, $products = null)
{
$order = new Order($order_id);
if (!Validate::isLoadedObject($order)) {
return false;
}
$ecommerce = new stdClass();
if ($this->isEE()) {
$ecommerce->id = (string) $order->id;
}
if ($this->isGA4()) {
$ecommerce->transaction_id = (string) $order->id;
}
$this->addSubtotalsFromOrder($ecommerce, $order);
if ($products !== "all" && is_array($products) && count($products)) {
foreach ($products as $product_key => $qty) {
$productIdData = explode(',', $product_key);
$product = new Product($productIdData[0]);
$product->id_product_attribute = $productIdData[1];
$product->quantity = $qty;
$this->dataLayer->addItem($product, 'refund');
}
}
$this->dataLayer->eventCallback = $this->getCallback("orderrefund", array('order' => $order->id, 'id_shop' => $order->id_shop));
if ($this->isEE()) {
if (!isset($this->dataLayer->refund)) {
$this->dataLayer->refund = new EcsGtmProRefund();
}
$this->dataLayer->refund->actionField = $ecommerce;
$this->dataLayer->event = "order_refund";
}
if ($this->isGA4()) {
$this->dataLayer->ecommerce->mergeObject($ecommerce);
$this->dataLayer->event = "refund";
}
}
}