ee0f47d068c2d0af3c089db53f3095fa400bdf0c
[ldapsaisie.git] / public_html / includes / class / class.LSformElement_jsonCompositeAttribute.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 LSsession :: loadLSclass('LSformElement');
24
25 /**
26  * Element jsonCompositeAttribute d'un formulaire pour LdapSaisie
27  *
28  * Cette classe permet de gérer les attributs composite encodé en JSON.
29  * Elle étant la classe basic LSformElement.
30  *
31  * @author Benjamin Renard <brenard@easter-eggs.com>
32  */
33
34 class LSformElement_jsonCompositeAttribute extends LSformElement {
35
36   var $template = 'LSformElement_jsonCompositeAttribute.tpl';
37   var $fieldTemplate = 'LSformElement_jsonCompositeAttribute_field.tpl';
38
39   function LSformElement_jsonCompositeAttribute (&$form, $name, $label, $params,&$attr_html){
40     parent :: LSformElement($form, $name, $label, $params,$attr_html);
41     if (is_array($this -> params['html_options']['components'])) {
42       $this -> components = $this -> params['html_options']['components'];
43     }
44   }
45   
46   /*
47    * Composants des valeurs composites : 
48    * 
49    * Format :
50    *   array (
51    *     '[clé composant1]' => array (
52    *       'label' => '[label composant]',
53    *       'type' => '[type de composant]',
54    *       'required' => '[booléen obligatoire]'
55    *     ),
56    *     '[clé composant 2]' => array (
57    *       'label' => 'label2',
58    *       'type'  => 'select_list',
59    *       'options' => array([config as LSattr_html_select_list html_options]),
60    *     ),
61    *     [...]
62    *   )
63    * Types :
64    *   - 'select_list' => Composant alimenté à partir d'une liste de valeur configurable
65    *                      de la même manière qu'un LSattr_html :: select_list.
66    *   - 'text'        => saisie manuelle
67    * 
68    */
69   var $components = array();
70   
71  /**
72   * Retourne les infos d'affichage de l'élément
73   * 
74   * Cette méthode retourne les informations d'affichage de l'élement
75   *
76   * @retval array
77   */
78   function getDisplay(){
79     $return = $this -> getLabelInfos();
80
81     $parseValues=array();
82     $invalidValues=array();
83     foreach($this -> values as $val) {
84       $decodedValue=json_decode($val, true);
85       if (is_array($decodedValue)) {
86         $parseValue=array('value' => $val);
87         foreach($decodedValue as $c => $cvalue) {
88           $parseValue[$c]=$this -> translateComponentValue($c,$cvalue);
89         }
90         $parseValues[]=$parseValue;
91       }
92       else {
93         $invalidValues[]=$val;
94       }
95     }
96
97     $components = $this -> components;
98     foreach($components as $c => $cconf) {
99       if ($cconf['type']=='select_list') {
100         $components[$c]['possible_values']=$this -> getSelectListComponentPossibleValues($c);
101       }
102     }
103
104     $return['html'] = $this -> fetchTemplate(NULL,
105       array(
106         'parseValues' => $parseValues,
107         'components' => $components
108       )
109     );
110     LSsession :: addCssFile('LSformElement_jsonCompositeAttribute.css');
111     return $return;
112   }
113   
114     
115  /**
116   * Retourne le code HTML d'un champ vide
117   *
118   * @retval string Code HTML d'un champ vide.
119   */
120   function getEmptyField() {
121     return $this -> fetchTemplate($this -> fieldTemplate,array('components' => $this -> components));
122   }
123   
124   /**
125    * Traduit la valeur d'un composant
126    * 
127    * Retourne un array contenant :
128    *  - label : l'étiquette de la valeur ou 'no' sinon
129    *  - value : la valeur brute
130    *  - translated : la valeur traduite ou la valeur elle même
131    * 
132    * @param[in] $c string Le nom du composant 
133    * @param[in] $val string La valeur
134    * 
135    * @retval array
136    **/
137   function translateComponentValue($c,$val) {
138     $retval = array (
139       'translated' => $val,
140       'value' => $val,
141     );
142     if (isset($this -> components[$c])) {
143       if ($this -> components[$c]['type']=='select_list') {
144         $retval['translated'] = $this -> getSelectListComponentValueLabel($c,$val);
145       }
146       //elseif type == 'text' => aucune transformation
147     }
148     return $retval;
149   }
150
151   protected $_cache_getSelectListComponentPossibleValues=array();
152   protected function getSelectListComponentPossibleValues($c) {
153     if (!isset($this -> _cache_getSelectListComponentPossibleValues[$c])) {
154       if (!LSsession :: loadLSclass('LSattr_html_select_list')) return;
155       $this -> _cache_getSelectListComponentPossibleValues[$c]=LSattr_html_select_list :: getPossibleValues($this -> components[$c]['options'], $this -> name, $this->attr_html->attribute->ldapObject);
156     }
157     return $this -> _cache_getSelectListComponentPossibleValues[$c];
158   }
159
160   protected function getSelectListComponentValueLabel($c,$value) {
161     if ($this -> getSelectListComponentPossibleValues($c)) {
162       foreach ($this -> _cache_getSelectListComponentPossibleValues[$c] as $v => $label) {
163         if (is_array($label)) {
164           if (!isset($label['possible_values'])) continue;
165           foreach ($label['possible_values'] as $vk => $vl)
166             if ($vk == $$value) return $vl;
167         }
168         if ($v == $value) return $label;
169       }
170     }
171     return;
172   }
173   
174   /**
175    * Recupère la valeur de l'élement passée en POST
176    *
177    * Cette méthode vérifie la présence en POST de la valeur de l'élément et la récupère
178    * pour la mettre dans le tableau passer en paramètre avec en clef le nom de l'élément
179    *
180    * @param[] array Pointeur sur le tableau qui recupèrera la valeur.
181    *
182    * @retval boolean true si la valeur est présente en POST, false sinon
183    */
184   function getPostData(&$return) {
185     if($this -> isFreeze()) {
186       return true;
187     }
188    
189     $count=0;
190     $end=false;
191     $return[$this -> name]=array();
192     while ($end==false) {
193       $value=array();
194       $parseValue=array();
195       $errors=array();
196       $unemptyComponents=array();
197       foreach ($this -> components as $c => $cconf) {
198         if (isset($_POST[$this -> name.'__'.$c][$count])) {
199           $parseValue[$c]=$_POST[$this -> name.'__'.$c][$count];
200           if ($cconf['required'] && empty($parseValue[$c])) {
201             $errors[]=getFData(__('Component %{c} must be defined'),__($cconf['label']));
202             continue;
203           }
204           if (empty($parseValue[$c])) {
205             continue;
206           }
207           $unemptyComponents[]=$c;
208           if ($cconf['type']=='select_list') {
209             if (!$this -> getSelectListComponentValueLabel($c, $parseValue[$c])) {
210               $errors[]=getFData(__('Invalid value for component %{c}.'),__($cconf['label']));
211             }
212           }
213           if (is_array($cconf['check_data'])) {
214             foreach($cconf['check_data'] as $ruleType => $rconf) {
215               $className='LSformRule_'.$ruleType;
216               if (LSsession::loadLSclass($className)) {
217                 $r=new $className();
218                 if (!$r -> validate($parseValue[$c],$rconf,$this)) {
219                   if (isset($rconf['msg'])) {
220                     $errors[]=getFData(__($rconf['msg']),__($cconf['label']));
221                   }
222                   else {
223                     $errors[]=getFData(__('Invalid value for component %{c}.'),__($cconf['label']));
224                   }
225                 }
226               }
227               else {
228                 $errors[]=getFData(__("Can't validate value of component %{c}."),__($cconf['label']));
229               }
230             }
231           }
232           $value[$c]=$parseValue[$c];
233         }
234         else {
235           // end of value break
236           $end=true;
237           break;
238         }
239         
240       }
241       if (!$end) {
242         if (!empty($unemptyComponents)) {
243           foreach($errors as $e) {
244             $this -> form -> setElementError($this -> attr_html,$e);
245           }
246           $return[$this -> name][]=json_encode($value);
247         }
248         $count++;
249       }
250     }
251     return true;
252   }
253     
254 }