Subida del módulo y tema de PrestaShop

This commit is contained in:
Kaloyan
2026-04-09 18:31:51 +02:00
parent 12c253296f
commit 16b3ff9424
39262 changed files with 7418797 additions and 0 deletions

View File

@@ -0,0 +1,138 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Database;
use Configuration;
use Db;
use Language;
use Ps_Googleanalytics;
use Shop;
use Tab;
class Install
{
/**
* @var Ps_Googleanalytics
*/
private $module;
public function __construct(Ps_Googleanalytics $module)
{
if (Shop::isFeatureActive()) {
Shop::setContext(Shop::CONTEXT_ALL);
}
$this->module = $module;
}
/**
* installTables
*
* @return bool
*/
public function installTables()
{
$sql = [];
$sql[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'ganalytics` (
`id_google_analytics` int(11) NOT NULL AUTO_INCREMENT,
`id_order` int(11) NOT NULL,
`id_customer` int(10) NOT NULL,
`id_shop` int(11) NOT NULL,
`sent` tinyint(1) DEFAULT NULL,
`refund_sent` tinyint(1) DEFAULT NULL,
`date_add` datetime DEFAULT NULL,
PRIMARY KEY (`id_google_analytics`),
KEY `id_order` (`id_order`),
KEY `sent` (`sent`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 AUTO_INCREMENT=1';
$sql[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'ganalytics_data` (
`id_cart` int(11) NOT NULL,
`id_shop` int(11) NOT NULL,
`data` TEXT DEFAULT NULL,
PRIMARY KEY (`id_cart`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8';
foreach ($sql as $query) {
if (!Db::getInstance()->execute($query)) {
return false;
}
}
return true;
}
/**
* Insert default data to database
*
* @return bool
*/
public function setDefaultConfiguration()
{
Configuration::updateValue('GA_CANCELLED_STATES', json_encode([Configuration::get('PS_OS_CANCELED')]));
Configuration::updateValue('GA_BACKLOAD_ENABLED', false);
Configuration::updateValue('GA_BACKLOAD_DAYS', 30);
return true;
}
/**
* Register Module hooks
*
* @return bool
*/
public function registerHooks()
{
return $this->module->registerHook('displayHeader') &&
$this->module->registerHook('displayAdminOrder') &&
$this->module->registerHook('displayBeforeBodyClosingTag') &&
$this->module->registerHook('displayFooterProduct') &&
$this->module->registerHook('displayOrderConfirmation') &&
$this->module->registerHook('actionProductCancel') &&
$this->module->registerHook('actionValidateOrder') &&
$this->module->registerHook('actionOrderStatusPostUpdate') &&
$this->module->registerHook('actionCartUpdateQuantityBefore') &&
$this->module->registerHook('actionObjectProductInCartDeleteBefore') &&
$this->module->registerHook('displayBackOfficeHeader') &&
$this->module->registerHook('actionCarrierProcess');
}
/**
* Installs hidden tab for our ajax controller
*
* @return bool
*/
public function installTab()
{
$tab = new Tab();
$tab->class_name = 'AdminGanalyticsAjax';
$tab->module = $this->module->name;
$tab->active = true;
$tab->id_parent = -1;
$tab->name = array_fill_keys(
Language::getIDs(false),
$this->module->displayName
);
return $tab->add();
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Database;
use Db;
use Tab;
use Validate;
class Uninstall
{
/**
* uninstallTables
*
* @return bool
*/
public function uninstallTables()
{
$sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'ganalytics`';
$sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'ganalytics_data`';
foreach ($sql as $query) {
if (!Db::getInstance()->execute($query)) {
return false;
}
}
return true;
}
/**
* uninstall tab
*
* @return bool
*/
public function uninstallTab()
{
$result = true;
$id_tab = (int) Tab::getIdFromClassName('AdminGanalyticsAjax');
$tab = new Tab($id_tab);
if (Validate::isLoadedObject($tab)) {
$result = $tab->delete();
}
return $result;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,260 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Form;
use Configuration;
use Context;
use HelperForm;
use OrderState;
use Ps_Googleanalytics;
use Tools;
class ConfigurationForm
{
private $module;
public function __construct(Ps_Googleanalytics $module)
{
$this->module = $module;
}
/**
* generate
*
* @return string
*/
public function generate()
{
// Get default language
$default_lang = (int) Configuration::get('PS_LANG_DEFAULT');
$helper = new HelperForm();
// Module, token and currentIndex
$helper->module = $this->module;
$helper->name_controller = $this->module->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = Context::getContext()->link->getAdminLink('AdminModules', true, [], [
'configure' => $this->module->name,
'tab_module' => $this->module->tab,
'module_name' => $this->module->name,
]);
// Language
$helper->default_form_language = $default_lang;
$helper->allow_employee_form_lang = $default_lang;
// Title and toolbar
$helper->title = $this->module->displayName;
$helper->show_toolbar = true; // false -> remove toolbar
$helper->toolbar_scroll = true; // yes - > Toolbar is always visible on the top of the screen.
$helper->submit_action = 'submit' . $this->module->name;
$helper->toolbar_btn = [
'save' => [
'desc' => $this->module->getTranslator()->trans('Save', [], 'Modules.Googleanalytics.Admin'),
'href' => Context::getContext()->link->getAdminLink('AdminModules', true, [], [
'configure' => $this->module->name,
'tab_module' => $this->module->tab,
'module_name' => $this->module->name,
'save' => $this->module->name,
]),
],
'back' => [
'href' => Context::getContext()->link->getAdminLink('AdminModules', true),
'desc' => $this->module->getTranslator()->trans('Back to list', [], 'Modules.Googleanalytics.Admin'),
],
];
$fields_form = [];
// Init Fields form array
$fields_form[0]['form'] = [
'legend' => [
'title' => $this->module->getTranslator()->trans('Settings', [], 'Modules.Googleanalytics.Admin'),
],
'input' => [
[
'type' => 'text',
'label' => $this->module->getTranslator()->trans('Google Analytics Tracking ID', [], 'Modules.Googleanalytics.Admin'),
'name' => 'GA_ACCOUNT_ID',
'size' => 20,
'required' => true,
'desc' => $this->module->getTranslator()->trans('This information is available in your Google Analytics account. Google Analytics 4 tracking ID starts with "G-".', [], 'Modules.Googleanalytics.Admin'),
],
[
'type' => 'switch',
'label' => $this->module->getTranslator()->trans('Enable User ID tracking', [], 'Modules.Googleanalytics.Admin'),
'name' => 'GA_USERID_ENABLED',
'desc' => $this->module->getTranslator()->trans('This option adds unique user ID to the tag to better track the customer. Use this option only if it complies with laws in your country.', [], 'Modules.Googleanalytics.Admin'),
'values' => [
[
'id' => 'ga_userid_enabled',
'value' => 1,
'label' => $this->module->getTranslator()->trans('Yes', [], 'Modules.Googleanalytics.Admin'),
],
[
'id' => 'ga_userid_disabled',
'value' => 0,
'label' => $this->module->getTranslator()->trans('No', [], 'Modules.Googleanalytics.Admin'),
],
],
],
[
'type' => 'switch',
'label' => $this->module->getTranslator()->trans('Anonymize IP', [], 'Modules.Googleanalytics.Admin'),
'name' => 'GA_ANONYMIZE_ENABLED',
'desc' => $this->module->getTranslator()->trans('Use this option to anonymize the visitors IP to comply with data privacy laws in some countries', [], 'Modules.Googleanalytics.Admin'),
'values' => [
[
'id' => 'ga_anonymize_enabled',
'value' => 1,
'label' => $this->module->getTranslator()->trans('Yes', [], 'Modules.Googleanalytics.Admin'),
],
[
'id' => 'ga_anonymize_disabled',
'value' => 0,
'label' => $this->module->getTranslator()->trans('No', [], 'Modules.Googleanalytics.Admin'),
],
],
],
[
'type' => 'switch',
'label' => $this->module->getTranslator()->trans('Enable Back Office Tracking', [], 'Modules.Googleanalytics.Admin'),
'name' => 'GA_TRACK_BACKOFFICE_ENABLED',
'desc' => $this->module->getTranslator()->trans('Use this option to enable the tracking inside the Back Office', [], 'Modules.Googleanalytics.Admin'),
'values' => [
[
'id' => 'ga_track_backoffice',
'value' => 1,
'label' => $this->module->getTranslator()->trans('Yes', [], 'Modules.Googleanalytics.Admin'),
],
[
'id' => 'ga_do_not_track_backoffice',
'value' => 0,
'label' => $this->module->getTranslator()->trans('No', [], 'Modules.Googleanalytics.Admin'),
],
],
],
[
'type' => 'select',
'label' => $this->module->getTranslator()->trans('Canceled order states', [], 'Modules.Googleanalytics.Admin'),
'name' => 'GA_CANCELLED_STATES',
'desc' => $this->module->getTranslator()->trans('Choose order states in which you consider the given order canceled. This will usually be the default "Canceled" state, but some stores may have extra states like "Returned", etc.', [], 'Modules.Googleanalytics.Admin'),
'class' => 'chosen',
'multiple' => true,
'options' => [
'query' => OrderState::getOrderStates((int) Context::getContext()->language->id),
'id' => 'id_order_state',
'name' => 'name',
],
],
[
'type' => 'switch',
'label' => $this->module->getTranslator()->trans('Re-send failed orders', [], 'Modules.Googleanalytics.Admin'),
'name' => 'GA_BACKLOAD_ENABLED',
'desc' => $this->module->getTranslator()->trans('This option will resend all orders that failed to be sent normally in front-office, due to failures or ad-blockers.', [], 'Modules.Googleanalytics.Admin'),
'values' => [
[
'id' => 'ga_backload_enabled',
'value' => 1,
'label' => $this->module->getTranslator()->trans('Yes', [], 'Modules.Googleanalytics.Admin'),
],
[
'id' => 'ga_backload_enabled',
'value' => 0,
'label' => $this->module->getTranslator()->trans('No', [], 'Modules.Googleanalytics.Admin'),
],
],
],
[
'type' => 'text',
'label' => $this->module->getTranslator()->trans('Failed orders period', [], 'Modules.Googleanalytics.Admin'),
'name' => 'GA_BACKLOAD_DAYS',
'class' => 'input fixed-width-md',
'suffix' => 'days',
'desc' => $this->module->getTranslator()->trans('If you want to resend failed orders, specify how many days back the module should look for them. Default: 30.', [], 'Modules.Googleanalytics.Admin'),
],
],
'submit' => [
'title' => $this->module->getTranslator()->trans('Save', [], 'Modules.Googleanalytics.Admin'),
],
];
// Load current value
$helper->fields_value['GA_ACCOUNT_ID'] = Configuration::get('GA_ACCOUNT_ID');
$helper->fields_value['GA_USERID_ENABLED'] = (bool) Configuration::get('GA_USERID_ENABLED');
$helper->fields_value['GA_ANONYMIZE_ENABLED'] = (bool) Configuration::get('GA_ANONYMIZE_ENABLED');
$helper->fields_value['GA_TRACK_BACKOFFICE_ENABLED'] = (bool) Configuration::get('GA_TRACK_BACKOFFICE_ENABLED');
$helper->fields_value['GA_CANCELLED_STATES[]'] = json_decode(Configuration::get('GA_CANCELLED_STATES'), true);
$helper->fields_value['GA_BACKLOAD_ENABLED'] = (bool) Configuration::get('GA_BACKLOAD_ENABLED');
$helper->fields_value['GA_BACKLOAD_DAYS'] = (int) Configuration::get('GA_BACKLOAD_DAYS');
return $helper->generateForm($fields_form);
}
/**
* treat the form datas if submited
*
* @return string
*/
public function treat()
{
$gaAccountId = Tools::getValue('GA_ACCOUNT_ID');
$gaUserIdEnabled = Tools::getValue('GA_USERID_ENABLED');
$gaAnonymizeEnabled = Tools::getValue('GA_ANONYMIZE_ENABLED');
$gaTrackBackOffice = Tools::getValue('GA_TRACK_BACKOFFICE_ENABLED');
$gaCancelledStates = Tools::getValue('GA_CANCELLED_STATES');
$gaBackloadEnabled = Tools::getValue('GA_BACKLOAD_ENABLED');
$gaBackloadDays = Tools::getValue('GA_BACKLOAD_DAYS');
if (!empty($gaAccountId)) {
Configuration::updateValue('GA_ACCOUNT_ID', $gaAccountId);
Configuration::updateValue('GANALYTICS_CONFIGURATION_OK', true);
}
if (null !== $gaUserIdEnabled) {
Configuration::updateValue('GA_USERID_ENABLED', (bool) $gaUserIdEnabled);
}
if (null !== $gaAnonymizeEnabled) {
Configuration::updateValue('GA_ANONYMIZE_ENABLED', (bool) $gaAnonymizeEnabled);
}
if (null !== $gaTrackBackOffice) {
Configuration::updateValue('GA_TRACK_BACKOFFICE_ENABLED', (bool) $gaTrackBackOffice);
}
if (null !== $gaBackloadEnabled) {
Configuration::updateValue('GA_BACKLOAD_ENABLED', (bool) $gaBackloadEnabled);
}
if (null !== $gaBackloadDays) {
Configuration::updateValue('GA_BACKLOAD_DAYS', (int) $gaBackloadDays);
}
if ($gaCancelledStates === false) {
Configuration::updateValue('GA_CANCELLED_STATES', '');
} else {
Configuration::updateValue('GA_CANCELLED_STATES', json_encode($gaCancelledStates));
}
return $this->module->displayConfirmation($this->module->getTranslator()->trans('Settings updated successfully.', [], 'Modules.Googleanalytics.Admin'));
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,115 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics;
use Configuration;
class GoogleAnalyticsTools
{
/**
* Renders purchase event for order
*
* @param array $orderProducts
* @param array $orderData
* @param string $callbackUrl
*
* @return string|void
*/
public function renderPurchaseEvent($orderProducts, $orderData, $callbackUrl)
{
if (!is_array($orderProducts)) {
return;
}
$callbackData = [
'orderid' => $orderData['transaction_id'],
'customer' => $orderData['customer'],
];
$eventData = [
'transaction_id' => (int) $orderData['transaction_id'],
'affiliation' => $orderData['affiliation'],
'value' => (float) $orderData['value'],
'tax' => (float) $orderData['tax'],
'shipping' => (float) $orderData['shipping'],
'currency' => $orderData['currency'],
'items' => $orderProducts,
'event_callback' => "function() {
$.get('" . $callbackUrl . "', " . json_encode($callbackData, JSON_UNESCAPED_UNICODE) . ');
}',
];
return $this->renderEvent(
'purchase',
$eventData,
['event_callback']
);
}
/**
* Encodes array of data into JSON, optionally ignoring some of the values
*
* @param array $data Data pairs
* @param array $ignoredKeys Values of these keys won't be encoded, for literal output of functions
*
* @return string json encoded data
*/
public function jsonEncodeWithBlacklist($data, $ignoredKeys = [])
{
$return = [];
foreach ($data as $k => $v) {
if (in_array($k, $ignoredKeys)) {
$return[] = json_encode($k, JSON_UNESCAPED_UNICODE) . ': ' . $v;
} else {
$return[] = json_encode($k, JSON_UNESCAPED_UNICODE) . ': ' . json_encode($v, JSON_UNESCAPED_UNICODE);
}
}
return '{' . implode(', ', $return) . '}';
}
/**
* Renders gtag event and encodes the data. You can optionally pass which data keys you want to
* output in a raw way - callbacks for example.
*
* @param string $eventName
* @param array $eventData
* @param array $ignoredKeys Values of these keys won't be encoded, for literal output of functions
*
* @return string render gtag event for output
*/
public function renderEvent($eventName, $eventData, $ignoredKeys = [])
{
// Automatically add send_to parameter to all events to avoid sending extra events
// to other gtag configs (Ads for example).
$eventData = array_merge(
['send_to' => Configuration::get('GA_ACCOUNT_ID')],
$eventData
);
return sprintf(
'gtag("event", "%1$s", %2$s);',
$eventName,
$this->jsonEncodeWithBlacklist($eventData, $ignoredKeys)
);
}
}

View File

@@ -0,0 +1,122 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Handler;
use PrestaShop\Module\Ps_Googleanalytics\Repository\GanalyticsDataRepository;
class GanalyticsDataHandler
{
private $ganalyticsDataRepository;
private $cartId;
private $shopId;
/**
* __construct
*
* @param int $cartId
* @param int $shopId
*/
public function __construct($cartId, $shopId)
{
$this->ganalyticsDataRepository = new GanalyticsDataRepository();
$this->cartId = (int) $cartId;
$this->shopId = (int) $shopId;
}
/**
* readData
*
* @return array
*/
public function readData()
{
$dataReturned = $this->ganalyticsDataRepository->findDataByCartIdAndShopId(
$this->cartId,
$this->shopId
);
if (false === $dataReturned) {
return [];
}
return $this->jsonDecodeValidJson($dataReturned);
}
/**
* Deletes all persisted data, probably because it was flushed.
*
* @return bool
*/
public function deleteData()
{
return $this->ganalyticsDataRepository->deleteRow(
$this->cartId,
$this->shopId
);
}
/**
* Stores event into data repository so we can output it
* on first available chance.
*
* @param string $dataToPersist
*
* @return bool
*/
public function persistData($dataToPersist)
{
// Try to get current data
$currentData = $this->readData();
// If no data has been persisted yet, we create a new array, otherwise
// we add it to the previous events stored.
if (!empty($currentData)) {
$newData = $currentData;
$newData[] = $dataToPersist;
} else {
$newData = [$dataToPersist];
}
return $this->ganalyticsDataRepository->addNewRow(
(int) $this->cartId,
(int) $this->shopId,
json_encode($newData)
);
}
/**
* Check if the json is valid and returns an empty array if not
*
* @param string $json
*
* @return array
*/
protected function jsonDecodeValidJson($json)
{
$array = json_decode($json, true);
if (JSON_ERROR_NONE === json_last_error()) {
return $array;
}
return [];
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Handler;
use Configuration;
use Context;
use Ps_Googleanalytics;
class GanalyticsJsHandler
{
private $module;
private $context;
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* Generate Google Analytics js
*
* @param string $jsCode
*
* @return void|string
*/
public function generate($jsCode)
{
if (Configuration::get('GA_ACCOUNT_ID')) {
$this->context->smarty->assign(
[
'jsCode' => $jsCode,
]
);
return $this->module->display(
$this->module->getLocalPath() . $this->module->name,
'ga_tag.tpl'
);
}
}
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Handler;
use Module;
class ModuleHandler
{
/**
* @param string $moduleName
*
* @return bool
*/
public function isModuleEnabled($moduleName)
{
$module = Module::getInstanceByName($moduleName);
if (!($module instanceof Module)) {
return false;
}
if (false === Module::isInstalled($moduleName)) {
return false;
}
if (false === $module->active) {
return false;
}
return true;
}
/**
* @param string $moduleName
* @param string $hookName
*
* @return bool
*/
public function isModuleEnabledAndHookedOn($moduleName, $hookName)
{
$module = Module::getInstanceByName($moduleName);
if (false === $this->isModuleEnabled($moduleName)) {
return false;
}
return $module->isRegisteredInHook($hookName);
}
/**
* @param string $moduleName
*
* @return bool
*/
public function uninstallModule($moduleName)
{
if (false === Module::isInstalled($moduleName)) {
return false;
}
$oldModule = Module::getInstanceByName($moduleName);
if (!($oldModule instanceof Module)) {
return false;
}
if (method_exists($oldModule, 'uninstallTab')) {
$oldModule->uninstallTab();
}
// This closure calls the parent class to prevent data to be erased
$parentUninstallClosure = function () {
return parent::uninstall();
};
$parentUninstallClosure = $parentUninstallClosure->bindTo($oldModule, get_class($oldModule));
return $parentUninstallClosure();
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,80 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Context;
use PrestaShop\Module\Ps_Googleanalytics\Repository\CarrierRepository;
use Ps_Googleanalytics;
class HookActionCarrierProcess implements HookInterface
{
private $module;
private $context;
private $params;
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* run
*
* @return void
*/
public function run()
{
if (isset($this->params['cart']->id_carrier)) {
$carrierRepository = new CarrierRepository();
// Load carrier name
$carrierName = (string) $carrierRepository->findByCarrierId((int) $this->params['cart']->id_carrier);
// Check if we actually have some name
if (empty($carrierName)) {
return;
}
// Prepare and render the event
$eventData = [
'currency' => $this->context->currency->iso_code,
'value' => (float) $this->context->cart->getSummaryDetails()['total_price'],
'shipping_tier' => $carrierName,
];
$jsCode = $this->module->getTools()->renderEvent(
'add_shipping_info',
$eventData
);
// Store it into our repository so we can flush it on next page load
$this->module->getDataHandler()->persistData($jsCode);
}
}
/**
* @param array $params
*/
public function setParams($params)
{
$this->params = $params;
}
}

View File

@@ -0,0 +1,106 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Context;
use PrestaShop\Module\Ps_Googleanalytics\Wrapper\ProductWrapper;
use Product;
use Ps_Googleanalytics;
class HookActionCartUpdateQuantityBefore implements HookInterface
{
private $module;
/**
* @var Context
*/
private $context;
private $params;
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* run
*
* @return void
*/
public function run()
{
/*
* The hook passes a legacy Product object to add, but no attribute information.
* But thankfully, we can use id_product_attribute for this.
*
* Other info is fairly standard:
*
* Add to cart from product page + up from cart page
* $this->params['operator'] == up
* $this->params['quantity'] to determine quantity
*
* Down from cart page
* $this->params['operator'] == down
* $this->params['quantity'] to determine quantity
*/
// Format product and standardize ID
$product = (array) $this->params['product'];
$product['id_product'] = $product['id'];
// Add information about attribute
if (!empty($this->params['id_product_attribute'])) {
$product['id_product_attribute'] = (int) $this->params['id_product_attribute'];
}
// Get some basic information
$product = Product::getProductProperties($this->context->language->id, $product);
// Add information about quantity difference
$product['quantity'] = (int) $this->params['quantity'];
// Prepare it and format it for our purpose
$productWrapper = new ProductWrapper($this->context);
$item = $productWrapper->prepareItemFromProduct($product, true);
// Prepare and render event
$eventData = [
'currency' => $this->context->currency->iso_code,
'value' => $item['price'] * $item['quantity'],
'items' => [$item],
];
$jsCode = $this->module->getTools()->renderEvent(
$this->params['operator'] == 'up' ? 'add_to_cart' : 'remove_from_cart',
$eventData
);
// Store this event
$this->module->getDataHandler()->persistData($jsCode);
}
/**
* @param array $params
*/
public function setParams($params)
{
$this->params = $params;
}
}

View File

@@ -0,0 +1,94 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Context;
use PrestaShop\Module\Ps_Googleanalytics\Wrapper\ProductWrapper;
use Product;
use Ps_Googleanalytics;
use Validate;
class HookActionObjectProductInCartDeleteBefore implements HookInterface
{
private $module;
/**
* @var Context
*/
private $context;
private $params;
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* run
*
* @return void
*/
public function run()
{
// Format product and standardize ID
$product = new Product((int) $this->params['id_product'], false, (int) $this->context->language->id);
if (!Validate::isLoadedObject($product)) {
return;
}
$product = (array) $product;
$product['id_product'] = $product['id'];
// Get some basic information
$product = Product::getProductProperties($this->context->language->id, $product);
// Add information about attribute
if (!empty($this->params['id_product_attribute'])) {
$product['id_product_attribute'] = (int) $this->params['id_product_attribute'];
}
// Prepare it and format it for our purpose
$productWrapper = new ProductWrapper($this->context);
$item = $productWrapper->prepareItemFromProduct($product, false);
// Prepare and render event
$eventData = [
'currency' => $this->context->currency->iso_code,
'value' => $item['price'] * $item['quantity'],
'items' => [$item],
];
$jsCode = $this->module->getTools()->renderEvent(
'remove_from_cart',
$eventData
);
// Store this event
$this->module->getDataHandler()->persistData($jsCode);
}
/**
* @param array $params
*/
public function setParams($params)
{
$this->params = $params;
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Configuration;
use Context;
use Db;
use Ps_Googleanalytics;
class HookActionOrderStatusPostUpdate implements HookInterface
{
/**
* @var Ps_Googleanalytics
*/
private $module;
/**
* @var Context
*/
private $context;
/**
* @var array
*/
private $params;
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* run
*
* @return void
*/
public function run()
{
// If we do not have an order or a new order status, we return
if (empty($this->params['id_order']) || empty($this->params['newOrderStatus']->id)) {
return;
}
// We get all states in which the merchant want to have refund sent and check if the new state being set belongs there
$gaCancelledStates = json_decode(Configuration::get('GA_CANCELLED_STATES'), true);
if (empty($gaCancelledStates) || !in_array($this->params['newOrderStatus']->id, $gaCancelledStates)) {
return;
}
// We check if the refund was already sent to Google Analytics
$gaRefundSent = Db::getInstance()->getValue(
'SELECT id_order FROM `' . _DB_PREFIX_ . 'ganalytics` WHERE id_order = ' . (int) $this->params['id_order'] . ' AND refund_sent = 1'
);
// If it was not already refunded
if ($gaRefundSent === false) {
// We refund it and set the "sent" flag to true
$jsCode = $this->getGoogleAnalytics4($this->params['id_order']);
$this->context->cookie->ga_admin_refund = $jsCode;
$this->context->cookie->write();
// We save this information to database
Db::getInstance()->execute(
'UPDATE `' . _DB_PREFIX_ . 'ganalytics` SET refund_sent = 1 WHERE id_order = ' . (int) $this->params['id_order']
);
}
}
/**
* setParams
*
* @param array $params
*/
public function setParams($params)
{
$this->params = $params;
}
/**
* @param int $idOrder
*/
protected function getGoogleAnalytics4($idOrder)
{
$eventData = [
'transaction_id' => (int) $idOrder,
];
return $this->module->getTools()->renderEvent(
'refund',
$eventData
);
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Context;
use OrderDetail;
use Ps_Googleanalytics;
use Validate;
class HookActionProductCancel implements HookInterface
{
/**
* @var Ps_Googleanalytics
*/
private $module;
/**
* @var Context
*/
private $context;
private $params;
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* run
*
* @return void
*/
public function run()
{
if (!isset($this->params['id_order_detail']) || !isset($this->params['cancel_quantity'])) {
return;
}
// Display GA refund product
$orderDetail = new OrderDetail($this->params['id_order_detail']);
// Check if the hook provided us with a valid existing ID of order detail.
// An example are automatic tests, which do not provide it unfortunately.
if (!Validate::isLoadedObject($orderDetail)) {
return;
}
$idProduct = empty($orderDetail->product_attribute_id) ? $orderDetail->product_id : $orderDetail->product_id . '-' . $orderDetail->product_attribute_id;
$jsCode = $this->getGoogleAnalytics4(
(int) $this->params['order']->id,
$idProduct,
(float) $this->params['cancel_quantity'],
$orderDetail->product_name
);
$this->context->cookie->ga_admin_refund = $jsCode;
$this->context->cookie->write();
}
/**
* setParams
*
* @param array $params
*/
public function setParams($params)
{
$this->params = $params;
}
/**
* @param int $idOrder
* @param string $idProduct
* @param float $quantity
* @param string $nameProduct
*/
protected function getGoogleAnalytics4($idOrder, $idProduct, $quantity, $nameProduct)
{
$eventData = [
'transaction_id' => (int) $idOrder,
'items' => [
[
'item_id' => (int) $idProduct,
'item_name' => $nameProduct,
'quantity' => (int) $quantity,
],
],
];
return $this->module->getTools()->renderEvent(
'refund',
$eventData
);
}
}

View File

@@ -0,0 +1,89 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Context;
use Ps_Googleanalytics;
class HookActionValidateOrder implements HookInterface
{
/**
* @var Ps_Googleanalytics
*/
private $module;
/**
* @var Context
*/
private $context;
/**
* @var array
*/
private $params;
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* run
*
* @return void
*/
public function run()
{
// Check if we are creating backoffice order, we are only launching this hook when creating backoffice order
// For FO purposes, we use displayOrderConfirmation.
if (empty($this->context->controller->controller_name)
|| !in_array($this->context->controller->controller_name, ['AdminOrders', 'Admin'])) {
return;
}
// Mark this ID to immediately display it on next page load
$order = $this->params['order'];
// We are checking this, because in case of multishipping, there could be multiple orders
if (!empty($this->context->cookie->ga_admin_order)) {
$ga_admin_order = sprintf(
'%1$s,%2$s',
$this->context->cookie->ga_admin_order,
$order->id
);
} else {
$ga_admin_order = $order->id;
}
$this->context->cookie->ga_admin_order = $ga_admin_order;
$this->context->cookie->write();
}
/**
* setParams
*
* @param array $params
*/
public function setParams($params)
{
$this->params = $params;
}
}

View File

@@ -0,0 +1,184 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Cart;
use Configuration;
use Context;
use Db;
use Order;
use PrestaShop\Module\Ps_Googleanalytics\Handler\GanalyticsJsHandler;
use PrestaShop\Module\Ps_Googleanalytics\Repository\GanalyticsRepository;
use PrestaShop\Module\Ps_Googleanalytics\Wrapper\OrderWrapper;
use PrestaShop\Module\Ps_Googleanalytics\Wrapper\ProductWrapper;
use Ps_Googleanalytics;
use Tools;
use Validate;
class HookDisplayBackOfficeHeader implements HookInterface
{
private $module;
private $context;
private $gaScripts = '';
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* run
*
* @return string
*/
public function run()
{
// Add assets if we are on configuration page
if (strcmp(Tools::getValue('configure'), $this->module->name) === 0) {
$this->context->controller->addCSS($this->module->getPathUri() . 'views/css/ganalytics.css');
}
// Render base tag using displayHeader hook with backoffice parameter
$this->gaScripts .= $this->module->hookDisplayHeader(null, true);
// Process manual orders instantly, we have their IDs in cookie
$this->processManualOrders();
// Backload old orders that failed to load normally
$this->processFailedOrders();
return $this->gaScripts;
}
/**
* Checks if there are any orders that failed to be sent normally through front office and processes them
*/
protected function processFailedOrders()
{
if (empty(Configuration::get('GA_BACKLOAD_ENABLED'))) {
return;
}
// Check for value on how long back we will get them
$backloadDays = (int) Configuration::get('GA_BACKLOAD_DAYS');
if ($backloadDays < 1) {
return;
}
// Get all failed orders (either not present in our table or not sent)
// We go GA_BACKLOAD_DAYS into the past and at least 30 minutes old
$failedOrders = Db::getInstance()->ExecuteS(
'SELECT DISTINCT o.id_order, g.sent FROM `' . _DB_PREFIX_ . 'orders` o
LEFT JOIN `' . _DB_PREFIX_ . GanalyticsRepository::TABLE_NAME . '` g ON o.id_order = g.id_order
WHERE (g.sent IS NULL OR g.sent = 0) AND o.date_add BETWEEN NOW() - INTERVAL ' . $backloadDays . ' DAY AND NOW() - INTERVAL 30 MINUTE'
);
// Process each failed order
foreach ($failedOrders as $row) {
$this->processOrder((int) $row['id_order']);
}
}
/**
* Checks if there are any manual orders in cookie and processes them
*/
protected function processManualOrders()
{
$adminOrders = $this->context->cookie->ga_admin_order;
if (empty($adminOrders)) {
return;
}
// Separate them by IDs and process one by one
$adminOrders = explode(',', $adminOrders);
foreach ($adminOrders as $idOrder) {
$this->processOrder((int) $idOrder);
}
// Clean up the cookie
unset($this->context->cookie->ga_admin_order);
$this->context->cookie->write();
}
/**
* Renders tracking code for given order
*
* @param int $idOrder
*/
public function processOrder($idOrder)
{
$order = new Order((int) $idOrder);
if (!Validate::isLoadedObject($order) || $order->getCurrentState() == (int) Configuration::get('PS_OS_ERROR')) {
return;
}
// Load up our handlers and repositories
$ganalyticsRepository = new GanalyticsRepository();
$gaTagHandler = new GanalyticsJsHandler($this->module, $this->context);
$productWrapper = new ProductWrapper($this->context);
$orderWrapper = new OrderWrapper($this->context);
// If it's a completely new order, add order to repository, so we can later mark it as sent
if (empty($ganalyticsRepository->findGaOrderByOrderId((int) $order->id))) {
$ganalyticsRepository->addOrder((int) $order->id, (int) $order->id_shop);
}
// If the order was already sent for some reason, don't do anything
if ($ganalyticsRepository->hasOrderBeenAlreadySent((int) $order->id)) {
return;
}
// Prepare transaction data
$orderData = $orderWrapper->wrapOrder($order);
// Empty script for the current order
$gaScripts = '';
// Prepare order products, if the cart still exists
$orderProducts = [];
$cart = new Cart($order->id_cart);
if (Validate::isLoadedObject($cart)) {
$orderProducts = $productWrapper->prepareItemListFromProductList($cart->getProducts(), true);
}
// Add payment event
$gaScripts .= $this->module->getTools()->renderEvent(
'add_payment_info',
[
'currency' => $orderData['currency'],
'value' => (float) $orderData['value'],
'payment_type' => $orderData['payment_type'],
'items' => $orderProducts,
]
);
// Render transaction code
$gaScripts .= $this->module->getTools()->renderPurchaseEvent(
$orderProducts,
$orderData,
$this->context->link->getAdminLink('AdminGanalyticsAjax')
);
$this->gaScripts .= $gaTagHandler->generate($gaScripts);
}
}

View File

@@ -0,0 +1,279 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Context;
use PrestaShop\Module\Ps_Googleanalytics\Handler\GanalyticsJsHandler;
use PrestaShop\Module\Ps_Googleanalytics\Wrapper\ProductWrapper;
use Ps_Googleanalytics;
class HookDisplayBeforeBodyClosingTag implements HookInterface
{
private $module;
private $context;
private $gaScripts = '';
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* run
*
* @return string
*/
public function run()
{
// Prepare our tag handler
$gaTagHandler = new GanalyticsJsHandler($this->module, $this->context);
// Log information about product listing
$this->saveInformationAboutListing();
// Flush events stored in data storage from previous pages
$this->outputStoredEvents();
// Add events
$this->renderProductListing();
$this->renderSearch();
$this->renderCartPage();
$this->renderBeginCheckout();
$this->renderLogin();
$this->renderRegistration();
// Output everything
return $gaTagHandler->generate($this->gaScripts);
}
/**
* This method renders tracking code for product listings, like category pages.
*/
private function renderProductListing()
{
// Try to get product list variable
$listing = $this->context->smarty->getTemplateVars('listing');
if (empty($listing['products'])) {
return;
}
// Prepare items to our format
$productWrapper = new ProductWrapper($this->context);
$items = $productWrapper->prepareItemListFromProductList($listing['products']);
// Prepare info about the list
$item_list_id = $this->context->controller->php_self;
$item_list_name = $listing['label'];
// Render the event
$eventData = [
'item_list_id' => $item_list_id,
'item_list_name' => $item_list_name,
'items' => $items,
];
$this->gaScripts .= $this->module->getTools()->renderEvent(
'view_item_list',
$eventData
);
// Render quickview events
foreach ($items as $item) {
$eventData = [
'item_list_id' => $item_list_id,
'item_list_name' => $item_list_name,
'items' => [$item],
];
// Keep only product ID if id_product_attribute was appended
$productId = explode('-', $item['item_id']);
$productId = $productId[0];
// Render the event wrapped in onclick
$this->gaScripts .= '
$(\'article[data-id-product="' . $productId . '"] a.quick-view\').on(
"click",
function() {' . $this->module->getTools()->renderEvent('select_item', $eventData) . '}
);
';
}
}
/**
* This method renders tracking code when user searches on the shop.
*/
private function renderSearch()
{
// Check if we are on search page and we have a search string
if ($this->context->controller->php_self != 'search' || empty($_GET['s'])) {
return;
}
// Render the event
$eventData = [
'search_term' => (string) $_GET['s'],
];
$this->gaScripts .= $this->module->getTools()->renderEvent(
'search',
$eventData
);
}
/**
* This method renders tracking code for product listings, like category pages.
*/
private function renderCartpage()
{
// Check if we are on cart page
if ($this->context->controller->php_self != 'cart') {
return;
}
// Try to get product list variable and check if it's not empty
$cart = $this->context->smarty->getTemplateVars('cart');
if (empty($cart['products'])) {
return;
}
// Prepare items to our format
$productWrapper = new ProductWrapper($this->context);
$items = $productWrapper->prepareItemListFromProductList($cart['products'], true);
// Render the event
$eventData = [
'currency' => $this->context->currency->iso_code,
'value' => $cart['totals']['total']['amount'],
'items' => $items,
];
$this->gaScripts .= $this->module->getTools()->renderEvent(
'view_cart',
$eventData
);
}
/**
* This method renders tracking code for product listings, like category pages.
*/
private function renderBeginCheckout()
{
// Check if we are on some supported order controller
$allowed_controllers = ['order', 'orderopc', 'checkout'];
if (!in_array($this->context->controller->php_self, $allowed_controllers)) {
return;
}
// If the user reliably came from previous page, we won't render this event
// We want to do it just for first visiting checkout
if (!empty($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $_SERVER['REQUEST_URI']) !== false) {
return;
}
// Try to get product list variable and check if it's not empty
$cart = $this->context->smarty->getTemplateVars('cart');
if (empty($cart['products'])) {
return;
}
// Prepare items to our format
$productWrapper = new ProductWrapper($this->context);
$items = $productWrapper->prepareItemListFromProductList($cart['products'], true);
// Render the event
$eventData = [
'currency' => $this->context->currency->iso_code,
'value' => $cart['totals']['total']['amount'],
'items' => $items,
];
$this->gaScripts .= $this->module->getTools()->renderEvent(
'begin_checkout',
$eventData
);
}
/**
* This method renders tracking code after user logs in.
*/
private function renderLogin()
{
// Render it only on login page AND if we are not creating a new account in older PS versions
// For newer versions, registrations are handled with standalone registration controller.
if ($this->context->controller->php_self != 'authentication' || isset($_GET['create_account'])) {
return;
}
// Render the event
$this->gaScripts .= $this->module->getTools()->renderEvent('login', []);
}
/**
* This method renders tracking code after user registers.
*/
private function renderRegistration()
{
if ($this->context->controller->php_self != 'registration' &&
($this->context->controller->php_self != 'authentication' || !isset($_GET['create_account']))
) {
return;
}
// Render the event
$this->gaScripts .= $this->module->getTools()->renderEvent('sign_up', []);
}
/**
* Saves information about last visited product listing, so we can later use it for select_item event.
*/
private function saveInformationAboutListing()
{
// Try to get product list variable
$listing = $this->context->smarty->getTemplateVars('listing');
if (empty($listing['products']) || empty($listing['label'])) {
return;
}
// Save this information to a cookie
$this->context->cookie->ga_last_listing = json_encode([
'item_list_url' => $_SERVER['REQUEST_URI'],
'item_list_id' => $this->context->controller->php_self,
'item_list_name' => $listing['label'],
]);
}
/**
* Outputs all events we stored into data repository during previous AJAX requests
* on previous page.
*/
private function outputStoredEvents()
{
// Get all stored events
$storedEvents = $this->module->getDataHandler()->readData();
if (empty($storedEvents)) {
return;
}
foreach ($storedEvents as $event) {
$this->gaScripts .= $event;
}
// Delete the repository because everything has been flushed
$this->module->getDataHandler()->deleteData();
}
}

View File

@@ -0,0 +1,145 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Context;
use PrestaShop\Module\Ps_Googleanalytics\Handler\GanalyticsJsHandler;
use PrestaShop\Module\Ps_Googleanalytics\Wrapper\ProductWrapper;
use Ps_Googleanalytics;
class HookDisplayFooterProduct implements HookInterface
{
private $module;
private $context;
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* run
*
* @return string|void
*/
public function run()
{
// Check we are really on product page
if ($this->context->controller->php_self !== 'product') {
return;
}
// Get lazy array from context
$product = $this->context->smarty->getTemplateVars('product');
if (empty($product)) {
return;
}
// Initialize tag handler
$gaTagHandler = new GanalyticsJsHandler($this->module, $this->context);
// Prepare it and format it for our purpose
$productWrapper = new ProductWrapper($this->context);
$item = $productWrapper->prepareItemFromProduct($product);
$jsCode = '';
// Prepare and render event
$eventData = [
'currency' => $this->context->currency->iso_code,
'value' => $item['price'],
'items' => [$item],
];
$jsCode .= $this->module->getTools()->renderEvent(
'view_item',
$eventData
);
// If the user got to the product page from previous page on our shop,
// we will also send select_item event.
if ($this->wasPreviousPageOurShop()) {
$eventData = [
'items' => [$item],
];
// We will also try to get the information about the last visited listing.
// We save this information into a cookie. If it's the page that got the user here,
// we will use it.
$previousListingData = $this->getLastVisitedListing();
if (!empty($previousListingData)) {
$eventData = array_merge($previousListingData, $eventData);
}
// Render the event
$jsCode .= $this->module->getTools()->renderEvent(
'select_item',
$eventData
);
}
return $gaTagHandler->generate($jsCode);
}
/**
* Checks HTTP_REFERER to see if the previous page that got user to this product
* was our shop.
*
* @return bool
*/
private function wasPreviousPageOurShop()
{
if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST']) !== false) {
return true;
}
return false;
}
/**
* Tries to get details of previous listing from the cookie.
*
* @return bool|array
*/
private function getLastVisitedListing()
{
// Fetch it from the cookie
$last_listing = $this->context->cookie->ga_last_listing;
if (empty($last_listing)) {
return false;
}
// Decode the data and check if it contains something sensible
$last_listing = json_decode($last_listing, true);
if (empty($last_listing['item_list_id'])) {
return false;
}
// Check if the last listing is the page the user came from
if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $last_listing['item_list_url']) !== false) {
unset($last_listing['item_list_url']);
return $last_listing;
}
return false;
}
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Configuration;
use Context;
use Customer;
use Ps_Googleanalytics;
use Tools;
class HookDisplayHeader implements HookInterface
{
/**
* @var Ps_Googleanalytics
*/
private $module;
/**
* @var Context
*/
private $context;
/**
* @var bool
*/
private $backOffice;
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* @return false|string
*/
public function run()
{
if (!Configuration::get('GA_ACCOUNT_ID')) {
return '';
}
// Resolve if we should add user ID into the code
$userId = null;
if (Configuration::get('GA_USERID_ENABLED')
&& $this->context->customer instanceof Customer
&& $this->context->customer->isLogged()
) {
$userId = (int) $this->context->customer->id;
}
$this->context->smarty->assign(
[
'backOffice' => $this->backOffice,
'trackBackOffice' => Configuration::get('GA_TRACK_BACKOFFICE_ENABLED'),
'userId' => $userId,
'gaAccountId' => Tools::safeOutput(Configuration::get('GA_ACCOUNT_ID')),
'gaAnonymizeEnabled' => Configuration::get('GA_ANONYMIZE_ENABLED'),
]
);
return $this->module->display(
$this->module->getLocalPath() . $this->module->name,
'ps_googleanalytics.tpl'
);
}
/**
* @param bool $backOffice
*/
public function setBackOffice($backOffice)
{
$this->backOffice = $backOffice;
}
}

View File

@@ -0,0 +1,115 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Cart;
use Configuration;
use Context;
use PrestaShop\Module\Ps_Googleanalytics\Handler\GanalyticsJsHandler;
use PrestaShop\Module\Ps_Googleanalytics\Repository\GanalyticsRepository;
use PrestaShop\Module\Ps_Googleanalytics\Wrapper\OrderWrapper;
use PrestaShop\Module\Ps_Googleanalytics\Wrapper\ProductWrapper;
use Ps_Googleanalytics;
use Validate;
class HookDisplayOrderConfirmation implements HookInterface
{
private $module;
private $context;
private $params;
public function __construct(Ps_Googleanalytics $module, Context $context)
{
$this->module = $module;
$this->context = $context;
}
/**
* run
*
* @return string
*/
public function run()
{
$gaScripts = '';
$order = $this->params['order'];
if (!Validate::isLoadedObject($order) || $order->getCurrentState() == (int) Configuration::get('PS_OS_ERROR')) {
return $gaScripts;
}
// Load up our handlers and repositories
$ganalyticsRepository = new GanalyticsRepository();
$gaTagHandler = new GanalyticsJsHandler($this->module, $this->context);
$productWrapper = new ProductWrapper($this->context);
$orderWrapper = new OrderWrapper($this->context);
// If it's a completely new order, add order to repository, so we can later mark it as sent
if (empty($ganalyticsRepository->findGaOrderByOrderId((int) $order->id))) {
$ganalyticsRepository->addOrder((int) $order->id, (int) $order->id_shop);
}
// If the customer is revisiting confirmation screen and the order was already sent, we don't do anything
if ($ganalyticsRepository->hasOrderBeenAlreadySent((int) $order->id)) {
return $gaScripts;
}
// Prepare transaction data
$orderData = $orderWrapper->wrapOrder($order);
// Prepare order products, if the cart still exists
$orderProducts = [];
$cart = new Cart($order->id_cart);
if (Validate::isLoadedObject($cart)) {
$orderProducts = $productWrapper->prepareItemListFromProductList($cart->getProducts(), true);
}
// Add payment event
$gaScripts .= $this->module->getTools()->renderEvent(
'add_payment_info',
[
'currency' => $orderData['currency'],
'value' => (float) $orderData['value'],
'payment_type' => $orderData['payment_type'],
'items' => $orderProducts,
]
);
// Render transaction code
$gaScripts .= $this->module->getTools()->renderPurchaseEvent(
$orderProducts,
$orderData,
$this->context->link->getModuleLink('ps_googleanalytics', 'ajax', [], true)
);
return $gaTagHandler->generate($gaScripts);
}
/**
* setParams
*
* @param array $params
*/
public function setParams($params)
{
$this->params = $params;
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Hooks;
use Context;
use Ps_Googleanalytics;
interface HookInterface
{
/**
* @param Ps_Googleanalytics $module
* @param Context $context
*/
public function __construct(Ps_Googleanalytics $module, Context $context);
public function run();
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,44 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Repository;
use Db;
class CarrierRepository
{
const TABLE_NAME = 'carrier';
/**
* findByCarrierId
*
* @param int $carrierId
*
* @return string
*/
public function findByCarrierId($carrierId)
{
return Db::getInstance()->getValue(
'SELECT name
FROM `' . _DB_PREFIX_ . self::TABLE_NAME . '`
WHERE id_carrier = ' . (int) $carrierId
);
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Repository;
use Db;
class GanalyticsDataRepository
{
const TABLE_NAME = 'ganalytics_data';
/**
* findByCartId
*
* @param int $cartId
* @param int $shopId
*
* @return mixed
*/
public function findDataByCartIdAndShopId($cartId, $shopId)
{
return Db::getInstance()->getValue(
'SELECT data
FROM `' . _DB_PREFIX_ . self::TABLE_NAME . '`
WHERE id_cart = ' . (int) $cartId . '
AND id_shop = ' . (int) $shopId
);
}
/**
* addNewRow
*
* @param int $cartId
* @param int $shopId
* @param string $data
*
* @return bool
*/
public function addNewRow($cartId, $shopId, $data)
{
return Db::getInstance()->Execute(
'INSERT INTO `' . _DB_PREFIX_ . self::TABLE_NAME . '` (id_cart, id_shop, data)
VALUES(\'' . (int) $cartId . '\',\'' . (int) $shopId . '\',\'' . pSQL($data) . '\')
ON DUPLICATE KEY UPDATE data = \'' . pSQL($data) . '\';'
);
}
/**
* deleteRow
*
* @param int $cartId
* @param int $shopId
*
* @return bool
*/
public function deleteRow($cartId, $shopId)
{
return Db::getInstance()->delete(
self::TABLE_NAME,
'id_cart = ' . (int) $cartId . ' AND id_shop = ' . (int) $shopId
);
}
}

View File

@@ -0,0 +1,153 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Repository;
use Db;
class GanalyticsRepository
{
const TABLE_NAME = 'ganalytics';
/**
* Finds if we have a record for this order ID.
*
* @param int $orderId
*
* @return mixed
*/
public function findGaOrderByOrderId($orderId)
{
return Db::getInstance()->getValue(
'SELECT id_order
FROM `' . _DB_PREFIX_ . self::TABLE_NAME . '`
WHERE id_order = ' . (int) $orderId);
}
/**
* Checks if order is already sent to GA
*
* @param int $idOrder
*
* @return bool
*/
public function hasOrderBeenAlreadySent($idOrder)
{
return (bool) Db::getInstance()->getValue(
'SELECT `sent`
FROM `' . _DB_PREFIX_ . self::TABLE_NAME . '`
WHERE id_order = ' . (int) $idOrder);
}
/**
* findAllByShopIdAndDateAdd
*
* @param int $shopId
*
* @return array
*/
public function findAllByShopIdAndDateAdd($shopId)
{
return Db::getInstance()->ExecuteS(
'SELECT *
FROM `' . _DB_PREFIX_ . self::TABLE_NAME . '`
WHERE sent = 0
AND id_shop = ' . (int) $shopId . '
AND DATE_ADD(date_add, INTERVAL 30 minute) < NOW()'
);
}
/**
* addNewRow
*
* @param array $data
* @param int $type
*
* @return bool
*/
public function addNewRow(array $data, $type = Db::INSERT_IGNORE)
{
return Db::getInstance()->insert(
self::TABLE_NAME,
$data,
false,
true,
$type
);
}
/**
* Adds new order into repository
*
* @param int $idOrder
* @param int $idShop
*
* @return bool
*/
public function addOrder(int $idOrder, int $idShop)
{
return $this->addNewRow(
[
'id_order' => (int) $idOrder,
'id_shop' => (int) $idShop,
'sent' => 0,
'date_add' => ['value' => 'NOW()', 'type' => 'sql'],
]
);
}
/**
* updateData
*
* @param array $data
* @param string $where
* @param int $limit
*
* @return bool
*/
public function updateData($data, $where, $limit = 0)
{
return Db::getInstance()->update(
self::TABLE_NAME,
$data,
$where,
$limit
);
}
/**
* Marks order as successfully sent to GA via callback
*
* @param int $idOrder
*
* @return bool
*/
public function markOrderAsSent($idOrder)
{
return Db::getInstance()->update(
self::TABLE_NAME,
[
'date_add' => ['value' => 'NOW()', 'type' => 'sql'],
'sent' => 1,
],
'id_order = ' . (int) $idOrder
);
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,56 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Wrapper;
use Configuration;
use Context;
use Currency;
use Shop;
class OrderWrapper
{
private $context;
public function __construct(Context $context)
{
$this->context = $context;
}
/**
* Return a detailed transaction for Google Analytics
*/
public function wrapOrder($order)
{
// Prepare currency information
$currency = new Currency((int) $order->id_currency);
return [
'transaction_id' => (int) $order->id,
'affiliation' => Shop::isFeatureActive() ? $this->context->shop->name : Configuration::get('PS_SHOP_NAME'),
'value' => (float) $order->total_paid,
'shipping' => (float) $order->total_shipping,
'tax' => (float) $order->total_paid_tax_incl - $order->total_paid_tax_excl,
'customer' => (int) $order->id_customer,
'currency' => $currency->iso_code,
'payment_type' => (string) $order->payment,
];
}
}

View File

@@ -0,0 +1,256 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\Module\Ps_Googleanalytics\Wrapper;
use Configuration;
use Context;
use Db;
use Manufacturer;
use PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductLazyArray;
use PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductListingLazyArray;
use Shop;
class ProductWrapper
{
private $context;
private $categories = [];
private $homeCategory = 0;
public function __construct(Context $context)
{
$this->context = $context;
}
/**
* Takes provided list of product (lazy) arrays and converts it to a format that GA4 requires.
*
* @param array $productList
* @param bool $useProvidedQuantity Should provided quantity be used, usually for cart related events
*
* @return array Item data standardized for GA
*/
public function prepareItemListFromProductList($productList, $useProvidedQuantity = false)
{
$items = [];
// Check we actually got some product
if (empty($productList)) {
return [];
}
// Preload categories for the whole list
$productIds = [];
foreach ($productList as $product) {
if (!empty($product['id_product'])) {
$productIds[] = $product['id_product'];
} elseif (!empty($product['id'])) {
$productIds[] = $product['id'];
}
}
$this->loadCategories($productIds);
// Prepare each item and override the counter
$counter = 0;
foreach ($productList as $product) {
$product = $this->prepareItemFromProduct($product, $useProvidedQuantity);
$product['index'] = $counter;
$items[] = $product;
++$counter;
}
return $items;
}
/**
* Loads all product categories for provided product IDs
*
* @param array $productIds
*/
private function loadCategories($productIds)
{
if (empty($productIds)) {
return;
}
// Initialize home category
$this->homeCategory = (int) Configuration::get('PS_HOME_CATEGORY');
// Initialize our cache
$this->categories = [];
foreach ($productIds as $id) {
$this->categories[(int) $id] = [];
}
// Load categories for all products
$result = Db::getInstance()->executeS(
'
SELECT cp.`id_category`, cp.`id_product`, cl.`name` FROM `' . _DB_PREFIX_ . 'category_product` cp
LEFT JOIN `' . _DB_PREFIX_ . 'category` c ON (c.id_category = cp.id_category)
LEFT JOIN `' . _DB_PREFIX_ . 'category_lang` cl ON (cp.`id_category` = cl.`id_category`' . Shop::addSqlRestrictionOnLang('cl') . ')
' . Shop::addSqlAssociation('category', 'c') . '
WHERE cp.`id_product` IN (' . implode(',', $productIds) . ') AND cl.`id_lang` = ' . (int) $this->context->language->id . '
ORDER BY c.`level_depth` DESC'
);
// Store it by product ID
foreach ($result as $row) {
$this->categories[(int) $row['id_product']][] = $row;
}
}
/**
* Takes provided (lazy) array and converts it to a format that GA4 requires. It can handle:
* - ProductLazyArray from product page
* - ProductListingLazyArray from presented listings
* - ProductListingLazyArray from presented cart
* - Raw $cart->getProducts()
* - Legacy product object converted to an array enriched with Product::getProductProperties
*
* @param ProductLazyArray|ProductListingLazyArray|array $product
* @param bool $useProvidedQuantity Should provided quantity be used, usually for cart related events
*
* @return array Item data standardized for GA
*/
public function prepareItemFromProduct($product, $useProvidedQuantity = false)
{
// Standardize product ID
$product_id = 0;
if (!empty($product['id_product'])) {
$product_id = $product['id_product'];
} elseif (!empty($product['id'])) {
$product_id = $product['id'];
}
// Standardize product price, make sure this price went through calculation before you pass it here
if (empty($product['price_amount'])) {
$product['price_amount'] = $product['price'];
}
$item = [
'item_id' => (int) $product_id,
'item_name' => (string) $product['name'],
'affiliation' => Shop::isFeatureActive() ? $this->context->shop->name : Configuration::get('PS_SHOP_NAME'),
'index' => 0,
'price' => $product['price_amount'],
'quantity' => 1,
];
// Add manufacturer info if we have it
if (!empty($product['manufacturer_name'])) {
$item['item_brand'] = $product['manufacturer_name'];
// If we don't, which can happen due to some bugs in getProductProperties, we will fetch it manually
} elseif (!empty($product['id_manufacturer'])) {
$manufacturerName = Manufacturer::getNameById((int) $product['id_manufacturer']);
if (!empty($manufacturerName)) {
$item['item_brand'] = $manufacturerName;
}
}
// We will specify variant ID if we have it
if (!empty($product['id_product_attribute'])) {
$item['item_id'] .= '-' . $product['id_product_attribute'];
}
// Information about a chosen variant, if we have it (cart list has this out of the box)
if (!empty($product['attributes_small'])) {
$item['item_variant'] = $product['attributes_small'];
// If we don't, we will construct it in the same format
} elseif (!empty($product['id_product_attribute'])) {
$variant = $this->getProductVariant((int) $product['id_product_attribute']);
if (!empty($variant)) {
$item['item_variant'] = $variant;
}
}
if ($useProvidedQuantity === true) {
// Info about quantity in cart, if we have it
$item['quantity'] = $product['quantity'];
}
// Prepare category information, if not loaded before, we will fetch it
if (!isset($this->categories[(int) $product_id])) {
$this->loadCategories([(int) $product_id]);
}
$productCategories = $this->categories[(int) $product_id];
// If the category is our default one, we will move it to the beginning of that list
foreach ($productCategories as $key => $category) {
if ($category['id_category'] == $product['id_category_default']) {
$productCategories = [$key => $category] + $productCategories;
break;
}
}
// Add it to our item
$counter = 1;
foreach ($productCategories as $productCategory) {
// Skip home category if we have more than 1 category
if (count($productCategories) > 1 && $productCategory['id_category'] == $this->homeCategory) {
continue;
}
// Add it with proper key
$item[$counter == 1 ? 'item_category' : 'item_category' . $counter] = $productCategory['name'];
if ($counter == 5) {
break;
}
++$counter;
}
return $item;
}
/**
* Method that will provide product combination attribute in the same format and order as cart does.
*
* @param int $id_product_attribute ID of the combination
*
* @return string Attribute list
*/
public function getProductVariant($id_product_attribute)
{
$result = Db::getInstance()->executeS(
'SELECT al.`name` AS attribute_name
FROM `' . _DB_PREFIX_ . 'product_attribute_combination` pac
LEFT JOIN `' . _DB_PREFIX_ . 'attribute` a ON a.`id_attribute` = pac.`id_attribute`
LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group`
LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al ON (
a.`id_attribute` = al.`id_attribute`
AND al.`id_lang` = ' . (int) $this->context->language->id . '
)
WHERE pac.`id_product_attribute` = ' . $id_product_attribute . '
ORDER BY ag.`position` ASC, a.`position` ASC'
);
$attributes = array_column($result, 'attribute_name');
// Prepare our separator
$separator = Configuration::get('PS_ATTRIBUTE_ANCHOR_SEPARATOR');
if ($separator === '-') {
// Add a space before the dash between attributes
$separator = ' - ';
}
return implode($separator, $attributes);
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

2309
modules/ps_googleanalytics/composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>ps_googleanalytics</name>
<displayName><![CDATA[Google Analytics]]></displayName>
<version><![CDATA[5.0.3]]></version>
<description><![CDATA[Gain clear insights into important metrics about your customers, using Google Analytics]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[analytics_stats]]></tab>
<confirmUninstall><![CDATA[Are you sure you want to uninstall Google Analytics? You will lose all the data related to this module.]]></confirmUninstall>
<is_configurable>1</is_configurable>
<need_instance>1</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,41 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\Module\Ps_Googleanalytics\Repository\GanalyticsRepository;
class AdminGanalyticsAjaxController extends ModuleAdminController
{
public $ssl = true;
public function init()
{
$orderId = (int) Tools::getValue('orderid');
$order = new Order($orderId);
if (Validate::isLoadedObject($order) && (isset($this->context->employee->id) && $this->context->employee->id)) {
(new GanalyticsRepository())->markOrderAsSent((int) $orderId);
$this->ajaxRender('OK');
exit;
}
$this->ajaxRender('KO');
exit;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,47 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\Module\Ps_Googleanalytics\Repository\GanalyticsRepository;
class ps_GoogleanalyticsAjaxModuleFrontController extends ModuleFrontController
{
public $ssl = true;
/*
* @see FrontController::initContent()
*/
public function initContent()
{
parent::initContent();
$orderId = (int) Tools::getValue('orderid');
$order = new Order($orderId);
if (!Validate::isLoadedObject($order) || $order->id_customer != (int) Tools::getValue('customer')) {
$this->ajaxRender('KO');
exit;
}
(new GanalyticsRepository())->markOrderAsSent((int) $orderId);
$this->ajaxRender('OK');
exit;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,281 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (!defined('_PS_VERSION_')) {
exit;
}
$autoloadPath = __DIR__ . '/vendor/autoload.php';
if (file_exists($autoloadPath)) {
require_once $autoloadPath;
}
class Ps_Googleanalytics extends Module
{
public $name;
public $tab;
public $version;
public $ps_versions_compliancy;
public $author;
public $module_key;
public $bootstrap;
public $displayName;
public $description;
public $confirmUninstall;
public $products = [];
public $_debug = 0;
private $tools = null;
private $dataHandler = null;
public function __construct()
{
$this->name = 'ps_googleanalytics';
$this->tab = 'analytics_stats';
$this->version = '5.0.3';
$this->ps_versions_compliancy = ['min' => '1.7.7', 'max' => _PS_VERSION_];
$this->author = 'PrestaShop';
$this->module_key = 'fd2aaefea84ac1bb512e6f1878d990b8';
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->trans('Google Analytics', [], 'Modules.Googleanalytics.Admin');
$this->description = $this->trans('Gain clear insights into important metrics about your customers, using Google Analytics', [], 'Modules.Googleanalytics.Admin');
$this->confirmUninstall = $this->trans('Are you sure you want to uninstall Google Analytics? You will lose all the data related to this module.', [], 'Modules.Googleanalytics.Admin');
}
/**
* Back office module configuration page content
*/
public function getContent()
{
$configurationForm = new PrestaShop\Module\Ps_Googleanalytics\Form\ConfigurationForm($this);
$output = '';
if (Tools::isSubmit('submit' . $this->name)) {
$output .= $configurationForm->treat();
}
$output .= $this->display(__FILE__, './views/templates/admin/configuration.tpl');
$output .= $configurationForm->generate();
return $output;
}
public function hookDisplayHeader($params, $back_office = false)
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookDisplayHeader($this, $this->context);
$hook->setBackOffice($back_office);
return $hook->run();
}
/**
* Confirmation page hook.
* This function is run to track transactions.
*/
public function hookDisplayOrderConfirmation($params)
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookDisplayOrderConfirmation($this, $this->context);
$hook->setParams($params);
return $hook->run();
}
/**
* Footer hook
* This function is run to load JS script for standards actions such as product clicks
*/
public function hookDisplayBeforeBodyClosingTag()
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookDisplayBeforeBodyClosingTag($this, $this->context);
return $hook->run();
}
/**
* Product page footer hook
* This function is run to load JS for product details view
*/
public function hookDisplayFooterProduct()
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookDisplayFooterProduct($this, $this->context);
return $hook->run();
}
/**
* Hook admin order.
* This function is run to send transactions and refunds details
*/
public function hookDisplayAdminOrder()
{
$gaTagHandler = new PrestaShop\Module\Ps_Googleanalytics\Handler\GanalyticsJsHandler($this, $this->context);
$output = $gaTagHandler->generate($this->context->cookie->ga_admin_refund);
unset($this->context->cookie->ga_admin_refund);
$this->context->cookie->write();
return $output;
}
/**
* Admin office header hook.
* This function is run to add Google Analytics JavaScript
*/
public function hookDisplayBackOfficeHeader()
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookDisplayBackOfficeHeader($this, $this->context);
return $hook->run();
}
/**
* Product cancel action hook (in Back office).
* This function is run to add Google Analytics JavaScript
*/
public function hookActionProductCancel($params)
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookActionProductCancel($this, $this->context);
$hook->setParams($params);
$hook->run();
}
/**
* Hook used to detect backoffice orders and store their IDs into cookie.
*/
public function hookActionValidateOrder($params)
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookActionValidateOrder($this, $this->context);
$hook->setParams($params);
$hook->run();
}
/**
* Hook called after order status change, used to "refund" order after cancelling it
*/
public function hookActionOrderStatusPostUpdate($params)
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookActionOrderStatusPostUpdate($this, $this->context);
$hook->setParams($params);
$hook->run();
}
/**
* Hook to process add and remove items from cart events
* This function is run to implement 'add to cart' and 'remove from cart' functionalities
*/
public function hookActionCartUpdateQuantityBefore($params)
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookActionCartUpdateQuantityBefore($this, $this->context);
$hook->setParams($params);
$hook->run();
}
/**
* Hook to process remove items from cart events
* This function is run to implement 'remove from cart' functionalities
*/
public function hookActionObjectProductInCartDeleteBefore($params)
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookActionObjectProductInCartDeleteBefore($this, $this->context);
$hook->setParams($params);
$hook->run();
}
public function hookActionCarrierProcess($params)
{
$hook = new PrestaShop\Module\Ps_Googleanalytics\Hooks\HookActionCarrierProcess($this, $this->context);
$hook->setParams($params);
$hook->run();
}
protected function _debugLog($function, $log)
{
if (!$this->_debug) {
return true;
}
$myFile = _PS_MODULE_DIR_ . $this->name . '/logs/analytics.log';
$fh = fopen($myFile, 'a');
fwrite($fh, date('F j, Y, g:i a') . ' ' . $function . "\n");
fwrite($fh, print_r($log, true) . "\n\n");
fclose($fh);
}
/**
* This method is triggered at the installation of the module
* - it installs all module tables
* - it registers the hooks used by this module
*
* @return bool
*/
public function install()
{
$database = new PrestaShop\Module\Ps_Googleanalytics\Database\Install($this);
return parent::install() &&
$database->registerHooks() &&
$database->setDefaultConfiguration() &&
$database->installTab() &&
$database->installTables();
}
/**
* Triggered at the uninstall of the module
* - erases this module SQL tables
*
* @return bool
*/
public function uninstall()
{
$database = new PrestaShop\Module\Ps_Googleanalytics\Database\Uninstall();
return parent::uninstall() &&
$database->uninstallTab() &&
$database->uninstallTables();
}
/**
* Returns instance of GoogleAnalyticsTools
*/
public function getTools()
{
if ($this->tools === null) {
$this->tools = new PrestaShop\Module\Ps_Googleanalytics\GoogleAnalyticsTools();
}
return $this->tools;
}
/**
* Returns instance of GanalyticsDataHandler
*/
public function getDataHandler()
{
if ($this->dataHandler === null) {
$this->dataHandler = new PrestaShop\Module\Ps_Googleanalytics\Handler\GanalyticsDataHandler(
$this->context->cart->id,
$this->context->shop->id
);
}
return $this->dataHandler;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_3_1_0($object)
{
Configuration::updateValue('GANALYTICS', '3.1.0');
return Db::getInstance()->execute('
CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'ganalytics_data` (
`id_cart` int(11) NOT NULL,
`id_shop` int(11) NOT NULL,
`data` TEXT DEFAULT NULL,
PRIMARY KEY (`id_cart`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8');
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_4_1_0($object)
{
if (!$object->registerHook('actionOrderStatusPostUpdate')) {
return false;
}
Configuration::updateValue('GA_CANCELLED_STATES', json_encode([Configuration::get('PS_OS_CANCELED')]));
return Db::getInstance()->execute('ALTER TABLE `' . _DB_PREFIX_ . 'ganalytics` ADD `refund_sent` tinyint(1) NULL AFTER `sent`;');
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (!defined('_PS_VERSION_')) {
exit;
}
/**
* @param Ps_Googleanalytics $object
*/
function upgrade_module_4_2_0($object)
{
return Configuration::updateValue('GA_V4_ENABLED', false)
&& $object->unregisterHook('displayHome')
&& $object->registerHook('displayBeforeBodyClosingTag');
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (!defined('_PS_VERSION_')) {
exit;
}
/**
* @param Ps_Googleanalytics $object
*/
function upgrade_module_5_0_0($object)
{
$database = new PrestaShop\Module\Ps_Googleanalytics\Database\Install($object);
return
Configuration::deleteByName('GA_V4_ENABLED') &&
$object->registerHook('actionValidateOrder') &&
$object->unregisterHook('actionCartSave') &&
$object->registerHook('actionCartUpdateQuantityBefore') &&
$object->registerHook('actionObjectProductInCartDeleteBefore') &&
$database->installTab() &&
Configuration::updateValue('GA_BACKLOAD_ENABLED', false) &&
Configuration::updateValue('GA_BACKLOAD_DAYS', 30);
}

View File

@@ -0,0 +1,36 @@
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
.google-analytics-advantages-list, .google-analytics-create {
margin-bottom: 1rem;
}
.google-analytics-advantages-list .col-sm-6 {
height: 5em;
display: flex;
align-items: center;
}
.google-analytics-advantages-list div > img {
margin: 1em;
width: 60px;
}
.google-analytics-stats {
margin: 0 auto;
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 790 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,49 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*}
<div class="panel">
<div id="google_analytics_top">
<img src="{$module_dir}views/img/ga_logo.png" class="img-responsive" alt="Google Analytics" />
</div>
<hr/>
<div id="google_analytics_content">
<div class="row">
<div class="col-lg-6">
<p>{l s='Your customers go everywhere; shouldn\'t your analytics.' d='Modules.Googleanalytics.Admin'}</p>
<p>{l s='Google Analytics shows you the full customer picture across ads and videos, websites and social tools, tables and smartphones. That makes it easier to serve your current customers and win new ones.' d='Modules.Googleanalytics.Admin'}</p>
<p><b>{l s='With ecommerce functionality in Google Analytics you can gain clear insight into important metrics about shopper behavior and conversion, including:' d='Modules.Googleanalytics.Admin'}</b></p>
<div class="row google-analytics-advantages-list">
<div class="col-sm-6"><img src="{$module_dir}views/img/product_detail_icon.png" alt="" />{l s='Product detail views' d='Modules.Googleanalytics.Admin'}</div>
<div class="col-sm-6"><img src="{$module_dir}views/img/merchandising_tools_icon.png" alt="" />{l s='Internal merchandising Success' d='Modules.Googleanalytics.Admin'}</div>
<div class="col-sm-6"><img src="{$module_dir}views/img/add_to_cart_icon.png" alt="" />{l s='"Add to cart" actions' d='Modules.Googleanalytics.Admin'}</div>
<div class="col-sm-6"><img src="{$module_dir}views/img/checkout_icon.png" alt="" />{l s='The checkout process' d='Modules.Googleanalytics.Admin'}</div>
<div class="col-sm-6"><img src="{$module_dir}views/img/campaign_clicks_icon.png" alt="" />{l s='Internal campaign clicks' d='Modules.Googleanalytics.Admin'}</div>
<div class="col-sm-6"><img src="{$module_dir}views/img/purchase_icon.png" alt="" />{l s='And purchase' d='Modules.Googleanalytics.Admin'}</div>
</div>
<div class="google-analytics-create">
<a href="https://support.google.com/analytics/answer/1008015" rel="external" class="btn btn-primary">{l s='Create your account to get started' d='Modules.Googleanalytics.Admin'}</a>
</div>
</div>
<div class="col-lg-6 text-center">
<img src="{$module_dir}views/img/stats.png" class="img-responsive google-analytics-stats" alt="" /><br />
<span class="small"><em>{l s='Merchants are able to understand how far along users get in the buying process and where they are dropping off.' d='Modules.Googleanalytics.Admin'}</em></span>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,26 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*}
{if (!empty($jsCode))}
<script type="text/javascript">
{literal}document.addEventListener('DOMContentLoaded', function() {{/literal}
{$jsCode nofilter}
{literal}});{/literal}
</script>
{/if}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,36 @@
{**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*}
<script async src="https://www.googletagmanager.com/gtag/js?id={$gaAccountId|escape:'htmlall':'UTF-8'}"></script>
<script>
window.dataLayer = window.dataLayer || [];
{literal}function gtag(){dataLayer.push(arguments);}{/literal}
gtag('js', new Date());
gtag(
'config',
'{$gaAccountId|escape:'htmlall':'UTF-8'}',
{ldelim}
'debug_mode':false
{if $gaAnonymizeEnabled}, 'anonymize_ip': true{/if}
{if $userId && !$backOffice}, 'user_id': '{$userId|escape:'htmlall':'UTF-8'}'{/if}
{if $backOffice && !$trackBackOffice}, 'non_interaction': true, 'send_page_view': false{/if}
{rdelim}
);
</script>

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1998 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;