Jump to content

Módulo de Recaptcha para PS 1.5


Recommended Posts

Hola a [email protected]

 

Esto viene a ser una pequeña actualización de un post que ya escribí hace tiempo para insertar reCaptcha en los formularios de registro y contacto en PS 1.4 (este es el post). Por las muchas peticiones que he recibido por privado, os comento cómo podéis hacer que funcione en PS 1.5.

 

Lo primero que tenéis que saber es que la solución que voy a proponer hoy seguramente no es la más ideal u óptima, ya que al menos para la parte de registro requiere de un pequeño "truco".

 

Esta vez he realizado un módulo, con lo que los cambios que hay que hacer son menos que en el anterior post, pero aún así hay que tocar algo de código.

 

Os adjuntaré al final del post el módulo que he realizado, así como las clases necesarias a modo de ejemplo para que funcione.

 

Por supuesto, se admiten sugerencias, comentarios y mejoras.

 

Vamos allá.

 

El primer paso es instalar el módulo. Una vez hecho, aseguráos de que está anclado al hook "Customer account creation form". Lo siguiente es configurar el módulo, para introducir las claves pública y privada que tendréis después de registraros en reCaptcha.

 

Con esto el módulo ya debería funcionar para el formulario de registro. Peeeero, no es tán fácil. A ver: aquí me he encontrado un problema que por falta de tiempo no he podido resolver (este es el pequeño "truco" que comenté al principio del post). ESTE PROBLEMA SÓLO TE AFECTA SI TU PLANTILLA REALIZA LA CARGA DE LA PÁGINA DE REGISTRO POR AJAX. El problema es que en prestashop 1.5, cuando estás en la página para logarte o crear una nueva cuenta, si quieres crear una nueva cuenta, la página se carga a través de una llamada AJAX. Para mi gusto, igual de bonito que de inútil. El problema de todo esto es, que el módulo reCaptcha introduce el "desafío" a través de una llamada javascript a los servidores de Google, que también se carga por AJAX. ¿Y dónde está el problema? Pues que la página de registro (la que se carga por AJAX) se recibe en formato json, y si introduces código javascript en esta llamada, al parsearse, supongo que por motivos de seguridad el código javascript es eliminado y no se carga. Es un poco complicado de entender, pero en resumidas cuentas, al cargarse la página por AJAX, no permite que lo que se está trayendo (la página de registro) contenga otras llamadas AJAX. Buff, vaya tocho. Bueno, supongo que esto se podrá resolver, pero ya os digo, no tengo ahora mucho tiempo para dedicarle a esto así que os dejo todo el código para que intentéis solventar este escollo.

 

Bueno, para resolver este problema, el "truquito" del que os hablaba es, básicamente, desactivar esa llamada AJAX y convertirla en una carga de página normal. Afortunadamente esto se realiza bastante fácil. Si sufrís este problema, id a la plantilla authentication.tpl, buscad esta línea

$('#create-account_form').submit(function(){submitFunction();return false;});

y comentádla. Problema resuelto. Con truco, claro está.

 

Por ahora, después de todo este tocho, en realidad hemos tenido que hacer muy poco, y ya tenemos el formulario de registro protegido por reCaptcha.

 

Vamos ahora a por el de contacto.

 

Con el formulario de contacto tenemos el mismo problema que os comenté para la versión 1.4. Puede parecer igual de sencillo que el de registro, pero, tal y como está el código del controlador, cualquier validación de campos extra que introduzcamos no se realizará, y lo dará por bueno.

Para hacer esto aplicamos la misma solución que entonces: modificar el código del controlador.

Para que no tengáis problemas a la hora de actualizar la versión, todas las modificaciones que realizaremos sobre el controlador lo haremos en la carpeta que PS nos propone para ello: override. Por tanto, crearemos un archivo llamado ContactControler.php en la ruta /override/controllers/front.

 

Aquí, lo que haremos será añadir de manera correcta la validación del campo recaptcha. Os he adjuntado este archivo como ejemplo, pero yo que vosotros lo que haría sería coger el código que tengáis en el controlador original, copiarlo en la clase override, y añadir las pocas modificaciones que en realidad se realizan.

 

