Danygras

Gestion des Formulaires HTML

Cette classe étends la classe de base, et s'utilise pareillement, mais elle ajoute un captcha simplissime qui consiste seulement à demander à l'utilisateur d'écrire un chiffre entre zéro et neuf, en chiffre. L'astuce étant que l'on demande de recopier un chiffre mais on l'écrit en lettre, ça bluffe les robots simplistes de nos amis chinois ou russes (ou même anglais) qui ne comprennent pas forcément la langue de Molière.

<?php

/*
 * formlaire pour poster des commentaires
 * contient : nom mail url et message
 *  tend formclass.php 
 * ajoute un captcha simpliste :
 * "Ecrivez le chiffre 'cinq' ... en chiffre :"
 * ajouter une fonction antiflood dans la validation
 */
class comment extends form {

	private $captcha = array('zro', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf');

	// protection anti flood : ne pas poster plus de X messages par minute
	protected $last_post;
	protected $first_post;
	protected $nb_posts;

	
	function __construct($cond = null) {
	
	
		// liste des champs ncessaires - sauf token non crypt
		//$this->fields = array('nom', 'url', 'email', 'texto');
		$this->fields['nom'] = array('type'=>'text', 'name'=>'nom', 'size'=>18, 'maxlength'=>20, 'value'=>'', 'label'=>array('txt'=>'Nom : '));
		$this->fields['email'] = array('type'=>'text', 'name'=>'email', 'size'=>22, 'maxlength'=>40, 'value'=>'', 'label'=>array('txt'=>'Email : '));
		$this->fields['url'] = array('type'=>'text', 'name'=>'url', 'size'=>25, 'maxlength'=>50, 'value'=>'http://', 'label'=>array('txt'=>'URL : '));
		$this->fields['texto'] = array('type'=>'textarea', 'name'=>'texto', 'cols'=>60, 'rows'=>4, 'wrap'=>'virtual', 'value'=>'');
		$this->fields['submit'] = array('type'=>'submit', 'name'=>'Submit', 'value'=>'Envoyer',
			'label'=>array('txt'=>'Nom et message obligatoires.'));
		$this->fields['question'] = array('type'=>'text', 'size'=>2, 'name'=>'question');
		$this->fields['answer'] = array('type'=>'hidden', 'name'=>'answer');
			
		parent::__construct($cond);
	}
	

	function getForm() {
		
		$date = get_date();
		$now = time();
		$token = sha1(self::SALT.$now.self::SALT);
		$signed = $now.'#'.$token;

		// demander la question pige et ajouter la rponse
		$answer = rand(0,9);
		$this->fields['question']['label']['txt'] = 'Ecrivez le chiffre '. $this->captcha[$answer] . ' en chiffre :';
		$this->fields['answer']['value'] = $this->captcha[$answer];

		// crypter les noms des champs
		$fld = array();
		foreach($this->fields as $key => $value) {
			$this->names[$key] = form::crypt($key, $token);
			$value['name'] = $this->names[$key];
			$fld[$key] = parent::getField($value);
		}
		
		
		return <<
  
$date {$fld['nom']} {$fld['email']} {$fld['url']}
{$fld['texto']}
{$fld['question']} {$fld['submit']} {$fld['answer']} {$fld['message']}
MYFORM; } public function validateForm() { if (parent::validateForm()) { // tester la bonne rponse au captcha if(!is_numeric($this->values['question'])) { $this->valide = false; $this->err = 'Question = "'.$this->values['question'] . '" pas numrique'; } else if (!isset($this->captcha[$this->values['question']])) { $this->valide = false; $this->err = 'Question = "'.$this->values['question'] . '" hors champs'; } else if ($this->values['answer'] != $this->captcha[$this->values['question']]) { $this->valide = false; $this->err = 'Question = "'.$this->values['answer'] . '" Reponse="' . $this->values['question'] .'"'; } else { // formulaire valide $this->last_post = request('last_post', 'int', 'session'); $this->first_post = request('first_post', 'int', 'session',0); $this->nb_posts = request('nb_posts', 'uint', 'session',0); // MAJ des infos antiflood en session $_SESSION['last_post'] = time(); if(isset($_SESSION['nb_posts'])) $_SESSION['nb_posts'] ++; else { $_SESSION['nb_posts'] = 1; $_SESSION['first_post'] = time(); // heure du 1er post } } } return $this->valide; } // fonction anti-flood : enregistrer en session les temps et nb de $_POST chaque validation de formulaire function antiflood() { // protection anti flood : ne pas poster plus de X messages par minute $duree = time() - $this->last_post; $dureeh = time_elapsed($duree); if($this->last_post && $duree < 30) { $this->err = "Anti-spam : moins d'un message par 30 secondes svp ($duree = $dureeh)."; return true; } if ($this->nb_posts > 20) { $duree = time() - $this->first_post; if ($this->first_post && $duree < 3600) { $this->err = "Anti-spam : moins de 20 messages par heure svp !! ($nb_posts, $duree, $dureeh)"; return true; } } return false; } } ?>