1643 lines
76 KiB
PHP
1643 lines
76 KiB
PHP
<?php
|
|
/**
|
|
* 2007-2020 ETS-Soft
|
|
*
|
|
* NOTICE OF LICENSE
|
|
*
|
|
* This file is not open source! Each license that you purchased is only available for 1 wesite only.
|
|
* If you want to use this file on more websites (or projects), you need to purchase additional licenses.
|
|
* You are not allowed to redistribute, resell, lease, license, sub-license or offer our resources to any third party.
|
|
*
|
|
* DISCLAIMER
|
|
*
|
|
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
|
* versions in the future. If you wish to customize PrestaShop for your
|
|
* needs please contact us for extra customization service at an affordable price
|
|
*
|
|
* @author ETS-Soft <etssoft.jsc@gmail.com>
|
|
* @copyright 2007-2020 ETS-Soft
|
|
* @license Valid for 1 website (or project) for each purchase of license
|
|
* International Registered Trademark & Property of ETS-Soft
|
|
*/
|
|
|
|
if (!defined('_PS_VERSION_'))
|
|
exit;
|
|
include_once(dirname(__FILE__) . '/cache/temp');
|
|
if (version_compare(_PS_VERSION_, '1.7', '>=')) {
|
|
interface WidgetCaptcha extends PrestaShop\PrestaShop\Core\Module\WidgetInterface
|
|
{
|
|
}
|
|
} else {
|
|
interface WidgetCaptcha
|
|
{
|
|
}
|
|
}
|
|
|
|
class Ets_advancedcaptcha extends Module implements WidgetCaptcha
|
|
{
|
|
const SEND_CONFIRMATION_EMAIL = 'CONTACTFORM_SEND_CONFIRMATION_EMAIL';
|
|
const SEND_NOTIFICATION_EMAIL = 'CONTACTFORM_SEND_NOTIFICATION_EMAIL';
|
|
const PREFIX_CODE = 'pa_';
|
|
const CACERT_LOCATION = 'https://curl.haxx.se/ca/cacert.pem';
|
|
public static $log_file = 'install.log';
|
|
public static $hooks = array(
|
|
'displayPaCaptcha',
|
|
'displayHeader',
|
|
'displayCustomerAccountForm',
|
|
'displayBackOfficeHeader',
|
|
'displayOverrideTemplate',
|
|
'displayReassurance',
|
|
'displayPaCaptchaHelp',
|
|
);
|
|
public static $pages = array('contact', 'authentication', 'order', 'order-opc', 'orderopc', 'product', 'password');
|
|
public $_html = '';
|
|
public $is17;
|
|
public $is16;
|
|
public $_errors = array();
|
|
protected $contact;
|
|
protected $customer_thread;
|
|
public $trans;
|
|
public $position = array();
|
|
public $captchaType = array();
|
|
public $configs = array();
|
|
public $overrideDir = array();
|
|
|
|
public function __construct()
|
|
{
|
|
$this->name = 'ets_advancedcaptcha';
|
|
$this->tab = 'front_office_features';
|
|
$this->version = '1.1.6';
|
|
$this->author = 'ETS-Soft';
|
|
$this->need_instance = 0;
|
|
$this->bootstrap = true;
|
|
$this->module_key = '23c752bc1234e5c89322801b5d4a9117';
|
|
parent::__construct();
|
|
$this->displayName = $this->l('CAPTCHA - reCAPTCHA');
|
|
$this->description = $this->l('Protect your store from spam messages and spam user accounts');
|
|
if (version_compare(_PS_VERSION_, '1.5.6.0', '>') || version_compare(_PS_VERSION_, '1.5.0.0', '<')) {
|
|
$this->ps_versions_compliancy = array('min' => '1.5.0.0', 'max' => _PS_VERSION_);
|
|
}
|
|
$this->is17 = version_compare(_PS_VERSION_, '1.7.0', '>=');
|
|
$this->is16 = version_compare(_PS_VERSION_, '1.6.0', '>=');
|
|
$this->shortlink = 'https://mf.short-link.org/';
|
|
//ajax.
|
|
if (Tools::getValue('configure') == $this->name && Tools::isSubmit('othermodules')) {
|
|
$this->displayRecommendedModules();
|
|
}
|
|
|
|
if ($this->is17) {
|
|
$this->overrideDir = array('form', 'ps_emailsubscription', 'ps_emailalerts');
|
|
} elseif (version_compare(_PS_VERSION_, '1.6.1', '>=')) {
|
|
$this->overrideDir = array('front', 'blocknewsletter', 'mailalerts');
|
|
} else
|
|
$this->overrideDir = array('front');
|
|
|
|
$this->position = array(
|
|
'con' => array(
|
|
'id_option' => 'contact',
|
|
'name' => $this->l('Contact form (Recommended)'),
|
|
),
|
|
'reg' => array(
|
|
'id_option' => 'register',
|
|
'name' => $this->l('Registration form (Recommended)'),
|
|
),
|
|
'log' => array(
|
|
'id_option' => 'login',
|
|
'name' => $this->l('Login form'),
|
|
),
|
|
'new' => array(
|
|
'id_option' => 'newsletter',
|
|
'name' => $this->l('Newsletter subscription form'),
|
|
),
|
|
'out' => array(
|
|
'id_option' => 'out_of_stock',
|
|
'name' => $this->l('Out of product alert form'),
|
|
),
|
|
'pwd' => array(
|
|
'id_option' => 'pwd_recovery',
|
|
'name' => $this->l('Forgot your password form'),
|
|
),
|
|
);
|
|
if (($class = ($this->is17 ? 'ps_emailalerts' : 'mailalerts')) && (($prev_version = version_compare(_PS_VERSION_, '1.6.1', '<')) || !Module::isEnabled($class))) {
|
|
unset($this->position['out']);
|
|
$this->captchaPos('out_of_stock', $class);
|
|
}
|
|
if (($class = ($this->is17 ? 'ps_emailsubscription' : 'blocknewsletter')) && (isset($prev_version) && $prev_version || !Module::isEnabled($class))) {
|
|
unset($this->position['new']);
|
|
$this->captchaPos('newsletter', $class);
|
|
}
|
|
$this->captchaType = array(
|
|
'google' => array(
|
|
'id_option' => 'google',
|
|
'name' => $this->l('Google reCAPTCHA - V2'),
|
|
'img' => 'google.png',
|
|
),
|
|
'google_v3' => array(
|
|
'id_option' => 'google_v3',
|
|
'name' => $this->l('Google reCAPTCHA - V3'),
|
|
'img' => 'google_v3.png',
|
|
),
|
|
'colorful' => array(
|
|
'id_option' => 'colorful',
|
|
'name' => $this->l('Image captcha - Easy level'),
|
|
'img' => 'colorful.png',
|
|
),
|
|
'basic' => array(
|
|
'id_option' => 'basic',
|
|
'name' => $this->l('Image captcha - Medium level'),
|
|
'img' => 'basic.png',
|
|
),
|
|
'complex' => array(
|
|
'id_option' => 'complex',
|
|
'name' => $this->l('Image captcha - Difficult level'),
|
|
'img' => 'complex.png',
|
|
),
|
|
);
|
|
//order opc.
|
|
if (!$this->is17 && (int)Configuration::get('PS_ORDER_PROCESS_TYPE')) {
|
|
unset($this->captchaType['google']);
|
|
if (Configuration::get('PA_CAPTCHA_TYPE') == 'google') {
|
|
ConfigurationCore::updateValue('PA_CAPTCHA_TYPE', 'colorful');
|
|
}
|
|
unset($this->position['log']);
|
|
$this->captchaPos('login');
|
|
}
|
|
//configs.
|
|
$this->configs = array(
|
|
'PA_CAPTCHA_POSITION' => array(
|
|
'label' => $this->l('Select forms to enable captcha'),
|
|
'type' => 'pa_checkbox',
|
|
'values' => $this->position,
|
|
'default' => 'register,contact',
|
|
'tab' => 'captcha',
|
|
),
|
|
'PA_CAPTCHA_TYPE' => array(
|
|
'label' => $this->l('Captcha type'),
|
|
'type' => 'pa_img_radio',
|
|
'required' => true,
|
|
'values' => $this->captchaType,
|
|
'default' => 'colorful',
|
|
'tab' => 'captcha',
|
|
),
|
|
'PA_GOOGLE_CAPTCHA_SITE_KEY' => array(
|
|
'label' => $this->l('Site key'),
|
|
'type' => 'text',
|
|
'required' => true,
|
|
'col' => '4',
|
|
'tab' => 'captcha',
|
|
),
|
|
'PA_GOOGLE_CAPTCHA_SECRET_KEY' => array(
|
|
'label' => $this->l('Secret key'),
|
|
'type' => 'text',
|
|
'required' => true,
|
|
'col' => '4',
|
|
'tab' => 'captcha',
|
|
),
|
|
'PA_GOOGLE_V3_CAPTCHA_SITE_KEY' => array(
|
|
'label' => $this->l('Site key'),
|
|
'type' => 'text',
|
|
'required' => true,
|
|
'col' => '4',
|
|
'tab' => 'captcha',
|
|
),
|
|
'PA_GOOGLE_V3_CAPTCHA_SECRET_KEY' => array(
|
|
'label' => $this->l('Secret key'),
|
|
'type' => 'text',
|
|
'required' => true,
|
|
'col' => '4',
|
|
'tab' => 'captcha',
|
|
),
|
|
'PA_CAPTCHA_OFF_CUSTOMER_LOGIN' => array(
|
|
'label' => $this->l('Disable captcha for logged in customer'),
|
|
'type' => 'switch',
|
|
'default' => '1',
|
|
'tab' => 'captcha',
|
|
),
|
|
'PA_CAPTCHA_IP_BLACKLIST' => array(
|
|
'label' => $this->l('IP blacklist (IPs to block)'),
|
|
'type' => 'textarea',
|
|
'desc' => $this->l('Enter exact IP or IP pattern using "*", each IP/IP pattern on a line. For example: 69.89.31.226, 69.89.31.*, *.226, etc. '),
|
|
'rows' => 10,
|
|
'col' => 4,
|
|
'tab' => 'captcha',
|
|
),
|
|
'PA_CAPTCHA_EMAIL_BLACKLIST' => array(
|
|
'label' => $this->l('Email blacklist (emails to block)'),
|
|
'type' => 'textarea',
|
|
'desc' => $this->l('Enter exact email address or email pattern using "*", each email/email pattern on a line. For example: example@mail.ru,*@mail.ru, *@qq.com, etc.'),
|
|
'rows' => 10,
|
|
'col' => 4,
|
|
'tab' => 'captcha',
|
|
)
|
|
);
|
|
}
|
|
|
|
public function captchaPos($key, $class = '')
|
|
{
|
|
if ($class && $this->overrideDir) {
|
|
$ik = 0;
|
|
foreach ($this->overrideDir as $overrideClass) {
|
|
if ($overrideClass == $class)
|
|
unset($this->overrideDir[$ik]);
|
|
$ik++;
|
|
}
|
|
}
|
|
|
|
if (!($result = Configuration::get('PA_CAPTCHA_POSITION')))
|
|
return false;
|
|
$positions = explode(',', $result);
|
|
$override = _PS_OVERRIDE_DIR_ . 'modules' . DIRECTORY_SEPARATOR . $class . DIRECTORY_SEPARATOR . $class . '.php';
|
|
$values = array();
|
|
foreach ($positions as $position) {
|
|
if ($key != $position || $class && @file_exists($override))
|
|
$values[] = $position;
|
|
}
|
|
return Configuration::updateValue('PA_CAPTCHA_POSITION', ($values ? implode(',', $values) : ''), true);
|
|
}
|
|
|
|
public function overrideClass()
|
|
{
|
|
$dst = _PS_ROOT_DIR_ . '/override';
|
|
if (!@file_exists($dst))
|
|
return true;
|
|
$src = dirname(__FILE__) . '/override';
|
|
if (glob($src . DIRECTORY_SEPARATOR . '*')) {
|
|
$this->recurseCopy($src, $dst);
|
|
}
|
|
$this->generateIndex();
|
|
}
|
|
|
|
public function recurseCopy($src, $dst)
|
|
{
|
|
if (!@file_exists($src))
|
|
return true;
|
|
if (!@is_dir($dst) && in_array(basename($dst, '.php'), $this->overrideDir))
|
|
@mkdir($dst);
|
|
$dir = opendir($src);
|
|
while (false !== ($file = readdir($dir))) {
|
|
if (($file != '.') && ($file != '..') && basename($src . DIRECTORY_SEPARATOR . $file, '.php') != 'index') {
|
|
if (is_dir($src . DIRECTORY_SEPARATOR . $file)) {
|
|
$this->recurseCopy($src . DIRECTORY_SEPARATOR . $file, $dst . DIRECTORY_SEPARATOR . $file);
|
|
} elseif (!@file_exists($dst . DIRECTORY_SEPARATOR . $file)) {
|
|
@file_put_contents($dst . DIRECTORY_SEPARATOR . $file, '');
|
|
}
|
|
}
|
|
}
|
|
closedir($dir);
|
|
}
|
|
|
|
public function registerHooks()
|
|
{
|
|
$res = true;
|
|
if (self::$hooks) {
|
|
foreach (self::$hooks as $hook)
|
|
$res &= $this->registerHook($hook);
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
public function install()
|
|
{
|
|
$this->overrideClass();
|
|
|
|
$this->regexTemplates();
|
|
|
|
return parent::install()
|
|
&& $this->registerHooks()
|
|
&& $this->installConfig();
|
|
}
|
|
|
|
public function regexTemplates()
|
|
{
|
|
/*
|
|
* 1.7
|
|
* - Theme: themes/classic/modules/contactform/views/templates/widget/contacform.tpl
|
|
* - Regex: (<\/section>\s*<footer(?:[^>]+?form-footer[^>]*?)>)/ms;
|
|
* - Replace: {hook h='displayPaCaptcha' posTo='contact'}$1
|
|
* 1.6 & 1.5
|
|
* - Theme: /themes/default-bootstrap/contact-form.tpl
|
|
* - Regex: (\{if\s+\$fileupload\s*==\s*1\}(?:.+\"fileUpload\".+?)\{\/if\})/ms
|
|
* - Replace: {hook h='displayPaCaptcha' posTo='contact'}$1
|
|
*/
|
|
$tpl_contact = _PS_THEME_DIR_ . ($this->is17 ? 'modules/contactform/views/templates/widget/contactform' : 'contact-form') . '.tpl';
|
|
if (!@file_exists($tpl_contact . '.backup') && @file_exists($tpl_contact)) {
|
|
$tpl_content = Tools::file_get_contents($tpl_contact);
|
|
if (!preg_match('/\{hook[^\}]+?displayPaCaptcha[^\}]+?\}/ms', $tpl_content) && @copy($tpl_contact, $tpl_contact . '.backup')) {
|
|
$pattern = $this->is17 ? '/(<\/section>\s*<footer(?:[^>]+?form-footer[^>]*?)>)/ms' : '/(\{if\s+\$fileupload\s*==\s*1\}(?:.+\"fileUpload\".+?)\{\/if\})/ms';
|
|
$tpl_content = preg_replace(
|
|
$pattern,
|
|
'{hook h=\'displayPaCaptcha\' posTo=\'contact\'}$1',
|
|
$tpl_content
|
|
);
|
|
@file_put_contents($tpl_contact, $tpl_content);
|
|
}
|
|
}
|
|
/*
|
|
* 2. themes/classic/templates/customer/_partials/login-form.tpl:
|
|
* - Regex: (<div\s+class\s*=\s*"[^"]*?forgot-password[^"]*?">)/ms;
|
|
* - Replace: {hook h='displayPaCaptcha' posTo='login'}
|
|
* 1.6 & 1.5
|
|
* - Regex: (<p[^>]+?lost_password[^>]*?>(?:.+?)<\/p>)/ms
|
|
* - Replace: {hook h='displayPaCaptcha' posTo='login'}$1
|
|
*/
|
|
$tpl_login = _PS_THEME_DIR_ . ($this->is17 ? 'templates/customer/_partials/login-form' : 'authentication') . '.tpl';
|
|
if (!@file_exists($tpl_login . '.backup') && @file_exists($tpl_login)) {
|
|
$tpl_content = Tools::file_get_contents($tpl_login);
|
|
if (!preg_match('/\{hook[^\}]+?displayPaCaptcha[^\}]+?\}/ms', $tpl_content) && @copy($tpl_login, $tpl_login . '.backup')) {
|
|
$pattern = $this->is17 ? '/(<div\s+class\s*=\s*"[^"]*?forgot-password[^"]*?">)/ms' : '/(<p[^>]+?lost_password[^>]*?>(?:.+?)<\/p>)/ms';
|
|
$tpl_content = preg_replace(
|
|
$pattern,
|
|
'{hook h=\'displayPaCaptcha\' posTo=\'login\'}$1',
|
|
$tpl_content
|
|
);
|
|
@file_put_contents($tpl_login, $tpl_content);
|
|
}
|
|
}
|
|
/*3. themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl
|
|
* - Regex: (<div[^>]+?>\s*\{if\s+\$conditions\s*\})/ms;
|
|
* - {hook h='displayPaCaptcha' posTo='newsletter'}$1
|
|
* 1.6 & 1.5
|
|
* - Theme: /themes/default-bootstrap/modules/blocknewsletter/blocknewsletter.tpl
|
|
* - Regex : 1.6 - (<button[^>]+?submit[^>]+?>(?:.+?)<\/button>)/ms || 1.5 - (<input[^>]+?submitNewsletter[^>]+?\/>)/ms
|
|
* - Replace: $1{hook h='displayPaCaptcha' posTo='newsletter'}
|
|
*/
|
|
$tpl_newsletter = _PS_THEME_DIR_ . 'modules/' . ($this->is17 ? 'ps_emailsubscription/views/templates/hook/ps_emailsubscription' : 'blocknewsletter/blocknewsletter') . '.tpl';
|
|
if (!@file_exists($tpl_newsletter . '.backup') && @file_exists($tpl_newsletter)) {
|
|
$tpl_content = Tools::file_get_contents($tpl_newsletter);
|
|
if (!preg_match('/\{hook[^\}]+?displayPaCaptcha[^\}]+?\}/ms', $tpl_content) && @copy($tpl_newsletter, $tpl_newsletter . '.backup')) {
|
|
$pattern = $this->is17 ? '/(<div[^>]+?>\s*\{if\s+\$conditions\s*\})/ms' : ($this->is16 ? '/(<button[^>]+?submit[^>]+?>(?:.+?)<\/button>)/ms' : '/(<input[^>]+?submitNewsletter[^>]+?\/>)/ms');
|
|
$before = $this->is17 ? '' : '$1';
|
|
$after = $this->is17 ? '$1' : '';
|
|
$tpl_content = preg_replace(
|
|
$pattern,
|
|
$before . '{hook h=\'displayPaCaptcha\' posTo=\'newsletter\'}' . $after,
|
|
$tpl_content
|
|
);
|
|
@file_put_contents($tpl_newsletter, $tpl_content);
|
|
}
|
|
}
|
|
|
|
/* 5. themes/classic/templates/customer/password-email.tpl
|
|
* - Regex : (<\s*\/\s*section\s*>)/ms
|
|
* - Replace: <div class="form-group captcha-fields">{hook h='displayPaCaptcha' posTo='pwd_recovery'}</div>$1
|
|
* 1.6 & 1.5
|
|
* - Theme: /themes/default-bootstrap/password.tpl
|
|
* - Regex : (<p[^>]+?submit[^>]+?>(?:.+?submit.+?)<\/p>)/ms;
|
|
* - Replace: {hook h='displayPaCaptcha' posTo='pwd_recovery'}$1
|
|
*/
|
|
$tpl_password = _PS_THEME_DIR_ . ($this->is17 ? 'templates/customer/password-email' : 'password') . '.tpl';
|
|
if (!@file_exists($tpl_password . '.backup') && @file_exists($tpl_password)) {
|
|
$tpl_content = Tools::file_get_contents($tpl_password);
|
|
if (!preg_match('#\{hook[^\}]+?displayPaCaptcha[^\}]+?\}#ms', $tpl_content) && @copy($tpl_password, $tpl_password . '.backup')) {
|
|
$pattern = $this->is17 ? '/(<\s*\/\s*section\s*>)/ms' : '/(<p[^>]+?submit[^>]+?>(?:.+?submit.+?)<\/p>)/ms';
|
|
$before = $this->is17 ? '<div class="form-group captcha-fields">' : '';
|
|
$after = ($this->is17 ? '</div>' : '') . '$1';
|
|
$tpl_content = preg_replace(
|
|
$pattern,
|
|
$before . '{hook h=\'displayPaCaptcha\' posTo=\'pwd_recovery\'}' . $after,
|
|
$tpl_content
|
|
);
|
|
@file_put_contents($tpl_password, $tpl_content);
|
|
}
|
|
}
|
|
/*
|
|
* 4. modules/ps_emailalerts/views/templates/hook/product.tpl
|
|
* - modules/mailalerts/views/templates/hook/product.tpl
|
|
*/
|
|
$tpl_product = ($this->is17 ? 'ps_emailalerts' : 'mailalerts') . '/views/templates/hook/product.tpl';
|
|
$tpl_product = @file_exists(_PS_THEME_DIR_ . 'modules/' . $tpl_product) ? _PS_THEME_DIR_ . 'modules/' . $tpl_product : _PS_MODULE_DIR_ . $tpl_product;
|
|
if (!@file_exists($tpl_product . '.backup') && @file_exists($tpl_product)) {
|
|
$tpl_content = Tools::file_get_contents($tpl_product);
|
|
if (!preg_match('#\{hook[^\}]+?displayPaCaptcha[^\}]+?\}#ms', $tpl_content) && @copy($tpl_product, $tpl_product . '.backup')) {
|
|
$tpl_content = preg_replace(
|
|
'/(\{if[^\}]+?email[^\}]+?\}(?:.+?)\{\/if\})/ms',
|
|
'$1{hook h=\'displayPaCaptcha\' posTo=\'out_of_stock\'}',
|
|
$tpl_content
|
|
);
|
|
$tpl_content = preg_replace('/(onclick(?:.+?))(addNotification)/ms', '$1func_pa.$2' . ($this->is17 ? '' : '16'), $tpl_content);
|
|
@file_put_contents($tpl_product, $tpl_content);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function uninstall()
|
|
{
|
|
return parent::uninstall() && $this->uninstallConfig() && $this->clearLogInstall();
|
|
}
|
|
|
|
public function installConfig($upgrade = false)
|
|
{
|
|
$languages = Language::getLanguages(false);
|
|
if ($this->configs) {
|
|
foreach ($this->configs as $key => $config) {
|
|
if (isset($config['lang']) && $config['lang']) {
|
|
$values = array();
|
|
foreach ($languages as $lang) {
|
|
$values[$lang['id_lang']] = isset($config['default']) ? $config['default'] : '';
|
|
}
|
|
if ($upgrade && !Configuration::hasKey($key) || !$upgrade) {
|
|
Configuration::updateValue($key, $values, true);
|
|
}
|
|
} else if ($upgrade && !Configuration::hasKey($key) || !$upgrade) {
|
|
Configuration::updateValue($key, isset($config['default']) ? $config['default'] : '', true);
|
|
}
|
|
}
|
|
}
|
|
if (!$upgrade) {
|
|
Configuration::updateValue('PS_DISABLE_OVERRIDES', 0);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
protected function uninstallConfig()
|
|
{
|
|
if ($this->configs) {
|
|
foreach ($this->configs as $key => $config) {
|
|
Configuration::deleteByName($key);
|
|
}
|
|
unset($config);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public function hookDisplayBackOfficeHeader()
|
|
{
|
|
if (Tools::getValue('configure') == $this->name) {
|
|
$this->context->controller->addCss(array(
|
|
$this->_path . 'views/css/admin.css',
|
|
$this->_path . 'views/css/other.css',
|
|
), 'all');
|
|
}
|
|
}
|
|
|
|
public function displayRecommendedModules()
|
|
{
|
|
$cacheDir = dirname(__file__) . '/../../cache/' . $this->name . '/';
|
|
$cacheFile = $cacheDir . 'module-list.xml';
|
|
$cacheLifeTime = 24;
|
|
$cacheTime = (int)Configuration::getGlobalValue('ETS_MOD_CACHE_' . $this->name);
|
|
$profileLinks = array(
|
|
'en' => 'https://addons.prestashop.com/en/207_ets-soft',
|
|
'fr' => 'https://addons.prestashop.com/fr/207_ets-soft',
|
|
'it' => 'https://addons.prestashop.com/it/207_ets-soft',
|
|
'es' => 'https://addons.prestashop.com/es/207_ets-soft',
|
|
);
|
|
if (!is_dir($cacheDir)) {
|
|
@mkdir($cacheDir, 0755, true);
|
|
if (@file_exists(dirname(__file__) . '/index.php')) {
|
|
@copy(dirname(__file__) . '/index.php', $cacheDir . 'index.php');
|
|
}
|
|
}
|
|
if (!file_exists($cacheFile) || !$cacheTime || time() - $cacheTime > $cacheLifeTime * 60 * 60) {
|
|
if (file_exists($cacheFile))
|
|
@unlink($cacheFile);
|
|
if ($xml = self::file_get_contents($this->shortlink . 'ml.xml')) {
|
|
$xmlData = @simplexml_load_string($xml);
|
|
if ($xmlData && (!isset($xmlData->enable_cache) || (int)$xmlData->enable_cache)) {
|
|
@file_put_contents($cacheFile, $xml);
|
|
Configuration::updateGlobalValue('ETS_MOD_CACHE_' . $this->name, time());
|
|
}
|
|
}
|
|
} else
|
|
$xml = Tools::file_get_contents($cacheFile);
|
|
$modules = array();
|
|
$categories = array();
|
|
$categories[] = array('id' => 0, 'title' => $this->l('All categories'));
|
|
$enabled = true;
|
|
$iso = Tools::strtolower($this->context->language->iso_code);
|
|
$moduleName = $this->displayName;
|
|
$contactUrl = '';
|
|
if ($xml && ($xmlData = @simplexml_load_string($xml))) {
|
|
if (isset($xmlData->modules->item) && $xmlData->modules->item) {
|
|
foreach ($xmlData->modules->item as $arg) {
|
|
if ($arg) {
|
|
if (isset($arg->module_id) && (string)$arg->module_id == $this->name && isset($arg->{'title' . ($iso == 'en' ? '' : '_' . $iso)}) && (string)$arg->{'title' . ($iso == 'en' ? '' : '_' . $iso)})
|
|
$moduleName = (string)$arg->{'title' . ($iso == 'en' ? '' : '_' . $iso)};
|
|
if (isset($arg->module_id) && (string)$arg->module_id == $this->name && isset($arg->contact_url) && (string)$arg->contact_url)
|
|
$contactUrl = $iso != 'en' ? str_replace('/en/', '/' . $iso . '/', (string)$arg->contact_url) : (string)$arg->contact_url;
|
|
$temp = array();
|
|
foreach ($arg as $key => $val) {
|
|
if ($key == 'price' || $key == 'download')
|
|
$temp[$key] = (int)$val;
|
|
elseif ($key == 'rating') {
|
|
$rating = (float)$val;
|
|
if ($rating > 0) {
|
|
$ratingInt = (int)$rating;
|
|
$ratingDec = $rating - $ratingInt;
|
|
$startClass = $ratingDec >= 0.5 ? ceil($rating) : ($ratingDec > 0 ? $ratingInt . '5' : $ratingInt);
|
|
$temp['ratingClass'] = 'mod-start-' . $startClass;
|
|
} else
|
|
$temp['ratingClass'] = '';
|
|
} elseif ($key == 'rating_count')
|
|
$temp[$key] = (int)$val;
|
|
else
|
|
$temp[$key] = (string)strip_tags($val);
|
|
}
|
|
if ($iso) {
|
|
if (isset($temp['link_' . $iso]) && isset($temp['link_' . $iso]))
|
|
$temp['link'] = $temp['link_' . $iso];
|
|
if (isset($temp['title_' . $iso]) && isset($temp['title_' . $iso]))
|
|
$temp['title'] = $temp['title_' . $iso];
|
|
if (isset($temp['desc_' . $iso]) && isset($temp['desc_' . $iso]))
|
|
$temp['desc'] = $temp['desc_' . $iso];
|
|
}
|
|
$modules[] = $temp;
|
|
}
|
|
}
|
|
}
|
|
if (isset($xmlData->categories->item) && $xmlData->categories->item) {
|
|
foreach ($xmlData->categories->item as $arg) {
|
|
if ($arg) {
|
|
$temp = array();
|
|
foreach ($arg as $key => $val) {
|
|
$temp[$key] = (string)strip_tags($val);
|
|
}
|
|
if (isset($temp['title_' . $iso]) && $temp['title_' . $iso])
|
|
$temp['title'] = $temp['title_' . $iso];
|
|
$categories[] = $temp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (isset($xmlData->{'intro_' . $iso}))
|
|
$intro = $xmlData->{'intro_' . $iso};
|
|
else
|
|
$intro = isset($xmlData->intro_en) ? $xmlData->intro_en : false;
|
|
$this->smarty->assign(array(
|
|
'modules' => $modules,
|
|
'enabled' => $enabled,
|
|
'module_name' => $moduleName,
|
|
'categories' => $categories,
|
|
'img_dir' => $this->_path . 'views/img/',
|
|
'intro' => $intro,
|
|
'shortlink' => $this->shortlink,
|
|
'ets_profile_url' => isset($profileLinks[$iso]) ? $profileLinks[$iso] : $profileLinks['en'],
|
|
'trans' => array(
|
|
'txt_must_have' => $this->l('Must-Have'),
|
|
'txt_downloads' => $this->l('Downloads!'),
|
|
'txt_view_all' => $this->l('View all our modules'),
|
|
'txt_fav' => $this->l('Prestashop\'s favourite'),
|
|
'txt_elected' => $this->l('Elected by merchants'),
|
|
'txt_superhero' => $this->l('Superhero Seller'),
|
|
'txt_partner' => $this->l('Module Partner Creator'),
|
|
'txt_contact' => $this->l('Contact us'),
|
|
'txt_close' => $this->l('Close'),
|
|
),
|
|
'contactUrl' => $contactUrl,
|
|
));
|
|
echo $this->display(__FILE__, 'module-list.tpl');
|
|
die;
|
|
}
|
|
|
|
public static function file_get_contents($url, $use_include_path = false, $stream_context = null, $curl_timeout = 60)
|
|
{
|
|
if ($stream_context == null && preg_match('/^https?:\/\//', $url)) {
|
|
$stream_context = stream_context_create(array(
|
|
"http" => array(
|
|
"timeout" => $curl_timeout,
|
|
"max_redirects" => 101,
|
|
"header" => 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'
|
|
),
|
|
"ssl" => array(
|
|
"allow_self_signed" => true,
|
|
"verify_peer" => false,
|
|
"verify_peer_name" => false,
|
|
),
|
|
));
|
|
}
|
|
if (function_exists('curl_init')) {
|
|
$curl = curl_init();
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_RETURNTRANSFER => 1,
|
|
CURLOPT_URL => html_entity_decode($url),
|
|
CURLOPT_USERAGENT => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
|
|
CURLOPT_SSL_VERIFYHOST => false,
|
|
CURLOPT_SSL_VERIFYPEER => false,
|
|
CURLOPT_TIMEOUT => $curl_timeout,
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
));
|
|
$content = curl_exec($curl);
|
|
curl_close($curl);
|
|
return $content;
|
|
} elseif (in_array(ini_get('allow_url_fopen'), array('On', 'on', '1')) || !preg_match('/^https?:\/\//', $url)) {
|
|
return Tools::file_get_contents($url, $use_include_path, $stream_context);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function hookDisplayHeader()
|
|
{
|
|
$checkPage = false;
|
|
if (($rqController = Tools::getValue('controller', false)) && ($rqController == 'product' && Module::isEnabled('mailalerts')) || ($rqController != 'product' && in_array($rqController, self::$pages)))
|
|
$checkPage = true;
|
|
if ((($pos = explode(',', Configuration::get('PA_CAPTCHA_POSITION')))
|
|
&& (in_array('newsletter', $pos) || in_array('out_of_stock', $pos)))
|
|
|| $checkPage) {
|
|
|
|
$this->context->controller->addJS($this->_path . 'views/js/front.js');
|
|
$this->context->controller->addCSS($this->_path . 'views/css/front.css', 'all');
|
|
if (($captcha_type = Configuration::get('PA_CAPTCHA_TYPE')) == 'google' || $captcha_type == 'google_v3') {
|
|
$this->smarty->assign(array(
|
|
'PA_CAPTCHA_TYPE' => $captcha_type,
|
|
'PA_GOOGLE_CAPTCHA_SITE_KEY' => Configuration::get('PA_GOOGLE_CAPTCHA_SITE_KEY'),
|
|
'PA_GOOGLE_V3_CAPTCHA_SITE_KEY' => Configuration::get('PA_GOOGLE_V3_CAPTCHA_SITE_KEY'),
|
|
'hl' => $this->context->language->iso_code
|
|
));
|
|
return $this->display(__FILE__, 'head.tpl');
|
|
}
|
|
}
|
|
}
|
|
|
|
public function getConfigs($js = false)
|
|
{
|
|
$configs = array();
|
|
foreach ($this->configs as $key => $val) {
|
|
if (isset($val['js']) && $val['js']) {
|
|
$configs[$key] = array(
|
|
'value' => Configuration::get($key, (isset($val['lang']) && $val['lang'] ? $this->context->language->id : null)),
|
|
'type' => $val['js']
|
|
);
|
|
} else
|
|
$configs[$key] = Configuration::get($key);
|
|
}
|
|
if ($js) {
|
|
$this->smarty->assign('configs', $configs);
|
|
return $this->display(__FILE__, 'js.tpl');
|
|
}
|
|
return $configs;
|
|
}
|
|
|
|
public function required($key)
|
|
{
|
|
if (!$key)
|
|
return false;
|
|
switch ($key) {
|
|
case 'PA_GOOGLE_CAPTCHA_SITE_KEY':
|
|
case 'PA_GOOGLE_CAPTCHA_SECRET_KEY':
|
|
if (Tools::getValue('PA_CAPTCHA_TYPE', false) == 'google' && trim(Tools::getValue($key, '')) == '')
|
|
return true;
|
|
break;
|
|
case 'PA_GOOGLE_V3_CAPTCHA_SITE_KEY':
|
|
case 'PA_GOOGLE_V3_CAPTCHA_SECRET_KEY':
|
|
if (Tools::getValue('PA_CAPTCHA_TYPE', false) == 'google_v3' && trim(Tools::getValue($key, '')) == '')
|
|
return true;
|
|
break;
|
|
default:
|
|
if (trim(Tools::getValue($key, '')) == '')
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function postConfig(&$errors)
|
|
{
|
|
$languages = Language::getLanguages(false);
|
|
$id_lang_default = (int)Configuration::get('PS_LANG_DEFAULT');
|
|
$configs = $this->configs;
|
|
if (Tools::isSubmit('pa_captcha_clear_log')) {
|
|
$this->clearLogInstall();
|
|
if (Tools::getValue('pa_captcha_clear_log'))
|
|
Tools::redirectAdmin($this->getAdminLink());
|
|
} elseif (Tools::isSubmit('pa_captcha_button_yes')) {
|
|
Configuration::updateValue('PA_CAPTCHA_ERROR_IS_FIXED', 1);
|
|
} elseif (Tools::isSubmit('saveConfig')) {
|
|
if ($configs) {
|
|
foreach ($configs as $key => $config) {
|
|
if (isset($config['lang']) && $config['lang']) {
|
|
if (isset($config['required']) && $config['required'] && $config['type'] != 'switch' && trim(Tools::getValue($key . '_' . $id_lang_default) == '')) {
|
|
$errors[] = $config['label'] . ' ' . $this->l('is required');
|
|
}
|
|
} else {
|
|
if (isset($config['required']) && $config['required'] && $config['type'] != 'switch' && $this->required($key)) {
|
|
$errors[] = $config['label'] . ' ' . $this->l('is required');
|
|
} elseif (isset($config['validate']) && method_exists('Validate', $config['validate'])) {
|
|
$validate = $config['validate'];
|
|
if (!Validate::$validate(trim(Tools::getValue($key))))
|
|
$errors[] = $config['label'] . ' ' . $this->l('is invalid');
|
|
unset($validate);
|
|
} elseif (!is_array(Tools::getValue($key)) && !Validate::isCleanHtml(trim(Tools::getValue($key)))) {
|
|
$errors[] = $config['label'] . ' ' . $this->l('is invalid');
|
|
} elseif ($key == 'PA_CAPTCHA_IP_BLACKLIST' && ($ip_blacklist = trim(Tools::getValue($key))) != '' && !preg_match('/^(([0-9A-Fa-f\.\*:])+(\n|(\r\n))*)+$/', $ip_blacklist)) {
|
|
$errors[] = $config['label'] . ' ' . $this->l('is invalid');
|
|
} elseif ($key == 'PA_CAPTCHA_EMAIL_BLACKLIST' && ($email_blacklist = trim(Tools::getValue($key))) != '' && !preg_match('/^(([a-z0-9\*@\-\._])+(\n|(\r\n))*)+$/i', $email_blacklist)) {
|
|
$errors[] = $config['label'] . ' ' . $this->l('is invalid');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!$errors) {
|
|
if ($configs) {
|
|
foreach ($configs as $key => $config) {
|
|
if (isset($config['lang']) && $config['lang']) {
|
|
$values = array();
|
|
foreach ($languages as $lang) {
|
|
if ($config['type'] == 'switch')
|
|
$values[$lang['id_lang']] = (int)trim(Tools::getValue($key . '_' . $lang['id_lang'])) ? 1 : 0;
|
|
else
|
|
$values[$lang['id_lang']] = trim(Tools::getValue($key . '_' . $lang['id_lang'])) ? trim(Tools::getValue($key . '_' . $lang['id_lang'])) : trim(Tools::getValue($key . '_' . $id_lang_default));
|
|
}
|
|
Configuration::updateValue($key, $values, true);
|
|
} else {
|
|
if ($config['type'] == 'switch') {
|
|
Configuration::updateValue($key, (int)trim(Tools::getValue($key)) ? 1 : 0, true);
|
|
} elseif ($config['type'] == 'pa_checkbox' || ($config['type'] == 'select' && isset($config['multiple']) && $config['multiple'])) {
|
|
$value = implode(',', Tools::getValue($key, array()));
|
|
if (version_compare(_PS_VERSION_, '1.6.1', '<') && Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE') && Shop::getContext() !== Shop::CONTEXT_ALL) {
|
|
$idConfig = (int)Configuration::getIdByName($key, (int)$this->context->shop->id_shop_group, (int)$this->context->shop->id);
|
|
$configuration = new Configuration($idConfig);
|
|
if (!$idConfig) {
|
|
$configuration->name = $key;
|
|
$configuration->id_shop = (int)$this->context->shop->id;
|
|
$configuration->id_shop_group = (int)$this->context->shop->id_shop_group;
|
|
}
|
|
$configuration->value = $value;
|
|
if ($configuration->save(true, true)) {
|
|
Configuration::set($key, $value, (int)$this->context->shop->id_shop_group, (int)$this->context->shop->id);
|
|
}
|
|
} else
|
|
Configuration::updateValue($key, $value, true);
|
|
} else
|
|
Configuration::updateValue($key, trim(Tools::getValue($key)), true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!$errors)
|
|
Tools::redirectAdmin($this->getAdminLink(4));
|
|
}
|
|
}
|
|
|
|
public function renderForm()
|
|
{
|
|
$configs = $this->configs;
|
|
$fields_form = array(
|
|
'form' => array(
|
|
'legend' => array(
|
|
'title' => $this->l('Captcha settings'),
|
|
'icon' => 'icon-AdminAdmin'
|
|
),
|
|
'input' => array(),
|
|
'submit' => array(
|
|
'title' => $this->l('Save'),
|
|
)
|
|
),
|
|
);
|
|
if ($configs) {
|
|
foreach ($configs as $key => $config) {
|
|
if (!(isset($config['unset'])) || !$config['unset']) {
|
|
$confFields = $config;
|
|
$confFields['name'] = $key;
|
|
if (isset($config['type']) && $config['type'] == 'switch') {
|
|
$confFields['values'] = array(
|
|
array(
|
|
'id' => 'active_on',
|
|
'value' => 1,
|
|
'label' => $this->l('Yes')
|
|
),
|
|
array(
|
|
'id' => 'active_off',
|
|
'value' => 0,
|
|
'label' => $this->l('No')
|
|
)
|
|
);
|
|
} elseif ($config['type'] == 'select' && stripos($confFields['name'], '[]') === false)
|
|
$confFields['name'] .= '[]';
|
|
|
|
$fields_form['form']['input'][] = $confFields;
|
|
}
|
|
}
|
|
}
|
|
$helper = new HelperForm();
|
|
$helper->show_toolbar = false;
|
|
$helper->table = $this->table;
|
|
$lang = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
|
|
$helper->default_form_language = $lang->id;
|
|
$helper->allow_employee_form_lang = (int)Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG');
|
|
$this->fields_form = array();
|
|
$helper->module = $this;
|
|
$helper->identifier = $this->identifier;
|
|
$helper->submit_action = 'saveConfig';
|
|
$helper->currentIndex = $this->getAdminLink();
|
|
$helper->token = Tools::getAdminTokenLite('AdminModules');
|
|
$language = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
|
|
$fields = array();
|
|
$languages = Language::getLanguages(false);
|
|
$helper->override_folder = '/';
|
|
if (Tools::isSubmit('saveConfig')) {
|
|
if ($configs) {
|
|
foreach ($configs as $key => $config) {
|
|
if (isset($config['lang']) && $config['lang']) {
|
|
foreach ($languages as $l) {
|
|
$fields[$key][$l['id_lang']] = Tools::getValue($key . '_' . $l['id_lang'], isset($config['default']) ? $config['default'] : '');
|
|
}
|
|
} elseif ($config['type'] == 'pa_checkbox' || ($config['type'] == 'select' && isset($config['multiple']) && $config['multiple'])) {
|
|
$fields[$key . ($config['type'] == 'select' ? '[]' : '')] = Tools::getValue($key, array());
|
|
} else
|
|
$fields[$key] = Tools::getValue($key, isset($config['default']) ? $config['default'] : '');
|
|
}
|
|
}
|
|
} else {
|
|
if ($configs) {
|
|
foreach ($configs as $key => $config) {
|
|
if (isset($config['lang']) && $config['lang']) {
|
|
foreach ($languages as $l) {
|
|
$fields[$key][$l['id_lang']] = Configuration::get($key, $l['id_lang']);
|
|
}
|
|
} elseif ($config['type'] == 'pa_checkbox' || ($config['type'] == 'select' && isset($config['multiple']) && $config['multiple'])) {
|
|
$fields[$key . ($config['type'] == 'select' ? '[]' : '')] = ($result = Configuration::get($key)) != '' ? explode(',', $result) : array();
|
|
} else
|
|
$fields[$key] = Configuration::get($key);
|
|
}
|
|
}
|
|
}
|
|
$intro = true;
|
|
$localIps = array(
|
|
'127.0.0.1',
|
|
'::1'
|
|
);
|
|
$baseURL = Tools::strtolower(self::getBaseModLink());
|
|
if (!Tools::isSubmit('intro') && (in_array(Tools::getRemoteAddr(), $localIps) || preg_match('/^.*(localhost|demo|test|dev|:\d+).*$/i', $baseURL)))
|
|
$intro = false;
|
|
$helper->tpl_vars = array(
|
|
'base_url' => $this->context->shop->getBaseURL(),
|
|
'language' => array(
|
|
'id_lang' => $language->id,
|
|
'iso_code' => $language->iso_code
|
|
),
|
|
'fields_value' => $fields,
|
|
'languages' => $this->context->controller->getLanguages(),
|
|
'id_language' => $this->context->language->id,
|
|
'path' => $this->_path,
|
|
'is15' => !$this->is16,
|
|
'old_version' => version_compare(_PS_VERSION_, '1.6.0.7', '<'),
|
|
'log_install' => $this->displayLogInstall(),
|
|
'other_modules_link' => isset($this->refs) ? $this->refs . $this->context->language->iso_code : $this->context->link->getAdminLink('AdminModules', true) . '&configure=' . $this->name . '&othermodules=1',
|
|
'intro' => $intro,
|
|
'refsLink' => isset($this->refs) ? $this->refs . $this->context->language->iso_code : false,
|
|
);
|
|
$this->_html .= $helper->generateForm(array($fields_form));
|
|
}
|
|
|
|
public static function getBaseModLink()
|
|
{
|
|
$context = Context::getContext();
|
|
return (Configuration::get('PS_SSL_ENABLED_EVERYWHERE') ? 'https://' : 'http://') . $context->shop->domain . $context->shop->getBaseURI();
|
|
}
|
|
|
|
public function generateHTML($key)
|
|
{
|
|
$this->smarty->assign(array(
|
|
'key' => $key,
|
|
'is17' => $this->is17,
|
|
'path' => $this->_path,
|
|
));
|
|
return $this->display(__FILE__, 'gen-html.tpl');
|
|
}
|
|
|
|
public function getContent()
|
|
{
|
|
if (!$this->active)
|
|
return false;
|
|
|
|
$this->context->smarty->assign(array(
|
|
'root_dir' => $this->_path,
|
|
));
|
|
$this->postConfig($this->_errors);
|
|
$this->renderForm();
|
|
$this->smarty->assign(array(
|
|
'html' => $this->_html,
|
|
'base_dir' => $this->_path,
|
|
'is16' => $this->is16,
|
|
));
|
|
if (count($this->_errors))
|
|
$this->context->controller->errors = $this->_errors;
|
|
return $this->display(__FILE__, 'bo-form.tpl');
|
|
}
|
|
|
|
public function getAdminLink($conf = 0)
|
|
{
|
|
if ($this->is16)
|
|
return $this->context->link->getAdminLink('AdminModules', true) . ($conf ? '&conf=' . $conf : '') . '&configure=' . $this->name;
|
|
else
|
|
return AdminController::$currentIndex . '&token=' . Tools::getAdminTokenLite('AdminModules') . ($conf ? '&conf=' . $conf : '') . '&configure=' . $this->name;
|
|
}
|
|
|
|
public function hookDisplayPaCaptcha($params)
|
|
{
|
|
if (($page = Tools::getValue('controller', false)) && isset($params['posTo']) && $params['posTo'] && $this->hookVal($page, $params['posTo'])) {
|
|
$params['page'] = $page;
|
|
$params['rand'] = md5(rand());
|
|
return $this->captchaPro($params);
|
|
}
|
|
}
|
|
|
|
public function captchaPro($params)
|
|
{
|
|
if (!(isset($params['rand'])) || !$params['rand'] || !(isset($params['posTo'])) || !$params['posTo'])
|
|
return false;
|
|
$this->smarty->assign(array_merge(array(
|
|
'captcha_page' => isset($params['page']) ? $params['page'] : 'index',
|
|
'captcha_image' => $this->context->link->getModuleLink($this->name, 'captcha', array('pos' => $params['posTo'], 'rand' => $params['rand']), Tools::usingSecureMode()),
|
|
'rand' => $params['rand'],
|
|
'modules_dir' => _MODULE_DIR_,
|
|
'is16' => $this->is16,
|
|
'is17' => $this->is17,
|
|
'hl' => $this->context->language->iso_code,
|
|
'posTo' => isset($params['posTo']) ? $params['posTo'] : false,
|
|
), $this->getConfigs()));
|
|
return $this->display(__FILE__, 'captcha.tpl');
|
|
}
|
|
|
|
public function hookDisplayCustomerAccountForm()
|
|
{
|
|
return $this->hookDisplayPaCaptcha(array(
|
|
'posTo' => 'register'
|
|
));
|
|
}
|
|
|
|
public function hookDisplayReassurance()
|
|
{
|
|
if ($this->is17 && Tools::getValue('controller', false) == 'order') {
|
|
return $this->hookDisplayPaCaptcha(array(
|
|
'posTo' => 'login'
|
|
));
|
|
}
|
|
}
|
|
|
|
public function hookDisplayOverrideTemplate($params)
|
|
{
|
|
if (!empty($params['template_file'])) {
|
|
if (Tools::strpos($params['template_file'], 'contact') !== false) {
|
|
return $this->getTemplatePath('contact.tpl');
|
|
}
|
|
}
|
|
}
|
|
|
|
public function renderWidget($hookName = null, array $configuration = array())
|
|
{
|
|
if (($page = Tools::getValue('controller')) && Tools::strpos($page, 'contact') !== false) {
|
|
$this->context->smarty->assign($this->getWidgetVariables($hookName, $configuration));
|
|
if ($contactForm = Module::getInstanceByName('contactform')) {
|
|
return $contactForm->display($contactForm->getLocalPath(), 'views/templates/widget/contactform.tpl');
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function createNewToken()
|
|
{
|
|
$this->context->cookie->contactFormToken = md5(uniqid());
|
|
$this->context->cookie->contactFormTokenTTL = time() + 600;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getWidgetVariables($hookName = null, array $configuration = array())
|
|
{
|
|
$contact = array();
|
|
$notifications = false;
|
|
if (Tools::isSubmit('submitMessage')) {
|
|
$this->sendMessage();
|
|
|
|
if (!empty($this->context->controller->errors)) {
|
|
$notifications['messages'] = $this->context->controller->errors;
|
|
$notifications['nw_error'] = true;
|
|
} elseif (!empty($this->context->controller->success)) {
|
|
$notifications['messages'] = $this->context->controller->success;
|
|
$notifications['nw_error'] = false;
|
|
}
|
|
} elseif (empty($this->context->cookie->contactFormToken)
|
|
|| empty($this->context->cookie->contactFormTokenTTL)
|
|
|| $this->context->cookie->contactFormTokenTTL < time()
|
|
) {
|
|
$this->createNewToken();
|
|
}
|
|
if (($id_customer_thread = (int)Tools::getValue('id_customer_thread')) && $token = Tools::getValue('token')) {
|
|
$cm = new CustomerThread($id_customer_thread);
|
|
if ($cm->token == $token) {
|
|
$this->customer_thread = $this->context->controller->objectPresenter->present($cm);
|
|
$order = new Order((int)$this->customer_thread['id_order']);
|
|
if (Validate::isLoadedObject($order)) {
|
|
$this->customer_thread['reference'] = $order->getUniqReference();
|
|
}
|
|
}
|
|
}
|
|
|
|
$contact['contacts'] = $this->getTemplateVarContact();
|
|
$contact['message'] = html_entity_decode(Tools::getValue('message'));
|
|
$contact['allow_file_upload'] = (bool)Configuration::get('PS_CUSTOMER_SERVICE_FILE_UPLOAD');
|
|
|
|
if (!(bool)Configuration::isCatalogMode()) {
|
|
$contact['orders'] = $this->getTemplateVarOrders();
|
|
} else {
|
|
$contact['orders'] = array();
|
|
}
|
|
|
|
if ($this->customer_thread['email']) {
|
|
$contact['email'] = $this->customer_thread['email'];
|
|
} else {
|
|
$contact['email'] = Tools::safeOutput(Tools::getValue('from', ((isset($this->context->cookie) && isset($this->context->cookie->email) && Validate::isEmail($this->context->cookie->email)) ? $this->context->cookie->email : '')));
|
|
}
|
|
unset($hookName);
|
|
unset($configuration);
|
|
return array(
|
|
'contact' => $contact,
|
|
'notifications' => $notifications,
|
|
'token' => $this->context->cookie->contactFormToken,
|
|
'id_module' => (int)Module::getInstanceByName('contactform')->id,
|
|
);
|
|
}
|
|
|
|
public function sendMessage()
|
|
{
|
|
if ($this->hookVal(Tools::getValue('controller', false), 'contact')) {
|
|
$this->captchaVal($this->context->controller->errors);
|
|
}
|
|
if ($this->context->controller->errors)
|
|
return false;
|
|
$extension = array('.txt', '.rtf', '.doc', '.docx', '.pdf', '.zip', '.png', '.jpeg', '.gif', '.jpg');
|
|
$file_attachment = Tools::fileAttachment('fileUpload');
|
|
$message = Tools::getValue('message');
|
|
|
|
if (!($from = trim(Tools::getValue('from'))) || !Validate::isEmail($from)) {
|
|
$this->context->controller->errors[] = $this->l('Invalid email address.');
|
|
} elseif (!$message) {
|
|
$this->context->controller->errors[] = $this->l('The message cannot be blank.');
|
|
} elseif (!Validate::isCleanHtml($message)) {
|
|
$this->context->controller->errors[] = $this->l('Invalid message');
|
|
} elseif (!($id_contact = (int)Tools::getValue('id_contact')) || !(Validate::isLoadedObject($contact = new Contact($id_contact, $this->context->language->id)))) {
|
|
$this->context->controller->errors[] = $this->l('Please select a subject from the list provided. ');
|
|
} elseif (!empty($file_attachment['name']) && $file_attachment['error'] != 0) {
|
|
$this->context->controller->errors[] = $this->l('An error occurred during the file-upload process.');
|
|
} elseif (!empty($file_attachment['name']) && !in_array(Tools::strtolower(Tools::substr($file_attachment['name'], -4)), $extension) && !in_array(Tools::strtolower(Tools::substr($file_attachment['name'], -5)), $extension)) {
|
|
$this->context->controller->errors[] = $this->l('Bad file extension');
|
|
} else {
|
|
$customer = $this->context->customer;
|
|
if (!$customer->id) {
|
|
$customer->getByEmail($from);
|
|
}
|
|
|
|
$id_order = (int)Tools::getValue('id_order');
|
|
|
|
$id_customer_thread = CustomerThread::getIdCustomerThreadByEmailAndIdOrder($from, $id_order);
|
|
|
|
if ($contact->customer_service) {
|
|
if ((int)$id_customer_thread) {
|
|
$ct = new CustomerThread($id_customer_thread);
|
|
$ct->status = 'open';
|
|
$ct->id_lang = (int)$this->context->language->id;
|
|
$ct->id_contact = (int)$id_contact;
|
|
$ct->id_order = (int)$id_order;
|
|
if ($id_product = (int)Tools::getValue('id_product')) {
|
|
$ct->id_product = $id_product;
|
|
}
|
|
$ct->update();
|
|
} else {
|
|
$ct = new CustomerThread();
|
|
if (isset($customer->id)) {
|
|
$ct->id_customer = (int)$customer->id;
|
|
}
|
|
$ct->id_shop = (int)$this->context->shop->id;
|
|
$ct->id_order = (int)$id_order;
|
|
if ($id_product = (int)Tools::getValue('id_product')) {
|
|
$ct->id_product = $id_product;
|
|
}
|
|
$ct->id_contact = (int)$id_contact;
|
|
$ct->id_lang = (int)$this->context->language->id;
|
|
$ct->email = $from;
|
|
$ct->status = 'open';
|
|
$ct->token = Tools::passwdGen(12);
|
|
$ct->add();
|
|
}
|
|
|
|
if ($ct->id) {
|
|
|
|
$lastMessage = CustomerMessage::getLastMessageForCustomerThread($ct->id);
|
|
$testFileUpload = (isset($file_attachment['rename']) && !empty($file_attachment['rename']));
|
|
|
|
// if last message is the same as new message (and no file upload), do not consider this contact
|
|
if ($lastMessage != $message || $testFileUpload) {
|
|
$cm = new CustomerMessage();
|
|
$cm->id_customer_thread = $ct->id;
|
|
$cm->message = $message;
|
|
if ($testFileUpload && rename($file_attachment['tmp_name'], _PS_UPLOAD_DIR_ . basename($file_attachment['rename']))) {
|
|
$cm->file_name = $file_attachment['rename'];
|
|
@chmod(_PS_UPLOAD_DIR_ . basename($file_attachment['rename']), 0664);
|
|
}
|
|
$cm->ip_address = (int)ip2long(Tools::getRemoteAddr());
|
|
$cm->user_agent = $_SERVER['HTTP_USER_AGENT'];
|
|
if (!$cm->add()) {
|
|
$this->context->controller->errors[] = $this->l('An error occurred while sending the message.');
|
|
}
|
|
} else {
|
|
$mailAlreadySend = true;
|
|
}
|
|
} else {
|
|
$this->context->controller->errors[] = $this->l('An error occurred while sending the message.');
|
|
}
|
|
}
|
|
$sendConfirmationEmail = Module::isEnabled('contactform') && (Configuration::hasKey(self::SEND_CONFIRMATION_EMAIL) || Configuration::hasKey(self::SEND_CONFIRMATION_EMAIL, null, $this->context->shop->id_shop_group, $this->context->shop->id)) ? (int)Configuration::get(self::SEND_CONFIRMATION_EMAIL) : 1;
|
|
$sendNotificationEmail = Module::isEnabled('contactform') && (Configuration::hasKey(self::SEND_NOTIFICATION_EMAIL) || Configuration::hasKey(self::SEND_NOTIFICATION_EMAIL, null, $this->context->shop->id_shop_group, $this->context->shop->id)) ? (int)Configuration::get(self::SEND_NOTIFICATION_EMAIL) : 1;
|
|
|
|
if (!count($this->context->controller->errors)
|
|
&& empty($mailAlreadySend)
|
|
&& ($sendConfirmationEmail || $sendNotificationEmail)
|
|
) {
|
|
$var_list = array(
|
|
'{order_name}' => '-',
|
|
'{attached_file}' => '-',
|
|
'{message}' => Tools::nl2br(Tools::stripslashes($message)),
|
|
'{email}' => $from,
|
|
'{product_name}' => '',
|
|
);
|
|
|
|
if (isset($file_attachment['name'])) {
|
|
$var_list['{attached_file}'] = $file_attachment['name'];
|
|
}
|
|
|
|
$id_product = (int)Tools::getValue('id_product');
|
|
|
|
if (isset($ct) && Validate::isLoadedObject($ct) && $ct->id_order) {
|
|
$order = new Order((int)$ct->id_order);
|
|
$var_list['{order_name}'] = $order->getUniqReference();
|
|
$var_list['{id_order}'] = (int)$order->id;
|
|
}
|
|
|
|
if ($id_product) {
|
|
$product = new Product((int)$id_product);
|
|
if (Validate::isLoadedObject($product) && isset($product->name[Context::getContext()->language->id])) {
|
|
$var_list['{product_name}'] = $product->name[Context::getContext()->language->id];
|
|
}
|
|
}
|
|
|
|
if (empty($contact->email) && $sendConfirmationEmail) {
|
|
Mail::Send(
|
|
$this->context->language->id,
|
|
'contact_form',
|
|
((isset($ct) && Validate::isLoadedObject($ct)) ? sprintf($this->l('Your message has been correctly sent #ct%s #tc%s'), $ct->id, $ct->token) : $this->l('Your message has been correctly sent')),
|
|
$var_list,
|
|
$from,
|
|
null,
|
|
null,
|
|
null,
|
|
$file_attachment
|
|
);
|
|
} elseif ($contact->email) {
|
|
if ($sendNotificationEmail && !Mail::Send(
|
|
$this->context->language->id,
|
|
'contact',
|
|
$this->l('Message from contact form') . ' [no_sync]',
|
|
$var_list,
|
|
$contact->email,
|
|
$contact->name,
|
|
null,
|
|
null,
|
|
$file_attachment,
|
|
null,
|
|
_PS_MAIL_DIR_,
|
|
false,
|
|
null,
|
|
null,
|
|
$from
|
|
) || $sendConfirmationEmail && !Mail::Send(
|
|
$this->context->language->id,
|
|
'contact_form',
|
|
((isset($ct) && Validate::isLoadedObject($ct)) ? sprintf($this->l('Your message has been correctly sent #ct%s #tc%s'), $ct->id, $ct->token) : $this->l('Your message has been correctly sent')),
|
|
$var_list,
|
|
$from,
|
|
null,
|
|
null,
|
|
null,
|
|
$file_attachment,
|
|
null,
|
|
_PS_MAIL_DIR_,
|
|
false,
|
|
null,
|
|
null,
|
|
$contact->email
|
|
)) {
|
|
$this->context->controller->errors[] = $this->l('An error occurred while sending the message.');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!count($this->context->controller->errors)) {
|
|
$this->context->controller->success[] = $this->l('Your message has been successfully sent to our team.');
|
|
}
|
|
}
|
|
}
|
|
|
|
public function getTemplateVarContact()
|
|
{
|
|
$contacts = array();
|
|
$all_contacts = Contact::getContacts($this->context->language->id);
|
|
|
|
foreach ($all_contacts as $one_contact) {
|
|
$contacts[$one_contact['id_contact']] = $one_contact;
|
|
}
|
|
|
|
if ($this->customer_thread['id_contact']) {
|
|
$contacts_arr = array();
|
|
$contacts_arr[] = $contacts[$this->customer_thread['id_contact']];
|
|
return $contacts_arr;
|
|
}
|
|
|
|
return $contacts;
|
|
}
|
|
|
|
public function getTemplateVarOrders()
|
|
{
|
|
$orders = array();
|
|
|
|
if (!isset($this->customer_thread['id_order']) && $this->context->customer->isLogged()) {
|
|
$customer_orders = Order::getCustomerOrders($this->context->customer->id);
|
|
foreach ($customer_orders as $customer_order) {
|
|
$myOrder = new Order((int)$customer_order['id_order']);
|
|
if (Validate::isLoadedObject($myOrder)) {
|
|
$orders[$customer_order['id_order']] = $customer_order;
|
|
$orders[$customer_order['id_order']]['products'] = $myOrder->getProducts();
|
|
}
|
|
}
|
|
} elseif ((int)$this->customer_thread['id_order'] > 0) {
|
|
$myOrder = new Order($this->customer_thread['id_order']);
|
|
if (Validate::isLoadedObject($myOrder)) {
|
|
$orders[$myOrder->id] = $this->context->controller->objectPresenter->present($myOrder);
|
|
$orders[$myOrder->id]['id_order'] = $myOrder->id;
|
|
$orders[$myOrder->id]['products'] = $myOrder->getProducts();
|
|
}
|
|
}
|
|
|
|
if ($this->customer_thread['id_product']) {
|
|
$id_order = 0;
|
|
if (isset($this->customer_thread['id_order'])) {
|
|
$id_order = (int)$this->customer_thread['id_order'];
|
|
}
|
|
$orders[$id_order]['products'][(int)$this->customer_thread['id_product']] = $this->context->controller->objectPresenter->present(new Product((int)$this->customer_thread['id_product']));
|
|
}
|
|
|
|
return $orders;
|
|
}
|
|
|
|
public function hookVal($page, $posTo)
|
|
{
|
|
if ($this->context->customer->isLogged() && Configuration::get('PA_CAPTCHA_OFF_CUSTOMER_LOGIN') || !$posTo)
|
|
return false;
|
|
$position = ($result = Configuration::get('PA_CAPTCHA_POSITION')) != '' ? explode(',', $result) : false;
|
|
if (!$position)
|
|
return false;
|
|
if (in_array($posTo, $position)) {
|
|
switch ($posTo) {
|
|
case 'newsletter':
|
|
if ((Module::isEnabled('ps_emailsubscription') || Module::isEnabled('blocknewsletter')))
|
|
return true;
|
|
break;
|
|
case 'out_of_stock':
|
|
if ($page == 'product' && (Module::isEnabled('ps_emailalerts') || Module::isEnabled('mailalerts')))
|
|
return true;
|
|
break;
|
|
case 'register':
|
|
case 'login':
|
|
if (($this->is17 || !Configuration::get('PS_ORDER_PROCESS_TYPE') || Configuration::get('PA_CAPTCHA_TYPE') != 'google') && in_array($page, self::$pages))
|
|
return true;
|
|
break;
|
|
default:
|
|
if (in_array($page, self::$pages))
|
|
return true;
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function captchaVal(&$errors)
|
|
{
|
|
if (($captcha_type = Configuration::get('PA_CAPTCHA_TYPE')) == 'google' || $captcha_type == 'google_v3') {
|
|
if (Tools::getIsset('g-recaptcha-response') && ($reCaptcha = Tools::getValue('g-recaptcha-response'))) {
|
|
$secret = Configuration::get('PA_GOOGLE' . ($captcha_type == 'google_v3' ? '_V3' : '') . '_CAPTCHA_SECRET_KEY');
|
|
$site_verify = "https://www.google.com/recaptcha/api/siteverify";
|
|
$query_build = http_build_query(array(
|
|
'secret' => $secret,
|
|
'response' => $reCaptcha
|
|
));
|
|
$curl_timeout = 5;
|
|
$this->refreshCACertFile();
|
|
$stream_context = @stream_context_create(array(
|
|
'http' => array('timeout' => $curl_timeout),
|
|
'ssl' => array(
|
|
'verify_peer' => true,
|
|
'cafile' => $this->getBundledCaBundlePath(),
|
|
),
|
|
));
|
|
$response = Tools::file_get_contents($site_verify . '?' . $query_build, false, $stream_context, $curl_timeout);
|
|
$response = Tools::jsonDecode($response);
|
|
if (!$response || (property_exists($response, 'success') && $response->success == false) || (property_exists($response, 'score') && $response->score < 0.5)) {
|
|
$errors[] = $this->l('reCaptcha is invalid.');
|
|
}
|
|
} else
|
|
$errors[] = $this->l('reCaptcha error');
|
|
if (!Tools::getIsset('g-recaptcha-response')) {
|
|
die(Tools::jsonEncode(array(
|
|
'error' => true,
|
|
'message' => $this->l('404 not found!'),
|
|
)));
|
|
}
|
|
} else {
|
|
$antiHack = true;
|
|
if (($posTo = Tools::getValue('posTo', false))) {
|
|
$security = ($captcha = self::PREFIX_CODE . $posTo) && isset($this->context->cookie->{$captcha}) && ($cookieVal = $this->context->cookie->{$captcha}) ? $cookieVal : false;
|
|
$pa_captcha = Tools::getIsset('pa_captcha') && ($val = Tools::getValue('pa_captcha', false)) ? Tools::strtolower(trim($val)) : false;
|
|
if (!$security || ($security !== $pa_captcha)) {
|
|
$errors[] = $this->l('Security code does not match');
|
|
}
|
|
if (!(isset($this->context->cookie->{$captcha})))
|
|
$antiHack = false;
|
|
}
|
|
if (!Tools::getIsset('pa_captcha') || !Tools::getIsset('posTo') || !$antiHack) {
|
|
die(Tools::jsonEncode(array(
|
|
'error' => true,
|
|
'message' => $this->l('404 not found!'),
|
|
)));
|
|
}
|
|
}
|
|
|
|
if (!$errors) {
|
|
if ($this->ipBlackList(Configuration::get('PA_CAPTCHA_IP_BLACKLIST'))) {
|
|
$errors[] = $this->l('Your IP is blocked. Contact webmaster for more info.');
|
|
} elseif ($this->emailBlackList(Configuration::get('PA_CAPTCHA_EMAIL_BLACKLIST'))) {
|
|
$errors[] = $this->l('Your email is blocked. Contact webmaster for more info.');
|
|
}
|
|
}
|
|
}
|
|
|
|
public function ipBlackList($ip_blacklist)
|
|
{
|
|
if (!$ip_blacklist)
|
|
return false;
|
|
$remote_addr = Tools::getRemoteAddr();
|
|
$ips = explode("\n", $ip_blacklist);
|
|
if ($ips) {
|
|
foreach ($ips as $ip) {
|
|
if (preg_match('/^' . $this->formatPattern($ip) . '$/', $remote_addr)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function emailBlackList($email_blacklist)
|
|
{
|
|
if (!$email_blacklist || !($email = Tools::getValue('email', Tools::getValue('from'))))
|
|
return false;
|
|
$emails = explode("\n", $email_blacklist);
|
|
if ($emails) {
|
|
foreach ($emails as $pattern) {
|
|
if (preg_match('/^' . $this->formatPattern($pattern) . '$/', $email)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function formatPattern($pattern)
|
|
{
|
|
return str_replace('*', '(.*)', trim($pattern));
|
|
}
|
|
|
|
public function refreshCACertFile()
|
|
{
|
|
if ((time() - @filemtime($this->local_path . 'cache/cacert.pem') > 0)) {
|
|
$stream_context = @stream_context_create(array(
|
|
'http' => array('timeout' => 3),
|
|
'ssl' => array(
|
|
'cafile' => $this->getBundledCaBundlePath(),
|
|
),
|
|
));
|
|
$ca_cert_content = Tools::file_get_contents(self::CACERT_LOCATION, false, $stream_context);
|
|
if (empty($ca_cert_content)) {
|
|
$ca_cert_content = Tools::file_get_contents($this->getBundledCaBundlePath());
|
|
}
|
|
if (preg_match('/(.*-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE-----){50}$/Uims', $ca_cert_content) && Tools::substr(rtrim($ca_cert_content), -1) == '-') {
|
|
@file_put_contents(_PS_CACHE_CA_CERT_FILE_, $ca_cert_content);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function getBundledCaBundlePath()
|
|
{
|
|
$caBundleFile = $this->local_path . 'cache/cacert.pem';
|
|
if (0 === strpos($caBundleFile, 'phar://')) {
|
|
@file_put_contents(
|
|
$tempCaBundleFile = tempnam(sys_get_temp_dir(), 'openssl-ca-bundle-'),
|
|
Tools::file_get_contents($caBundleFile)
|
|
);
|
|
register_shutdown_function(function () use ($tempCaBundleFile) {
|
|
@unlink($tempCaBundleFile);
|
|
});
|
|
$caBundleFile = $tempCaBundleFile;
|
|
}
|
|
return $caBundleFile;
|
|
}
|
|
|
|
public function getOverrides()
|
|
{
|
|
if (!$this->is17) {
|
|
if (!is_dir($this->getLocalPath() . 'override')) {
|
|
return null;
|
|
}
|
|
$autoload = ($this->is16 ? 'PrestaShop' : '') . 'Autoload';
|
|
$result = array();
|
|
foreach (Tools::scandir($this->getLocalPath() . 'override', 'php', '', true) as $file) {
|
|
$class = basename($file, '.php');
|
|
if ($autoload::getInstance()->getClassPath($class . 'Core') || Module::getModuleIdByName($class)) {
|
|
$result[] = $class;
|
|
}
|
|
}
|
|
return $result;
|
|
} else
|
|
return parent::getOverrides();
|
|
}
|
|
|
|
public function addOverride($classname)
|
|
{
|
|
$_errors = array();
|
|
$autoload = ($this->is16 ? 'PrestaShop' : '') . 'Autoload';
|
|
$orig_path = $path = $autoload::getInstance()->getClassPath($classname . 'Core');
|
|
if (!$path) {
|
|
$path = 'modules' . DIRECTORY_SEPARATOR . $classname . DIRECTORY_SEPARATOR . $classname . '.php';
|
|
}
|
|
$path_override = $this->getLocalPath() . 'override' . DIRECTORY_SEPARATOR . $path;
|
|
if (!@file_exists($path_override)) {
|
|
return true;
|
|
} else {
|
|
@file_put_contents($path_override, preg_replace('#(\r\n|\r)#ism', "\n", Tools::file_get_contents($path_override)));
|
|
}
|
|
$pattern_escape_com = '#(^\s*?\/\/.*?\n|\/\*(?!\n\s+\* module:.*?\* date:.*?\* version:.*?\*\/).*?\*\/)#ism';
|
|
if ($file = $autoload::getInstance()->getClassPath($classname)) {
|
|
$override_path = _PS_ROOT_DIR_ . '/' . $file;
|
|
|
|
if ((!@file_exists($override_path) && !is_writable(dirname($override_path))) || (@file_exists($override_path) && !is_writable($override_path))) {
|
|
$_errors[] = sprintf($this->l('file (%s) is not writable'), $override_path);
|
|
}
|
|
do {
|
|
$uniq = uniqid();
|
|
} while (@class_exists($classname . 'OverrideOriginal_remove', false));
|
|
|
|
$override_file = file($override_path);
|
|
$override_file = array_diff($override_file, array("\n"));
|
|
$this->execEval(preg_replace(array('#^\s*<\?(?:php)?#', '#class\s+' . $classname . '\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?#i'), array(' ', 'class ' . $classname . 'OverrideOriginal' . $uniq), implode('', $override_file)));
|
|
$override_class = new ReflectionClass($classname . 'OverrideOriginal' . $uniq);
|
|
|
|
$module_file = file($path_override);
|
|
$module_file = array_diff($module_file, array("\n"));
|
|
$this->execEval(preg_replace(array('#^\s*<\?(?:php)?#', '#class\s+' . $classname . '(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'), array(' ', 'class ' . $classname . 'Override' . $uniq), implode('', $module_file)));
|
|
$module_class = new ReflectionClass($classname . 'Override' . $uniq);
|
|
|
|
foreach ($module_class->getMethods() as $method) {
|
|
if ($override_class->hasMethod($method->getName())) {
|
|
$method_override = $override_class->getMethod($method->getName());
|
|
if (preg_match('/module: (.*)/ism', $override_file[$method_override->getStartLine() - 5], $name) && preg_match('/date: (.*)/ism', $override_file[$method_override->getStartLine() - 4], $date) && preg_match('/version: ([0-9.]+)/ism', $override_file[$method_override->getStartLine() - 3], $version)) {
|
|
$_errors[] = sprintf($this->l('The method %1$s in the class %2$s is already overridden by the module %3$s version %4$s at %5$s.'), $method->getName(), $classname, $name[1], $version[1], $date[1]);
|
|
} else {
|
|
$_errors[] = sprintf($this->l('The method %1$s in the class %2$s is already overridden.'), $method->getName(), $classname);
|
|
}
|
|
}
|
|
$module_file = preg_replace('/((:?public|private|protected)\s+(static\s+)?function\s+(?:\b' . $method->getName() . '\b))/ism', "/*\n * module: " . $this->name . "\n * date: " . date('Y-m-d H:i:s') . "\n * version: " . $this->version . "\n */\n $1", $module_file);
|
|
if ($module_file === null) {
|
|
$_errors[] = sprintf($this->l('Failed to override method %1$s in class %2$s.'), $method->getName(), $classname);
|
|
}
|
|
}
|
|
if (!$_errors) {
|
|
$copy_from = array_slice($module_file, $module_class->getStartLine() + 1, $module_class->getEndLine() - $module_class->getStartLine() - 2);
|
|
array_splice($override_file, $override_class->getEndLine() - 1, 0, $copy_from);
|
|
$code = implode('', $override_file);
|
|
|
|
@file_put_contents($override_path, preg_replace($pattern_escape_com, '', $code));
|
|
}
|
|
} else {
|
|
$override_src = $path_override;
|
|
$override_dest = _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'override' . DIRECTORY_SEPARATOR . $path;
|
|
$dir_name = dirname($override_dest);
|
|
if (!$orig_path && !is_dir($dir_name)) {
|
|
$oldumask = umask(0000);
|
|
@mkdir($dir_name, 0777);
|
|
umask($oldumask);
|
|
}
|
|
if (!is_writable($dir_name)) {
|
|
$_errors[] = sprintf($this->l('directory (%s) is not writable'), $dir_name);
|
|
}
|
|
$module_file = file($override_src);
|
|
$module_file = array_diff($module_file, array("\n"));
|
|
if ($orig_path) {
|
|
do {
|
|
$uniq = uniqid();
|
|
} while (@class_exists($classname . 'OverrideOriginal_remove', false));
|
|
$this->execEval(preg_replace(array('#^\s*<\?(?:php)?#', '#class\s+' . $classname . '(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'), array(' ', 'class ' . $classname . 'Override' . $uniq), implode('', $module_file)));
|
|
$module_class = new ReflectionClass($classname . 'Override' . $uniq);
|
|
|
|
foreach ($module_class->getMethods() as $method) {
|
|
$module_file = preg_replace('/((:?public|private|protected)\s+(static\s+)?function\s+(?:\b' . $method->getName() . '\b))/ism', "/*\n * module: " . $this->name . "\n * date: " . date('Y-m-d H:i:s') . "\n * version: " . $this->version . "\n */\n $1", $module_file);
|
|
if ($module_file === null) {
|
|
$_errors[] = sprintf($this->l('Failed to override method %1$s in class %2$s.'), $method->getName(), $classname);
|
|
}
|
|
}
|
|
}
|
|
if (!$_errors) {
|
|
@file_put_contents($override_dest, preg_replace($pattern_escape_com, '', $module_file));
|
|
$this->generateIndex();
|
|
}
|
|
}
|
|
if ($_errors)
|
|
$this->logInstall($classname, $_errors);
|
|
return true;
|
|
}
|
|
|
|
public function generateIndex()
|
|
{
|
|
if ($this->is16) {
|
|
Tools::generateIndex();
|
|
} else {
|
|
Autoload::getInstance()->generateIndex();
|
|
}
|
|
}
|
|
|
|
public function execEval($php_code)
|
|
{
|
|
if (function_exists('ets_captcha_excelVal')) {
|
|
return call_user_func('ets_captcha_excelVal', $php_code);
|
|
} else {
|
|
$temp = @tempnam($this->getLocalPath() . 'cache', 'execEval');
|
|
$handle = fopen($temp, "w+");
|
|
fwrite($handle, "<?php\n" . $php_code);
|
|
fclose($handle);
|
|
include $temp;
|
|
@unlink($temp);
|
|
}
|
|
}
|
|
|
|
public function removeOverride($classname)
|
|
{
|
|
if ($this->isLogInstall($classname))
|
|
return true;
|
|
$autoload = ($this->is16 ? 'PrestaShop' : '') . 'Autoload';
|
|
$orig_path = $path = $autoload::getInstance()->getClassPath($classname . 'Core');
|
|
if ($orig_path && !$file = $autoload::getInstance()->getClassPath($classname))
|
|
return true;
|
|
elseif (!$orig_path && Module::getModuleIdByName($classname))
|
|
$path = 'modules' . DIRECTORY_SEPARATOR . $classname . DIRECTORY_SEPARATOR . $classname . '.php';
|
|
$override_path = $orig_path ? _PS_ROOT_DIR_ . '/' . $file : _PS_OVERRIDE_DIR_ . $path;
|
|
if (!@is_file($override_path) || !is_writable($override_path))
|
|
return true;
|
|
return parent::removeOverride($classname);
|
|
}
|
|
|
|
public function logInstall($classname, $_errors)
|
|
{
|
|
$log_file = $this->getLocalPath() . self::$log_file;
|
|
$data = array();
|
|
if (@file_exists($log_file))
|
|
$data = (array)Tools::jsonDecode(Tools::file_get_contents($log_file));
|
|
$data[$classname] = $_errors;
|
|
@file_put_contents($log_file, Tools::jsonEncode($data));
|
|
}
|
|
|
|
public function isLogInstall($classname)
|
|
{
|
|
$log_file = $this->getLocalPath() . self::$log_file;
|
|
if (!@file_exists($log_file))
|
|
return false;
|
|
$cached = (array)Tools::jsonDecode(Tools::file_get_contents($log_file));
|
|
if ($cached && !empty($cached[$classname]))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
public function clearLogInstall()
|
|
{
|
|
$log_file = $this->getLocalPath() . self::$log_file;
|
|
if (@file_exists($log_file))
|
|
@unlink($log_file);
|
|
Configuration::deleteByName('PA_CAPTCHA_ERROR_IS_FIXED');
|
|
return true;
|
|
}
|
|
|
|
public function displayLogInstall()
|
|
{
|
|
$log_file = $this->getLocalPath() . self::$log_file;
|
|
if (!@file_exists($log_file))
|
|
return false;
|
|
$errors = (array)Tools::jsonDecode(Tools::file_get_contents($log_file));
|
|
if ($errors) {
|
|
$this->smarty->assign(array(
|
|
'PA_CAPTCHA_ERROR_IS_FIXED' => (int)Configuration::get('PA_CAPTCHA_ERROR_IS_FIXED'),
|
|
'link' => $this->_path . self::$log_file,
|
|
'errors' => $errors,
|
|
));
|
|
return $this->display(__FILE__, 'bo-log.tpl');
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} |