Como tenéis el código adjuntado, os voy a comentar simplemente los cambios.

En primer lugar, tenemos que añadir la librería recaptcha.php, que es la que entiende cómo crear y validar los desafíos.

require_once(dirname(__FILE__) . '/../../../modules/recaptcha/lib/recaptchalib.php');

En principio la ruta debería ser la misma en vuestro proyecto, pero por si acaso, comprobadla.

 

Lo siguiente es mostrar el código en el formulario. Esto lo hacemos en el método initContent:

parent::initContent();
        
$htmlCaptcha = recaptcha_get_html(Configuration::get('reCaptcha_public_key'));

$this->context->smarty->assign('htmlCaptcha', $htmlCaptcha);

Como veis, nada del otro mundo, por ahora.

 

A continuación viene la parte "tocha", pues como os he explicado, hay que cambiar todo el código del método postProcess para que nuestra validación se realice correctamente. Os repito que lo que he hecho ha sido coger el código original y añadirle las validaciones siguientes:

.....
$this->errors[] = Tools::displayError('Bad file extension');

/*
* Validación de captcha
*/
$challenge = Tools::getValue('recaptcha_challenge_field');
$respuesta = Tools::getValue('recaptcha_response_field');

$privatekey = Configuration::get('reCaptcha_private_key');

$resp = recaptcha_check_answer($privatekey, $_SERVER["REMOTE_ADDR"], $challenge, $respuesta);

if (!$resp->is_valid) {
    // What happens when the CAPTCHA was entered incorrectly
    $this->errors[] = Tools::displayError("The recaptcha wasn't entered correctly. Please try it again.");
}

if (count($this->errors) === 0) {

.......

Y listo. Ya sólo nos falta asignarle la etiqueta en la plantilla de contacto para que se vea. Esto lo hacemos en la plantilla contact-form.tpl.

....

	 <textarea id="message" name="message">{if isset($message)}{$message|escape:'htmlall':'UTF-8'|stripslashes}{/if}</textarea>
</p>
		
<p class="textarea">
	<label for="message">{l s='Captcha'}</label>
	{$htmlCaptcha}
</p>
		
<p class="submit">


.....

Ya sólo queda comprobar que todo funciona. Seguramente hay otras formas de hacerlo mucho más elegantes o completas, pero al menos esto os puede sacar del paso.

 

Como he dicho antes, se admiten comentarios, sugerencias, mejoras, etc. y sois libres de modificar este código, aunque si al menos hacéis mención al autor o a este post, os quedaré agradecidos.

 

Un saludo y espero de verdad que os sirva.

ContactController.php

recaptcha.zip

  • Like 2

Share this post


Link to post
Share on other sites

Hola.

 

Buffaldo, nada hombre, para eso estamos. Espero que este post pueda ayudar a más gente.

 

Nadie, gracias por volver a poner un post mío en el índice de aportes.

 

Joseantgv, sí, lo sé, pero al ser un controlador no me gusta ponerlo dentro del módulo, porque puede que otra persona tenga otros cambios en el archivo y, si te digo la verdad, no sé en qué modo puede llegar a afectar la solapación de cambios, así que he decidido no subirlo.

 

De todas formas, gracias a todos por comentar :)

  • Like 1

Share this post


Link to post
Share on other sites

Hola soy.amarillo primero de todo muy bueno!!! y gracias!

 

 

Joseantgv, sí, lo sé, pero al ser un controlador no me gusta ponerlo dentro del módulo, porque puede que otra persona tenga otros cambios en el archivo y, si te digo la verdad, no sé en qué modo puede llegar a afectar la solapación de cambios, así que he decidido no subirlo.

 

 

 

En cuanto a no sobreescribir el controlador sería mi caso, así que te agradezco el tiempo que me has ahorrado :)

 

Una duda,

 

En el formulario contacto funciona como has comentado perfectamente. Pero he descubierto que ahora el captcha aparece automáticamente en los formularios de registro de los clientes, esto lo veo incluso bien, me ahorras tener que colocar yo el código. El error que me aparece es el siguiente:

 

  captcha_error.png

