1.4 1.5 1.6 1.7 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 8.0 8.1 +
N'hésitez pas à me le signaler si nécessaire via le formulaire de contact.
Afin d’éviter le spam sur vos différents formulaires je recommande en général la mise en place d’un captcha.
Ça fait plusieurs années que j’édite un module de captcha gratuit ( eicaptcha ) qui permets de l’éviter sur les formulaires suivants :
- Formulaire de contact
- Formulaire de création de compte
- Formulaire d’inscription à la newsletter
Celui-ci est disponible sur github et a été téléchargé des dizaines de milliers de fois : https://github.com/nenes25/eicaptcha
Je viens de sortir une nouvelle version de ce module ( 2.4.0 ) qui rajoute une nouvelle fonctionnalité qui permets d’utiliser la vérification du captcha intégrée dans le module directement dans vos modules spécifiques.
Ceci à travers 2 nouvelles méthodes :
hookDisplayEicaptchaVerification : permets de récupérer un template d’affichage complet du captcha ( le captcha s’affiche directement )
hookActionGetEicaptchaParams : permets de récupérer les paramètres nécessaires à l’affichage du captcha ( il est possible de faire un affichage spécifique )
Nous allons voir à travers cet article comment le mettre en place à travers la création d’un module hhcustomform
Le captcha sera implémenté dans 2 situations
- Dans un formulaire sur la fiche produit
- Dans un controller front
Captcha dans un formulaire sur la fiche produit
Pour afficher un formulaire sur la fiche produit nous allons utiliser le hook displayProductExtraContent qui va nous permettre de l’afficher comme sur la capture ci-dessous, directement dans les onglets de la fiche produit.
Voici le code du hook qui va permettre de gérer l’affichage du formulaire dans l’onglet.
La fonction importante du module eicaptcha utilisée est le hook displayEicaptchaVerification qui va permettre de récupérer le contenu nécessaire à l’affichage du captcha dans le formulaire.
/** * [Front office] Affichage des contenus dans les onglets de la fiche produit * @param array $params * @return array */ public function hookDisplayProductExtraContent(array $params) { $return = []; $id_product = $params['product']->id; $return[] = (new PrestaShop\PrestaShop\Core\Product\ProductExtraContent()) ->setTitle($this->l('Customization')) ->setContent($this->getFormContent($id_product)); return $return; } /** * Récupération du contenu du formulaire * @param int $id_product * @return string */ protected function getFormContent(int $id_product): string { try { $smartyParams = [ 'id_product' => $id_product, 'formAction' => $this->context->link->getModuleLink( $this->name, 'form' ), 'backUrl' => $this->context->link->getProductLink( $id_product ), ]; //Gestion de l'affichage du captcha if ($eicaptcha = Module::getInstanceByName('eicaptcha')) { $smartyParams['renderCaptcha'] = $eicaptcha->hookDisplayEicaptchaVerification(['module' => $this->name]); } $this->context->smarty->assign($smartyParams); return $this->context->smarty->fetch( 'module:'.$this->name.'/views/templates/hook/displayProductExtraContent.tpl' ); } catch (Exception $e) { PrestaShopLogger::addLog(__METHOD__ . ' error : ' . $e->getMessage()); } return ''; } |
Voici le fichier tpl views/templates/hook/displayProductExtraContent.tpl qui va gérer l’affichage du formulaire sur la fiche produit.
<div class="hhcustomform--form"> <form name="hhcustomform--customization-form" method="post" action="{$formAction}" class="form"> <input type="hidden" name="id_product" value="{$id_product}"> <input type="hidden" name="submit_form" value="1"> <input type="hidden" name="back" value="{$backUrl}"> <div class="form-group"> <label for="name">{l s='your name' mod='hhcustomform'}</label> <input type="text" name="name" class="form-control" placeholder="{l s='your name' mod='hhcustomform'}" required=""> </div> <div class="form-group"> <label for="email">{l s='your email' mod='hhcustomform'}</label> <input type="email" name="email" class="form-control" placeholder="{l s='your email' mod='hhcustomform'}" required=""> </div> <div class="form-group"> <label for="customization">{l s='your customization' mod='hhcustomform'}</label> <textarea name="customization" class="form-control" rows="4" required="" placeholder="{l s='explain your requested customization' mod='hhcustomform'}"></textarea> </div> {* On utilise la fonctionnalité de eicaptcha *} {$renderCaptcha nofilter} <button type="submit" class="btn btn-primary">{l s='Send' mod='hhcustomform'}</button> </form> </div> |
Captcha dans un controller front
Dans cet exemple j’utilise l’autre fonctionnalité d’affichage du captcha ( hookActionGetEicaptchaParams )
Voici le code du controller controllers/front/form.php qui va appeller le module.
<?php class HhcustomformFormModuleFrontController extends ModuleFrontController { /** * Manage Post Vars */ public function postProcess() { if (Tools::isSubmit('submit_form')) { parent::postProcess(); if (false !== $this->processCustomizationForm()) { $this->success[] = $this->l('Thank you. Your message have been send with success'); } else { $this->errors[] = $this->l('Error when sending your message'); } $redirectUrl = Tools::getValue('back'); if ($redirectUrl) { $this->redirectWithNotifications($redirectUrl); } } } /** * Generate controller breadCrumb * @return array */ public function getBreadcrumbLinks() { $breadcrumb = parent::getBreadcrumbLinks(); $breadcrumb['links'][] = [ 'title' => 'form', 'url' => '#' ]; return $breadcrumb; } /** * Traitement du formulaire * @return bool|int */ protected function processCustomizationForm() { //Captcha validation if ($eicaptcha = Module::getInstanceByName('eicaptcha')) { if (!$eicaptcha->hookActionValidateCaptcha()) { return false; } } //Traitement du formulaire à implémenter return true; } /** * Controller Content * @throws PrestaShopException */ public function initContent() { parent::initContent(); $this->context->smarty->assign( 'formAction', $this->context->link->getModuleLink($this->module->name, 'form') ); //Récupération des paramètres du captcha pour affichage custom if ($eicaptcha = Module::getInstanceByName('eicaptcha')) { $this->context->smarty->assign('captchaParams', $eicaptcha->hookActionGetEicaptchaParams([])); } $this->setTemplate('module:hhcustomform/views/templates/front/form.tpl'); } } |
Et voici le code du template d’affichage associé
{extends file='page.tpl'} {block name="content"} <div class="hhcustomform--form"> <form name="hhcustomform--customization-form" method="post" action="{$formAction}" class="form"> <div class="form-group"> <label for="name">{l s='your name' mod='hhcustomform'}</label> <input type="text" name="name" class="form-control" placeholder="{l s='your name' mod='hhcustomform'}" required=""> </div> <div class="form-group"> <label for="email">{l s='your email' mod='hhcustomform'}</label> <input type="email" name="email" class="form-control" placeholder="{l s='your email' mod='hhcustomform'}" required=""> </div> <div class="form-group"> <label for="customization">{l s='your customization' mod='hhcustomform'}</label> <textarea name="customization" class="form-control" rows="4" required="" placeholder="{l s='explain your requested customization' mod='hhcustomform'}"></textarea> </div> {* On utilise la fonctionnalité de eicaptcha mais avec un formulaire qu'on défini comme on veut *} <div class="form-group row"> {if $captchaParams.captchaVersion == 2} <label class="col-md-3">{l s='Captcha' mod='eicaptcha'}</label> <div class="col-md-9"> <div class="g-recaptcha" data-sitekey="{$captchaParams.publicKey|escape:'html'}" id="captcha-box" data-theme="{$captchaParams.captchatheme}"></div> <script src="https://www.google.com/recaptcha/api.js{if isset($captchaParams.captchaforcelang)}?hl={$captchaParams.captchaforcelang}{/if}" async="" defer=""></script> </div> {else} <input type="hidden" id="captcha-box-custom" name="g-recaptcha-response"> <script src="https://www.google.com/recaptcha/api.js?render={$publicKey|escape:'html'}"></script> <script> grecaptcha.ready(function () {ldelim} grecaptcha.execute('{$captchaParams.publicKey|escape:'html'}', {ldelim}action: 'contact'{rdelim}).then(function (token) {ldelim} var recaptchaResponse = document.getElementById('captcha-box-custom'); recaptchaResponse.value = token; {rdelim}); {rdelim}); </script> {/if} </div> <button type="submit" class="btn btn-primary">{l s='Send' mod='hhcustomform'}</button> </form> </div> {/block} |
A travers ces différents exemples vous pouvez donc voir qu’il est relativement facile d’ajouter un captcha sur n’importe quel formulaire de vos modules 🙂
Pour télécharger le module de captcha eicaptcha, ou signaler des problèmes vous rendre directement sur github : https://github.com/nenes25/eicaptcha
Bonjour,
Je suis sous PS 1.7.8.7 et j’ai récupéré la version eCaptcha 2.4.0.
J’ai activé la V3 et collé les clés de sécurités correspondantes. Cependant, j’ai une erreur
Erreurs
Le module n’est pas greffé sur le hook actionContactFormSubmitCaptcha
Avez-vous une solution ?
Merci 🙂
Bonjour,
Merci pour le retour.
Je vais regarder en détails asap, j’ai ouvert une issue sur github pour le suivi : https://github.com/nenes25/eicaptcha/issues/230
Mais je pense que c’est un faux positif du débug suite à un changement de nom dans cette version.
Cordialement,
Hervé
Bonjour,
Hi thanks for you work! I have been trying to get this working because I’m spammed with fake accounts.
It does work on the contact form but not on registration page. Captcha seems active but it doesn’t check if valid. I also replied on a open issue on github.
Recaptcha version : 2 and 3
Prestashop version : 8.0.3
Theme name : classic
Php version : 7.4.33