phpJSvForm  v11.11.12
Des classes PHP, des JavaScripts pour créer facilement un formulaire.
phpJSvForm/form/clVerifForm.php
Aller à la documentation de ce fichier.
00001 <?php
00002 /*******************************************************************************
00003  This file is part of 'phpJSvForm'.
00004  Copyright (C) 2010-2011  Pierre POISSON (synanceia)
00005 
00006     'phpJSvForm' is free software: you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation, either version 3 of the License, or
00009     (at your option) any later version.
00010 
00011     'phpJSvForm' is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with 'phpJSvForm'.  If not, see <http://www.gnu.org/licenses/>.
00018 *******************************************************************************/
00019 
00041 /*******************************************************************************
00042 Historique : -------------------------------------------------------------------
00043 31/07/2010     PP   Création du fichier
00044 13/08/2010     PP   Première version finalisée
00045 15/08/2010     PP   Ajout de la classe 'Boutons'
00046 26/08/2010     PP   Ajout prise en compte du style CSS 'cssObligatoire'
00047 27/08/2010     PP   Correction bogue : ajout du saut de ligne si label trop long
00048 03/09/2010     PP   Correction bogue : miseEnForme_POST, les caractères spéciaux (exemple : 'apostrophe') n'étaient pas traités...
00049 04/09/2010     PP   Correction bogue : Form::verifForm, affichage message 'Le champ ... doit obligatoirement être renseigné'.
00050 05/09/2010     PP   Correction bogue : ajout du saut de ligne si label trop long (la correction du 27/08/2010 comportait une erreur)
00051 13/09/2010     PP   Ajout gestion de scripts personnalisés      
00052 19/09/2010     PP   Classe 'Liste' : Ajout possibilité de désactiver une option         
00053 21/09/2010     PP   Classe 'clFormConteneur' : Ajout des méthodes setDisabled, resetDisabled, setReadOnly, resetReadOnly, setValeurPOST
00054 21/02/2011     PP   Modification expression régulière pour URL
00055 26/07/2011     PP   Classe 'clFormElement' : Ajout de la méthode getDisabled
00056 27/07/2011     PP   Si les objets sont inhibés (disabled) alors le format des champs n'est pas vérifié (correction suite à maj du 26/07 de jsVerifForm.js)
00057 28/07/2011     PP   Ajout : inhibition de champs si case à cocher...
00058 24/08/2011     PP   Ajout : 'selectall_', un click sur une case particulière permet de valider automatiquement un ensemble de case à cocher
00059 05/09/2011     PP   Modif constructeur de la classe 'Liste' pour pouvoir intialiser l'objet sans fournir le tableau des valeurs
00060                     Ajout de la méthode 'setBtn' pour la classe 'Form'
00061 15/10/2011     PP   Bouton 'Annuler' renommé en 'Effacer'
00062 25/10/2011     PP   Correction bogue : ajout script perso. à un objet de type 'boutons' (boutons radios ou cases à cocher)
00063 01/11/2011     PP   Validation automatique du formulaire  (en l'absence du bouton 'Valider') dès qu'un champ est modifié
00064 05/11/2011     PP   Ajout de l'attribut "action" pour le formulaire, codage des méthodes setAction et getAction
00065 xx/11/2011     PP   Documentation au format doxygen
00066 *******************************************************************************/
00072 function htmlFormat($data)
00073 {
00074      return str_replace("\n",'<br/>',htmlentities($data, ENT_QUOTES, 'UTF-8')) ;
00075 }
00076 
00086 function miseEnForme_POST($clef)
00087 {
00088      if(!isset($_POST[$clef]))
00089      {
00090           return '' ;
00091      }
00092      else
00093      {
00094           if(is_array($_POST[$clef]))
00095           {
00096                for($i=0, $imax=count($_POST[$clef]) ; $i<$imax ; $i++)
00097                     $_POST[$clef][$i] = trim($_POST[$clef][$i]);
00098           }
00099           else
00100           {
00101                $_POST[$clef] = trim($_POST[$clef]) ;// suppression des espaces au début/à la fin...
00102           }
00103           $data=$_POST[$clef] ;
00104           if (get_magic_quotes_gpc()) // l'option magic_quotes protège automatiquement les guillemets simples et doubles
00105           { // échappement de tous les caractères qui doivent l'être, pour être utilisés dans une requête de base de données
00106                if(is_array($data))
00107                {
00108                     for($i=0, $imax=count($data) ; $i<$imax ; $i++)
00109                          $data[$i] = stripslashes($data[$i]);
00110                }
00111                else
00112                {
00113                     $data = stripslashes($data);
00114                }
00115           }    
00116           return $data ; 
00117      }
00118 }
00119 
00120 
00125 abstract class clFormBase
00126 {
00127      protected $id; 
00128      protected $classe; 
00130      protected $valeur; 
00133      protected $largeur; 
00141      public function setId($id)
00142      {
00143           $this->id=$id;
00144           return $this;
00145      }
00146      
00151      public function getId()
00152      {
00153           return $this->id;
00154      }
00155      
00161      public function setClasse($classe)
00162      {
00163           $this->classe=$classe;
00164           return $this;
00165      }
00166      
00172      public function addClasse($classe)
00173      {
00174           $this->classe=($this->classe=='')?$classe:(strstr($this->classe, $classe)?$this->classe:$this->classe.' '.$classe);
00175           return $this;
00176      }
00177 
00182      public function getClasse()
00183      {
00184           return $this->classe;
00185      }
00186      
00192      public function setValeur($valeur)
00193      {
00194           $this->valeur= trim($valeur) ;
00195           return $this;
00196      }
00197 
00202      public function getValeur()
00203      {
00204           return $this->valeur;
00205      }         
00206 
00212      public function setLargeur($largeur)
00213      {
00214           $this->largeur=$largeur;
00215           return $this;
00216      }
00217 
00221      abstract public function render();
00222 
00226      public function __toString()
00227      {
00228           return $this->render();
00229      }
00230 }
00231 
00235 abstract class clFormElement extends clFormBase
00236 {
00237      protected $label; 
00239      protected $disabled=false;
00241      protected $readonly=false;
00243      protected $textinfo; 
00245      protected $name ; 
00252      public function setLabel($label)
00253      {
00254           $this->label=$label;
00255           return $this;
00256      }
00257 
00262      public function getLabel()
00263      {
00264           return $this->label;
00265      }
00266      
00272      public function setName($name)
00273      {
00274           $this->name=$name;
00275           return $this;
00276      }
00277 
00282      public function getName()
00283      {
00284           return $this->name;
00285      }
00286      
00291      public function setValeurPOST()
00292      {
00293           $valeur=miseEnForme_POST($this->id) ;
00294           if($valeur)
00295           {
00296                $this->valeur=$valeur ;
00297                return true ;
00298           }
00299           return false ;
00300      }
00301      
00309      public function setTexteInfo($info)
00310      {
00311           $this->textinfo=$info;
00312           return $this;
00313      }
00314 
00318      public function setDisabled()
00319      {
00320           $this->disabled=true ;
00321      }
00322 
00326      public function resetDisabled()
00327      {
00328           $this->disabled=false ;
00329      }
00330      
00335      public function getDisabled() // (26/07/2011 - PP)
00336      {
00337           return $this->disabled ;
00338      }
00339      
00343      public function setReadOnly()
00344      {
00345           $this->readonly=true ;
00346      }
00347 
00351      public function resetReadOnly()
00352      {
00353           $this->readonly=false ;
00354      }
00355      
00359       public function render()
00360      {
00361           $ret='' ;
00362           if($this->classe!='') $ret.=' class="'.$this->classe.'"' ;
00363           if($this->name!='') $ret.=' name="'.$this->name.'"';
00364           else $ret.=' name="'.$this->id.'"';
00365           $ret.=' id="'.$this->id.'"';
00366           if($this->largeur!="") $ret.=' style="width:'.$this->largeur.'"' ;
00367           if($this->disabled) $ret.=' disabled="disabled"' ;
00368           if($this->readonly) $ret.=' readonly="readonly"' ;
00369           return $ret ;
00370      }
00371      
00375     protected function renderLabel()
00376      {    
00377           if($this->label!='') 
00378           {
00379                $ret="\t\t\t".'<label' ;
00380                if($this->classe!='') $ret.=' class="'.$this->classe.'"' ;
00381                $ret.='for="'.$this->id.'">'.$this->label.'</label>'."\r";
00382           }
00383           else $ret='';
00384           if($this->textinfo!='') 
00385                $ret.="\t\t\t".'<span class="invisible">'.htmlFormat($this->textinfo).'</span>'."\r" ;
00386 
00387           return $ret ;
00388      }
00389 }
00390      
00394 abstract class clFormConteneur extends clFormBase
00395 {
00397      protected  $tabInput;    
00398      
00403      public function addElement()
00404      {
00405           $fin = func_num_args();
00406           for($i=0;$i<$fin;$i++)
00407           {
00408                $this->tabInput[]=func_get_arg($i) ;
00409           }
00410           return $this ;
00411      }
00412      
00416      public function setDisabled()
00417      {
00418           if(!$this->tabInput) return ; // Si aucun élément dans tabInput ...
00419           foreach($this->tabInput as &$objet)
00420           {
00421                if(!is_string($objet)) $objet->setDisabled() ;
00422           }
00423      }
00424 
00428      public function resetDisabled()
00429      {
00430           if(!$this->tabInput) return ; // Si aucun élément dans tabInput ...
00431           foreach($this->tabInput as &$objet)
00432           {
00433                if(!is_string($objet)) $objet->resetDisabled() ;
00434           }
00435      }
00436 
00440      public function setReadOnly()
00441      {
00442           if(!$this->tabInput) return ; // Si aucun élément dans tabInput ...
00443           foreach($this->tabInput as &$objet)
00444           {
00445                if(!is_string($objet)) $objet->setReadOnly() ;
00446           }
00447      }
00448 
00452      public function resetReadOnly()
00453      {
00454           if(!$this->tabInput) return ; // Si aucun élément dans tabInput ...
00455           foreach($this->tabInput as &$objet)
00456           {
00457                if(!is_string($objet)) $objet->resetReadOnly() ;
00458           }
00459      }
00460      
00465      public function setValeurPOST()
00466      {
00467           if(!$this->tabInput) return ; // Si aucun élément dans tabInput ...
00468           foreach($this->tabInput as &$objet)
00469           {
00470                if(!is_string($objet)) $objet->setValeurPOST() ;
00471           }
00472      }
00473 
00477      public function render()
00478      {
00479           $ret='' ;
00480           $paragraphe=false ; 
00481           $div=false ;
00482           if(get_class($this)=='Form') // Faut-il ajouter une balise <div> au début ?
00483           {
00484                if (is_string($this->tabInput[0]))
00485                     $div=true ;
00486                else if(get_class($this->tabInput[0])!='Groupe') 
00487                     $div=true ;
00488           }
00489           if(get_class($this)=='Form' || get_class($this)=='Groupe') // Faut-il ajouter une balise <p> au début ?
00490           {
00491                if (is_string($this->tabInput[0]))
00492                     $paragraphe=true ;
00493                else if (get_class($this->tabInput[0])!='Paragraphe' && get_class($this->tabInput[0])!='Groupe') 
00494                     $paragraphe=true ;
00495           }    
00496           if($div)  $ret.="\t".'<div class="'.$this->classe.'">'."\r" ;
00497           if($paragraphe)     $ret.="\t\t".'<p class="'.$this->classe.' cssSansBordure">'."\r" ;
00498           for($i=0;$i<count($this->tabInput);$i++)
00499           {
00500                if (is_string($this->tabInput[$i]))
00501                     $ret.="\t\t\t".$this->tabInput[$i]."\r" ;
00502                else
00503                //Avant de préparer le code HTML : ajout de la classe 'cssformX' du parent si l'objet n'en possède pas ...
00504                {
00505                     $objet=$this->tabInput[$i] ;
00506                     if(preg_match('#cssform\d?#u', $this->classe,$matches)
00507                          && !preg_match('#cssform\d?#u', $objet->getClasse())) 
00508                               $objet->addClasse($matches[0]) ;   
00509                     $ret.=$objet->render() ;
00510                }
00511                if((get_class($this)=='Paragraphe' || $paragraphe) && $i+1<count($this->tabInput))
00512                {
00513                // Ajout d'un saut de ligne au sein des paragraphes...
00514                // uniquement si l'objet suivant est une chaine de caractères ou si le label n'est pas vide
00515                     if(!strstr($this->classe,'cssform0'))
00516                     {
00517                          if (is_string($this->tabInput[$i+1])) $ret.="\t\t\t<br />\r";
00518                          else if(get_class($this->tabInput[$i+1])!='Paragraphe' && get_class($this->tabInput[$i+1])!='Groupe') 
00519                          {
00520                                if($this->tabInput[$i+1]->getLabel()!='') $ret.="\t\t\t<br />\r";
00521                          }
00522                     }
00523                }
00524           }
00525           if($paragraphe)     $ret.="\t\t</p>\r" ;
00526           if($div)  $ret.="\t</div>\r" ;
00527           return $ret ;
00528      }
00529 }
00530 
00534 class Form extends clFormConteneur
00535 {
00536      private $boutons;   /*   indique si présence boutons en fin de formulaire */
00537      
00538      private $txtBtnPerso='La méthode "setTxtBtn" permet de personnaliser ce texte' ; /* (* Ajout du 29/07/2011 *) */
00539      
00540      private $verif=array();
00541                               /*   Tableau des vérifications à faire...
00542                                    Liste des champs séparés par une espace
00543                                    Exemple : array("exist" =>"Champ1 Champ3","tel"=>"Champ1 Champ2","courriel"=>"Champ3")
00544                                    Ce tableau permet de créer les champs de type HIDDEN indispensables au contrôle de validité du formulaire
00545                               */
00546      private $verifObj=array();
00547                               /*   Liste des objets...
00548                                    Exemple : array("exist" => array(Champ1, Champ3), "tel" => array(Champ1, Champ2) ...
00549                                    Ce tableau permet de valider (ou non) le formulaire.
00550                               */
00551      private $scripts=array() ;
00552                               /*   Tableau permettant de générer des scripts personnalisés
00553                                    Exemple : array(0 => array("Champ1", "change", "this.form.submit() ;"))
00554                                    Ce tableau est mis à jour par la méthode addScript
00555                               */
00556      private $nbScript=0 ;
00557                               /*   Nombre de scripts ajoutés dans $scripts
00558                                    idem à count($scripts) !
00559                               */
00560      private $action='' ;
00561                               /*
00562                                    Attribut action de la balise 'form'.
00563                               */
00564      /* La propriété $valeur est utilisée pour stocker le-s message-s d'erreur suite à un
00565         contrôle de validation du formulaire. */
00566      
00573      public function __construct($u_id='', $u_boutons=7, $u_classe='cssform')
00574      {
00575           $this->id=($u_id==''?'formulaire':$u_id);
00576           $this->classe=$u_classe;
00577           $this->boutons=$u_boutons ;
00578      }
00579 
00589      public function setBtn($u_boutons)
00590      {
00591           $this->boutons=$u_boutons ;
00592      }
00593      
00600      public function setTxtBtn($chaine)
00601      {
00602           $this->txtBtnPerso=$chaine ;
00603           return $this ;
00604      }
00605      
00611      public function setAction($chaine) 
00612      {
00613           $this->action=$chaine ;
00614           return $this ;
00615      }
00616      
00620      public function getAction() {
00621           return $this->action ;
00622      }
00623      
00634      public function addScript($objet, $evenement, $fonction)
00635      {
00636 
00637           $this->scripts[$this->nbScript]=array($objet->getId(), $evenement, $fonction) ;
00638           $this->nbScript++ ;
00639      }
00640      
00646      public function addVerif()
00647      {
00648           $fin = func_num_args();
00649           if($fin<2) return 0;
00650           if(!is_string(func_get_arg(0))) return 0;
00651           
00652           for($i=0;$i<$fin;$i++)
00653           {
00654                $variable=func_get_arg($i);
00655                if(is_string($variable)) $key=$variable ;
00656                else
00657                {    //$variable est un objet (ou un tableau de 2 objet dans le cas de 'copie_') ...
00658                     if(array_key_exists($key, $this->verifObj))
00659                     {
00660                          if(!preg_match('#^copie_#u',$key)) $this->verif[$key].=' '.$variable->getId();
00661                          else $this->verif[$key].=' '.$variable[0]->getId().' '.$variable[1]->getId();
00662                          $this->verifObj[$key][] = $variable ;
00663                     }
00664                     else
00665                     {
00666                          $this->verif[$key] = $variable->getId();
00667                          $this->verifObj[$key] = array($variable) ;
00668                     }    
00669 
00670                     // si la clé vaut 'exist' alors on ajoute la classe 'cssObligatoire' à l'objet
00671                     if ($key=='exist') $variable->addClasse('cssObligatoire') ;
00672                }
00673           }
00674           return count($this->verif) ;
00675      }
00676      
00687      public function verifForm($premiereFois='silence')
00688      { 
00689           $modeSilence=FALSE ;
00690           if(!isset($_POST['soumettre']) || $_POST['soumettre']=='Réinitialiser')
00691           {// La première fois (si $_POST['soumettre'] n'existe pas) alors
00692                if($premiereFois == 'non') return FALSE ; // verifForm peut ne pas être exécuté...
00693                if($premiereFois == 'silence') $modeSilence=TRUE ; //verifForm s'éxécute discrètement (mise en forme seulement)
00694           }
00695           foreach($this->verifObj as $key => $listeObj)
00696           {
00697                foreach($listeObj as $champ)
00698                {
00699                     if(preg_match('#^desact_#u', $key) && is_object($listeObj[0]))
00700                     // (28/07/2011 - PP)
00701                     {
00702                          if(!is_array($champ)) 
00703                          {
00704                               if($champ->getId()!=$listeObj[0]->getId() && $listeObj[0]->getValeur()!=NULL) 
00705                               // Si le champ à traiter est la case à cocher elle-même, alors pas de traitement
00706                               // Si le champ est réellement à traiter et que la case est cochée alors traitement
00707                               { 
00708                                    if($premiereFois != 'silence' && $champ->getValeur()!="")
00709                                    // La première fois, on ne supprime pas toutes les données
00710                                    {
00711                                         $champ->setValeur("") ;
00712                                         $this->valeur.='Le champ <i>'.$champ->getLabel().'</i> a été vidé.<br />' ;
00713                                    }
00714                                    $champ->setDisabled() ;
00715                               }
00716                          }
00717                     }
00718                     else if(preg_match('#^copie_#u', $key) && is_object($listeObj[0]))
00719                     {
00720                          // Si case cochée et recopie attendue ...
00721                          if(is_array($champ) && $listeObj[0]->getValeur()!=NULL)
00722                               // Recopie des valeurs 
00723                               if($champ[0]->getValeur()!=$champ[1]->getValeur() && !$champ[0]->getDisabled() && !$champ[1]->getDisabled())
00724                               {
00725                                    $champ[0]->setValeur($champ[1]->getValeur());
00726                                    $this->valeur.='Le champ <i>'.$champ[0]->getLabel().'</i> a été remplacé.<br />' ;
00727                               }
00728                     }
00729                     else
00730                     {
00731                          $aTester=$champ->getValeur() ;
00732                          if(!$modeSilence)
00733                          {
00734                               if($key=='exist' || (preg_match('#^exist_#u', $key) && $listeObj[0]->getValeur()!=''))
00735                               {
00736                                    if ($aTester=='' && !$champ->getDisabled() ) // Test uniquement si le champ n'est pas désactivé
00737                                    {
00738                                         $this->valeur.='Le champ <i>'.$champ->getLabel().'</i> doit obligatoirement être renseigné.::'.$champ->getDisabled().'::<br />' ;
00739                                         $champ->addClasse('cssErreur') ;
00740                                    }
00741                               }
00742                               else if(preg_match('#^exist_#u', $key) && $listeObj[0]->getValeur()=='')
00743                               { // La case à cocher 'existe si...' n'est pas cochée et le champ 'à tester' n'est pas vide
00744                                    if ($aTester!='') 
00745                                    {
00746                                         $this->valeur.='Le champ <i>'.$champ->getLabel().'</i> ne peut pas être pris en compte. Supprimez son contenu ou cochez la case autorisant ce champ.<br />' ;
00747                                         $champ->addClasse('cssErreur') ;
00748                                    }
00749                               }
00750                               else if(preg_match('#^egal_#u', $key))
00751                               {
00752                                    if($listeObj[0]->getValeur()!=$aTester && !$listeObj[0]->getDisabled() && !$champ->getDisabled()) // Test uniquement si les champs ne sont pas désactivés
00753                                    {
00754                                         $this->valeur.='Le champ <i>'.$champ->getLabel().'</i> n\'est pas identique au champ <i>'.$listeObj[0]->getLabel().'</i><br />' ;
00755                                         $champ->addClasse('cssErreur') ;
00756                                    }
00757                               }
00758                          }
00759                          
00760                          if (!preg_match('#^exist#u', $key) && !preg_match('#^egal#u', $key) && !preg_match('#^desact#u', $key) 
00761                                         && !preg_match('#^selectall_#u', $key) && $aTester!='')
00762                          {
00763                               switch($key)
00764                               {
00765                                    case 'date' :
00766                                         $varTime=strtotime(preg_replace(array('#\/#u','#^(\d{2})\-(\d{2})\-(\d{2})$#u'),array('-','$3-$2-$1'),$aTester)) ;
00767                                         $misEnForme=$varTime?date('d/m/Y',$varTime):'' ;
00768                                         $expReg='/^\d{2}\/\d{2}\/\d{4}$/' ;
00769                                         $messErr='La date <i>'.$champ->getLabel().'</i> n\'est pas valide. Formats autorisés : 2010-08-23, 23/08/2010<br />' ;
00770                                         break ;
00771                                    case 'tel' :
00772                                         $misEnForme=preg_replace(array('/[^0-9]/u','#^0?([1-9])(\d{2})(\d{2})(\d{2})(\d{2})$#u'), array('','0$1.$2.$3.$4.$5'), $aTester) ;
00773                                         $expReg='/^0\d\.\d{2}\.\d{2}\.\d{2}\.\d{2}$/' ;
00774                                         //$expReg='#^([0-9]{2}[ -]?){5}$#' ;
00775                                         $messErr='Le champ <i>'.$champ->getLabel().'</i> n\'est pas valide. Le numéro doit être constitué de 10 chiffres et débuter par 0.<br />' ;
00776                                         break ;
00777                                    case 'courriel' :
00778                                         $misEnForme=mb_strtolower($aTester,'utf-8') ;                                        
00779                                         $expReg='/^[a-z0-9_.-]+@[a-z0-9_.-]+\.[a-z]{2,6}$/' ;
00780                                         $messErr='L\'adresse électronique <i>'.$champ->getLabel().'</i> n\'est pas valide.<br />' ;
00781                                         break ;
00782                                    case 'url' :
00783                                         $misEnForme=mb_strtolower($aTester,'utf-8') ;
00784                                         // $expReg='/^https?:\/\/((\d+\.\d+\.\d+\.\d+)|(([a-z0-9_-]+\.)+([a-z][a-z0-9_-]*)))\/?$/' ;
00785                                         // $expReg='/^http(s)?:\/\/([a-zA-Z0-9-_]+.){0,4}[a-zA-Z0-9-]+\.[a-zA-Z]{2,4}(:[0-9]+)?(\/[a-zA-Z0-9-]*\/?|\/[a-zA-Z0-9]+\.[a-zA-Z0-9]{1,4})?$/' ;
00786                                         $expReg='/^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/' ;
00787                                         $messErr='L\'adresse du site Web (URL) <i>'.$champ->getLabel().'</i> n\'est pas valide (ne pas oublier le préfixe http:// !).<br />' ;
00788                                         break ;
00789                                    case 'login' :                               
00790                                         $misEnForme=preg_replace('/[^\w.-]/u', '', $aTester) ; // ne conserver que les caractères autorisés
00791                                         $expReg='/^[\w.-]+$/' ;
00792                                         $messErr='Le champ <i>'.$champ->getLabel().'</i> n\'est pas valide. Il ne doit être constitué que de lettres non accentuées, de chiffres ou des signes \'-\', \'_\' et \'.\'<br />' ;
00793                                         break ;
00794                                    case 'codePostal' : // 2 ou 5 chiffres !
00795                                         $misEnForme=preg_replace('/[^0-9]/u', '', $aTester) ; // ne conserver que les chiffres
00796                                         $expReg='/^(\d{2})(\d{3})?$/' ;
00797                                         $messErr='Le code postal <i>'.$champ->getLabel().'</i> n\'est pas valide. Il doit être constitué de 2 ou 5 chiffres.<br />' ;
00798                                         break ;
00799                                    case 'APE' : // code de 4 chiffres suivis d'une lettre majuscule
00800                                         $misEnForme=mb_strtoupper($aTester,'utf-8') ;
00801                                         $expReg='/^\d{4}[A-Z]$/' ;
00802                                         $messErr='Le code APE <i>'.$champ->getLabel().'</i> n\'est pas valide. Il doit être constitué de de 4 chiffres suivis d\'une lettre.<br />' ;
00803                                         break ;
00804                                    case 'SIRET' :
00805                                         $misEnForme=rtrim(preg_replace(array('/[^0-9]/u','/^(\d{3})(\d{3})(\d{3})(\d{5})?$/u'), array('','$1-$2-$3 $4'), $aTester)) ;
00806                                         $expReg='/^(\d{3})-(\d{3})-(\d{3})( \d{5})?$/' ;
00807                                         $messErr='Le code SIRET <i>'.$champ->getLabel().'</i> n\'est pas valide. Il doit être constitué de 14 chiffres. A défaut, le code SIREN, constitué de 9 chiffres peut être accepté.<br/>' ;
00808                                         break ;
00809                                    case 'NIRPP' : // num. sécu.
00810                                         $misEnForme=preg_replace(array('/[^0-9]/u','/^(\d{1})(\d{2})(\d{2})(\d{2})(\d{3})(\d{3})(\d{2})$/u'), array('','$1.$2.$3.$4.$5.$6 ($7)'), $aTester) ;
00811                                         $expReg='/^\d.(\d{2}).(\d{2}).(\d{2}).(\d{3}).(\d{3}) \((\d{2})\)$/' ;
00812                                         $messErr='Le NIRPP <i>'.$champ->getLabel().'</i> n\'est pas valide. Il doit être constitué de 15 chiffres.<br/>' ;
00813                                         break ;
00814                               }
00815                               if (!preg_match($expReg, $misEnForme))
00816                               {
00817                                    $this->valeur.=$messErr ;
00818                                    if(!$modeSilence) $champ->addClasse('cssErreur') ;
00819                               }
00820                               elseif ($misEnForme!=$aTester)
00821                               {
00822                                    $this->valeur.='Le champ <i>'.$champ->getLabel().'</i> a été remis en forme.<br />' ;
00823                                    if(!$modeSilence)$champ->addClasse('cssAvert') ;
00824                                    $champ->setValeur($misEnForme) ;
00825                               }
00826                          }
00827                          
00828                          if($modeSilence) $this->valeur='' ;
00829                     }
00830                }
00831           }
00832           return (($this->valeur=='' && isset($_POST['soumettre']) && $_POST['soumettre']!='Réinitialiser')?$_POST['soumettre']:NULL) ;
00833      }
00837      public function render()
00838      {
00839           /* Génération de la fonction JS verifAvantSoumission */
00840           $ret='
00841 <script language="javascript" type="text/javascript">
00842      <!--
00843           function verifAvantSoumission()
00844           {
00845                var Erreur ;
00846                nettoieFormulaireAvantSoumission(document.getElementById("'.$this->id.'")) ;
00847                Erreur = 0 ';
00848           foreach($this->verif as $key => $value)
00849           {
00850                if(preg_match('#^exist#u', $key))
00851                     $ret.='
00852                + verifExist(document.getElementById("'.$this->id.'"), "'.$key.'", "'.$value.'") ' ;
00853                else if(preg_match('#^egal_#u', $key))
00854                {
00855                     $tok=strtok($value,' ') ;
00856                     $tok=strtok(' ') ;
00857                     while($tok!==false)
00858                     {
00859                          $ret.='
00860                + egalVerif(document.getElementById("'.$tok.'")) ' ;
00861                          $tok=strtok(' ') ;
00862                     }
00863                }
00864                else if(strstr(' date tel url courriel login codePostal APE SIRET NIRPP ',' '.$key.' ')!=NULL)
00865                {
00866                     $tok=strtok($value,' ') ;
00867                     while($tok!==false)
00868                     {
00869                          $ret.='
00870                + verif_'.$key.'(document.getElementById("'.$tok.'")) ' ;
00871                          $tok=strtok(' ') ;  
00872                     }
00873                }
00874           }         
00875           $ret.=' ;
00876                return Erreur ;
00877           }' ;
00878 
00879           /* Génération des javascripts ajoutés à l'aide de addScript */
00880           if($this->nbScript)
00881           {
00882                for($i=0 ; $i<$this->nbScript ; $i++)
00883                {
00884                     $tok = strtok($this->scripts[$i][0], ' '); // La chaine scripts[$i][0] est parcouru s'il s'agit d'une liste d'éléments
00885                     while ($tok !== false)
00886                     {
00887                          $ret.='
00888      add_Event(document.getElementById("'.$tok.'"),"'.$this->scripts[$i][1].'",function() {
00889      '.$this->scripts[$i][2].'
00890      }) ;' ;
00891                          $tok = strtok(' ');
00892                     }
00893                }
00894           }
00895           $ret.='
00896      // -->
00897 </script>' ;
00898 
00899           /* Génération du formulaire */
00900           $ret.='
00901 <form';
00902           $ret.=' id="'.$this->id.'"'; 
00903           $ret.=' name="'.$this->id.'"'; // pas de choix name == id !
00904           $ret.=' class="'.$this->classe.'"'; 
00905           $ret.=' method="post"'; // pas de choix dans la méthode !
00906           $ret.=' enctype="multipart/form-data"'; 
00907           $ret.=' action="'.$this->action.'" >
00908           '; // pas de choix dans l'action, le traitement sera réalisé par la même page PHP
00909           
00910           if($this->valeur!='') // $valeur contient un message d'erreur...
00911                $ret.="\t".'<p class="cssErreur">'.$this->valeur.'</p>'."\r" ;
00912                
00913           foreach($this->verif as $key => $value)
00914           {
00915                $ret.="\t".'<input type="hidden" id="'.$this->id.'__'.$key.'" name="'.$this->id.'__'.$key.'" value="'.$value.'" />'."\r" ;
00916           }
00917           
00918           $ret.=parent::render() ;
00919           if($this->boutons!=-1) 
00920           {
00921                $ret.="\t\t".'<p class="cssBtn cssSansBordure">'."\r" ;
00922                if($this->boutons==0 || $this->boutons==4)
00923                {
00924                /*   $this->boutons==0 : cas particulier, si JS activé, pas de bouton le formulaire est validé automatiquement
00925                     $this->boutons==4 : cas particulier, si JS activé, seul le bouton "Réinitialiser" est affiché, le formulaire est validé automatiquement
00926                     Le bouton "Valider" est supprimé par JS
00927                 */
00928                     $ret.="\t\t\t".'<input id="'.$this->id.'__valid_nodisp" type="submit"' ;
00929                     if($this->largeur!='') $ret.=' style="width:'.$this->largeur.'"' ;
00930                     $ret.=' name="soumettre" value="Valider" />'."\r";
00931                }
00932                else if($this->boutons&0x01)
00933                {
00934                     $ret.="\t\t\t".'<input id="'.$this->id.'__valider" type="submit"' ;
00935                     if($this->largeur!='') $ret.=' style="width:'.$this->largeur.'"' ;
00936                     $ret.=' name="soumettre" value="Valider" />'."\r";
00937                }
00938                if($this->boutons&0x08)
00939                {
00940                     $ret.="\t\t\t".'<input id="'.$this->id.'__perso" type="submit"' ;
00941                     if($this->largeur!='') $ret.=' style="width:'.$this->largeur.'"' ;
00942                     $ret.=' name="soumettre" value="'.$this->txtBtnPerso.'" />'."\r";
00943                }
00944                if($this->boutons&0x02)
00945                {
00946                     $ret.="\t\t\t".'<input id="'.$this->id.'__annuler" type="reset"' ;
00947                     if($this->largeur!='') $ret.=' style="width:'.$this->largeur.'"' ;
00948                     $ret.=' name="effacer" value="Effacer" />'."\r";
00949                }
00950                if($this->boutons&0x04)
00951                {
00952                     $ret.="\t\t\t".'<input id="'.$this->id.'__reinit" type="submit"' ;
00953                     if($this->largeur!='') $ret.=' style="width:'.$this->largeur.'"' ;
00954                     $ret.=' name="soumettre" value="Réinitialiser" />'."\r";
00955                }
00956                $ret.="\t\t</p>\r" ;
00957           }
00958           $ret.='</form>'."\r";
00959           
00960           return $ret;
00961      }
00962 }
00963 
00967 class Paragraphe extends clFormConteneur
00968 {
00977      public function __construct($u_id='', $u_valeur='', $u_classe='', $u_largeur='')
00978      {
00979           $this->id=$u_id;
00980           $this->valeur=$u_valeur;
00981           $this->classe=$u_classe ;
00982           $this->largeur=$u_largeur ;
00983      }
00984 
00989      public function render()
00990      {
00991           $ret="\t\t<p" ;
00992           if($this->classe!='') $ret.=' class="'.$this->classe.'"' ;
00993           if($this->id!='') $ret.=' id="'.$this->id.'"';
00994           if($this->largeur!='') $ret.=' style="width:'.$this->largeur.'"' ;
00995           $ret.=' > ';
00996           if($this->valeur!='') $ret.=$this->valeur.'<br />' ;   
00997           $ret.="\r" ;
00998           $ret.=parent::render() ;
00999           $ret.="\t\t</p>\r";
01000           return $ret;
01001      }
01002 }
01003 
01007 class Groupe extends clFormConteneur
01008 {
01009      private $legende ;
01010      
01019      public function __construct($u_id='', $u_legende='', $u_valeur='', $u_classe='', $u_largeur='')
01020      {
01021           $this->id=$u_id;
01022           $this->legende=$u_legende;
01023           $this->valeur=$u_valeur;
01024           $this->classe=$u_classe ;
01025           $this->largeur=$u_largeur ;
01026      }
01027 
01031      public function setLegende($legende)
01032      {
01033           $this->legende=$legende;
01034           return $this;
01035      }
01036 
01041      public function render()
01042      {
01043           $ret="\t".'<fieldset' ;
01044           if($this->valeur!='') $ret.=' title="'.htmlFormat($this->valeur).'"' ;
01045           if($this->classe!='') $ret.=' class="'.$this->classe.'"' ;
01046           if($this->id!='') $ret.=' id="'.$this->id.'"';
01047           if($this->largeur!='') $ret.=' style="width:'.$this->largeur.'"' ;
01048           $ret.=" >\r";
01049           if($this->legende!='') $ret.="\t".'<legend>'.htmlFormat($this->legende).'</legend>'."\r" ;     
01050           $ret.=parent::render() ;
01051           $ret.="\t".'</fieldset>'."\r";
01052           return $ret;
01053      }
01054 }
01055 
01059 class Input extends clFormElement
01060 {
01061      private $type ; 
01062      
01075      public function __construct($u_id, $u_label='', $u_valeur='', $u_type='', $u_info='', $u_classe='', $u_largeur='')
01076      {              
01077           $this->id=$u_id;
01078           if($u_type=='button'||$u_type=='submit') // Le texte du bouton n'est pas modifié par la soumission du formulaire !!!
01079                $this->valeur=trim($u_valeur) ;
01080           else
01081                $this->valeur=((isset($_POST['soumettre']) && $_POST['soumettre']!='Réinitialiser') ? miseEnForme_POST($u_id) : trim($u_valeur)) ;
01082           $this->label=$u_label;
01083           $this->type=($u_type=='' ? 'text' : $u_type) ;
01084           $this->textinfo=$u_info ;
01085           $this->classe=$u_classe ;
01086           $this->largeur=$u_largeur ;
01087      }
01088 
01093      public function render()
01094      {
01095           $ret=parent::renderLabel();
01096           if(strlen(utf8_decode($this->label))>30 && (strstr($this->getClasse()." ", "cssform ") || strstr($this->getClasse()." ", "cssform2 "))) $ret.="\t\t\t<br />\r" ; // Le label est trop long pour être affiché sur une seule ligne
01097           $ret.="\t\t\t<input type='".$this->type."'" ;
01098           $ret.=parent::render() ;
01099           if($this->valeur!='')
01100           {
01101                $ret.=' value="'.htmlFormat($this->valeur).'"' ;
01102           }
01103           if($this->type=="checkbox" && $this->valeur)
01104           {
01105                $ret.=' checked="checked" ';
01106           }
01107           $ret.=" />\r";
01108           return $ret;
01109      }
01110 }
01111 
01115 class Texte extends clFormElement
01116 {
01117      private $lignes ;
01118      private $colonnes ;
01119      
01133      public function __construct($u_id, $u_label='', $u_valeur='', $u_lignes=4, $u_colonnes='', $u_info='', $u_classe='', $u_largeur='')
01134      {
01135           $this->id=$u_id;
01136           $this->lignes=$u_lignes;
01137           $this->colonnes=$u_colonnes;
01138           $this->valeur=((isset($_POST['soumettre']) && $_POST['soumettre']!='Réinitialiser') ? miseEnForme_POST($u_id) : trim($u_valeur)) ;
01139           $this->textinfo=$u_info ;
01140           $this->label=$u_label;
01141           $this->classe=$u_classe ;
01142           $this->largeur=$u_largeur ;
01143      }
01144 
01149      public function render()
01150      {
01151           $ret=parent::renderLabel();
01152           //if(strlen(utf8_decode($this->label))>30 && (strstr($this->getClasse().' ', 'cssform ') || strstr($this->getClasse().' ', 'cssform2 '))) $ret.="\t\t\t<br />\r" ; // Le label est trop long pour être affiché sur une seule ligne
01153           /* On peut supposer, qu'il y a suffisamment de place à gauche de la TextArea pour écrire l'intégralité
01154           du texte long ==> pas de vérification */
01155           
01156           $ret.="\t\t\t".'<textarea' ;
01157           $ret.=parent::render() ;
01158           $ret.=' cols="'.$this->colonnes.'"';
01159           $ret.=' rows="'.$this->lignes.'"';
01160           $ret.=' >';
01161           if($this->valeur!='') $ret.=$this->valeur ;
01162           $ret.='</textarea>'."\r";
01163           return $ret;
01164      }
01165 }
01166 
01170 class Liste extends clFormElement
01171 {
01172      private $tabOption ; // Tableau à 2 dimensions
01173      // $tabOption['texte'] : texte à afficher
01174      // $tabOption['valeur'] : valeur correspondante
01175      // $tabOption['desactive'] : contient une valeur différente de 0 si la valeur associée doit être désactivée (grisée)
01176      private $tabTexte ;
01177      
01191      public function __construct($u_id, $u_label='', $u_valeur='', $tabValeur=array(), $tabTexte=array(), $u_info='', $u_classe='', $u_largeur='')
01192      {
01193           $this->id=$u_id;
01194           $this->valeur=((isset($_POST['soumettre']) && $_POST['soumettre']!='Réinitialiser' ) ? miseEnForme_POST($u_id) : trim($u_valeur)) ;
01195           if($tabValeur==NULL && $tabTexte!=NULL)
01196           { // [05/09/2011 (PP) : si $tabValeur vaut NULL alors on initialise la liste des valeurs de 0 à ...]
01197                for($i=0, $i_max=count($tabTexte); $i<$i_max ; $i++)
01198                {
01199                     $this->tabOption['valeur'][$i]= $i ;
01200                     $this->tabOption['texte'][$i]=trim($tabTexte[$i]) ;
01201                     $this->tabOption['desactive'][$i]=false ;
01202                }
01203           }
01204           else
01205           {
01206                $this->tabOption['valeur']= $tabValeur ;
01207                for($i=0, $i_max=count($tabValeur); $i<$i_max ; $i++)
01208                {
01209                     $this->tabOption['texte'][$i]=trim($tabTexte==NULL?$tabValeur[$i]:$tabTexte[$i]) ;
01210                     $this->tabOption['desactive'][$i]=false ;
01211                }
01212           }
01213           $this->textinfo=$u_info ;
01214           $this->label=$u_label;
01215           $this->classe=$u_classe ;
01216           $this->largeur=$u_largeur ;
01217      }
01218 
01230      public function majOptions($tab, $mode='valeur')
01231      {
01232           $this->tabOption[$mode]=$tab ;
01233      }
01234 
01240      public function setDisabledValeur($valeur)
01241      {
01242           $key = array_search($valeur, $this->tabOption['valeur']) ;
01243           if($key!==false)
01244           {
01245                $this->tabOption['desactive'][$key]=true ;
01246                return true ;
01247           }
01248           else
01249                return false ;
01250      }
01251 
01257      public function resetDisabledValeur($valeur)
01258      {
01259           $key = array_search($valeur, $this->tabOption['valeur']) ;
01260           if($key!==false)
01261           {
01262                $this->tabOption['desactive'][$key]=false ;
01263                return true ;
01264           }
01265           else
01266                return false ;
01267      }
01268 
01274      public function setReadOnly(){
01275           return false ;}
01276 
01282      public function resetReadOnly(){
01283           return false ;}
01284      
01288      public function render()
01289      {
01290           $ret=parent::renderLabel();
01291           if(strlen(utf8_decode($this->label))>30 && (strstr($this->getClasse().' ', 'cssform ') || strstr($this->getClasse().' ', 'cssform2 '))) $ret.="\t\t\t<br />\r" ; // Le label est trop long pour être affiché sur une seule ligne
01292           
01293           $ret.="\t\t\t".'<select' ;
01294           $ret.=parent::render() ;
01295           $ret.=' >'."\r";
01296           
01297           if($this->textinfo!='') // Si textinfo est défini, il est intéressant d'avoir la valeur 'vide' autorisé !
01298           {
01299                $ret.="\t\t\t\t".'<option value=""';
01300                $ret.='>&nbsp;</option>'."\r" ;
01301           }
01302           
01303           /* Ici, on suppose que le tableau tabOption['valeur'] contient suffisament de données par rapport à
01304           tabOption['texte']. Aucune vérification n'est faite ! */
01305           for($i=0 ; $i<count($this->tabOption['texte']) ; $i++)
01306           {
01307                $ret.="\t\t\t\t".'<option value="'.$this->tabOption['valeur'][$i].'"';
01308                if($this->valeur==$this->tabOption['valeur'][$i]) $ret.=' selected="selected"' ;
01309                if($this->tabOption['desactive'][$i]) $ret.=' disabled="disabled"' ;
01310                $ret.='>'.htmlFormat($this->tabOption['texte'][$i]).'</option>'."\r" ;
01311           }
01312           $ret.="\t\t\t".'</select>'."\r";
01313           return $ret;
01314      }
01315 }
01316 
01320 class Boutons extends clFormElement
01321 {
01322      private $type ; /* TYPE de l'input : "radio" ou "checkbox" */
01323      private $valeurS ; // Tableau, liste des valeurs
01324      /* ATTENTION 
01325       * La propriété '$id' est détournée, ici, il s'agira de la valeur de 'name'
01326           L' 'id' sera obtenu en combinant 'name' et 'value'
01327       * La propriété '$label' est un tableau qui contient la liste des étiquettes
01328       * La propriété '$textinfo' n'est pas utilisée !
01329       */
01330      
01343      public function __construct($u_name, $u_type, $tab_label, $tab_valeur=NULL, $u_valeur='', $u_classe='', $u_largeur='')
01344      {
01345           $this->id=$u_name;  
01346           $this->type=$u_type ;
01347           $this->label=$tab_label ; // Tableau, liste des étiquettes
01348           if($tab_valeur!=NULL)
01349                $this->valeurS=$tab_valeur ; // Tableau, liste des valeurs
01350           else
01351                $this->valeurS=$tab_label ; 
01352           
01353           $u_name=(substr($u_name,-2)=='[]' ? substr($u_name,0,-2) : $u_name);
01354           $this->valeur=((isset($_POST['soumettre']) && $_POST['soumettre']!='Réinitialiser') ? miseEnForme_POST($u_name) : $u_valeur) ;
01355           $this->classe=$u_classe ;
01356           $this->largeur=$u_largeur ;
01357      }
01358 
01362      public function getLabel()
01363      {
01364           $ret='' ;
01365           for($i=0, $imax=count($this->label) ; $i<$imax ;$i++)
01366           {
01367                $ret.=$this->label[$i] ;
01368                if($i<$imax-1) $ret.=', ' ;
01369           }
01370           return $ret ;
01371      }
01372 
01376      public function getId()
01377      {
01378           $id_nom=(substr($this->id,-2)=='[]'?substr($this->id,0,-2):$this->id);
01379           $ret='' ;
01380           for($i=0, $imax=count($this->valeurS) ; $i<$imax ;$i++)
01381           {
01382                $ret.=$id_nom.'_'.$this->valeurS[$i] ;
01383                if($i<$imax-1) $ret.=' ' ;
01384           }
01385           return $ret ;
01386      }
01387      
01391      public function getValeur()
01392      {
01393           if($this->type=='radio')
01394           {
01395                // $this->valeur, n'est retournée que si elle est dans $this->valeurS
01396                return (in_array($this->valeur,$this->valeurS)?$this->valeur:'') ;
01397           }
01398           else //$this->type=='checkbox'
01399           {
01400                return $this->valeur ;
01401           }
01402      }    
01403      
01408      public function render()
01409      {
01410           $id_nom=(substr($this->id,-2)=='[]'?substr($this->id,0,-2):$this->id);
01411           $ret='';
01412           for($i=0, $imax=count($this->valeurS) ; $i<$imax ; $i++)
01413           {
01414                if($this->label[$i]!='') // A priori : l'étiquette est obligatoire...
01415                {
01416                     $ret.="\t\t\t".'<label' ;
01417                     if($this->classe!='') $ret.=' class="'.$this->classe.'"' ;
01418                     $ret.='for="'.$id_nom.'_'.$this->valeurS[$i].'">'.htmlFormat($this->label[$i]).'</label>';
01419                }
01420                if(strlen($this->label[$i])>30 && (strstr($this->getClasse().' ', 'cssform ') || strstr($this->getClasse().' ', 'cssform2 '))) $ret.='<br />' ; // Le label est trop long pour être affiché sur une seule ligne
01421                $ret.='<input type="'.$this->type.'"' ;
01422                if($this->classe!='') $ret.=' class="'.$this->classe.'"' ;
01423                $ret.=' name="'.$this->id.'"';
01424                $ret.=' id="'.$id_nom.'_'.$this->valeurS[$i].'"';
01425                if($this->largeur!='') $ret.=' style="width:'.$this->largeur.'"' ;
01426                if($this->disabled) $ret.=' disabled="disabled"' ;
01427                if($this->readonly) $ret.=' readonly="readonly"' ;
01428                if(is_array($this->valeur))
01429                {
01430                     if(in_array($this->valeurS[$i],$this->valeur)) $ret.=' checked="checked"' ;
01431                }                   
01432                else
01433                {
01434                     if($this->valeur==$this->valeurS[$i]) $ret.=' checked="checked"' ;
01435                }
01436                $ret.=' value="'.$this->valeurS[$i].'"' ;                   
01437                $ret.=' />'."\r";
01438                if(!strstr($this->classe,'cssform0')) $ret.="\t\t\t<br />\r";
01439           }
01440           return $ret;
01441      }
01442 }
01443 ?>