como ves no carga la imagen. Si envías el formulario da error de captcha y la imagen ya aparece.

 

Estoy multitienda y prestashop 1.5.6.0

 

Muchas gracias, un saludo.

Share this post


Link to post
Share on other sites

Hola onlygoliat.

 

Pues lo que te pasa es lo que expliqué en el post:

 

ESTE PROBLEMA SÓLO TE AFECTA SI TU PLANTILLA REALIZA LA CARGA DE LA PÁGINA DE REGISTRO POR AJAX. El problema es que en prestashop 1.5, cuando estás en la página para logarte o crear una nueva cuenta, si quieres crear una nueva cuenta, la página se carga a través de una llamada AJAX

 

Para solucionarlo, simplemente haz lo que yo hice (a falta de que alguien proponga una solución mejor, o que yo encuentre tiempo y consiga solucionarlo :)

 

 

Bueno, para resolver este problema, el "truquito" del que os hablaba es, básicamente, desactivar esa llamada AJAX y convertirla en una carga de página normal. Afortunadamente esto se realiza bastante fácil. Si sufrís este problema, id a la plantilla authentication.tpl, buscad esta línea

$('#create-account_form').submit(function(){submitFunction();return false;});

y comentádla. Problema resuelto. Con truco, claro está.

 

Con eso se debería solucionar tu problema. Si no es así, me lo comentas.

 

Un saludo!

Share this post


Link to post
Share on other sites

Buen día,

 

Muchas gracias por el aporte, he seguido todos los pasos señalados sin embargo en el formulario de registro para pagar puedo dejar recaptcha vacío, guardar la información y lo acepta. No me marca ningún error como debería hacerlo. ¿Sabe cómo podría arreglar ésto? 

 

Uso PS 1.5.6.1, el tema por defecto y el pago a una sola página.

 

Saludos,

Share this post


Link to post
Share on other sites

Hola onlygoliat.

 

Pues lo que te pasa es lo que expliqué en el post:

 

Para solucionarlo, simplemente haz lo que yo hice (a falta de que alguien proponga una solución mejor, o que yo encuentre tiempo y consiga solucionarlo :)

 

 

Con eso se debería solucionar tu problema. Si no es así, me lo comentas.

 

Un saludo!

 

Muchas gracias, siento no haber leído con más atención el primer post :( . Funciona perfectamente.  :)

Share this post


Link to post
Share on other sites

  • 1 month later...

Hola.

 

A ver, ni siquiera he probado el código de la versión nueva, pero en un rápido vistazo, veo que han separado el código html del javascript (por fin). Ahora esa llamada está en la carpeta js de la plantilla, en el archivo authentication.js.

 

En teoría (y digo esto porque no lo he probado) debería valer con comentar las siguientes líneas:

 

e.preventDefault();
submitFunction();

 

Pruébalo y me comentas ok?

 

Un saludo!

Share this post


Link to post
Share on other sites

  • 2 weeks later...

Hola,

 

He estado realizando pruebas en PrestaShop con este sistema de captcha y he visto que el problema está en que en esta nueva versión los scripts se cargan al final, supongo que para acelerar la carga de la web. Esto provoca que el script que carga el recaptcha también se ejecute al final, lo que provoca que se cargue al final de la página fuera del formulario, con lo que no funciona.

 

Para solucionar esto he encontrado un truco que parece funcionar, al menos en las pruebas que he realizado. Para ello hay que editar el archivo modules/recaptcha/lib/recaptchalib.php y cambiar la líneas de código:

define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api");
define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api");

por estas otras:

define("RECAPTCHA_API_SERVER", "//www.google.com/recaptcha/api");
define("RECAPTCHA_API_SECURE_SERVER", "//www.google.com/recaptcha/api");

De esta forma el recaptcha se cargará en el lugar correcto y funcionará bien. Por supuesto, seguirá siendo necesario aplicar las modificaciones que indicaba soy.amarillo en el archivo authentication.js, si se usa el tema por defecto de PrestaShop, o en el lugar que corresponda si utilizamos otra plantilla.

