Tutorial: come realizzare un captcha custom per WordPress

Tutorial per realizzare un captcha custom

Avevamo già parlato in un tutorial della personalizzazione dei commenti di un post di WordPress (WP), per continuità proponiamo come costruire una plugin WP per realizzare un “capcha”, con l’obiettivo di bloccare (o arginare il più possibile) commenti spam.

Pronti? Iniziamo!

Questo modulo si basa su chiamate asincrone generate dall’evento di un click sul bottone per inserire il commento (oppure sul pulsante per ricaricare il captcha).

È propedeutico possedere un minimo di conoscenza di MySQL, PHP, Javascript e, nello specifico, CSS (che non tratteremo in questo articolo).

Per cominciare bisogna creare la struttura sul nostro DB.

Il fornitore dell’hosting vi avrà senz’altro messo a disposizione gli accessi al server MySQL.

In alternativa potete recuperarli dal file di configurazione di WP per poi effettuare l’accesso tramite phpMyAdmin o programma di connessione a database (MySQL Workbench: http://dev.mysql.com/downloads/workbench/ oppure Sequel Pro: http://www.sequelpro.com/).

Solo dopo aver effettuato l’accesso possiamo procedere alla costruzione della nostra tabella captcha che conterrà 4 campi. Ecco qui di seguito il codice SQL:


CREATE TABLE IF NOT EXISTS `captcha` (

`id` int(2) unsigned NOT NULL auto_increment,

`testoDomanda` varchar(80) collate utf8_unicode_ci default NULL,

`risposta` varchar(15) collate utf8_unicode_ci NOT NULL,

`pathImg` varchar(150) collate utf8_unicode_ci default NULL,

PRIMARY KEY  (`id`)

) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;

Il significato del codice sopra è abbastanza chiaro (solo per gli addetti ai lavori naturalmente!), non sarà analizzato in questo articolo.

Una piccola indicazione: PathImg in questo tutorial sarà sempre settato a NULL e non verrà utilizzato; lo lasciamo in previsione di una espansione del modulo che visualizzerà immagini al posto del testo.

Una volta realizzata la struttura della nostra tabella possiamo inserire dei valori, esempio:

testoDomanda: “Completa la frase: Tanto va la … al lardo che ci lascia lo zampino”

risposta: “gatta”

testoDomanda: “Completa la frase: … di sera bel tempo si spera”

risposta: “rosso”

Solo dopo aver terminato di riempire la nostra tabella, potremo procedere alla stesura del codice.

Ecco i passi da seguire:

Per prima cosa inseriamo nel nostro file comments.php (il template che contiene il form dei commenti del nostro precedente tutorial) il codice riportato qui di seguito. Apriamo quindi il file comments.php con un editor di testo e inseriamo, in base a dove vogliamo visualizzare il captcha, il seguente codice HTML:


<div id="formCaptcha">

<div id="domanda"></div>

<input type="text" name="codice" id="codiceCaptcha" />

<input type="text" name="risposta" id="rispostaCaptcha" style="visibility: hidden" />

<div id="ricaricaCaptcha"></div>

</div>

L’operazione da eseguire è la medesima, anche se state utilizzando un altro plugin per gestire i commenti oppure il file base di WordPress.

Al momento il nostro codice HTML non fa praticamente nulla.

A questo punto è necessario creare un file Javascript che ci permetterà di gestire il codice appena inserito.

Se avete seguito il precedente tutorial sulla personalizzazione dei commenti, dovrete andare a modificare il file gestCommenti.js, in caso contrario va creato (per le istruzioni di inclusione vi invitiamo a seguire sempre il tutorial segnalato) e, al suo interno, dovrete aggiungere come variabile globale un flag che abbiamo chiamato “tuttoOK” (a breve esamineremo l’utilizzo).


var tuttoOK;

subito dopo il document.ready() aggiungiamo la chiamata a funzione: caricaCaptcha()

Di seguito il codice:


function caricaCaptcha(){

$.ajax({

type: "post",

url: getBaseURL()+"wp-admin/admin-ajax.php?action=captcha",

cache: false,

global: false,

success: function(data){

if(typeof(data)=== "string" ) data= JSON.parse(data);

$('#domanda').html(data.domanda);

$('#rispostaCaptcha').attr('value',data.id);

}

});

}

Con queste righe di codice, una volta caricata la pagina dal nostro browser, verrà effettuata una chiamata AJAX. Da questo momento è possibile editare il file functions.php ed aggiungere le azioni per la chiamata asincrona:


add_action("wp_ajax_nopriv_captcha", "caricaCaptcha");

add_action("wp_ajax_captcha", "caricaCaptcha");

e la nostra funzione caricaCaptcha() (sempre in functions.php o nel nostro file che contiene le funzioni Ajax).


function caricaCaptcha() {

header("Content-Type: application/json"); //forziamo l’header HTTP a restituire un JSON

$risultato = Array('id' => 0, "domanda" => ''); // array dei risultati

global $wpdb; // rendiamo disponibile la classe WPDB per interfacciarci con il database di WP

//adesso recuperiamo il totale delle tuple per andare a calcolare il random

$q = "SELECT count( id ) numero FROM captcha";

$resTot = $wpdb->get_results($q, OBJECT); //eseguo la query, i risultati saranno restituiti      come array di oggetto WPDB

$rand = rand(1, $resTot[0]->numero);

//adesso che ho il totale vado a caricare un captcha random

$qCaptcha = "SELECT id, testoDomanda FROM captcha where id=" . $rand . " ";

$resCaptcha = $wpdb->get_results($qCaptcha, OBJECT);

$risultato['id'] = $resCaptcha[0]->id;

$risultato['domanda'] = $resCaptcha[0]->testoDomanda;

echo json_encode($risultato);

exit;

}

Ricaricando la pagina, se i passaggi saranno stati eseguiti correttamente, troveremo la nostra domanda inserita nel div #domanda e in #rispostaCaptcha l’id della tupla contenente la domanda e la risposta, che ci servirà in fase di inserimento di un commento.

Lo step successivo prevede l’inserimento di un controllo sul “submit” del form di commenti.

Attenzione: se state partendo dal precedente tutorial, l’id del bottone che genera l’evento di invio sarà: #submit.

In caso contrario si deve andare a recuperare l’id (oppure l’id del form dei commenti) ed associarlo all’evento click() oppure, se stiamo triggerando il form, all’evento submit().

All’interno di questo blocco di codice inseriamo la validazione sul captcha come di seguito:


...

...

tuttoOK=checkCaptcha(); //chiamiamo una funzione che restituisce un booleano

$(document).ajaxComplete(function(){ //controllo per evitare che venga eseguito il codice sotto PRIMA della risposta dal server sul controllo del captcha inserito

if(tuttoOK==1){ //se il controllo sul captcha è andato a buon fine, possiamo far inserire il commento al core di WP o alle nostre funzioni custom

$('#commentform').submit(function(){  return true   });

}

});

….

...

Di seguito il codice della funzione checkCaptcha():


function checkCaptcha(){

//recuperiamo i dati che ci servono per controllare il dato inserito: la risposta inserita dall’utente e l’id della tupla da controllare

var idCaptcha= $('#rispostaCaptcha').attr('value');

var valCaptcha= $('#codiceCaptcha').val() ;

//eseguiamo la chiamata AJAX per controllare il dato inserito

$.ajax({

type: "post",

url: getBaseURL()+"wp-admin/admin-ajax.php?action=controllaCaptcha",

data: "idCaptcha="+idCaptcha+"&valCaptcha="+valCaptcha,

success: function(data){

if(typeof(data)=== "string" ) data= JSON.parse(data);

if(data.ok==0){

Dialog('<span>La risposta non è corretta</span><span class="errore-validazione"></span>');

tuttoOK = 0;

}else if(data.ok==1){

tuttoOK= 1;

// il blocco sottostante chiama il file di WP che si occupa di inserire il commento. Se non state partendo dal nostro precedente tutorial, ma state gestendo l’inserimento, potete evitare di utilizzare questo blocco

$.ajax({

type:"post",

url: getBaseURL()+'wp-comments-post.php',

data: $('#commentform').serialize(),

success: function(){

$('#commentform input, #commentform textarea').val('');

str='<span class="successo-validazione-testo">Il tuo commento è stato inserito con successo e verrà reso visibile una volta moderato.<br />Grazie</span><span class="successo-validazione"></span>';

Dialog(str,'si');

},

statusCode:{

500: function(){

Dialog('<span class="errore-validazione">Si direbbe che hai appena inserito un commento uguale!</span>','si');

}

}

});

// fine inserimento commento

}else{

tuttoOK= 0;

}

}

});

}

//Inseriamo l’azione per ricaricare il captcha

$(‘#ricaricaCaptcha’).click(function(evt){

evt.preventDefault();

caricaCaptcha();

});

