Files
bio-concept-labo/web/modules/ets_advancedcaptcha/ets_advancedcaptcha.php

1759 lines
77 KiB
PHP

<?php
/**
* 2007-2019 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-2019 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 $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 $link_capcha;
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.5';
$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');
} else {
if (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_TMP_CONTACT' => array(
'label' => $this->l('Disable template overrides contact form'),
'type' => 'switch',
'default' => '0',
'unset' => $this->is17 ? 1 : 0,
'desc' => $this->l('Enable this to use contact-form.tpl file of your theme (keep your custom contact form design and its translation). You will need to add a custom hook to your contact-form.tpl file MANUALLY.'),
'tab' => 'captcha',
),
'PA_CAPTCHA_TMP_LOGIN' => array(
'label' => $this->l('Disable template overrides Login form'),
'type' => 'switch',
'default' => '0',
'unset' => $this->is17 ? 1 : 0,
'desc' => $this->l('Enable this to use authentication.tpl file of your theme (keep your custom login form design and its translation). You will need to add a custom hook to your authentication.tpl file MANUALLY.'),
'tab' => 'captcha',
),
'PA_CAPTCHA_TMP_RE_PASSWORD' => array(
'label' => $this->l('Disable template overrides Forgot your password form'),
'type' => 'switch',
'default' => '0',
'unset' => $this->is17 ? 1 : 0,
'desc' => $this->l('Enable this to use password.tpl file of your theme (keep your custom password recovery form design and its translation). You will need to add a custom hook to your password.tpl file MANUALLY.'),
'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',
)
);
}
/**
* @param $key
* @param $class
* @return bool
*/
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);
}
/**
* @return bool
*/
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();
}
/**
* @param $src
* @param $dst
* @return bool
*/
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);
}
/**
* @return bool
*/
public function registerHooks()
{
$res = true;
if (self::$hooks) {
foreach (self::$hooks as $hook)
$res &= $this->registerHook($hook);
}
return $res;
}
/**
* @see Module::install()
*/
public function install()
{
$this->overrideClass();
return parent::install()
&& $this->registerHooks()
&& $this->installConfig()
&& $this->configGDPR();
}
public function configGDPR($install = true)
{
if (Module::isInstalled('psgdpr') && $this->id) {
$id_module = Db::getInstance()->getValue('SELECT id_module FROM `' . _DB_PREFIX_ . 'psgdpr_consent` psgdpr WHERE id_module = ' . (int)$this->id);
if (!$id_module && $install) {
Db::getInstance()->execute("
INSERT INTO `" . _DB_PREFIX_ . "psgdpr_consent` (id_module, active, error, error_message, date_add, date_upd)
VALUES(" . (int)$this->id . ", 1, '', '', '" . date('Y-m-d H:i:s') . "', '" . date('Y-m-d H:i:s') . "')"
);
}
if ($id_module && !$install) {
Db::getInstance()->execute("DELETE FROM `" . _DB_PREFIX_ . "psgdpr_consent` WHERE id_module = " . (int)$this->id);
}
}
return true;
}
/**
* @see Module::uninstall()
*/
public function uninstall()
{
return parent::uninstall() && $this->uninstallConfig() && $this->clearLogInstall() && $this->configGDPR(false);
}
/**
* @param bool $upgrade
* @return bool
*/
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;
}
/**
* @return bool
*/
protected function uninstallConfig()
{
if ($this->configs) {
foreach ($this->configs as $key => $config) {
Configuration::deleteByName($key);
}
unset($config);
}
return true;
}
/**
*
*/
public function hookDisplayBackOfficeHeader()
{
if (Tools::strtolower(trim(Tools::getValue('controller'))) == 'adminmodules' && Tools::getValue('configure') == $this->name) {
$this->context->controller->addCss(array(
$this->_path . 'views/css/admin.css',
$this->_path . 'views/css/font-awesome.min.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;
}
}
/**
* @return string
*/
public function hookDisplayHeader()
{
if ((($pos = explode(',', Configuration::get('PA_CAPTCHA_POSITION'))) && (in_array('newsletter', $pos) || in_array('out_of_stock', $pos))) || in_array(Tools::getValue('controller', false), self::$pages)) {
$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');
}
}
}
/**
* @param bool $js
* @return array|string
*/
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;
}
/**
* @param $key
* @return bool
*/
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;
}
/**
* @param $errors
* @throws PrestaShopDatabaseException
* @throws PrestaShopException
*/
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));
}
}
/**
* @throws PrestaShopDatabaseException
* @throws PrestaShopException
*/
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 = array(
'name' => $key,
'type' => $config['type'],
'label' => $config['label'],
'desc' => isset($config['desc']) ? $config['desc'] : false,
'col' => isset($config['col']) && $config['col'] ? $config['col'] : 9,
'required' => isset($config['required']) && $config['required'] ? true : false,
'autoload_rte' => isset($config['autoload_rte']) && $config['autoload_rte'] ? true : false,
'options' => isset($config['options']) && $config['options'] ? $config['options'] : array(),
'suffix' => isset($config['suffix']) && $config['suffix'] ? $config['suffix'] : false,
'multiple' => isset($config['multiple']) ? $config['multiple'] : false,
'rows' => isset($config['rows']) ? $config['rows'] : false,
'cols' => isset($config['cols']) ? $config['cols'] : false,
'validate' => isset($config['validate']) ? $config['validate'] : false,
'values' => isset($config['values']) ? $config['values'] : ($config['type'] == 'switch' ? array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
) : false),
'lang' => isset($config['lang']) ? $config['lang'] : false,
'tab' => isset($config['tab']) ? $config['tab'] : false,
);
if (isset($config['tab']))
$confFields['tab'] = $config['tab'];
if (isset($config['tree']))
$confFields['tree'] = $config['tree'];
if (!$confFields['suffix'])
unset($confFields['suffix']);
if (!$confFields['cols'])
unset($confFields['cols']);
if (!$confFields['rows'])
unset($confFields['rows']);
if (!$confFields['values'])
unset($confFields['values']);
if (!$confFields['validate'])
unset($confFields['validate']);
if (!$confFields['multiple'])
unset($confFields['multiple']);
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 = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
$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' => $this->context->link->getAdminLink('AdminModules', true) . '&configure=' . $this->name.'&othermodules=1',
'intro' => $intro,
);
$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();
}
/**
* @param $key
* @return string
*/
public function generateHTML($key)
{
$this->smarty->assign(array(
'key' => $key,
'is17' => $this->is17,
'path' => $this->_path,
));
return $this->display(__FILE__, 'gen-html.tpl');
}
/**
* @return bool|string
*/
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__, 'admin-form.tpl');
}
/**
* @param int $conf
* @return string
* @throws PrestaShopException
*/
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;
}
/**
* @param $params
* @return bool|string
*/
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);
}
}
/**
* @param $params
* @return bool|string
*/
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');
}
/**
* @return bool|string
*/
public function hookDisplayCustomerAccountForm()
{
return $this->hookDisplayPaCaptcha(array(
'posTo' => 'register'
));
}
/**
* @return bool|string
*/
public function hookDisplayReassurance()
{
if ($this->is17 && Tools::getValue('controller', false) == 'order') {
return $this->hookDisplayPaCaptcha(array(
'posTo' => 'login'
));
}
}
/**
* @param $params
* @return string
*/
public function hookDisplayOverrideTemplate($params)
{
if (isset($params['template_file']) && $params['template_file']) {
if (Tools::strpos($params['template_file'], 'contact') !== false) {
return $this->getTemplatePath('contact.tpl');
} elseif (Tools::strpos($params['template_file'], 'authentication') !== false) {
return $this->getTemplatePath('authentication.tpl');
} elseif (Tools::strpos($params['template_file'], 'password-email') !== false) {
return $this->getTemplatePath('password-email.tpl');
}
}
}
/**
* @param null $hookName
* @param array $configuration
* @return string
* @throws PrestaShopDatabaseException
* @throws PrestaShopException
*/
public function renderWidget($hookName = null, array $configuration = array())
{
if (($page = Tools::getValue('controller', false)) && Tools::strpos($page, 'contact') !== false) {
$this->smarty->assign($this->getWidgetVariables($hookName, $configuration));
return $this->display(__FILE__, 'contact-form.tpl');
}
}
/**
* @return $this
*/
protected function createNewToken()
{
$this->context->cookie->contactFormToken = md5(uniqid());
$this->context->cookie->contactFormTokenTTL = time() + 600;
return $this;
}
/**
* @param null $hookName
* @param array $configuration
* @return array
* @throws PrestaShopDatabaseException
* @throws PrestaShopException
*/
public function getWidgetVariables($hookName = null, array $configuration = 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();
}
}
}
$this->contact['contacts'] = $this->getTemplateVarContact();
$this->contact['message'] = html_entity_decode(Tools::getValue('message'));
$this->contact['allow_file_upload'] = (bool)Configuration::get('PS_CUSTOMER_SERVICE_FILE_UPLOAD');
if (!(bool)Configuration::isCatalogMode()) {
$this->contact['orders'] = $this->getTemplateVarOrders();
} else {
$this->contact['orders'] = array();
}
if ($this->customer_thread['email']) {
$this->contact['email'] = $this->customer_thread['email'];
} else {
$this->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' => $this->contact,
'notifications' => $notifications,
'token' => $this->context->cookie->contactFormToken,
'id_module' => $this->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.');
}
}
}
/**
* @return array
*/
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;
}
/**
* @return array
* @throws PrestaShopDatabaseException
* @throws PrestaShopException
*/
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;
}
/**
* @param $page
* @param $posTo
* @return bool
*/
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;
}
/**
* @param $errors
*/
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 checkFile($dir, $name, $ver = false)
{
$checkFile = _PS_THEME_DIR_ . 'modules' . DIRECTORY_SEPARATOR . ($baseDir = @str_replace('/', DIRECTORY_SEPARATOR, 'ets_advancedcaptcha/views/templates/') . $dir . DIRECTORY_SEPARATOR . $name . (!$this->is16 && $ver ? '-15' : '') . '.tpl');
if (!@file_exists($checkFile))
$checkFile = _PS_MODULE_DIR_ . $baseDir;
return @file_exists($checkFile) ? ($this->is17 ? 'module:' . $baseDir : $checkFile) : false;
}
/**
* @return array|null
*/
public function getOverrides()
{
if (!$this->is17) {
if (!is_dir($this->getLocalPath() . 'override')) {
return null;
}
$result = array();
foreach (Tools::scandir($this->getLocalPath() . 'override', 'php', '', true) as $file) {
$class = basename($file, '.php');
if (PrestaShopAutoload::getInstance()->getClassPath($class . 'Core') || Module::getModuleIdByName($class)) {
$result[] = $class;
}
}
return $result;
} else
return parent::getOverrides();
}
/**
* @param string $classname
* @return bool
* @throws ReflectionException
*/
public function addOverride($classname)
{
$_errors = array();
$orig_path = $path = PrestaShopAutoload::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 = PrestaShopAutoload::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();
}
}
/**
* @param $php_code
*/
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);
}
}
/**
* @param string $classname
* @return bool
*/
public function removeOverride($classname)
{
if ($this->isLogInstall($classname))
return true;
$orig_path = $path = PrestaShopAutoload::getInstance()->getClassPath($classname . 'Core');
if ($orig_path && !$file = PrestaShopAutoload::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 $log_file = 'install.log';
/**
* @param $classname
* @param $_errors
*/
public function logInstall($classname, $_errors)
{
$log_file = $this->getLocalPath() . $this->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));
}
/**
* @param $classname
* @return bool
*/
public function isLogInstall($classname)
{
$log_file = $this->getLocalPath() . $this->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;
}
/**
* @return bool
*/
public function clearLogInstall()
{
$log_file = $this->getLocalPath() . $this->log_file;
if (@file_exists($log_file))
@unlink($log_file);
Configuration::deleteByName('PA_CAPTCHA_ERROR_IS_FIXED');
return true;
}
/**
* @return bool|string
*/
public function displayLogInstall()
{
$log_file = $this->getLocalPath() . $this->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 . $this->log_file,
'errors' => $errors,
));
return $this->display(__FILE__, 'log.tpl');
}
return false;
}
}