Share this post


Link to post
Share on other sites

Hola:

 

Yo lo he solucionado pero no cambiando lo que dices, sino como bien tu dices, especificando que los scripts no se vayan al final de la pagina sino que los mantengan en la posicion que tienen puesta en el CSS.

 

Salu2

Felix

http://www.allyear.es

 

PD: A ver si busco la solucion que aplique y la pongo aqui

Share this post


Link to post
Share on other sites

Hola felixdpg,

 

La solución que propones también debería ser válida, ya que así se respetaría la posición de los scripts, incluido el que se usa para cargar el recaptcha. ¿La opción para que los scripts se vayan al final de la web está en la administración de PrestaShop?

 

De todas formas me parece mejor solución hacer el cambio que indico ya que precisamente el aplazamiento de la carga de los scripts (colocarlos al final) sirve para acelerar la carga de la web.

Share this post


Link to post
Share on other sites

Hola pablolgi

 

Lo solucione asi:

 

 En classes/controller/Controller.php lo deshabilito cambiando:
 
$dom_available = extension_loaded('dom') ? true : false;por
 
//$dom_available = extension_loaded('dom') ? true : false;
$dom_available = false;
 

 

No obstante he probado tu solucion y funciona perfecto, creo que lo voy a dejar asi, tienes razon, es mejor dejar los jscript que carguen al final

 

salu2

 

felix

http://www.allyear.es

Share this post


Link to post
Share on other sites

  • 3 months later...

Hola,

 

Con la última versión 1.6.0.8 que he probado he visto que, en algunos casos, el recaptcha se vuelve a cargar en la parte inferior de la web, incluso con el cambio que había indicado en una respuesta anterior en el archivo modules/recaptcha/lib/recaptchalib.php

 

Para arreglarlo, he preparado una nueva versión de ese archivo recaptchalib.php para que cargue la caja de recaptcha usando un script que sustituye una capa div por el recaptcha. De esta forma, aunque se aplace la carga de los scripts el recaptcha debería cargar en su sitio. Pongo aquí el nuevo código del archivo recaptchalib.php.

<?php
/*
 * This is a PHP library that handles calling reCAPTCHA.
 *    - Documentation and latest version
 *          http://recaptcha.net/plugins/php/'>http://recaptcha.net/plugins/php/
 *    - Get a reCAPTCHA API Key
 *          https://www.google.com/recaptcha/admin/create
 *    - Discussion group
 *          http://groups.google.com/group/recaptcha
 *
 * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
 * AUTHORS:
 *   Mike Crawford
 *   Ben Maurer
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * The reCAPTCHA server URL's
 */
define("RECAPTCHA_VERIFY_SERVER", "www.google.com");

/**
 * Encodes the given data into a query string format
 * @param $data - array of string elements to be encoded
 * @return string - encoded request
 */
function _recaptcha_qsencode ($data) {
        $req = "";
        foreach ( $data as $key => $value )
                $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';

        // Cut the last '&'
        $req=substr($req,0,strlen($req)-1);
        return $req;
}



/**
 * Submits an HTTP POST to a reCAPTCHA server
 * @param string $host
 * @param string $path
 * @param array $data
 * @param int port
 * @return array response
 */
function _recaptcha_http_post($host, $path, $data, $port = 80) {

        $req = _recaptcha_qsencode ($data);

        $http_request  = "POST $path HTTP/1.0\r\n";
        $http_request .= "Host: $host\r\n";
        $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
        $http_request .= "Content-Length: " . strlen($req) . "\r\n";
        $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
        $http_request .= "\r\n";
        $http_request .= $req;

        $response = '';
        if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
                die ('Could not open socket');
        }

        fwrite($fs, $http_request);

        while ( !feof($fs) )
                $response .= fgets($fs, 1160); // One TCP-IP packet
        fclose($fs);
        $response = explode("\r\n\r\n", $response, 2);

        return $response;
}



