Cette classe permet de creer des sondages a choix simple ou multiple. Sont point fort est l'ulisation d'ajax qui permet d'enregistrer le choix et d'afficher les resultat du sondage sans poster la page et donc sans refresh.
<?php /***************************** Auteur :iDo (ido@woow-fr.com) License :CreativeCommons (http://creativecommons.org/licenses/by-nc-sa/2.0/) Date Creation :07/11/05 Derniere modif. :07/11/05 *****************************/ class Poll { /***************************** Cree le sondage $question = string -> Question $reponse = array -> [0] réponse 1 [1] Réponse 2... $classes = array -> ['p'] classe de barre de progression ['q'] classe de la question ['r'] classe de la liste de réponse ['b'] classe du bouton valider [0] classe de la réponse 1 [1] classe de la réponse 2... $Ip = String -> Contient l'ip du votant, laisser vide pour ne pas le géré $TpsEntreVote = integer -> Tps en seconde entre chaque autorisation de vote $ProgressShade = string -> Si il contient une couleur hexadecimale (sans le #), cette couleur sera utlisé pour géré la barre de progression (avec nuance) $ChoixMultiple = boolean -> True pour des check, False pour des radio $nomFichier = string -> Fichier de sauvegarde des resultats *****************************/ function Poll($question,$reponses,$classes,$Ip='',$TpsEntreVote=10,$ProgressShade='',$ChoixMultiple=false,$nomFichier="poll.txt") { $this->IdQuestion =md5($question); $this->nomFichier =$nomFichier; $this->nbQuestion =count($reponses); $this->classes =$classes; $this->question =$question; $this->reponses =$reponses; $this->ChoixMultiple=$ChoixMultiple; $this->IP =$Ip; $this->TpsEntreVote =$TpsEntreVote; $this->ProgressShade=$ProgressShade; } /***************************** Assombri ou eclairci une couleur *****************************/ function correctshade($color, $shade) { $r = hexdec(substr($color,0,2)); $g = hexdec(substr($color,2,2)); $b = hexdec(substr($color,4,2)); $sum = ($r + $g + $b); $x = (($shade * 3) - $sum) / $sum; if ($x >= 0) { $x = $x + 1; } else { $x = 1 + $x; } $r = intval($x * $r); $g = intval($x * $g); $b = intval($x * $b); $r = dechex($r); $g = dechex($g); $b = dechex($b); $r=(strlen($r)<2)?'0'.$r:$r; $g=(strlen($g)<2)?'0'.$g:$g; $b=(strlen($b)<2)?'0'.$b:$b; return $r.$g.$b; } /***************************** Donne la couleur opposé d'une couleur *****************************/ function OppositeHex($color) { $r = dechex(255 - hexdec(substr($color,0,2))); $r = (strlen($r) > 1) ? $r : '0'.$r; $g = dechex(255 - hexdec(substr($color,2,2))); $g = (strlen($g) > 1) ? $g : '0'.$g; $b = dechex(255 - hexdec(substr($color,4,2))); $b = (strlen($b) > 1) ? $b : '0'.$b; return $r.$g.$b; } /***************************** Renvoie True si l'ip a déja voté, false sinon *****************************/ function AdejaVoter() { $ret=false; if ($this->IP=='') return $ret; //cree le fichier si c la premiere fois $handle = fopen($this->nomFichier, "a"); fclose ($handle); //lit le fichier $fline = file($this->nomFichier); //recupere ke les ip et strip le \n $started=false; $cptvotes=0; $cptip=0; $ip[0]=''; for ($j=0;$j!=count($fline);$j++) { $fline[$j]=rtrim($fline[$j]); if ($fline[$j]=='') continue; //si je suis dans la récupération des ips if ($started==true) { //si c pas encore la fin de la liste des ip if ($fline[$j]{0} != '[') { $tmp=split(' ',$fline[$j]); if ((floatval(trim($tmp[0]))+$this->TpsEntreVote) >= date('YmdHis')) { //date encore valide if ((trim($tmp[1])==$this->IP) && (trim($tmp[2])==$this->IdQuestion)) { //mm ip, mm question !! tu peu pas revoté $ret = true; }//else on continu a vérifier les autre ligne $ip[$cptip]=$fline[$j]; $cptip++; } else { //date delai dépassé $fline[$j]=""; } } else { //si la liste est fini $started=false; $votes[$cptvotes]=$fline[$j]; $cptvotes++; } } else { $votes[$cptvotes]=$fline[$j]; $cptvotes++; } //la liste va commencer if ($fline[$j]=='[IP]') { $started=true; } } //Si j'arrive ici c'est que j'ai parcouru toute la liste d'ip et que celle en cours n'a pas été trouvé //au pasage, on va sauvegarder la liste vidé des ligne obsolete if (!@$votes) return $ret; for ($j=0;$j!=count($votes);$j++) { $votes[$j].="\n"; } for ($j=0;$j!=count($ip);$j++) { $ip[$j].="\n"; } //Stoket le array dans une variable string $votes = @implode ('', $votes); $ip = @implode ('', $ip); $votes .= $ip."\r\n"; //Ecrit le fichier definit //php5 => file_put_contents ($_POST['nf'], $fline); $handle = fopen($this->nomFichier, "w"); fwrite($handle, $votes); fclose($handle); return $ret; } /***************************** Affiche le sondage *****************************/ function ShowPoll() { if ($this->AdejaVoter()==true) { return $this->ShowPollResult(); } $this->Poll = ''; $this->Poll .= sprintf($this->_GetHTML('q'),$this->IdQuestion,@$this->classes['q'],$this->question); $tmp = ''; $tmp2 = ''; foreach ($this->reponses as $key => $value) { $tmp2 = sprintf($this->_GetHTML('i'),(($this->ChoixMultiple)?"Checkbox":"Radio"),$this->IdQuestion.strval($key),$this->IdQuestion.strval($key),@$this->classes[$key],$this->IdQuestion.strval($key),@$this->classes[$key],$value); $tmp .= sprintf($this->_GetHTML($key),@$this->classes[$key],$this->IdQuestion.strval($key),$tmp2); } $this->Poll .= sprintf($this->_GetHTML('r'),$this->IdQuestion,@$this->classes['r'],$tmp); $this->Poll .= sprintf($this->_GetHTML('b'),$this->IdQuestion,@$this->classes['b'],$this->IdQuestion,@$this->classes['p'],$this->nomFichier,$this->nbQuestion,$this->IP,$this->ProgressShade); $this->Poll = sprintf($this->_GetHTML('c'),'i'.$this->IdQuestion,$this->Poll); return $this->Poll; } /***************************** Affiche le résultat du sondage *****************************/ function ShowPollResult() { //initialise le tableau des valeur $Q='['.$this->IdQuestion.']'; for ($j=0;$j<$this->nbQuestion;$j++) { $v='R'.$j; $$v=0; } //cree le fichier si c la premiere fois $handle = fopen($this->nomFichier, "a"); fclose ($handle); //Vire les \n $fline = file($this->nomFichier); for ($j=0;$j!=count($fline);$j++) { $fline[$j]=rtrim($fline[$j]); } $cpt=0; $startL=0; //recupere les precedente valeur foreach ($fline as $key => $value) { if ($value == $Q) { $cpt++; $startL=$cpt; for ($j=0;$j<$this->nbQuestion;$j++) { $v='R'.$j; $$v+=floatval($fline[$cpt+$j]); } } $cpt++; } $total=0; for ($j=0;$j<$this->nbQuestion;$j++) { $v='R'.$j; $total+=floatval($$v); } $this->rPoll = ''; $this->rPoll .= sprintf($this->_GetHTML('q'),'R'.$this->IdQuestion,@$this->classes['q'],$this->question.' ('.$total.' vote(s))'); $tmp = ''; $tmp2 = ''; foreach ($this->reponses as $key => $value) { $v = 'R'.$key; $prc = @round(($$v*100)/$total); $v = $$v; $back=($this->ProgressShade!='')?';background:#'.$this->correctshade($this->ProgressShade,(101-$prc)):''; $col =($this->ProgressShade!='')?';color:#'.$this->OppositeHex($this->correctshade($this->ProgressShade,(101-$prc))):''; $tmp2 = sprintf($this->_GetHTML('is'),@$this->classes[$key],$value,$prc.'%'.$back.$col,@$this->classes['p'],$prc.'%'); $tmp .= sprintf($this->_GetHTML($key),@$this->classes[$key],'R'.$this->IdQuestion.strval($key),$tmp2); } $this->rPoll .= sprintf($this->_GetHTML('r'),'R'.$this->IdQuestion,@$this->classes['r'],$tmp); $this->rPoll = sprintf($this->_GetHTML('c'),'i'.'R'.$this->IdQuestion,$this->rPoll); return $this->rPoll; } /***************************** Implemente les javascripts obligatoire /!\ Attention, a n'appeller qu'une fois par page *****************************/ function AjaxPoll() { return "<script type=\"text/javascript\">\n function correctshade(color, shade) {\n r = hexToDec(color.substring(0,2));\n g = hexToDec(color.substring(2,4));\n b = hexToDec(color.substring(4,6));\n sum = (r + g + b);\n x = ((shade * 3) - sum) / sum;\n if (x >= 0) {\n x = x + 1;\n } else {\n x = 1 + x;\n }\n r = (x * r);\n g = (x * g);\n b = (x * b);\n r = decToHex(r);\n g = decToHex(g);\n b = decToHex(b);\n r=(r.length<2)?'0'+r:r;\n g=(g.length<2)?'0'+g:g;\n b=(b.length<2)?'0'+b:b;\n return r+g+b;\n }\n function OppositeHex(color) {\n r = decToHex(255 - hexToDec(color.substring(0,2)));\n r = (r.length > 1) ? r : '0'+r;\n g = decToHex(255 - hexToDec(color.substring(2,4)));\n g = (g.length > 1) ? g : '0'+g;\n b = decToHex(255 - hexToDec(color.substring(4,6)));\n b = (b.length > 1) ? b : '0'+b;\n return r+g+b;\n }\n function decToHex(dec) {\n var hexa=\"0123456789ABCDEF\";\n var hex=\"\";\n while (dec>15) {\n tmp=dec-(Math.floor(dec/16))*16;\n hex=hexa.charAt(tmp)+hex;\n dec=Math.floor(dec/16);\n }\n hex=hexa.charAt(dec)+hex;\n return(hex);\n }\n function hexToDec(hex) {\n return parseInt(hex,16);\n } \n function SendPollAjax(page,retfonc,methode,data) { \n var xhr_object = null; \n if(window.XMLHttpRequest) // Firefox \n xhr_object = new XMLHttpRequest(); \n else if(window.ActiveXObject) // Internet Explorer \n xhr_object = new ActiveXObject(\"Microsoft.XMLHTTP\"); \n else { // XMLHttpRequest non supporté par le navigateur \n alert(\"Votre navigateur ne supporte pas les objets XMLHTTPRequest...\"); \n return; \n } \n if (data=='') \n data=null; \n if(methode == \"GET\" && data != null) { \n page += \"?\"+data; \n data = null; \n } \n xhr_object.open(methode, page, true); \n xhr_object.onreadystatechange = function() { \n if(xhr_object.readyState == 4) \n eval(retfonc+'(\''+xhr_object.responseText+'\');'); \n } \n if(methode == \"POST\") \n xhr_object.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\"); \n xhr_object.send(data); \n } \n function SendPoll(mdid,p,n,b,i,c) { \n var x = document.forms['P'+mdid].elements; \n var data = 'p='+p+'&mdid='+mdid+'&nf='+n+'&nbq='+b+'&ip='+i+'&c='+c; \n for (var i = 0; i < x.length; i++) { \n if (x[i].checked==true) \n data += '&'+x[i].id+'='+x[i].value; \n \n } \n SendPollAjax('".basename(__FILE__)."','GetPollResult','POST',data); \n } function GetPollResult(r) { \n var d=r.split(';'); \n var id=d[0]; \n var classe=d[1]; \n var total=d[2]; \n var col=d[3]; \n var cpt=0; \n document.getElementById('Q'+id).innerHTML+=' ('+total+' vote(s))'; \n for(i=4;i<d.length-1;i++) { \n var prc=Math.round((d[i]*100)/total); \n var back=(col!='')?';background:#'+correctshade(col,101-prc):''; var fon =(col!='')?';color:#'+OppositeHex(correctshade(col,101-prc)):''; document.getElementById('R'+id+cpt).style.display='none'; \n document.getElementById('L'+id+cpt).innerHTML+='<div style=\"width:100%\"><div style=\"width:'+prc+'%'+back+fon+'\" class=\"'+classe+'\">'+prc+'%</div></div>'; \n cpt++; \n } \n document.getElementById('B'+id).style.display='none'; \n } \n </script>\n"; } /***************************** fonction interne qui regroupe les différentes balise html utlisée *****************************/ function _GetHTML($w) { $Cr="\n"; if (is_numeric($w)) return '<li class="%s" id="L%s">%s</li>'.$Cr; if ($w=='q') return '<div id="Q%s" class="%s">%s</div>'.$Cr; if ($w=='c') return '<div id="%s">%s</div>'.$Cr; if ($w=='r') return '<form name="P%s" action="?" method="POST"><ul class="%s">%s</ul></form>'.$Cr; if ($w=='is') return'<label class="%s">%s</label><div style="width:100%%"><div style="width:%s" class="%s">%s</div></div>'.$Cr; if ($w=='i') return '<input type="%s" name="Reponse" id="R%s" value="R%s" class="%s" /><label for="R%s" class="%s">%s</label>'.$Cr; if ($w=='b') return '<input type="button" id="B%s" value="Ok" class="%s" OnClick="SendPoll(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\');" />'; } } /***************************** Gestion de la sauvegarde des resultat dans le fichier *****************************/ if (@$_GET['mdid']) { $_POST=$_GET; } if (@$_POST['mdid']) { //initialise le tableau des valeur $Q='['.$_POST['mdid'].']'; for ($j=0;$j<$_POST['nbq'];$j++) { $v='R'.$j; $$v=0; } //cree le fichier si c la premiere fois $handle = fopen($_POST['nf'], "a"); fclose ($handle); //Vire les \n $fline = file($_POST['nf']); for ($j=0;$j!=count($fline);$j++) { $fline[$j]=rtrim($fline[$j]); } $cpt=0; $startL=0; //recupere les precedente valeur foreach ($fline as $key => $value) { if ($value == $Q) { $cpt++; $startL=$cpt; for ($j=0;$j<$_POST['nbq'];$j++) { $v='R'.$j; $$v+=floatval($fline[$cpt+$j]); } } $cpt++; } //Ajoute les nouvelle valeur foreach ($_POST as $key => $value) { if ($key == 'mdid') continue; if ($key == 'nf') continue; if ($key == 'nbq') continue; if ($key == 'p') continue; if ($key == 'c') continue; if ($key == 'ip') continue; $value=str_replace($_POST['mdid'],'',$value); eval('$'.$value.'++;'); } //replace les valeur dans le tableau if ($startL == 0) { $startL=$cpt; $fline[$startL]=$Q; $startL++; } for ($j=0;$j<$_POST['nbq'];$j++) { $v='R'.$j; $fline[$startL]=$$v; $startL++; } //Rajoute les \n for ($j=0;$j!=count($fline);$j++) { $fline[$j].="\n"; } //Stoket le array dans une variable string $fline = implode ('', $fline); //Ecrit le fichier definit //php5 => file_put_contents ($_POST['nf'], $fline); $handle = fopen($_POST['nf'], "w"); fwrite($handle, $fline); fclose($handle); //Genere et affiche la chaine de retour $tmp=''; $total=0; for ($j=0;$j<$_POST['nbq'];$j++) { $v='R'.$j; $tmp .= $$v.';'; $total+=floatval($$v); } if (@$_POST['ip']!='') { //Rajoute l'ip du voteur (format => Date(YmdHis) IP $md5question $insert_key = '[IP]'; $string=''; $old_data = file($_POST['nf']); $new_data = date('YmdHis').' '.$_POST['ip'].' '.$_POST['mdid']; $trouve=false; for($x=0;$x<count($old_data);$x++) { if(rtrim($old_data[$x]) != $insert_key) { $string .= $old_data[$x]; }else{ $string .= $insert_key."\r\n".$new_data."\r\n"; $trouve=true; } } if ($trouve==false) { $string .= "\r\n".$insert_key."\r\n".$new_data."\r\n"; } // write $string to file $handle = fopen($_POST['nf'], "w"); fwrite($handle, $string); fclose($handle); } //Affiche le retour echo $_POST['mdid'].';'.$_POST['p'].';'.$total.';'.$_POST['c'].';'.$tmp; exit; } ?>
Poll : instancie la classe et crée le sondage, sans l'afficher
ShowPoll : Affiche le sondage
ShowPollResult : Affiche le résultat du sondage sans poser la question.
AjaxPoll : Ajoute a la page les javascripts indispensable au post du sondage
AdejaVoter : Renvoie True si l'ip passé à Poll() à déja voté, false sinon.
Vous pouvez utliser ce bout de code pour essayer la classe :
<style type="text/css"> .progress { background:#654; font-size :10px; text-align:center } .rep { background:#789; font-size :12px } .quest { background:#987; font-weight:bold; text-align: center; font-size :14px } .btn { border:1px solid #000; background:#789 } .r { list-style-type:none } </style> <?php $r[0]="oui"; $r[1]="non"; $r[2]="c pas"; $c['r']="rep"; $c['p']="progress"; $c['q']="quest"; $c['b']="btn"; $c[0]="r"; $c[1]="r"; $c[2]="r"; $a= new Poll("sa va ?",$r,$c,'',3600,'112233',false); echo $a->AjaxPoll(); echo $a->ShowPoll(); echo $a->ShowPollResult(); $b= new Poll("sa va bien?",$r,$c,'',3600,'',true); echo $b->ShowPoll(); ?>
Discussion