LSform : Removed deprecated error 207
[ldapsaisie.git] / public_html / includes / class / class.LSform.php
1 <?php
2 /*******************************************************************************
3  * Copyright (C) 2007 Easter-eggs
4  * http://ldapsaisie.labs.libre-entreprise.org
5  *
6  * Author: See AUTHORS file in top-level directory.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License version 2
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 ******************************************************************************/
22
23
24 /**
25  * Formulaire pour LdapSaisie
26  *
27  * Cette classe gère les formulaires
28  *
29  * @author Benjamin Renard <brenard@easter-eggs.com>
30  */
31
32 class LSform {
33   var $ldapObject;
34   var $idForm;
35   var $can_validate = true;
36   var $elements = array();
37   var $_rules = array();
38
39   var $_postData = array();
40  
41   var $_elementsErrors = array();
42   var $_isValidate = false;
43
44   var $_notUpdate = array();
45   
46   var $maxFileSize = NULL;
47
48   var $warnings = array();
49
50   /**
51    * Constructeur
52    *
53    * Cette methode construit l'objet et définis la configuration.
54    *
55    * @author Benjamin Renard <brenard@easter-eggs.com>
56    *
57    * @param[in] $idForm [<b>required</b>] string L'identifiant du formulaire
58    * @param[in] $submit string La valeur du bouton submit
59    *
60    * @retval void
61    */ 
62   function LSform (&$ldapObject,$idForm,$submit=NULL){
63     $this -> idForm = $idForm;
64     if (!$submit) {
65       $this -> submit = _("Validate");
66     }
67     else {
68       $this -> submit = $submit;
69     }
70     $this -> ldapObject = $ldapObject;
71     LSsession :: loadLSclass('LSformElement');
72   }
73   
74   /**
75    * Affiche le formualaire
76    *
77    * @author Benjamin Renard <brenard@easter-eggs.com>
78    *
79    * @retval void
80    */ 
81   function display(){
82     if ($this -> idForm == 'view') {
83       self :: loadDependenciesDisplayView();
84     }
85     else {
86       LSsession :: addJSscript('LSformElement_field.js');
87       LSsession :: addJSscript('LSformElement.js');
88       LSsession :: addJSscript('LSform.js');
89       LSsession :: addCssFile('LSform.css');
90     }
91     
92     LSsession :: addHelpInfos(
93       'LSform',
94       array(
95         'addFieldBtn' => _('Add a field to add another values.'),
96         'removeFieldBtn' => _('Delete this field.')
97       )
98     );
99     
100     $GLOBALS['Smarty'] -> assign('LSform_action',$_SERVER['PHP_SELF']);
101     $LSform_header = "\t<input type='hidden' name='validate' value='LSform'/>\n
102     \t<input type='hidden' name='idForm' id='LSform_idform' value='".$this -> idForm."'/>\n
103     \t<input type='hidden' name='LSform_objecttype' id='LSform_objecttype'  value='".$this -> ldapObject -> getType()."'/>\n
104     \t<input type='hidden' name='LSform_objectdn' id='LSform_objectdn'  value='".$this -> ldapObject -> getValue('dn')."'/>\n";
105
106     
107     $LSform_object = array(
108       'type' => $this -> ldapObject -> getType(),
109       'dn' => $this -> ldapObject -> getValue('dn')
110     );
111     $GLOBALS['Smarty'] -> assign('LSform_object',$LSform_object);
112     
113     $layout_config=LSconfig :: get("LSobjects.".$LSform_object['type'].".LSform.layout");
114     if (is_array($layout_config)) {
115       $GLOBALS['Smarty'] -> assign('LSform_layout',$layout_config);
116       $GLOBALS['Smarty'] -> assign('LSform_layout_nofield_label',_('No field.'));
117     }
118     
119     $fields = array();
120     foreach($this -> elements as $element) {
121       $field = array();
122       $field = $element -> getDisplay();
123       if (isset($this -> _elementsErrors[$element -> name])) {
124         $field['errors']= $this -> _elementsErrors[$element -> name];
125       }
126       $fields[$element -> name] = $field;
127     }
128     
129     if ($this -> maxFileSize) {
130       $LSform_header.="\t<input type='hidden' name='MAX_FILE_SIZE' value='".$this -> maxFileSize."'/>\n";
131     }
132     $GLOBALS['Smarty'] -> assign('LSform_header',$LSform_header);
133     
134     $GLOBALS['Smarty'] -> assign('LSform_fields',$fields);
135
136     $JSconfig = array (
137       'ajaxSubmit' => ((isset($this -> config['LSform']['ajaxSubmit']))?$this -> config['LSform']['ajaxSubmit']:1)
138     );
139
140     if (!empty($this -> warnings)) {
141       $JSconfig['warnings']=$this -> warnings;
142     }
143
144     LSsession :: addJSconfigParam('LSform_'.$this -> idForm,$JSconfig);
145
146     if($this -> can_validate) {
147       $GLOBALS['Smarty'] -> assign('LSform_submittxt',$this -> submit);
148     }
149   }
150   
151  /*
152   * Méthode chargeant les dépendances d'affichage d'une LSview
153   * 
154   * @retval void
155   */
156   public static function loadDependenciesDisplayView() {
157     LSsession :: addCssFile('LSform.css');
158     LSsession :: addJSscript('LSform.js');
159     LSsession :: addJSconfigParam('LSview_labels', array(
160       'delete_confirm_text'     => _("Do you really want to delete"),
161       'delete_confirm_title'    => _("Caution"),
162       'delete_confirm_validate'  => _("Delete")
163     ));
164     if (LSsession :: loadLSclass('LSconfirmBox')) {
165       LSconfirmBox :: loadDependenciesDisplay();
166     }
167     LSsession :: addJSscript('LSview.js');
168   }
169   
170   /**
171    * Affiche la vue
172    *
173    * @author Benjamin Renard <brenard@easter-eggs.com>
174    *
175    * @retval void
176    */ 
177   function displayView(){
178     self :: loadDependenciesDisplayView();
179     
180     $LSform_object = array(
181       'type' => $this -> ldapObject -> getType(),
182       'dn' => $this -> ldapObject -> getDn()
183     );
184     $GLOBALS['Smarty'] -> assign('LSform_object',$LSform_object);
185     $fields = array();
186     foreach($this -> elements as $element) {
187       $field = $element -> getDisplay();
188       $fields[$element -> name] = $field;
189     }
190     $GLOBALS['Smarty'] -> assign('LSform_fields',$fields);
191     
192     $layout_config=LSconfig :: get("LSobjects.".$LSform_object['type'].".LSform.layout");
193     if (is_array($layout_config)) {
194       $GLOBALS['Smarty'] -> assign('LSform_layout',$layout_config);
195       $GLOBALS['Smarty'] -> assign('LSform_layout_nofield_label',_('No field.'));
196     }
197   }  
198   
199   /**
200    * Défini l'erreur sur un champ
201    *
202    * @author Benjamin Renard <brenard@easter-eggs.com>
203    *
204    * @param[in] $attr [<b>required</b>] string Le nom du champ
205    * @param[in] $msg Le format du message d'erreur à afficher (pouvant comporter
206    *                 des valeurs %{[n'importe quoi]} qui seront remplacé par le label
207    *                 du champs concerné.
208    *
209    * @retval void
210    */ 
211   function setElementError($attr,$msg=NULL) {
212     if($msg!='') {
213       $msg_error=getFData($msg,$attr->getLabel());
214     }
215     else {
216       $msg_error=getFData(_("%{label} attribute data is not valid."),$attr->getLabel());
217     }
218     $this -> _elementsErrors[$attr->name][]=$msg_error;
219   }
220   
221   /**
222    * Savoir si des erreurs son définie pour un élement du formulaire
223    *
224    * @author Benjamin Renard <brenard@easter-eggs.com>
225    *
226    * @param[in] $element [<b>required</b>] string Le nom de l'élement
227    * 
228    * @retval boolean
229    */ 
230   function definedError($element=NULL) {
231     if ($element) {
232       return isset($this -> _elementsErrors[$element]);
233     }
234     else {
235       return !empty($this -> _elementsErrors);
236     }
237   }
238   
239   /**
240    * Retourne le tableau des erreurs
241    * 
242    * @retval Array array(element => array(errors))
243    */
244   function getErrors() {
245     return $this -> _elementsErrors;
246   }
247   
248   /**
249    * Verifie si le formulaire a été validé et que les données sont valides.
250    *
251    * @author Benjamin Renard <brenard@easter-eggs.com>
252    *
253    * @retval boolean true si le formulaire a été validé et que les données ont été validées, false sinon
254    */ 
255   function validate(){
256     if(!$this -> can_validate)
257       return;
258     if ($this -> isSubmit()) {
259       if (!$this -> getPostData()) {
260         LSerror :: addErrorCode('LSform_01');
261         return;
262       }
263       $this -> setValuesFromPostData();
264       //Validation des données ici !!! ///
265       if (!$this -> checkData()) {
266         return;
267       }
268       LSdebug("Data are checked up");
269       $this -> _isValidate = true;
270       return true;
271     }
272     return false;
273   }
274
275   /**
276    * Vérifier les données du formulaire à partir des régles définis sur les champs
277    *
278    * @author Benjamin Renard <brenard@easter-eggs.com>
279    *
280    * @retval boolean true si toutes la saisie est OK, false sinon
281    */
282   function checkData() {
283     $retval=true;
284     foreach ($this -> _postData as $element => $values) {
285       if(!is_array($values)) {
286         $values=array($values);
287       }
288       if ($this -> elements[$element] -> isRequired()) {
289         if (!$this -> checkRequired($values)) {
290           $this -> setElementError($this -> elements[$element],_("Mandatory field"));
291           $retval=false;
292         }
293       }
294
295       foreach($values as $value) {
296         if (empty($value)) {
297           continue;
298         }
299         if (!is_array($this -> _rules[$element]))
300           continue;
301         LSsession :: loadLSclass('LSformRule');
302         foreach($this -> _rules[$element] as $rule) {
303           $ruleType="LSformRule_".$rule['name'];
304           LSsession :: loadLSclass($ruleType);
305           if (! call_user_func(array( $ruleType,'validate') , $value, $rule['options'], $this -> getElement($element))) {
306             $retval=false;
307             $this -> setElementError($this -> elements[$element],$rule['options']['msg']);
308           }
309         }
310       }
311     }
312     return $retval;
313   }
314
315   /**
316    * Vérifie si au moins une valeur est présente dans le tableau
317    *
318    * @author Benjamin Renard <brenard@easter-eggs.com>
319    *
320    * @param[in] $data array tableau de valeurs
321    *
322    * @retval boolean true si au moins une valeur est présente, false sinon
323    */
324   function checkRequired($data) {
325     foreach($data as $val) {
326       if (!empty($val)||(is_string($val)&&($val=="0")))
327         return true;
328     }
329     return;
330   }
331
332   /**
333    * Verifie si la saisie du formulaire est présente en POST
334    *
335    * @author Benjamin Renard <brenard@easter-eggs.com>
336    *
337    * @retval boolean true si la saisie du formulaire est présente en POST, false sinon
338    */
339   function isSubmit() {
340     if( (isset($_POST['validate']) && ($_POST['validate']=='LSform')) && (isset($_POST['idForm']) && ($_POST['idForm'] == $this -> idForm)) )
341       return true;
342     return;
343   }
344
345   /**
346    * Défini arbitrairement des données en POST
347    * 
348    * @author Benjamin Renard <brenard@easter-eggs.com>
349    * 
350    * @param[in] $data array('attr' => array(values)) Tableau des données du formulaire
351    * @param[in] $consideredAsSubmit Définie si on force le formualaire comme envoyer
352    * 
353    * @retval boolean true si les données ont été définies, false sinon
354    */
355   function setPostData($data,$consideredAsSubmit=false) {
356     if (is_array($data)) {
357       foreach($data as $key => $values) {
358         if (!is_array($values)) {
359           $values = array($values);
360         }
361         $_POST[$key] = $values;
362       }
363       
364       if ($consideredAsSubmit) {
365         $_POST['validate']='LSform';
366         $_POST['idForm']=$this -> idForm;
367       }
368       
369       return true;
370     }
371     return;
372   }
373
374   /**
375    * Récupère les valeurs postées dans le formulaire
376    *
377    * @author Benjamin Renard <brenard@easter-eggs.com>
378    *
379    * @retval boolean true si les valeurs ont bien été récupérées, false sinon.
380    */
381   function getPostData() {
382     foreach($this -> elements as $element_name => $element) {
383       if( !($element -> getPostData($this -> _postData)) ) {
384         LSerror :: addErrorCode('LSform_02',$element_name);
385         return;
386       }
387     }
388     return true;
389   }
390
391   /**
392    * Ajoute un élément au formulaire
393    * 
394    * Ajoute un élément au formulaire et définis les informations le concernant.
395    *
396    * @param[in] $type string Le type de l'élément
397    * @param[in] $name string Le nom de l'élément
398    * @param[in] $label string Le label de l'élément
399    * @param[in] $param mixed Paramètres supplémentaires
400    *
401    * @retval LSformElement
402    */
403   function addElement($type,$name,$label,$params=array(),&$attr_html) {
404     $elementType='LSformElement_'.$type;
405     LSsession :: loadLSclass($elementType);
406     if (!class_exists($elementType)) {
407       LSerror :: addErrorCode('LSform_05',array('type' => $type));  
408       return;
409     }
410     $element=$this -> elements[$name] = new $elementType($this,$name,$label,$params,$attr_html);
411     if ($element) {
412       return $element;
413     }
414     else {
415       unset ($this -> elements[$name]);
416       LSerror :: addErrorCode('LSform_06',array('element' => $name));
417       return;
418     }
419   }
420
421   /**
422    * Ajoute une règle sur un élément du formulaire
423    *
424    * @author Benjamin Renard <brenard@easter-eggs.com>
425    *
426    * @param[in] $element string Le nom de l'élément conserné
427    * @param[in] $rule string Le nom de la règle à ajouter
428    * @param[in] $options array Options (facultative)
429    *
430    * @retval boolean
431    */
432   function addRule($element, $rule, $options=array()) {
433     if ( isset($this ->elements[$element]) ) {
434       if ($this -> isRuleRegistered($rule)) {
435         $this -> _rules[$element][]=array(
436                   'name' => $rule,
437                   'options' => $options
438                   );
439         return true;
440       }
441       else {
442         LSerror :: addErrorCode('LSattribute_03',array('attr' => $element,'rule'=>$rule));      
443         return;
444       }
445     }
446     else {  
447       LSerror :: addErrorCode('LSform_04',array('element' => $element));
448       return;
449     }
450   }
451
452
453
454
455   /**
456    * Définis comme requis un élément
457    *
458    * @author Benjamin Renard <brenard@easter-eggs.com>
459    *
460    * @param[in] $element string Le nom de l'élément conserné
461    *
462    * @retval boolean
463    */
464   function setRequired($element) {
465     if (isset( $this -> elements[$element] ) )
466       return $this -> elements[$element] -> setRequired();
467     else
468       return;
469   }
470
471   /**
472    * Détermine la valider de la règle
473    *
474    * Devra déterminer si la règle passez en paramètre est correcte
475    *
476    * @author Benjamin Renard <brenard@easter-eggs.com>
477    *
478    * @param[in] $element string Le nom de l'élément conserné
479    */
480   function isRuleRegistered($rule) {
481     LSsession :: loadLSclass('LSformRule');
482     LSsession :: loadLSclass('LSformRule_'.$rule);
483     return class_exists('LSformRule_'.$rule);
484   }
485
486   /**
487    * Retourne les valeurs validés du formulaire
488    *
489    * @retval mixed Les valeurs validés du formulaire, ou false si elles ne le sont pas
490    */
491   function exportValues() {
492     if ($this -> _isValidate) {
493       $retval=array();
494       foreach($this -> _postData as $element => $values) {
495         $retval[$element] = $this -> elements[$element] -> exportValues();
496       }
497       return $retval;
498     }
499     else {
500       return;
501     }
502   }
503
504   /**
505    * Retourn un élement du formulaire
506    *
507    * @param[in] string $element Nom de l'élement voulu
508    *
509    * @retval LSformElement L'élement du formulaire voulu
510    */
511   function getElement($element) {
512     return $this -> elements[$element];
513   }
514
515   /**
516    * Défini les valeurs des élements à partir des valeurs postées
517    *
518    * @retval boolean True si les valeurs ont été définies, false sinon.
519    */
520   function setValuesFromPostData() {
521     if (empty($this -> _postData)) {
522       return;
523     }
524     foreach($this -> _postData as $element => $values) {
525       $this -> elements[$element] -> setValueFromPostData($values);
526     }
527     return true;
528   }
529
530   /**
531    * Retourne le code HTML d'un champ vide.
532    * 
533    * @param[in] string Le nom du champ du formulaire
534    *
535    * @retval string Le code HTML du champ vide.
536    */
537   function getEmptyField($element) {
538     $element = $this -> getElement($element);
539     if ($element) {      
540       return $element -> getEmptyField();     
541     }
542     else {
543       return;
544     }
545   }
546   
547   /**
548    * Défini la taille maximal pour les fichiers envoyés par le formualaire
549    * 
550    * @param[in] $size La taille maximal en octets
551    * 
552    * @retval  void
553    **/
554   function setMaxFileSize($size) {
555     $this -> maxFileSize = $size;
556   }
557
558    /**
559     * Ajoute un avertissement au sujet du formulaire
560     *
561     * @param[in] $txt string Le texte de l'avertissement
562     *
563     * @retval void
564     **/
565    function addWarning($txt) {
566      $this -> warnings[]=$txt;
567    }
568
569   /**
570    * Méthode Ajax permetant de retourner le code HTML d'un élément du formulaire vide
571    *
572    * @param[in] &$data Variable de retour
573    *
574    * @retval void
575    **/
576   public static function ajax_onAddFieldBtnClick(&$data) {
577     if ((isset($_REQUEST['attribute'])) && (isset($_REQUEST['objecttype'])) && (isset($_REQUEST['objectdn'])) && (isset($_REQUEST['idform'])) && (isset($_REQUEST['fieldId'])) ) {
578       if (LSsession ::loadLSobject($_REQUEST['objecttype'])) {
579         $object = new $_REQUEST['objecttype']();
580         $object -> loadData($_REQUEST['objectdn']);
581         $form = $object -> getForm($_REQUEST['idform']);
582         $emptyField=$form -> getEmptyField($_REQUEST['attribute']);
583         if ( $emptyField ) {
584           $data = array(
585             'html' => $form -> getEmptyField($_REQUEST['attribute']),
586             'fieldId' => $_REQUEST['fieldId'],
587             'fieldtype' => get_class($form -> getElement($_REQUEST['attribute']))
588           );
589         }
590       }
591     }
592   }
593 }
594
595 /**
596  * Error Codes
597  */
598 LSerror :: defineError('LSform_01',
599 _("LSform : Error during the recovery of the values of the form.")
600 );
601 LSerror :: defineError('LSform_02',
602 _("LSform : Error durring the recovery of the value of the field '%{element}'.")
603 );
604 // No longer used
605 /*LSerror :: defineError(203,
606 _("LSform : Data of the field %{element} are not validate.")
607 );*/
608 LSerror :: defineError('LSform_04',
609 _("LSform : The field %{element} doesn't exist.")
610 );
611 LSerror :: defineError('LSform_05',
612 _("LSfom : Field type unknow (%{type}).")
613 );
614 LSerror :: defineError('LSform_06',
615 _("LSform : Error during the creation of the element '%{element}'.")
616 );
617 ?>