/**
 * Gets the challenge HTML (javascript and non-javascript version).
 * This is called from the browser, and the resulting reCAPTCHA HTML widget
 * is embedded within the HTML form it was called from.
 * @param string $pubkey A public key for reCAPTCHA
 * @param string $error The error given by reCAPTCHA (optional, default is null)
 * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)

 * @return string - The HTML to be embedded in the user's form.
 */
function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
{
	if ($pubkey == null || $pubkey == '') {
		die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
	}
	
        $errorpart = "";
        if ($error) {
           $errorpart = "&error=" . $error;
        }
        return '<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
  <script>
  Recaptcha.create("' . $pubkey . '",
      "show_recaptcha",
      {
        theme: "red",
        callback: Recaptcha.focus_response_field
      }
    );
  </script>
  <div id="show_recaptcha"></div>
	<noscript>
  		<iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
  		<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
  		<input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
	</noscript>';
}




/**
 * A ReCaptchaResponse is returned from recaptcha_check_answer()
 */
class ReCaptchaResponse {
        var $is_valid;
        var $error;
}


/**
  * Calls an HTTP POST function to verify if the user's guess was correct
  * @param string $privkey
  * @param string $remoteip
  * @param string $challenge
  * @param string $response
  * @param array $extra_params an array of extra variables to post to the server
  * @return ReCaptchaResponse
  */
function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
{
	if ($privkey == null || $privkey == '') {
		die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
	}

	if ($remoteip == null || $remoteip == '') {
		die ("For security reasons, you must pass the remote ip to reCAPTCHA");
	}

	
	
        //discard spam submissions
        if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
                $recaptcha_response = new ReCaptchaResponse();
                $recaptcha_response->is_valid = false;
                $recaptcha_response->error = 'incorrect-captcha-sol';
                return $recaptcha_response;
        }

        $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
                                          array (
                                                 'privatekey' => $privkey,
                                                 'remoteip' => $remoteip,
                                                 'challenge' => $challenge,
                                                 'response' => $response
                                                 ) + $extra_params
                                          );

        $answers = explode ("\n", $response [1]);
        $recaptcha_response = new ReCaptchaResponse();

        if (trim ($answers [0]) == 'true') {
                $recaptcha_response->is_valid = true;
        }
        else {
                $recaptcha_response->is_valid = false;
                $recaptcha_response->error = $answers [1];
        }
        return $recaptcha_response;

}

/**
 * gets a URL where the user can sign up for reCAPTCHA. If your application
 * has a configuration page where you enter a key, you should provide a link
 * using this function.
 * @param string $domain The domain where the page is hosted
 * @param string $appname The name of your application
 */
function recaptcha_get_signup_url ($domain = null, $appname = null) {
	return "https://www.google.com/recaptcha/admin/create?" .  _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname));
}

function _recaptcha_aes_pad($val) {
	$block_size = 16;
	$numpad = $block_size - (strlen ($val) % $block_size);
	return str_pad($val, strlen ($val) + $numpad, chr($numpad));
}

/* Mailhide related code */

function _recaptcha_aes_encrypt($val,$ky) {
	if (! function_exists ("mcrypt_encrypt")) {
		die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");
	}
	$mode=MCRYPT_MODE_CBC;   
	$enc=MCRYPT_RIJNDAEL_128;
	$val=_recaptcha_aes_pad($val);
	return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
}


function _recaptcha_mailhide_urlbase64 ($x) {
	return strtr(base64_encode ($x), '+/', '-_');
}

/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
function recaptcha_mailhide_url($pubkey, $privkey, $email) {
	if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
		die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
		     "you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>'>http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>");
	}
	

	$ky = pack('H*', $privkey);
	$cryptmail = _recaptcha_aes_encrypt ($email, $ky);
	
	return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
}

/**
 * gets the parts of the email to expose to the user.
 * eg, given [email protected],com return ["john", "example.com"].
 * the email is then displayed as [email protected]
 */
function _recaptcha_mailhide_email_parts ($email) {
	$arr = preg_split("/@/", $email );

	if (strlen ($arr[0]) <= 4) {
		$arr[0] = substr ($arr[0], 0, 1);
	} else if (strlen ($arr[0]) <= 6) {
		$arr[0] = substr ($arr[0], 0, 3);
	} else {
		$arr[0] = substr ($arr[0], 0, 4);
	}
	return $arr;
}

