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