Se la funzione checkCaptcha() ci restituisce esito positivo, verrà inserito il commento. In caso contrario verrà visualizzato un errore.

Manca ora da analizzare il codice della chiamata AJAX che si occupa di controllare il dato inserito dall’utente.

Di seguito il codice per l’hook al core di WP (da inserire sempre in functions.php):


add_action("wp_ajax_nopriv_controllaCaptcha", "checkCaptcha");

add_action("wp_ajax_controllaCaptcha", "checkCaptcha");

ed il codice della funzione:


function checkCaptcha() {

header("Content-Type: application/json");

$risultato = Array('ok' => 0);

global $wpdb;

if (isset($_REQUEST['idCaptcha']) && is_numeric($_REQUEST['idCaptcha']) && isset($_REQUEST['valCaptcha']) && strlen($_REQUEST['valCaptcha']) > 0) {

$idCaptcha = filter_input(INPUT_POST, 'idCaptcha' , FILTER_VALIDATE_INT);

$captcha = filter_input(INPUT_POST, 'valCaptcha', FILTER_SANITIZE_STRING);

$q = "select risposta from captcha where id=$idCaptcha";

$res = $wpdb->query($q);

if($res[0]->risposta === $captcha) $risultato[‘ok’]=1;

echo json_encode($risultato);

exit;

}

A questo punto il controllo verrà rimandato al file gestCommenti.js che si occuperà di “sbloccare” il submit del nostro form e di procedere con l’inserimento del commento.

NOTE

Tutti i messaggi di validazione sono processati attraverso la chiamata a funzione Dialog(str, reload), non descritta in questo tutorial, perché semplice implementazione del plugin BlockUI (http://malsup.com/jquery/block/).

Attraverso il codice Javascript vengono eseguite chiamate alla funzione getBaseUrl() che non è fornita in questo tutorial. In breve, restituisce il path assoluto del dominio sul quale si sta eseguendo lo script.

Grazie per l’attenzione! :)

     

Partecipa alla discussione

Non è stato inserito ancora nessun commento, inizia tu!