/**
 * Gets html to display an email address given a public an private key.
 * to get a key, go to:
 *
 * http://www.google.com/recaptcha/mailhide/apikey
 */
function recaptcha_mailhide_html($pubkey, $privkey, $email) {
	$emailparts = _recaptcha_mailhide_email_parts ($email);
	$url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
	
	return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) .
		"' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]);

}


?>

Espero que os sirva de ayuda.

Share this post


Link to post
Share on other sites

  • 3 weeks later...

Hola a ver si alguien me puede ayudar al instalar el moulo ya segui todos los pasos y trabaja bien, si alguien quiere crear una cuenta el modulo trabaja bien, si existe algun error de el captcha lo informa y refresca la imagen.

 

el problema es a la hora de poner la tienda en un solo paso a la hora de llenar datos para crear la cuenta y los datos de envio si existe algun error el captcha no se actualiza se queda la misma imagen y si el cliente la sigue ingresando es erronea ya que a existir el error no pone una nueva imagen

 

espero me puedan ayudar ya que llevo varios dias con este problema y no puedo solucionarlo

 

Saludos....

Share this post


Link to post
Share on other sites

  • 1 year later...

Hola a [email protected]

 

Esto viene a ser una pequeña actualización de un post que ya escribí hace tiempo para insertar reCaptcha en los formularios de registro y contacto en PS 1.4 (este es el post). Por las muchas peticiones que he recibido por privado, os comento cómo podéis hacer que funcione en PS 1.5.

 

Lo primero que tenéis que saber es que la solución que voy a proponer hoy seguramente no es la más ideal u óptima, ya que al menos para la parte de registro requiere de un pequeño "truco".

 

Esta vez he realizado un módulo, con lo que los cambios que hay que hacer son menos que en el anterior post, pero aún así hay que tocar algo de código.

 

Os adjuntaré al final del post el módulo que he realizado, así como las clases necesarias a modo de ejemplo para que funcione.

 

Por supuesto, se admiten sugerencias, comentarios y mejoras.

 

Vamos allá.

 

El primer paso es instalar el módulo. Una vez hecho, aseguráos de que está anclado al hook "Customer account creation form". Lo siguiente es configurar el módulo, para introducir las claves pública y privada que tendréis después de registraros en reCaptcha.

 

Con esto el módulo ya debería funcionar para el formulario de registro. Peeeero, no es tán fácil. A ver: aquí me he encontrado un problema que por falta de tiempo no he podido resolver (este es el pequeño "truco" que comenté al principio del post). ESTE PROBLEMA SÓLO TE AFECTA SI TU PLANTILLA REALIZA LA CARGA DE LA PÁGINA DE REGISTRO POR AJAX. El problema es que en prestashop 1.5, cuando estás en la página para logarte o crear una nueva cuenta, si quieres crear una nueva cuenta, la página se carga a través de una llamada AJAX. Para mi gusto, igual de bonito que de inútil. El problema de todo esto es, que el módulo reCaptcha introduce el "desafío" a través de una llamada javascript a los servidores de Google, que también se carga por AJAX. ¿Y dónde está el problema? Pues que la página de registro (la que se carga por AJAX) se recibe en formato json, y si introduces código javascript en esta llamada, al parsearse, supongo que por motivos de seguridad el código javascript es eliminado y no se carga. Es un poco complicado de entender, pero en resumidas cuentas, al cargarse la página por AJAX, no permite que lo que se está trayendo (la página de registro) contenga otras llamadas AJAX. Buff, vaya tocho. Bueno, supongo que esto se podrá resolver, pero ya os digo, no tengo ahora mucho tiempo para dedicarle a esto así que os dejo todo el código para que intentéis solventar este escollo.

 

Bueno, para resolver este problema, el "truquito" del que os hablaba es, básicamente, desactivar esa llamada AJAX y convertirla en una carga de página normal. Afortunadamente esto se realiza bastante fácil. Si sufrís este problema, id a la plantilla authentication.tpl, buscad esta línea

