Improve and translate code comments
[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 for LSform
27  *
28  * This classe permit to handle compostie attributes encoded with JSON.
29  *
30  * @author Benjamin Renard <brenard@easter-eggs.com>
31  */
32
33 class LSformElement_jsonCompositeAttribute extends LSformElement {
34
35   var $template = 'LSformElement_jsonCompositeAttribute.tpl';
36   var $fieldTemplate = 'LSformElement_jsonCompositeAttribute_field.tpl';
37
38   function LSformElement_jsonCompositeAttribute (&$form, $name, $label, $params,&$attr_html){
39     parent :: LSformElement($form, $name, $label, $params,$attr_html);
40     if (is_array($this -> params['html_options']['components'])) {
41       $this -> components = $this -> params['html_options']['components'];
42     }
43   }
44
45   /*
46    * Value components :
47    *
48    * Format :
49    *   array (
50    *     '[component1_key]' => array (
51    *       'label' => '[component label]',
52    *       'type' => '[component type]',
53    *       'required' => '[booléen]',
54    *       'check_data' =>  array([config LSform_rule])
55    *     ),
56    *     '[component2_key]' => 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' => Component feed by a list of valeur configured like an
65    *                      atribute LSattr_html :: select_list.
66    *   - 'text'        => manual entry
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   * Return HTML code of an empty field
117   *
118   * @retval string HTML code of an empty field.
119   */
120   function getEmptyField() {
121     return $this -> fetchTemplate($this -> fieldTemplate,array('components' => $this -> components));
122   }
123
124   /**
125    * Translate componant value
126    *
127    * Return an array containing :
128    *  - value : untranslated value
129    *  - translated : translated value
130    *
131    * @param[in] $c string The component name
132    * @param[in] $value string The value
133    *
134    * @retval array
135    **/
136   function translateComponentValue($c,$value) {
137     $retval = array (
138       'translated' => $value,
139       'value' => $value,
140     );
141     if (isset($this -> components[$c])) {
142       if ($this -> components[$c]['type']=='select_list') {
143         $retval['translated'] = $this -> getSelectListComponentValueLabel($c,$value);
144       }
145       //elseif type == 'text' => no transformation
146     }
147     return $retval;
148   }
149
150   /**
151    * Retreive possible values of an select_list component
152    *
153    * @param[in] $c string The component name
154    *
155    * @retval array
156    **/
157   protected $_cache_getSelectListComponentPossibleValues=array();
158   protected function getSelectListComponentPossibleValues($c) {
159     if (!isset($this -> _cache_getSelectListComponentPossibleValues[$c])) {
160       if (!LSsession :: loadLSclass('LSattr_html_select_list')) return;
161       $this -> _cache_getSelectListComponentPossibleValues[$c]=LSattr_html_select_list :: getPossibleValues($this -> components[$c]['options'], $this -> name, $this->attr_html->attribute->ldapObject);
162     }
163     return $this -> _cache_getSelectListComponentPossibleValues[$c];
164   }
165
166   /**
167    * Retreive value's label of an select_list component
168    *
169    * @param[in] $c string The component name
170    * @param[in] $value string The value
171    *
172    * @retval array
173    **/
174   protected function getSelectListComponentValueLabel($c,$value) {
175     if ($this -> getSelectListComponentPossibleValues($c)) {
176       foreach ($this -> _cache_getSelectListComponentPossibleValues[$c] as $v => $label) {
177         if (is_array($label)) {
178           if (!isset($label['possible_values'])) continue;
179           foreach ($label['possible_values'] as $vk => $vl)
180             if ($vk == $$value) return $vl;
181         }
182         if ($v == $value) return $label;
183       }
184     }
185     return;
186   }
187
188   /**
189    * Retreive LSformElement value from POST data
190    *
191    * This method check present of this element's value in POST data and retreive
192    * it to feed the array passed in paramater.
193    *
194    * @param[] array Reference of the array for retreived values
195    *
196    * @retval boolean true if value is in POST data, false instead
197    */
198   function getPostData(&$return) {
199     if($this -> isFreeze()) {
200       return true;
201     }
202
203     $count=0;
204     $end=false;
205     $return[$this -> name]=array();
206     while ($end==false) {
207       $value=array();
208       $parseValue=array();
209       $errors=array();
210       $unemptyComponents=array();
211       foreach ($this -> components as $c => $cconf) {
212         if (isset($_POST[$this -> name.'__'.$c][$count])) {
213           $parseValue[$c]=$_POST[$this -> name.'__'.$c][$count];
214           if ($cconf['required'] && empty($parseValue[$c])) {
215             $errors[]=getFData(__('Component %{c} must be defined'),__($cconf['label']));
216             continue;
217           }
218           if (empty($parseValue[$c])) {
219             continue;
220           }
221           $unemptyComponents[]=$c;
222           if ($cconf['type']=='select_list') {
223             if (!$this -> getSelectListComponentValueLabel($c, $parseValue[$c])) {
224               $errors[]=getFData(__('Invalid value for component %{c}.'),__($cconf['label']));
225             }
226           }
227           if (is_array($cconf['check_data'])) {
228             foreach($cconf['check_data'] as $ruleType => $rconf) {
229               $className='LSformRule_'.$ruleType;
230               if (LSsession::loadLSclass($className)) {
231                 $r=new $className();
232                 if (!$r -> validate($parseValue[$c],$rconf,$this)) {
233                   if (isset($rconf['msg'])) {
234                     $errors[]=getFData(__($rconf['msg']),__($cconf['label']));
235                   }
236                   else {
237                     $errors[]=getFData(__('Invalid value for component %{c}.'),__($cconf['label']));
238                   }
239                 }
240               }
241               else {
242                 $errors[]=getFData(__("Can't validate value of component %{c}."),__($cconf['label']));
243               }
244             }
245           }
246           $value[$c]=$parseValue[$c];
247         }
248         else {
249           // end of value break
250           $end=true;
251           break;
252         }
253
254       }
255       if (!$end) {
256         if (!empty($unemptyComponents)) {
257           foreach($errors as $e) {
258             $this -> form -> setElementError($this -> attr_html,$e);
259           }
260           $return[$this -> name][]=json_encode($value);
261         }
262         $count++;
263       }
264     }
265     return true;
266   }
267
268 }