garancia/modules/ganalyticscom/ganalyticscom.php
2016-10-10 15:24:25 +02:00

468 lines
21 KiB
PHP
Executable File

<?php
if (!defined('_CAN_LOAD_FILES_'))
exit;
include_once(dirname(__FILE__).'/GanalyticsComs.php');
include_once(realpath(dirname(__FILE__)) . "/X_GoogleAnalyticsMobile.class.php");
include_once(realpath(dirname(__FILE__)) . "/X_Tools.php");
class Ganalyticscom extends Module
{
private $_html = '';
private $_postErrors = array();
var $_logFile = "debug/logs.txt";
var $_httpCodesFile = "debug/http_codes.txt";
function __construct()
{
$this->name = 'ganalyticscom';
$this->tab = 'analytics_stats';
$this->version = 1.1;
$this->author = 'Speedyweb';
$this->module_key = '90bbcd281e12778f64c01db88277a43c';
$this->need_instance = 0;
parent::__construct();
$this->displayName = $this->l('Google Analytics E-Commerce PHP');
$this->description = $this->l('Insertion des commandes dans Google Analytics en PHP');
/** Backward compatibility */
require(_PS_MODULE_DIR_.$this->name.'/backward_compatibility/backward.php');
}
public function install()
{
if (!parent::install()
OR !$this->registerHook('top')
OR !$this->registerHook('header')
OR ($this->checkVersion('is_1.4') AND !$this->registerHook('cart'))
OR ($this->checkVersion('is_1.5') AND !$this->registerHook('actionCartSave'))
OR !$this->registerHook('postUpdateOrderStatus')
OR !$this->registerHook('newOrder')
OR !$this->registerHook('backOfficeHeader')
OR !Configuration::updateValue('codeGA', '')
OR !Configuration::updateValue('ga_insert_statuts', '2')
OR !Configuration::updateValue('ga_annul_statuts', '6')
OR !Configuration::updateValue('ga_logs', 0)
OR !Configuration::updateValue('cookie_min_time', 18000))
return false;
return Db::getInstance()->Execute('
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'ganalyticscoms`(
`id` int(11) NOT NULL auto_increment,
`id_cart` int(11) DEFAULT \'0\' NOT NULL,
`commande` int(11) NOT NULL,
`referer` text NOT NULL,
`gclid` text NOT NULL,
`ga_statut` smallint(6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8');
}
public function uninstall()
{
Configuration::deleteByName('codeGA');
Configuration::deleteByName('ga_insert_statuts');
Configuration::deleteByName('ga_annul_statuts');
Configuration::deleteByName('ga_logs');
Configuration::deleteByName('cookie_min_time');
Db::getInstance()->Execute('DROP TABLE IF EXISTS `'._DB_PREFIX_.'ganalyticscoms`');
return parent::uninstall();
}
/***************************************************************************************************************/
public function getContent()
{
if (isset($_POST['submitAnalytics']))
{
$this->_postValidation();
if (!sizeof($this->_postErrors)) $this->_postProcess();
else $this->displayErrors();
}
elseif (isset($_POST['submitPurgeDB'])){
$this->PurgeDB();
if (!sizeof($this->_postErrors)) $this->displayPurgeConf();
else $this->displayErrors();
}
$this->_displayAnalytics();
$this->_displayForm();
return $this->_html;
}
private function _postProcess()
{
if (isset($_POST['submitAnalytics'])){
Configuration::updateValue('codeGA', strval($_POST['codeGA']));
Configuration::updateValue('ga_logs', ((isset($_POST['ga_logs']) AND intval($_POST['ga_logs'])) != 0 ? 1 : 0));
Configuration::updateValue('ga_insert_statuts', implode(',',Tools::getValue('ga_insert_statuts')));
Configuration::updateValue('ga_annul_statuts', implode(',',Tools::getValue('ga_annul_statuts')));
$cookie_min_time = intval(Tools::getValue('cookie_min_time'));
Configuration::updateValue('cookie_min_time', ($cookie_min_time > 18000) ? $cookie_min_time : 18000);
}
}
private function _postValidation(){
//
}
/****** HOOKS *************************************************************************************************/
public function getDateCookieCreation($cookie){
$tab_cookie = explode('__datecookie:',$cookie);
return (isset($tab_cookie[1]) ? $tab_cookie[1] : time());
}
public function cleanRefererFromCookie($cookie){
$tab_cookie = explode('__datecookie:',$cookie);
return $tab_cookie[0];
}
public function hookTop($params)
{
$referer = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
$gclid = (isset($_GET['gclid'])) ? $_GET['gclid'] : '';
$cookie_min_time_before_overwrite = intval(Configuration::get('cookie_min_time')); // 5h - Donnée que l'on peut rendre dynamique
$cookie_expire_time = time() + 15778800; // 6 mois
if((!isset($_COOKIE['ganalytics']) OR (!empty($referer) AND time() > ($this->getDateCookieCreation($_COOKIE['ganalytics']) + $cookie_min_time_before_overwrite)))
AND $this->GetDomain($referer) != str_replace('www.','',$_SERVER['HTTP_HOST']))
{
setcookie("ganalytics", $referer.'__datecookie:'.time(), $cookie_expire_time);
setcookie("gclid", $gclid, $cookie_expire_time);
}
}
public function hookActionCartSave($params)
{
$this->hookCart($params);
}
public function hookCart($params)
{
$referer = isset($_COOKIE['ganalytics']) ? $this->cleanRefererFromCookie($_COOKIE['ganalytics']) : '';
$gclid = isset($_COOKIE['gclid']) ? $_COOKIE['gclid'] : '';
if(isset($params['cart']) AND intval($params['cart']->id) > 0){
$row = Db::getInstance()->getRow('SELECT * FROM `'._DB_PREFIX_.'ganalyticscoms` WHERE `id_cart` = '.$params['cart']->id);
if(!$row){
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'ganalyticscoms` (`id_cart`, `commande`, `referer`, `gclid`)
VALUES('.(int)$params['cart']->id.',0, "'.$referer.'", "'.$gclid.'")');
}
}
}
public function hookHeader($params){
global $smarty;
$smarty->assign(array('codeGA' => Configuration::get('codeGA')));
return $this->display(__FILE__, 'header.tpl');
}
public function hookDisplayMobileHeader($params){
return $this->hookHeader($params);
}
public function hookBackOfficeHeader($params)
{
$return = '';
if(($this->checkVersion('is_1.5') AND (!$_GET['controller'] OR 'adminhome' == $_GET['controller']))
OR ($this->checkVersion('is_1.4') AND !isset($_GET['tab']))){
$return = '<link rel="stylesheet" href="'.__PS_BASE_URI__.'modules/ganalyticscom/css/ga.css" type="text/css" media="screen" charset="utf-8"/>';
}
return $return;
}
public function hookNewOrder($params)
{
$_codeGA = Configuration::get('codeGA');
if(!empty($_codeGA)){
$id_order = (isset($params['order'])) ? $params['order']->id : $params['id_order'];
$order = new Order(intval($id_order));
$row = Db::getInstance()->getRow('SELECT * FROM `'._DB_PREFIX_.'ganalyticscoms` WHERE `id_cart` = '.$order->id_cart);
if(!$row){
$referer = isset($_COOKIE['ganalytics']) ? $this->cleanRefererFromCookie($_COOKIE['ganalytics']) : '';
$gclid = isset($_COOKIE['gclid']) ? $_COOKIE['gclid'] : '';
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'ganalyticscoms` (`id_cart`, `commande`, `referer`, `gclid`)
VALUES('.$order->id_cart.','.(int)$id_order.', "'.$referer.'", "'.$gclid.'")');
}
else Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'ganalyticscoms` SET `commande` = '.(int)$id_order.' WHERE `id_cart` = '.$order->id_cart);
}
}
public function hookPostUpdateOrderStatus($params)
{
$this->statut($params);
}
/***************************************************************************************************************/
public function getArrayFromStringVar($nom, $sep = ',')
{
return explode($sep, Configuration::get($nom));
}
public function getUrlSite()
{
return 'http://'.htmlspecialchars($_SERVER['HTTP_HOST'], ENT_COMPAT, 'UTF-8').__PS_BASE_URI__;
}
public function _displayAnalytics()
{
$this->_html .= '
<div style="border: dashed 1px #666; padding: 8px;margin-bottom:30px;">
<img src="../modules/ganalyticscom/ganalytics.jpg" style="margin-right:15px;" />
<b>'.$this->l('Module de statistiques Google Analytics E-commerce - Pilotez votre CA et votre taux de conversion !').'</b><br />
</div>';
}
public function displayErrors()
{
foreach ($this->_postErrors AS $err) $this->_html .= '<div class="alert error">'. $err .'</div>';
}
public function GetDomain($url)
{
$domain = parse_url(preg_replace('`www\.`','',$url));
return (empty($domain["host"])) ? $domain["path"] : $domain["host"];
}
public function _displaySpeedyWeb()
{
return $this->l('Realisation : ').'<a href="http://www.speedyweb.fr" title="Cr&eacute;ation et r&eacute;f&eacute;rencement de sites web &agrave; Perpignan, Lille et Paris - SpeedyWeb">SpeedyWeb</a>';
}
/***************************************************************************************************************/
public function statut($params)
{
$id_order = (isset($params['order'])) ? $params['order']->id : $params['id_order'];
$new_order_status = (isset($params['orderStatus'])) ? $params['orderStatus'] : $params['newOrderStatus'];
if(Configuration::get('ga_logs')) X_writeLogs($this->_logFile, "");
if(Configuration::get('ga_logs')) X_writeLogs($this->_logFile, "## ".date('d-m-Y H:i:s')." #############################################");
if(Configuration::get('ga_logs')) X_writeLogs($this->_logFile, "#Function - statut | id_order = ".$id_order." | new_order_status = ".$new_order_status->name." id:".$new_order_status->id);
$ganalyticscom = GanalyticsComs::getByOrder($id_order);
if($ganalyticscom){
$ga_insert_statuts = $this->getArrayFromStringVar('ga_insert_statuts');
$ga_annul_statuts = $this->getArrayFromStringVar('ga_annul_statuts');
if(in_array($new_order_status->id, $ga_insert_statuts) and $ganalyticscom['ga_statut'] == 0){
$this->GanalyticsUpdate($id_order,$new_order_status);
Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'ganalyticscoms`
SET `ga_statut` = 1 WHERE `commande` = '.(int)$id_order);
}
elseif(in_array($new_order_status->id, $ga_annul_statuts) and $ganalyticscom['ga_statut'] == 1){
$this->GanalyticsUpdate($id_order,$new_order_status, -1);
Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'ganalyticscoms`
SET `ga_statut` = 0 WHERE `commande` = '.(int)$id_order);
}
}
}
public function GanalyticsUpdate($id_order,$order_state,$sens = 1)
{
$http_codes = (is_readable(realpath(dirname(__FILE__)).'/'.$this->_httpCodesFile)) ? parse_ini_file(realpath(dirname(__FILE__)).'/'.$this->_httpCodesFile) : array();
if(Configuration::get('ga_logs')) X_writeLogs($this->_logFile, "#Function - GanalyticsUpdate | order = ".$id_order." | sens = ".$sens);
$_codeGA = Configuration::get('codeGA');
$ganalyticscom = GanalyticsComs::getByOrder($id_order);
$commande_infos = $this->getTransaction($id_order,$sens);
if(Configuration::get('ga_logs')) X_writeLogs($this->_logFile, "#COMMANDE INFOS => ".serialize($commande_infos));
$ga_params = array();
$referer = $ganalyticscom['referer'];
$gclid = $ganalyticscom['gclid'];
if(Configuration::get('ga_logs')) X_writeLogs($this->_logFile, "#gclid => ".$gclid." | REFERER => ".$referer);
$url = $this->getUrlSite().'modules/ganalyticscom/ganalytics_update.php';
$commande_order = $commande_infos['order'];
if(Configuration::get('ga_logs')) X_writeLogs($this->_logFile, "#PAYMENT => ".$commande_order['payment']." | "."#STATUT => ".$order_state->name);
$ga = new X_GoogleAnalyticsMobile($_codeGA, str_replace('www.','',$_SERVER['HTTP_HOST']), $referer, $gclid, NULL, $ga_params);
$ga->SetTransaction($id_order, $commande_order['total'], $commande_order['port'], $commande_order['tva'], $commande_order['city'], $commande_order['region'], $commande_order['country'], $commande_order['currency']);
if(count($commande_infos['products']) > 0)
foreach($commande_infos['products'] as $product)
$ga->SetTransactionItem($id_order, $product['ref'], $product['category'], $product['name'], $product['price'], $product['quantity'], $commande_order['currency']);
if(Configuration::get('ga_logs')) X_writeLogs($this->_logFile, '#TrafficSource => '.serialize($ga->GetTrafficSource()));
$tracking_codes = $ga->GetTrackingCode();
if(count($tracking_codes) > 0){
$http_codes = (is_readable(realpath(dirname(__FILE__)).'/'.$this->_httpCodesFile)) ? parse_ini_file(realpath(dirname(__FILE__)).'/'.$this->_httpCodesFile) : array();
foreach($tracking_codes as $tracking_code){
$ch = @curl_init($tracking_code);
if ($ch){
@curl_setopt($ch, CURLOPT_TIMEOUT, 30);
@curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
@curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$result = @curl_exec($ch);
$http_code = @curl_getinfo($ch, CURLINFO_HTTP_CODE);
if(Configuration::get('ga_logs'))
X_writeLogs($this->_logFile, (array_key_exists($http_code,$http_codes) ? $http_code.' : '.$http_codes[$http_code] : 'Aucun code HTTP retourné' ).' ** '.$tracking_code);
@curl_close($ch);
}
}
}
}
public function getTransaction($id_order, $sens = 1)
{
$return = array();
$order = new Order(intval($id_order));
$address = new Address(intval($order->id_address_invoice));
$customer = new Customer(intval($order->id_customer));
$currency = new Currency(intval($order->id_currency));
$products = $order->getProductsDetail();
$i = 0;
$tva = 0;
foreach($products as $product){
$result = Db::getInstance()->getRow('
SELECT `name` FROM `'._DB_PREFIX_.'product`
LEFT JOIN `'._DB_PREFIX_.'category_lang` ON `'._DB_PREFIX_.'product`.`id_category_default` = `'._DB_PREFIX_.'category_lang`.`id_category`
WHERE `'._DB_PREFIX_.'product`.`id_product` = '.intval($product['product_id']).'
AND `'._DB_PREFIX_.'category_lang`.`id_lang` = '.intval($order->id_lang));
$total_produit = $product['product_price'] * $product['product_quantity'];
$total_produit_ht = $total_produit / (1 + $product['tax_rate']/100);
$tva += round($total_produit - $total_produit_ht,2);
$return['products']['product'.$i]['order_id'] = sprintf('%06d', (int)$order->id);
$return['products']['product'.$i]['ref'] = (NULL != $product['product_reference']) ? $product['product_reference'] : $product['product_id'];
$return['products']['product'.$i]['category'] = $result['name'];
$return['products']['product'.$i]['name'] = $product['product_name'];
$return['products']['product'.$i]['price'] = $sens * $product['product_price'];
$return['products']['product'.$i]['quantity'] = $sens * $product['product_quantity'];
$i++;
}
$return['order']['id'] = sprintf('%06d', (int)$order->id);
$return['order']['total'] = $sens * $order->total_paid;
$return['order']['port'] = $sens * $order->total_shipping;
$return['order']['tva'] = $sens * $tva;
$return['order']['city'] = $address->city;
$return['order']['region'] = '';
$return['order']['country'] = $address->country;
$return['order']['currency'] = $currency->iso_code;
$return['order']['payment'] = $order->payment;
return $return;
}
/***************************************************************************************************************/
public function _displayForm()
{
global $cookie;
$codeGA = Configuration::get('codeGA');
$ga_insert_statuts = $this->getArrayFromStringVar('ga_insert_statuts');
$ga_annul_statuts = $this->getArrayFromStringVar('ga_annul_statuts');
$ga_logs = Configuration::get('ga_logs');
$cookie_min_time = Configuration::get('cookie_min_time');
$checked = 'checked="checked"';
$isGaLogsChecked = ($ga_logs) ? $checked : '' ;
$orderStates = OrderState::getOrderStates($cookie->id_lang);
$this->_html .= '
<form action="'.$_SERVER['REQUEST_URI'].'" method="post" style="clear: both;">
<fieldset>
<legend><img src="../img/admin/contact.gif" />'.$this->l('Paramètres').'&nbsp;<img src="'._PS_ADMIN_IMG_.'up.gif" alt="" /></legend></legend>
<label>'.$this->l('Code de suivi Analytics').'</label>
<div class="margin-form">
<input type="text" size="20" name="codeGA" value="'.$codeGA.'" />
<p class="clear" style="display: block; width: 550px;">'.
$this->l('(UA-xxxxxxx-xx)').'
</p>
<div class="clear"></div>
</div>
<label>'.$this->l('Activer le fichier de logs').'</label>
<div class="margin-form">
<input type="checkbox" name="ga_logs" value="1" '.$isGaLogsChecked.'/>
</div>
<label>'.$this->l('Statuts insertion commande Analytics').'</label>
<div class="margin-form">
<select name="ga_insert_statuts[]" multiple="true" style="height:200px;width:360px;">';
foreach($orderStates as $orderState)
$this->_html .= '
<option value="'.intval($orderState['id_order_state']).'" '.(in_array($orderState['id_order_state'], $ga_insert_statuts) ? 'selected="selected" ' : '').'>'.$orderState['name'].'</option>';
$this->_html .= '
</select>
<p class="clear" style="display: block; width: 550px;">'.
$this->l('Statuts d&eacute;clenchant l\'insertion d\'une commande dans Google Analytics.').'
</p>
<div class="clear"></div>
</div>
<label>'.$this->l('Statuts annulation commande Analytics').'</label>
<div class="margin-form">
<select name="ga_annul_statuts[]" multiple="true" style="height:200px;width:360px;">';
foreach($orderStates as $orderState)
$this->_html .= '
<option value="'.intval($orderState['id_order_state']).'" '.(in_array($orderState['id_order_state'], $ga_annul_statuts) ? 'selected="selected" ' : '').'>'.$orderState['name'].'</option>';
$this->_html .= '
</select>
<p class="clear" style="display: block; width: 550px;">'.
$this->l('Statuts d&eacute;clenchant l\'annulation d\'une commande dans Google Analytics.').'
</p>
<div class="clear"></div>
</div>
<label>'.$this->l('Referer time minimum before overwrite').'</label>
<div class="margin-form">
<input type="text" size="20" name="cookie_min_time" value="'.$cookie_min_time.'" /> '.$this->l('s').'
<p class="clear" style="display: block; width: 550px;">'.
$this->l('Here is how GA updates the campaign tracking cookie based on referrer:').'<br />'.
$this->l('Direct traffic is always overwritten by referrals, organic and tagged campaigns and does not overwrite existing campaign information').'<br />'.
$this->l('New campaign, referral or organic link that brings a visitor to the site always overrides the existing campaign cookie').'<br /><br />'.
$this->l('For tracking transactions, the module creates a cookie different from that posed by Google Analytics, to retain the referer for a period of time that you can adjust.').'<br />'.
$this->l('If you wish to obtain statistics as close as possible to those of Google, we recommend that you leave the default value, 18 000 second (5 hours).').'<br />'.
$this->l('If you want to retain the referer more time to analyze your conversion sources differently, it is possible to define the cookie lifetime greater.').'<br />'.
$this->l('eg 5 hours = 18000s, 1 week = 604800s, 1 month = 2629800s').'
</p>
<div class="clear"></div>
</div>
<br /><br />
<center>
<input type="submit" name="submitAnalytics" value="'.$this->l('Enregistrer').'" class="button" />
</center>
</fieldset>
</form><br />
<form action="'.$_SERVER['REQUEST_URI'].'" method="post" style="clear: both;">
<fieldset>
<legend><img src="../img/admin/contact.gif" />'.$this->l('Purger la base de données').'&nbsp;</legend>
<p>'.$this->l('Ajoutez cette URL &agrave votre crontab pour automatiser la purge de la base de données:').'<br />
<b>'.Tools::getShopDomain(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/cron/purge.php</b></p>
<center><input type="submit" name="submitPurgeDB" value="'.$this->l('Purger').'" class="button" /></center>
<hr/>
<p>'.$this->_displaySpeedyWeb().'</p>
</fieldset>
</form><br />';
}
/***************************************************************************************************************/
public function displayPurgeConf(){
$this->_html .= '
<div class="conf confirm">'.$this->l('La purge a été correctement effectuée.').'</div>';
}
public function purgeDB()
{
$table = 'ganalyticscoms';
$carts = Db::getInstance()->ExecuteS('SELECT `id_cart` FROM `'._DB_PREFIX_.'cart` WHERE DATE(date_add) < (CURDATE() - INTERVAL 1 MONTH)');
if (sizeof($carts))
{
$list = '';
foreach ($carts AS $cart)
$list .= (int)$cart['id_cart'].',';
$list = rtrim($list, ',');
if(!Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.$table.'` WHERE `id_cart` IN ('.$list.')'))
{
$this->_postErrors[] = $this->l('Une erreur est survenue, la purge ne s\'est pas effectuée correctement.');
}
}
}
public function checkVersion($type)
{
$version = substr(_PS_VERSION_,0,3);
if('is_1.4' == $type) return ($version < 1.5) ? true : false ;
elseif('is_1.5' == $type) return ($version >= 1.5) ? true : false ;
}
}