$('#create-account_form').submit(function(){submitFunction();return false;});

y comentádla. Problema resuelto. Con truco, claro está.

 

Por ahora, después de todo este tocho, en realidad hemos tenido que hacer muy poco, y ya tenemos el formulario de registro protegido por reCaptcha.

 

Vamos ahora a por el de contacto.

 

Con el formulario de contacto tenemos el mismo problema que os comenté para la versión 1.4. Puede parecer igual de sencillo que el de registro, pero, tal y como está el código del controlador, cualquier validación de campos extra que introduzcamos no se realizará, y lo dará por bueno.

Para hacer esto aplicamos la misma solución que entonces: modificar el código del controlador.

Para que no tengáis problemas a la hora de actualizar la versión, todas las modificaciones que realizaremos sobre el controlador lo haremos en la carpeta que PS nos propone para ello: override. Por tanto, crearemos un archivo llamado ContactControler.php en la ruta /override/controllers/front.

 

Aquí, lo que haremos será añadir de manera correcta la validación del campo recaptcha. Os he adjuntado este archivo como ejemplo, pero yo que vosotros lo que haría sería coger el código que tengáis en el controlador original, copiarlo en la clase override, y añadir las pocas modificaciones que en realidad se realizan.

 

Como tenéis el código adjuntado, os voy a comentar simplemente los cambios.

En primer lugar, tenemos que añadir la librería recaptcha.php, que es la que entiende cómo crear y validar los desafíos.

require_once(dirname(__FILE__) . '/../../../modules/recaptcha/lib/recaptchalib.php');

En principio la ruta debería ser la misma en vuestro proyecto, pero por si acaso, comprobadla.

 

Lo siguiente es mostrar el código en el formulario. Esto lo hacemos en el método initContent:

parent::initContent();
        
$htmlCaptcha = recaptcha_get_html(Configuration::get('reCaptcha_public_key'));

$this->context->smarty->assign('htmlCaptcha', $htmlCaptcha);

Como veis, nada del otro mundo, por ahora.

 

A continuación viene la parte "tocha", pues como os he explicado, hay que cambiar todo el código del método postProcess para que nuestra validación se realice correctamente. Os repito que lo que he hecho ha sido coger el código original y añadirle las validaciones siguientes:

.....
$this->errors[] = Tools::displayError('Bad file extension');

/*
* Validación de captcha
*/
$challenge = Tools::getValue('recaptcha_challenge_field');
$respuesta = Tools::getValue('recaptcha_response_field');

$privatekey = Configuration::get('reCaptcha_private_key');

$resp = recaptcha_check_answer($privatekey, $_SERVER["REMOTE_ADDR"], $challenge, $respuesta);

if (!$resp->is_valid) {
    // What happens when the CAPTCHA was entered incorrectly
    $this->errors[] = Tools::displayError("The recaptcha wasn't entered correctly. Please try it again.");
}

if (count($this->errors) === 0) {

.......

Y listo. Ya sólo nos falta asignarle la etiqueta en la plantilla de contacto para que se vea. Esto lo hacemos en la plantilla contact-form.tpl.

....

	 <textarea id="message" name="message">{if isset($message)}{$message|escape:'htmlall':'UTF-8'|stripslashes}{/if}</textarea>
</p>
		
<p class="textarea">
	<label for="message">{l s='Captcha'}</label>
	{$htmlCaptcha}
</p>
		
<p class="submit">


.....

Ya sólo queda comprobar que todo funciona. Seguramente hay otras formas de hacerlo mucho más elegantes o completas, pero al menos esto os puede sacar del paso.

 

Como he dicho antes, se admiten comentarios, sugerencias, mejoras, etc. y sois libres de modificar este código, aunque si al menos hacéis mención al autor o a este post, os quedaré agradecidos.

 

Un saludo y espero de verdad que os sirva.

FUnciona para prestashop 1.6.1. ???   Gracias !

Edited by maxcrist (see edit history)

Share this post


Link to post
Share on other sites

  • 3 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More