File: /home/petsclubcc/prestashop1.6/modules/pixelmodule/pixelmodule.php
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
class Pixelmodule extends Module
{
protected $config_form = false;
public function __construct()
{
$this->name = 'pixelmodule';
$this->tab = 'administration';
$this->version = '2.1.1';
$this->author = 'ShopMyInfluence';
$this->need_instance = 0;
/**
* Set $this->bootstrap to true if your module is compliant with bootstrap (PrestaShop 1.6)
*/
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('ShopMyInfluence pixel');
$this->description = $this->l('Ce module vous permet de configurer notre pixel en quelques cliques sur votre boutique et commencer à utiliser l`expérience unique de notre outil ShopMyInfluence.');
$this->confirmUninstall = $this->l('Êtes-vous sûr de vouloir désinstaller ce module ?');
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
}
/**
* Don't forget to create update methods if needed:
* http://doc.prestashop.com/display/PS16/Enabling+the+Auto-Update
*/
public function install()
{
if (Shop::isFeatureActive()) {
Shop::setContext(Shop::CONTEXT_ALL);
}
return parent::install() &&
$this->registerHook('header') &&
$this->registerHook('displayBackOfficeHeader') &&
$this->registerHook('displayHeader') &&
$this->registerHook('displayOrderConfirmation') &&
Configuration::updateValue('PIXEL_SMI_API_KEY', '');
}
public function uninstall()
{
Configuration::deleteByName('PIXEL_SMI_API_KEY');
return parent::uninstall();
}
/**
* Load the configuration form
*/
public function getContent()
{
PrestaShopLogger::addLog('[PixelModule] getContent() loaded', 1);
$message = '';
if (Tools::isSubmit('submitPixelModule')) {
$api_key = trim((string)Tools::getValue('api_key'));
if ($api_key === '') {
$message .= $this->displayError($this->l('La clé API est vide. Veuillez entrer une clé valide.'));
} else {
$isValid = (bool)$this->validateApiKey($api_key);
PrestaShopLogger::addLog('[PixelModule] validateApiKey='.(int)$isValid, 1);
if ($isValid) {
Configuration::updateValue('PIXEL_SMI_API_KEY', $api_key);
$message .= $this->displayConfirmation($this->l('Clé API sauvegardée avec succès !'));
} else {
$message .= $this->displayError($this->l('La clé API est invalide. Veuillez vérifier et réessayer.'));
}
}
}
if ((string)$this->context->language->iso_code == 'en') {
$output = $this->context->smarty->fetch($this->local_path.'views/templates/admin/sss.tpl');
} else {
$output = $this->context->smarty->fetch($this->local_path.'views/templates/admin/ss.tpl');
}
return $message.$output.$this->displayForm();
}
private function validateApiKey($api_key)
{
$url = 'https://us-central1-shopmyinfluens.cloudfunctions.net/registerV3/brand/get/' . urlencode($api_key);
// cURL available?
if (!function_exists('curl_init')) {
$response = Tools::file_get_contents($url);
PrestaShopLogger::addLog('[PixelModule] no-curl response='.substr((string)$response, 0, 300), 1);
if ($response === false || $response === '') {
return false;
}
$result = json_decode($response, true);
if (!is_array($result)) {
PrestaShopLogger::addLog('[PixelModule] no-curl invalid JSON: '.substr($response, 0, 300), 2);
return false;
}
return (isset($result['status']) && (int)$result['status'] === 200);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// timeouts
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
// Important: set UA, some WAFs block empty UA
curl_setopt($ch, CURLOPT_USERAGENT, 'Prestashop/1.6 PixelModule');
// SSL: keep ON, but log failures
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
$response = curl_exec($ch);
$http_code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
curl_close($ch);
// Log what happened (trim response to avoid huge logs)
PrestaShopLogger::addLog(
'[PixelModule] url='.$url.' http='.$http_code.' errno='.$curl_errno.' err='.$curl_error.' body='.substr((string)$response, 0, 300),
1
);
// Network / TLS error
if ($response === false || $curl_errno) {
return false;
}
if ($http_code !== 200) {
return false;
}
$result = json_decode($response, true);
if (!is_array($result)) {
return false;
}
return (isset($result['status']) && (int)$result['status'] === 200);
}
/**
* Display form using Helper
* @return string
*/
public function displayForm()
{
$fieldsForm=null;
// Init Fields form array
$fieldsForm[0]['form'] = [
'legend' => [
'title' => $this->l('Paramètres du module'),'icon' => 'icon-cogs'
]
,
'input' => [
[
'type' => 'text',
'label' => $this->l('clé API'),
'desc' => $this->l('Veuillez entrer votre clé API pour authentifier votre accès aux fonctionnalités du plugin. Assurez-vous que la clé est correcte et valide.'),
'name' => 'api_key',
'size' => 20,
'required' => true
]
],
'submit' => [
'title' => $this->l('Valider'),
'class' => 'btn btn-default pull-right'
]
];
$helper = new HelperForm();
// Module, token and currentIndex
$helper->identifier = $this->identifier;
$helper->module = $this;
$helper->name_controller = $this->name;
$helper->submit_action = 'submitPixelModule';
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false)
.'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name;
// Load current value
$helper->tpl_vars = array(
'fields_value' => $this->getConfigFormValues(), /* Add values for your inputs */
'languages' => $this->context->controller->getLanguages(),
'id_language' => $this->context->language->id,
);
return $helper->generateForm($fieldsForm);
}
/**
* Set values for the inputs.
*/
protected function getConfigFormValues()
{
$api_key = Configuration::get('PIXEL_SMI_API_KEY', '');
if (empty($api_key)) {
$this->context->controller->warnings[] = $this->l('La clé API est vide. Veuillez la configurer.');
}
return [
'api_key' => $api_key
];
}
/**
* Add the CSS & JavaScript files you want to be loaded in the BO.
*/
public function hookBackOfficeHeader()
{
if (Tools::getValue('module_name') == $this->name) {
$this->context->controller->addJS($this->_path.'views/js/back.js');
$this->context->controller->addCSS($this->_path.'views/css/back.css');
}
}
/**
* Add the CSS & JavaScript files you want to be added on the FO.
*/
public function hookHeader()
{
$this->context->controller->addJS($this->_path.'/views/js/front.js');
$this->context->controller->addCSS($this->_path.'/views/css/front.css');
}
public function hookDisplayHeader()
{
$this->context->controller->addJS('https://firebasestorage.googleapis.com/v0/b/shopmyinfluens.appspot.com/o/Pixel%2FclickObserver.js?alt=media&token=aea9abc8-a7a7-4351-a78e-d9621d55abd6');
//$this->context->controller->registerJavascript('cdn', 'https://firebasestorage.googleapis.com/v0/b/shopmyinfluens.appspot.com/o/Pixel%2FclickObserver.js?alt=media&token=aea9abc8-a7a7-4351-a78e-d9621d55abd6', array('media' => 'all', 'priority' => 10, 'inline' => true, 'server' => 'remote'));
}
public function hookDisplayOrderConfirmation($params)
{
// 1) Récupérer l'order de manière robuste (PS 1.6 peut varier)
$order = null;
if (isset($params['order']) && $params['order'] instanceof Order) {
$order = $params['order'];
} elseif (isset($params['objOrder']) && $params['objOrder'] instanceof Order) {
$order = $params['objOrder'];
} elseif (!empty($params['id_order'])) {
$order = new Order((int)$params['id_order']);
} else {
// fallback via controller / request
$id_order = (int)Tools::getValue('id_order');
if ($id_order > 0) {
$order = new Order($id_order);
}
}
// 2) Si toujours pas d'order valide, ne pas casser la page
if (!$order || !Validate::isLoadedObject($order)) {
PrestaShopLogger::addLog('[PixelModule] OrderConfirmation: order not found in params. Keys='.implode(',', array_keys((array)$params)), 2);
return;
}
// 3) get API key
$api_key = (string)Configuration::get('PIXEL_SMI_API_KEY', '');
// get total transaction amount
$total = (float)$order->total_paid_tax_excl;
$total = Tools::convertPrice($total);
// get order id
$order_id = (int)$order->id;
// get products
$products = $order->getProducts();
//products count
$product_count = 0;
//get products details
$products_details = array();
foreach ($products as $item) {
$products_details[] = array(
"name" => $item['product_name'],
"product_id" => $item['product_id'],
"price" => $item['total_price_tax_excl'],
"quantity" => $item['product_quantity']
);
$product_count = $product_count + $item['product_quantity'] ;
}
//convert products details array to json object
$productsJsonData = json_encode($products_details);
// Get voucher details (if any)
$voucher_code = null;
if (!empty($order->getCartRules())) {
$cart_rules = $order->getCartRules();
foreach ($cart_rules as $rule) {
if (!empty($rule['id_cart_rule'])) {
// Fetch the promo code from the database using id_cart_rule
$sql = new DbQuery();
$sql->select('code');
$sql->from('cart_rule');
$sql->where('id_cart_rule = ' . (int)$rule['id_cart_rule']);
$promo_code = Db::getInstance()->getValue($sql);
if ($promo_code) {
$voucher_code = $promo_code; // Get the promo code
break;
}
}
}
}
$id_shop_group = (int)Shop::getContextShopGroupID();
$id_shop = (int)$this->context->shop->id;
if($id_shop_group == 0){
$id_shop_group = null ;
$id_shop = null ;
}
$configuration = unserialize(Configuration::get('PIXEL_SMI', null, $id_shop_group,$id_shop));
?>
<script language="JavaScript" type="text/javascript">
//total transaction amount
var afprice = <?php echo($total); ?>;
// pass order id
var custom_field2 = <?php echo($order_id); ?>;
//pass saled products details
var custom_field4 = <?php echo $productsJsonData; ?>;
custom_field4 = JSON.stringify(custom_field4);
var clickIdFromLocalStorage = localStorage.getItem('smiclickId');
var vc = "<?php echo urlencode($voucher_code); ?>";
var apikey = "<?php echo($api_key);?>"
var url = `https://us-central1-shopmyinfluens.cloudfunctions.net/pixelV3/img?smic=${clickIdFromLocalStorage}&a=${afprice}&cr=EUR&ref=${custom_field2}&vc=${vc}&smi_cart=${custom_field4}&api_key=${apikey}`;
const http = new XMLHttpRequest();
http.open("GET", url);
http.send();
http.onreadystatechange = () => {
}
</script>
<?php
}
}