HEX
Server: Apache
System: Linux webm019.cluster128.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64
User: petsclubcc (68997)
PHP: 5.4.45
Disabled: _dyuweyrj4,_dyuweyrj4r,dl
Upload Files
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
    }
}