f0d97f1b9e1a0a032e585613fad6c9015f1ccd4f
[atutor.git] / mods / basiclti / lib / at_form_util.php
1 <?php
2
3 // Parse a form field description
4 // field:type:key=value:key2=value2
5 function parseFormString($str) { 
6     $op = array(); 
7     $pairs = explode(":", $str); 
8     foreach ($pairs as $pair) { 
9         $kv = explode("=", $pair);
10         if ( sizeof($kv) == 1 ) {
11             $op[] = $pair;
12         } else {
13             $op[$kv[0]] = $kv[1];
14         }
15     } 
16     return $op; 
17
18
19 // Filter a form definition based on a controlling row.
20 //
21 // The controlling row has fields that are interpreted as
22 // 0=force off, 1=force on, 2 = delegate setting
23 // For radio buttons in our form, it simply checks for 
24 // the field of the same name in the controlling row.  
25 // For non-radio fields, it looks for a field in the 
26 // controlling row prepended by 'allow'.
27 function filterForm($control_row, $fieldinfo)
28 {
29     $new_form = array();
30     foreach ($fieldinfo as $line) {
31        $fields = parseFormString($line);
32        if ( $fields[1] == 'radio' ) {
33            if ( $control_row[$fields[0]] == 2 ) $new_form[] = $line;
34        }
35        // See if a non-radio field is controlled by an allow field
36        $allowfield = 'allow'.$fields[0];
37        if ( isset( $control_row[$allowfield] ) ) {
38            if ( $control_row[$allowfield] == 1 ) $new_form[] = $line;
39        }
40     }
41     return $new_form;
42 }
43
44 function at_form_input($row,$fieldinfo)
45 {
46     $info = parseFormString($fieldinfo);
47     if ( isset($info[0]) ) $field = $info[0]; else return;
48     if ( isset($info[1]) ) $type = $info[1]; else return;
49     $label = $field;
50     if ( isset($info['label']) ) $label = $info['label'];
51     $required = isset($info['required']);
52
53     if ( $type == 'text' || $type == 'url' || $type == 'id' || $type == 'integer' ) { 
54         $size = isset($info['size']) ? $info['size'] : 40; ?>
55         <div class="row">
56                 <?php if ($required) { ?><span class="required" title="<?php echo _AT('required_field'); ?>">*</span><?php } ?><label for="<?php echo $field;?>"><?php echo _AT($label); ?></label><br />
57                 <input type="text" id="<?php echo $field;?>" name="<?php echo $field;?>" size="<?php echo $size;?>" value="<?php echo htmlspecialchars($row[$field]); ?>" />
58         </div>
59     <?php }
60     else if ( $type == 'textarea' ) {
61         $cols = isset($info['cols']) ? $info['cols'] : 25;
62         $rows = isset($info['rows']) ? $info['rows'] : 2; ?>
63         <div class="row">
64                 <?php if ($required) { ?><span class="required" title="<?php echo _AT('required_field'); ?>">*</span><?php } ?><label for="<?php echo $field;?>"><?php echo _AT($label); ?></label><br />
65                 <textarea id="<?php echo $field;?>" name="<?php echo $field;?>" cols="<?php echo $cols;?>" rows="<?php echo $rows;?>"><?php echo htmlspecialchars($row[$field]); ?></textarea>
66         </div>
67     <?php }
68     else if ( $type == 'radio' ) {
69         if ( isset($info['choices']) ) {
70             $choices = explode(',', $info['choices']);
71         } else {
72             echo('<!-- at_form_radio requires choices=on,off,part -->');
73             return;
74         }
75         $current = isset($row[$field]) ? $row[$field] : -1;
76         ?>
77         <div class="row">
78             <?php if ($required) { ?><span class="required" title="<?php echo _AT('required_field'); ?>">*</span><?php } ?><label for="<?php echo $field;?>"><?php echo _AT($label); ?></label><br />
79 <?php
80 foreach($choices as $key => $value ) { 
81 $checked = '';
82 if ( $key == $current ) $checked = ' checked="checked"';
83 ?>
84                 <label><input type="radio" name="<?php echo $field; ?>" value="<?php echo $key?>" id="<?php echo $field.'_'.$value;?>"<?php echo $checked; ?>/><?php echo _AT($label.'_'.$value); ?></label><br />
85 <?php } ?>
86         </div>
87 <?php
88     }
89 }
90
91 function at_form_generate($row, $form_definition) {
92     foreach ( $form_definition as $forminput ) {
93       at_form_input($row,$forminput);
94     }
95 }
96
97
98 function at_form_output($row,$fieldinfo)
99 {
100     $info = parseFormString($fieldinfo);
101     if ( isset($info[0]) ) $field = $info[0]; else return;
102     if ( isset($info[1]) ) $type = $info[1]; else return;
103     $label = $field;
104     if ( isset($info['label']) ) $label = $info['label'];
105
106     if ( $type == 'text' || $type == 'url' || $type == 'id' || $type == 'integer' || $type == 'textarea') { 
107         if ( strlen($row[$field]) < 1 ) return; ?>
108         <div class="row">
109                 <?php  echo _AT($label); ?><br/>
110                 <?php echo htmlspecialchars($row[$field]); ?>
111         </div>
112     <?php }
113     else if ( $type == 'radio' ) {
114         if ( isset($info['choices']) ) {
115             $choices = explode(',', $info['choices']);
116         } else {
117             echo('<!-- at_form_radio requires choices=on,off,part -->');
118             return;
119         }
120         $current = isset($row[$field]) ? $row[$field] : 0;
121         if ( $current < 0 || $current >= sizeof($choices) ) $current = 0;
122         ?>
123         <div class="row"> <?php
124             $value = $choices[$current];
125             echo _AT($label)."<br/>\n";
126             echo _AT($label.'_'.$value); ?>
127         </div>
128 <?php
129     }
130 }
131
132 function at_form_view($row, $form_definition) {
133     foreach ( $form_definition as $forminput ) {
134       at_form_output($row,$forminput);
135     }
136 }
137
138 function at_form_validate($form_definition, $msg ) {
139     $retval = true;
140     $missing_fields = array();
141     $numeric_fields = array();
142     $url_fields = array();
143     $id_fields = array();
144
145     foreach ( $form_definition as $forminput ) {
146         $info =  parseFormString($forminput);
147         $label = isset($info['label']) ? $info['label'] : $info[0];
148         $datafield = $_POST[$info[0]];
149         $datafield = trim($datafield);
150         // echo($info[0] . '=' . $datafield. "<br/>\n");
151         if ( isset($info['required']) && strlen($datafield) < 1 ) {
152            $missing_fields[] = _AT($label);
153         }
154         if ( $info[1] == 'integer' || $info[1] == 'radio') {
155             if ( preg_match("/[0-9]+/", $datafield) == 1 || strlen($datafield) == 0 ) {
156                 // OK
157             } else {
158                 $numeric_fields[] = _AT($label);
159             }
160         }
161         if ( $info[1] == 'id' ) {
162             if ( preg_match("/^[0-9a-zA-Z._-]*$/", $datafield) == 1 || strlen($datafield) == 0 ) {
163                 // OK
164             } else {
165                 $id_fields[] = _AT($label);
166             }
167         }
168         if ( $info[1] == 'url' ) {
169             $pattern = "'^(http://|https://)[a-z0-9][a-z0-9]*'";
170             if ( preg_match($pattern, $datafield) == 1 || strlen($datafield) == 0 ) {
171                 // OK
172             } else {
173                 $url_fields[] = _AT($label);
174             }
175         }
176     }
177     if (sizeof($missing_fields) > 0) {
178         $missing_fields = implode(', ', $missing_fields);
179         $msg->addError(array('EMPTY_FIELDS', $missing_fields));
180         $retval = false;
181     }
182     if (sizeof($numeric_fields) > 0) {
183         $numeric_fields = implode(', ', $numeric_fields);
184         // TODO: Make sure this prints out the list of fields
185         $msg->addError(array('NUMERIC_FIELDS', $numeric_fields));
186         $msg->addError($numeric_fields);
187         $retval = false;
188     }
189     if (sizeof($url_fields) > 0) {
190         $url_fields = implode(', ', $url_fields);
191         $msg->addError(array('URL_FIELDS', $url_fields));
192         $retval = false;
193     }
194     if (sizeof($id_fields) > 0) {
195         $id_fields = implode(', ', $id_fields);
196         $msg->addError(array('ID_FIELDS', $id_fields));
197         $retval = false;
198     }
199     return $retval;
200 }
201
202 function at_get_field_value($fieldvalue, $type = false) {
203     global $addslashes;
204     
205         if ( $fieldvalue === false ) {
206        $fieldvalue = 'NULL';
207     } else if ( is_int($fieldvalue) ) {
208        $fieldvalue = $fieldvalue.'';
209     } else if ( $type == 'radio' || $type == 'integer') {
210         if ( strlen($fieldvalue) < 1 ) $fieldvalue = '0';
211         else $fieldvalue = intval($fieldvalue);
212     } else {
213         $fieldvalue = "'".$addslashes($fieldvalue)."'";
214     }
215     return $fieldvalue;
216 }
217
218 // $overrides = array('course_id' => 12, "title" => "yo", "toolid" => false);
219 // false in the array becomes NULL in the database
220 function at_form_insert($row, $form_definition, $overrides=false) {
221     $fieldlist = "";
222     $valuelist = "";
223     $handled = array();
224     foreach ( $form_definition as $forminput ) {
225         $info =  parseFormString($forminput);
226         $fieldname = $info[0]; 
227         $type = $info[1]; 
228         $fieldvalue = null;
229         if ( is_array($overrides) && isset($overrides[$fieldname]) ) $fieldvalue = $overrides[$fieldname];
230         if ( ! isset($fieldvalue) ) $fieldvalue = $row[$fieldname];
231         if ( ! isset($fieldvalue) ) continue;
232         $fieldvalue = trim($fieldvalue);
233         if ( strlen($fieldvalue) < 1 ) continue;
234         $fieldvalue = at_get_field_value($fieldvalue, $type);
235         $handled[] = $fieldname;
236         if ( $fieldlist != "" ) $fieldlist = $fieldlist.", ";
237         if ( $valuelist != "" ) $valuelist = $valuelist.", ";
238         $fieldlist = $fieldlist.$fieldname;
239         $valuelist = $valuelist.$fieldvalue;
240       }
241       if ( is_array($overrides) ) foreach($overrides as $fieldname => $fieldvalue) {
242         if ( in_array ( $fieldname , $handled) ) continue;
243         $fieldvalue = at_get_field_value($fieldvalue);
244         if ( $fieldlist != "" ) $fieldlist = $fieldlist.", ";
245         if ( $valuelist != "" ) $valuelist = $valuelist.", ";
246         $fieldlist = $fieldlist.$fieldname;
247         $valuelist = $valuelist.$fieldvalue;
248       }
249       $sql = "( $fieldlist ) VALUES ( $valuelist )";
250       return $sql;
251 }
252
253 function at_form_update($row, $form_definition, $overrides=false) {
254     $setlist = "";
255     $handled = array();
256     foreach ( $form_definition as $forminput ) {
257         $info =  parseFormString($forminput);
258         $fieldname = $info[0]; 
259         $type = $info[1]; 
260         $fieldvalue = null;
261         if ( is_array($overrides) && isset($overrides[$fieldname]) ) $fieldvalue = $overrides[$fieldname];
262         if ( ! isset($fieldvalue) ) $fieldvalue = $row[$info[0]];
263         if ( ! isset($fieldvalue) ) $fieldvalue = '';
264         $fieldvalue = trim($fieldvalue);
265         $fieldvalue = at_get_field_value($fieldvalue, $type);
266         if ( $setlist != "" ) $setlist = $setlist.", ";
267         $setlist = $setlist.$fieldname." = ".$fieldvalue;
268     }
269     if ( is_array($overrides) ) foreach($overrides as $fieldname => $fieldvalue) {
270         if ( in_array ( $fieldname , $handled) ) continue;
271         $fieldvalue = at_get_field_value($fieldvalue);
272         if ( $setlist != "" ) $setlist = $setlist.", ";
273         $setlist = $setlist.$fieldname." = ".$fieldvalue;
274     }
275     return $setlist;
276 }
277
278 function foorm_i18n_util($fieldinfo) {
279     $strings = array();
280     foreach ($fieldinfo as $line) {
281        $info = parseFormString($line);
282        $label = $info[0];
283        if ( isset($info['label']) ) $label = $info['label'];
284        $strings[] = $label;
285        if ( $info[1] == 'radio' ) {
286           if ( isset($info['choices']) ) {
287             $choices = explode(',', $info['choices']);
288             foreach($choices as $choice) {
289                $strings[] = $label.'_'.$choice;
290             }
291           }
292        }
293     }
294     return $strings;
295 }
296
297 if ( ! function_exists('isCli') ) {
298     function isCli() {
299         $sapi_type = php_sapi_name();
300         if (substr($sapi_type, 0, 3) == 'cli' && empty($_SERVER['REMOTE_ADDR'])) {
301             return true;
302         } else {
303             return false;
304         }
305     }
306 }
307
308 // If we are running from the command line - do a unit test
309 if ( isCli() ) {
310     print_r(parseFormString('title:text:required=true:size=25'));
311     print_r(parseFormString('description:textarea:required=true:rows=2:cols=25'));
312     print_r(parseFormString('sendemail:radio:requred=true:label=bl_sendemail:choices=on,off,part'));
313
314     $row = array();
315     $row['title'] = 'Fred';
316     $row['description'] = 'Desc';
317     $row['sendemail'] = 1;
318     function _AT($str) { return $str; }
319
320     at_form_input($row,'title:text:required=true:size=25');
321     at_form_input($row,'description:textarea:required=true:rows=2:cols=25');
322     at_form_input($row,'sendemail:radio:requred=true:label=bl_sendemail:choices=on,off,part');
323
324     $test_frm = array(
325         'title:text:size=80',
326         'preferheight:integer:label=bl_preferheight:size=80',
327         'sendname:radio:label=bl_sendname:choices=off,on,content',
328         'acceptgrades:radio:label=bl_acceptgrades:choices=off,on',
329         'customparameters:textarea:label=bl_customparameters:rows=5:cols=25',
330         );
331
332     $i18strings = foorm_i18n_util($test_frm);
333     print_r($i18strings);
334
335 }
336