Files
kalsport.pl/modules/eicaptcha/eicaptcha.php
2024-11-05 12:22:50 +01:00

405 lines
12 KiB
PHP

<?php
/**
* 2007-2021 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author Hennes Hervé <contact@h-hennes.fr>
* @copyright 2013-2021 Hennes Hervé
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* http://www.h-hennes.fr/blog/
*/
if (!defined('_PS_VERSION_')) {
exit;
}
require_once dirname(__FILE__) . '/vendor/autoload.php';
use Eicaptcha\Module\ConfigForm;
use Eicaptcha\Module\Debugger;
use Eicaptcha\Module\Installer;
use ReCaptcha\ReCaptcha;
class EiCaptcha extends Module
{
/** @var string */
private $_html = '';
/** @var array */
protected $themes = [];
/**
* @var Debugger
*/
protected $debugger;
/**
* @var Installer
*/
protected $installer;
public function __construct()
{
$this->author = 'hhennes';
$this->name = 'eicaptcha';
$this->tab = 'front_office_features';
$this->version = '2.3.1';
$this->need_instance = 1;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Ei Captcha');
$this->description = $this->l('Add a captcha to your website form');
if (
$this->active
&& (!Configuration::get('CAPTCHA_PUBLIC_KEY') || !Configuration::get('CAPTCHA_PRIVATE_KEY'))
) {
$this->warning = $this->l('Captcha Module need to be configurated');
}
$this->themes = [0 => 'light', 1 => 'dark'];
$this->dependencies = ['contactform'];
$this->ps_versions_compliancy = ['min' => '1.7.0.0', 'max' => _PS_VERSION_];
$this->debugger = new Debugger($this);
}
/**
* Install Module
*
* @return bool
*/
public function install()
{
if (!parent::install()
|| !$this->_getInstaller()->install()
) {
return false;
}
return true;
}
/**
* Uninstall Module
*
* @return bool
*/
public function uninstall()
{
if (!parent::uninstall()
|| !$this->_getInstaller()->uninstall()
) {
return false;
}
return true;
}
/**
* @return Installer
*/
protected function _getInstaller()
{
if (null === $this->installer) {
$this->installer = new Installer($this);
}
return $this->installer;
}
/**
* @return Debugger
*/
public function getDebugger()
{
return $this->debugger;
}
/**
* @return Context
*/
public function getContext()
{
return $this->context;
}
/**
* Module Configuration in Back Office
*
* @return string
*/
public function getContent()
{
$configForm = new ConfigForm($this);
$this->_html .= $this->debugger->checkComposer();
$this->_html .= $configForm->postProcess();
$this->_html .= $configForm->renderForm();
return $this->_html;
}
/**
* Hook Header
*
* @param array $params
*
* @return string|void
*/
public function hookHeader($params)
{
$captchaVersion = Configuration::get('CAPTCHA_VERSION');
//Add Content box to contact form page in order to display captcha
if ($this->context->controller instanceof ContactController
&& Configuration::get('CAPTCHA_ENABLE_CONTACT') == 1
) {
$this->context->controller->registerJavascript(
'modules-eicaptcha-contact-form',
'modules/' . $this->name . '/views/js/eicaptcha-contact-form-v' . $captchaVersion . '.js'
);
}
if ($captchaVersion == 2) {
return $this->renderHeaderV2();
} else {
return $this->renderHeaderV3();
}
}
/**
* Return content for (re)captcha v2
*
* @return string|void
*/
protected function renderHeaderV2()
{
if (($this->context->controller instanceof AuthController && Configuration::get('CAPTCHA_ENABLE_ACCOUNT') == 1) ||
($this->context->controller instanceof ContactController && Configuration::get('CAPTCHA_ENABLE_CONTACT') == 1)
) {
$this->context->controller->registerStylesheet(
'module-eicaptcha',
'modules/' . $this->name . '/views/css/eicaptcha.css'
);
//Dynamic insertion of the content
$js = '<script type="text/javascript">
//Recaptcha CallBack Function
var onloadCallback = function() {
//Fix captcha box issue in ps 1.7.7
if ( ! document.getElementById("captcha-box")){
var container = document.createElement("div");
container.setAttribute("id","captcha-box");
if ( null !== document.querySelector(".form-fields") ){
document.querySelector(".form-fields").appendChild(container);
}
}
if ( document.getElementById("captcha-box")){
grecaptcha.render("captcha-box", {"theme" : "' . $this->themes[Configuration::get('CAPTCHA_THEME')] . '", "sitekey" : "' . Configuration::get('CAPTCHA_PUBLIC_KEY') . '"});
} else {
console.warn("eicaptcha: unable to add captcha-box placeholder to display captcha ( not an error when form is submited sucessfully )");
}
};
</script>';
if (($this->context->controller instanceof ContactController && Configuration::get('CAPTCHA_ENABLE_CONTACT') == 1)) {
$js .= '<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=' . Configuration::get('CAPTCHA_FORCE_LANG') . '" async defer></script>';
}
return $js;
}
}
/**
* Return content for recaptcha v3
*
* @return string|void
*/
public function renderHeaderV3()
{
if (
$this->context->controller instanceof ContactController
&& Configuration::get('CAPTCHA_ENABLE_CONTACT') == 1
) {
$publicKey = Configuration::get('CAPTCHA_PUBLIC_KEY');
$js = '
<script src="https://www.google.com/recaptcha/api.js?render=' . $publicKey . '"></script>
<script>
grecaptcha.ready(function () {
grecaptcha.execute("' . $publicKey . '", {action: "contact"}).then(function (token) {
var recaptchaResponse = document.getElementById("captcha-box");
recaptchaResponse.value = token;
});
});
</script>';
return $js;
}
}
/**
* Add Captcha on the Customer Registration Form
*
* @param array $params
*
* @return string|void
*/
public function hookDisplayCustomerAccountForm($params)
{
if (Configuration::get('CAPTCHA_ENABLE_ACCOUNT') == 1) {
$this->context->smarty->assign([
'captchaVersion' => Configuration::get('CAPTCHA_VERSION'),
'publicKey' => Configuration::get('CAPTCHA_PUBLIC_KEY'),
'captchaforcelang' => Configuration::get('CAPTCHA_FORCE_LANG'),
'captchatheme' => $this->themes[Configuration::get('CAPTCHA_THEME')],
]);
return $this->display(__FILE__, 'views/templates/hook/hookDisplayCustomerAccountForm.tpl');
}
}
/**
* Check captcha before submit account
* Custom hook
*
* @param array $params
*
* @return bool|void
*/
public function hookActionContactFormSubmitCaptcha($params)
{
if (Configuration::get('CAPTCHA_ENABLE_ACCOUNT') == 1) {
return $this->_validateCaptcha();
}
}
/**
* Check captcha before submit contact form
* new custom hook
*
* @return bool|void
*/
public function hookActionContactFormSubmitBefore()
{
if (Configuration::get('CAPTCHA_ENABLE_CONTACT') == 1) {
return $this->_validateCaptcha();
}
}
/**
* Register media in back office
*
* @param array $params
*
* @return void
*
* @since 2.1.0
*/
public function hookActionAdminControllerSetMedia($params)
{
if (
$this->context->controller instanceof AdminModulesController
&& Tools::getValue('configure') == $this->name
&& Tools::getValue('display_debug') == 1
) {
$this->context->controller->addJS(
$this->_path . 'views/js/admin.js'
);
}
}
/**
* New hook to display content for newsletter registration
* ( Need to override theme template for themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl )
*
* @param array $params
*
* @return string|void
*
* @since 2.1.0
*/
public function hookDisplayNewsletterRegistration($params)
{
if (Configuration::get('CAPTCHA_ENABLE_NEWSLETTER') == 1 && $this->canUseCaptchaOnNewsletter()) {
$this->context->smarty->assign([
'captchaVersion' => Configuration::get('CAPTCHA_VERSION'),
'publicKey' => Configuration::get('CAPTCHA_PUBLIC_KEY'),
'captchaforcelang' => Configuration::get('CAPTCHA_FORCE_LANG'),
'captchatheme' => $this->themes[Configuration::get('CAPTCHA_THEME')],
]);
return $this->display(__FILE__, 'views/templates/hook/hookDisplayNewsletterRegistration.tpl');
}
}
/**
* New Hook to validate newsletter registration
*
* @param array $params
*
* @return void
*
* @since 2.1.0
*/
public function hookActionNewsletterRegistrationBefore($params)
{
if (Configuration::get('CAPTCHA_ENABLE_NEWSLETTER') == 1 && $this->canUseCaptchaOnNewsletter()) {
if (!$this->_validateCaptcha()) {
$params['hookError'] = $this->l('Please validate the captcha field before submitting your request');
}
}
}
/**
* Validate Captcha
*
* @return bool
*/
protected function _validateCaptcha()
{
$context = Context::getContext();
$captcha = new ReCaptcha(Configuration::get('CAPTCHA_PRIVATE_KEY'));
$result = $captcha->verify(
Tools::getValue('g-recaptcha-response'),
Tools::getRemoteAddr()
);
if (!$result->isSuccess()) {
$errorMessage = $this->l('Please validate the captcha field before submitting your request');
$this->debugger->log($errorMessage);
$this->debugger->log(sprintf($this->l('Recaptcha response %s'), print_r($result->getErrorCodes(), true)));
$context->controller->errors[] = $errorMessage;
return false;
}
$this->debugger->log($this->l('Captcha submited with success'));
return true;
}
/**
* Define if captcha can be use on newsletter form
* Needs a recent version of ps_emailsubscription which implements new required hooks
*
* @return bool
*/
public function canUseCaptchaOnNewsletter()
{
if (Module::isInstalled('ps_emailsubscription')) {
$emailSubcription = Module::getInstanceByName('ps_emailsubscription');
if (version_compare('2.6.0', $emailSubcription->version) <= 0) {
return true;
}
}
return false;
}
}