Marius Burkard
2016-04-20 4569cae57f127afd093794310ccd290d2d9fdf36
commit | author | age
5bff39 1 <?php
M 2
3 /*
4 Copyright (c) 2007, Till Brehm, projektfarm Gmbh
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 /**
b1a6a5 32  * Formularbehandlung
MC 33  *
34  * Functions to validate, display and save form values
35  *
36  *        Database table field definitions
37  *
38  *        Datatypes:
39  *        - INTEGER (Converts data to int automatically)
40  *        - DOUBLE
41  *        - CURRENCY (Formats digits in currency notation)
42  *        - VARCHAR (No format check)
43  *        - DATE (Date format, converts from and to UNIX timestamps automatically)
44  *
45  *        Formtype:
46  *        - TEXT (Normal text field)
47  *        - PASSWORD (password field, the content will not be displayed again to the user)
48  *        - SELECT (Option fiield)
49  *        - MULTIPLE (Allows selection of multiple values)
50  *
51  *        VALUE:
52  *        - Value or array
53  *
54  *        SEPARATOR
55  *        - separator char used for fileds with multiple values
56  *
57  *        Hint: The auto increment (ID) filed of the table has not be be definied separately.
58  *
59  */
60
5bff39 61
M 62 class tform_base {
63
b1a6a5 64     /**
MC 65      * Definition of the database table (array)
66      * @var tableDef
67      */
68     var $tableDef;
5bff39 69
b1a6a5 70     /**
MC 71      * Private
72      * @var action
73      */
74     var $action;
5bff39 75
b1a6a5 76     /**
MC 77      * Table name (String)
78      * @var table_name
79      */
80     var $table_name;
5bff39 81
b1a6a5 82     /**
MC 83      * Debug Variable
84      * @var debug
85      */
86     var $debug = 0;
5bff39 87
b1a6a5 88     /**
MC 89      * name of the primary field of the database table (string)
90      * @var table_index
91      */
92     var $table_index;
5bff39 93
b1a6a5 94     /**
MC 95      * contains the error messages
96      * @var errorMessage
97      */
98     var $errorMessage = '';
5bff39 99
b1a6a5 100     var $dateformat = "d.m.Y";
7adc6c 101     var $datetimeformat = 'd.m.Y H:i'; // is set to the correct value in loadFormDef
b1a6a5 102     var $formDef = array();
MC 103     var $wordbook;
104     var $module;
105     var $primary_id;
106     var $diffrec = array();
5bff39 107
b1a6a5 108     /**
MC 109      * Loading of the table definition
110      *
111      * @param file: path to the form definition file
112      * @return true
113      */
114     /*
5bff39 115         function loadTableDef($file) {
M 116                 global $app,$conf;
117
118                 include_once($file);
119                 $this->tableDef = $table;
120                 $this->table_name = $table_name;
121                 $this->table_index = $table_index;
122                 return true;
123         }
124         */
125
b1a6a5 126     function loadFormDef($file, $module = '') {
MC 127         global $app, $conf;
5bff39 128
b1a6a5 129         include $file;
216ea1 130         $app->plugin->raiseEvent($_SESSION['s']['module']['name'].':'.$form['name'] . ':on_before_formdef', $this);
b1a6a5 131         $this->formDef = $form;
5bff39 132
b1a6a5 133         $this->module = $module;
MC 134         $wb = array();
5bff39 135
b1a6a5 136         include_once ISPC_ROOT_PATH.'/lib/lang/'.$_SESSION['s']['language'].'.lng';
5bff39 137
b1a6a5 138         if(is_array($wb)) $wb_global = $wb;
5bff39 139
b1a6a5 140         if($module == '') {
MC 141             $lng_file = "lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng";
142             if(!file_exists($lng_file)) $lng_file = "lib/lang/en_".$this->formDef["name"].".lng";
143             include $lng_file;
144         } else {
145             $lng_file = "../$module/lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng";
146             if(!file_exists($lng_file)) $lng_file = "../$module/lib/lang/en_".$this->formDef["name"].".lng";
147             include $lng_file;
5bff39 148         }
M 149
b1a6a5 150         if(is_array($wb_global)) {
MC 151             $wb = $app->functions->array_merge($wb_global, $wb);
152         }
153         if(isset($wb_global)) unset($wb_global);
6b15d5 154         
b1a6a5 155         $this->wordbook = $wb;
216ea1 156         
MB 157         $app->plugin->raiseEvent($_SESSION['s']['module']['name'].':'.$app->tform->formDef['name'] . ':on_after_formdef', $this);
b1a6a5 158
MC 159         $this->dateformat = $app->lng('conf_format_dateshort');
43e5b6 160         $this->datetimeformat = $app->lng('conf_format_datetime');
b1a6a5 161
MC 162         return true;
163     }
164
165     /*
5bff39 166         * Converts the data in the array to human readable format
M 167         * Datatype conversion e.g. to show the data in lists
168         *
169         * @param record
170         * @param tab
171         * @param apply_filters
172         * @return record
173         */
b1a6a5 174     protected function _decode($record, $tab = '', $api = false) {
MC 175         global $app;
176         $new_record = '';
177         if($api == false) {
178             $table_idx = $this->formDef['db_table_idx'];
179             if(isset($record[$table_idx])) $new_record[$table_idx] = $app->functions->intval($record[$table_idx ]);
180             $fields = &$this->formDef['tabs'][$tab]['fields'];
181         } else {
182             $fields = &$this->formDef['fields'];
183         }
184
185         if(is_array($record)) {
186             foreach($fields as $key => $field) {
187
188                 //* Apply filter to record value.
189                 if($api == false && isset($field['filters']) && is_array($field['filters'])) {
190                     $record[$key] = $this->filterField($key, (isset($record[$key]))?$record[$key]:'', $field['filters'], 'SHOW');
5bff39 191                 }
M 192
b1a6a5 193                 switch ($field['datatype']) {
MC 194                 case 'VARCHAR':
195                     $new_record[$key] = ($api == true ? stripslashes($record[$key]) : $record[$key]);
196                     break;
5bff39 197
b1a6a5 198                 case 'TEXT':
MC 199                     $new_record[$key] = ($api == true ? stripslashes($record[$key]) : $record[$key]);
200                     break;
5bff39 201
b1a6a5 202                 case 'DATETSTAMP':
MC 203                     if($record[$key] > 0) {
204                         $new_record[$key] = date($this->dateformat, $record[$key]);
205                     }
206                     break;
5bff39 207
b1a6a5 208                 case 'DATE':
651642 209                     if($record[$key] != '' && !is_null($record[$key]) && $record[$key] != '0000-00-00') {
b1a6a5 210                         $tmp = explode('-', $record[$key]);
MC 211                         $new_record[$key] = date($this->dateformat, mktime(0, 0, 0, $tmp[1]  , $tmp[2], $tmp[0]));
212                     }
213                     break;
5bff39 214
b1a6a5 215                 case 'INTEGER':
MC 216                     $new_record[$key] = $app->functions->intval($record[$key]);
217                     break;
5bff39 218
b1a6a5 219                 case 'DOUBLE':
MC 220                     $new_record[$key] = $record[$key];
221                     break;
5bff39 222
b1a6a5 223                 case 'CURRENCY':
MC 224                     $new_record[$key] = $app->functions->currency_format($record[$key]);
225                     break;
5bff39 226
b1a6a5 227                 default:
MC 228                     $new_record[$key] = ($api == true ? stripslashes($record[$key]) : $record[$key]);
5bff39 229                 }
b1a6a5 230             }
MC 231
232         }
5bff39 233
M 234         return $new_record;
b1a6a5 235     }
MC 236
237
238     /**
239      * Converts the data in the array to human readable format
240      * Datatype conversion e.g. to show the data in lists
241      *
242      * @param record
243      * @return record
244      */
245     function decode($record, $tab) {
246         global $conf, $app;
247         if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab does not exist or the tab is empty (TAB: $tab).");
248         return $this->_decode($record, $tab, false);
249     }
250
251     /**
252      * Get the key => value array of a form filled from a datasource definitiom
253      *
254      * @param field = array with field definition
255      * @param record = Dataset as array
256      * @return key => value array for the value field of a form
257      */
258     protected function _getDatasourceData($field, $record, $api = false) {
259         global $app;
260
261         $values = array();
262
263         if($field["datasource"]["type"] == 'SQL') {
264
265             // Preparing SQL string. We will replace some
266             // common placeholders
267             $querystring = $field["datasource"]["querystring"];
268             $querystring = str_replace("{USERID}", $_SESSION["s"]["user"]["userid"], $querystring);
269             $querystring = str_replace("{GROUPID}", $_SESSION["s"]["user"]["default_group"], $querystring);
270             $querystring = str_replace("{GROUPS}", $_SESSION["s"]["user"]["groups"], $querystring);
271             $table_idx = $this->formDef['db_table_idx'];
272
273             $tmp_recordid = (isset($record[$table_idx]))?$record[$table_idx]:0;
274             $querystring = str_replace("{RECORDID}", $tmp_recordid, $querystring);
275             unset($tmp_recordid);
276
277             $querystring = str_replace("{AUTHSQL}", $this->getAuthSQL('r'), $querystring);
797215 278             $querystring = preg_replace_callback('@{AUTHSQL::(.+?)}@', create_function('$matches','global $app; $tmp = $app->tform->getAuthSQL("r", $matches[1]); return $tmp;'), $querystring);
b1a6a5 279
MC 280             // Getting the records
281             $tmp_records = $app->db->queryAllRecords($querystring);
282             if($app->db->errorMessage != '') die($app->db->errorMessage);
283             if(is_array($tmp_records)) {
284                 $key_field = $field["datasource"]["keyfield"];
285                 $value_field = $field["datasource"]["valuefield"];
286                 foreach($tmp_records as $tmp_rec) {
287                     $tmp_id = $tmp_rec[$key_field];
288                     $values[$tmp_id] = $tmp_rec[$value_field];
289                 }
290             }
5bff39 291         }
M 292
b1a6a5 293         if($field["datasource"]["type"] == 'CUSTOM') {
MC 294             // Calls a custom class to validate this record
295             if($field["datasource"]['class'] != '' and $field["datasource"]['function'] != '') {
296                 $datasource_class = $field["datasource"]['class'];
297                 $datasource_function = $field["datasource"]['function'];
298                 $app->uses($datasource_class);
299                 $values = $app->$datasource_class->$datasource_function($field, $record);
300             } else {
301                 $this->errorMessage .= "Custom datasource class or function is empty<br />\r\n";
302             }
5bff39 303         }
M 304
b1a6a5 305         if($api == false && isset($field['filters']) && is_array($field['filters'])) {
MC 306             $new_values = array();
307             foreach($values as $index => $value) {
308                 $new_index = $this->filterField($index, $index, $field['filters'], 'SHOW');
309                 $new_values[$new_index] = $this->filterField($index, (isset($values[$index]))?$values[$index]:'', $field['filters'], 'SHOW');
310             }
311             $values = $new_values;
312             unset($new_values);
313             unset($new_index);
314         }
5bff39 315
b1a6a5 316         return $values;
5bff39 317
b1a6a5 318     }
5bff39 319
797215 320     /*
cce3c1 321     function table_auth_sql($matches){
MC 322         return $this->getAuthSQL('r', $matches[1]);
323     }
797215 324     */
MC 325     
b1a6a5 326     /**
MC 327      * Get the key => value array of a form filled from a datasource definitiom
328      *
329      * @param field = array with field definition
330      * @param record = Dataset as array
331      * @return key => value array for the value field of a form
332      */
333     function getDatasourceData($field, $record) {
334         return $this->_getDatasourceData($field, $record, false);
335     }
5bff39 336
b1a6a5 337     //* If the parameter 'valuelimit' is set
MC 338     function applyValueLimit($limit, $values) {
5bff39 339
b1a6a5 340         global $app;
5bff39 341
b1a6a5 342         $limit_parts = explode(':', $limit);
5bff39 343
b1a6a5 344         //* values are limited to a comma separated list
MC 345         if($limit_parts[0] == 'list') {
346             $allowed = explode(',', $limit_parts[1]);
347         }
5bff39 348
b1a6a5 349         //* values are limited to a field in the client settings
MC 350         if($limit_parts[0] == 'client') {
351             if($_SESSION["s"]["user"]["typ"] == 'admin') {
5bff39 352                 return $values;
b1a6a5 353             } else {
MC 354                 $client_group_id = $_SESSION["s"]["user"]["default_group"];
cc7a82 355                 $client = $app->db->queryOneRecord("SELECT ".$limit_parts[1]." as lm FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id);
b1a6a5 356                 $allowed = explode(',', $client['lm']);
MC 357             }
5bff39 358         }
M 359
b1a6a5 360         //* values are limited to a field in the reseller settings
MC 361         if($limit_parts[0] == 'reseller') {
362             if($_SESSION["s"]["user"]["typ"] == 'admin') {
363                 return $values;
364             } else {
365                 //* Get the limits of the client that is currently logged in
366                 $client_group_id = $_SESSION["s"]["user"]["default_group"];
cc7a82 367                 $client = $app->db->queryOneRecord("SELECT parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id);
b1a6a5 368                 //echo "SELECT parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id";
MC 369                 //* If the client belongs to a reseller, we will check against the reseller Limit too
370                 if($client['parent_client_id'] != 0) {
5bff39 371
b1a6a5 372                     //* first we need to know the groups of this reseller
2af58c 373                     $tmp = $app->db->queryOneRecord("SELECT userid, groups FROM sys_user WHERE client_id = ?", $client['parent_client_id']);
b1a6a5 374                     $reseller_groups = $tmp["groups"];
MC 375                     $reseller_userid = $tmp["userid"];
5bff39 376
b1a6a5 377                     // Get the limits of the reseller of the logged in client
5bff39 378                     $client_group_id = $_SESSION["s"]["user"]["default_group"];
2af58c 379                     $reseller = $app->db->queryOneRecord("SELECT ".$limit_parts[1]." as lm FROM client WHERE client_id = ?", $client['parent_client_id']);
b1a6a5 380                     $allowed = explode(',', $reseller['lm']);
MC 381                 } else {
382                     return $values;
5bff39 383                 }
b1a6a5 384             } // end if admin
MC 385         } // end if reseller
5bff39 386
b1a6a5 387         //* values are limited to a field in the system settings
MC 388         if($limit_parts[0] == 'system') {
389             $app->uses('getconf');
390             $tmp_conf = $app->getconf->get_global_config($limit_parts[1]);
391             $tmp_key = $limit_parts[2];
392             $allowed = $tmp_conf[$tmp_key];
393         }
5bff39 394
b1a6a5 395         $values_new = array();
MC 396         foreach($values as $key => $val) {
397             if(in_array($key, $allowed)) $values_new[$key] = $val;
398         }
5bff39 399
b1a6a5 400         return $values_new;
MC 401     }
402
403
404     /**
405      * Prepare the data record to show the data in a form.
406      *
407      * @param record = Datensatz als Array
408      * @param action = NEW oder EDIT
409      * @return record
410      */
411     function getHTML($record, $tab, $action = 'NEW') {
412
413         global $app;
414
415         $this->action = $action;
416
417         if(!is_array($this->formDef)) $app->error("No form definition found.");
418         if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
419
985390 420         /* CSRF PROTECTION */
MC 421         // generate csrf protection id and key
8cb6f8 422         $csrf_token = $app->auth->csrf_token_get($this->formDef['name']);
MC 423         $_csrf_id = $csrf_token['csrf_id'];
424         $_csrf_value = $csrf_token['csrf_key'];
425         
985390 426         $this->formDef['tabs'][$tab]['fields']['_csrf_id'] = array(
MC 427             'datatype' => 'VARCHAR',
428             'formtype' => 'TEXT',
429             'default' => $_csrf_id,
430             'value' => $_csrf_id
431         );
432         $this->formDef['tabs'][$tab]['fields']['_csrf_key'] = array(
433             'datatype' => 'VARCHAR',
434             'formtype' => 'TEXT',
435             'default' => $_csrf_value,
436             'value' => $_csrf_value
437         );
438         $record['_csrf_id'] = $_csrf_id;
439         $record['_csrf_key'] = $_csrf_value;
440         /* CSRF PROTECTION */
441         
b1a6a5 442         $new_record = array();
MC 443         if($action == 'EDIT') {
444             $record = $this->decode($record, $tab);
445             if(is_array($record)) {
446                 foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
447
448                     if(isset($record[$key])) {
449                         $val = $record[$key];
5bff39 450                     } else {
b1a6a5 451                         $val = '';
5bff39 452                     }
M 453
b1a6a5 454                     // If Datasource is set, get the data from there
MC 455                     if(isset($field['datasource']) && is_array($field['datasource'])) {
456                         if(is_array($field["value"])) {
457                             //$field["value"] = array_merge($field["value"],$this->getDatasourceData($field, $record));
458                             $field["value"] = $app->functions->array_merge($field["value"], $this->getDatasourceData($field, $record));
459                         } else {
460                             $field["value"] = $this->getDatasourceData($field, $record);
5bff39 461                         }
M 462                     }
463
b1a6a5 464                     // If a limitation for the values is set
MC 465                     if(isset($field['valuelimit']) && is_array($field["value"])) {
466                         $field["value"] = $this->applyValueLimit($field['valuelimit'], $field["value"]);
467                     }
5bff39 468
b1a6a5 469                     switch ($field['formtype']) {
MC 470                     case 'SELECT':
471                         $out = '';
472                         if(is_array($field['value'])) {
473                             foreach($field['value'] as $k => $v) {
474                                 $selected = ($k == $val)?' SELECTED':'';
86e699 475                                 if(isset($this->wordbook[$v]))
b1a6a5 476                                     $v = $this->wordbook[$v];
MC 477                                 $out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
5bff39 478                             }
b1a6a5 479                         }
MC 480                         $new_record[$key] = $out;
481                         break;
482                     case 'MULTIPLE':
483                         if(is_array($field['value'])) {
484
485                             // Split
486                             $vals = explode($field['separator'], $val);
487
488                             // write HTML
489                             $out = '';
490                             foreach($field['value'] as $k => $v) {
491
492                                 $selected = '';
493                                 foreach($vals as $tvl) {
494                                     if(trim($tvl) == trim($k)) $selected = ' SELECTED';
495                                 }
496
497                                 $out .= "<option value='$k'$selected>$v</option>\r\n";
498                             }
499                         }
500                         $new_record[$key] = $out;
501                         break;
502
503                     case 'PASSWORD':
504                         $new_record[$key] = '';
505                         break;
506
507                     case 'CHECKBOX':
508                         $checked = ($val == $field['value'][1])?' CHECKED':'';
509                         $new_record[$key] = "<input name=\"".$key."\" id=\"".$key."\" value=\"".$field['value'][1]."\" type=\"checkbox\" $checked />\r\n";
510                         break;
511
512                     case 'CHECKBOXARRAY':
513                         if(is_array($field['value'])) {
514
515                             // aufsplitten ergebnisse
516                             $vals = explode($field['separator'], $val);
517
518                             // HTML schreiben
519                             $out = '';
520                             $elementNo = 0;
521                             foreach($field['value'] as $k => $v) {
522
523                                 $checked = '';
524                                 foreach($vals as $tvl) {
525                                     if(trim($tvl) == trim($k)) $checked = ' CHECKED';
526                                 }
527                                 // $out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"checkbox\" $checked /> $v</label>\r\n";
528                                 $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"checkbox\" $checked /> $v</label><br/>\r\n";
529                                 $elementNo++;
530                             }
531                         }
532                         $new_record[$key] = $out;
533                         break;
534
535                     case 'RADIO':
536                         if(is_array($field['value'])) {
537
538                             // HTML schreiben
539                             $out = '';
540                             $elementNo = 0;
541                             foreach($field['value'] as $k => $v) {
542                                 $checked = ($k == $val)?' CHECKED':'';
543                                 //$out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
544                                 $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"radio\" $checked/> $v </label>\r\n";
545                                 $elementNo++;
546                             }
547                         }
548                         $new_record[$key] = $out;
549                         break;
550
551                     case 'DATETIME':
552                         if (strtotime($val) !== false) {
553                             $dt_value = $val;
554                         } elseif ( isset($field['default']) && (strtotime($field['default']) !== false) ) {
555                             $dt_value = $field['default'];
556                         } else {
557                             $dt_value = 0;
558                         }
559
560                         $display_seconds = (isset($field['display_seconds']) && $field['display_seconds'] == true) ? true : false;
561
562                         $new_record[$key] = $this->_getDateTimeHTML($key, $dt_value, $display_seconds);
563                         break;
564
565                     default:
566                         if(isset($record[$key])) {
567                             $new_record[$key] = htmlspecialchars($record[$key]);
568                         } else {
569                             $new_record[$key] = '';
570                         }
571                     }
572                 }
573             }
574         } else {
575             // Action: NEW
576             foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
577
578                 // If Datasource is set, get the data from there
579                 if(@is_array($field['datasource'])) {
580                     if(is_array($field["value"])) {
581                         $field["value"] = $app->functions->array_merge($field["value"], $this->getDatasourceData($field, $record));
5bff39 582                     } else {
b1a6a5 583                         $field["value"] = $this->getDatasourceData($field, $record);
5bff39 584                     }
b1a6a5 585                 }
MC 586
587                 // If a limitation for the values is set
588                 if(isset($field['valuelimit']) && is_array($field["value"])) {
589                     $field["value"] = $this->applyValueLimit($field['valuelimit'], $field["value"]);
590                 }
591
592                 switch ($field['formtype']) {
593                 case 'SELECT':
594                     if(is_array($field['value'])) {
595                         $out = '';
596                         foreach($field['value'] as $k => $v) {
597                             $selected = ($k == $field["default"])?' SELECTED':'';
598                             $out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
599                         }
5bff39 600                     }
b1a6a5 601                     if(isset($out)) $new_record[$key] = $out;
MC 602                     break;
603                 case 'MULTIPLE':
604                     if(is_array($field['value'])) {
605
606                         // aufsplitten ergebnisse
607                         $vals = explode($field['separator'], $val);
608
609                         // HTML schreiben
610                         $out = '';
611                         foreach($field['value'] as $k => $v) {
612
613                             $out .= "<option value='$k'>$v</option>\r\n";
614                         }
5bff39 615                     }
b1a6a5 616                     $new_record[$key] = $out;
MC 617                     break;
618
619                 case 'PASSWORD':
620                     //$new_record[$key] = '';
621                     $new_record[$key] = htmlspecialchars($field['default']);
622                     break;
623
624                 case 'CHECKBOX':
625                     // $checked = (empty($field["default"]))?'':' CHECKED';
626                     $checked = ($field["default"] == $field['value'][1])?' CHECKED':'';
627                     $new_record[$key] = "<input name=\"".$key."\" id=\"".$key."\" value=\"".$field['value'][1]."\" type=\"checkbox\" $checked />\r\n";
628                     break;
629
630                 case 'CHECKBOXARRAY':
631                     if(is_array($field['value'])) {
632
633                         // aufsplitten ergebnisse
634                         $vals = explode($field['separator'], $field["default"]);
635
636                         // HTML schreiben
637                         $out = '';
638                         $elementNo = 0;
639                         foreach($field['value'] as $k => $v) {
640
641                             $checked = '';
642                             foreach($vals as $tvl) {
643                                 if(trim($tvl) == trim($k)) $checked = ' CHECKED';
644                             }
645                             // $out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"checkbox\" $checked /> $v</label>\r\n";
646                             $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"checkbox\" $checked /> $v</label> &nbsp;\r\n";
647                             $elementNo++;
648                         }
5bff39 649                     }
b1a6a5 650                     $new_record[$key] = $out;
MC 651                     break;
652
653                 case 'RADIO':
654                     if(is_array($field['value'])) {
655
656                         // HTML schreiben
657                         $out = '';
658                         $elementNo = 0;
659                         foreach($field['value'] as $k => $v) {
660                             $checked = ($k == $field["default"])?' CHECKED':'';
661                             //$out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
662                             $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
663                             $elementNo++;
664                         }
5bff39 665                     }
b1a6a5 666                     $new_record[$key] = $out;
MC 667                     break;
668
669                 case 'DATETIME':
670                     $dt_value = (isset($field['default'])) ? $field['default'] : 0;
671                     $display_seconds = (isset($field['display_seconds']) && $field['display_seconds'] == true) ? true : false;
672
673                     $new_record[$key] = $this->_getDateTimeHTML($key, $dt_value, $display_seconds);
674                     break;
675
676                 default:
677                     $new_record[$key] = htmlspecialchars($field['default']);
678                 }
679             }
680
681         }
682
683         if($this->debug == 1) $this->dbg($new_record);
684
685         return $new_record;
686     }
687
688     /**
689      * Rewrite the record data to be stored in the database
690      * and check values with regular expressions.
691      *
692      * @param record = Datensatz als Array
693      * @return record
694      */
695     protected function _encode($record, $tab, $dbencode = true, $api = false) {
696         global $app;
985390 697         if($api == true) {
MC 698             $fields = &$this->formDef['fields'];
699         } else {
700             $fields = &$this->formDef['tabs'][$tab]['fields'];
701             /* CSRF PROTECTION */
702             if(isset($_POST) && is_array($_POST)) {
703                 $_csrf_valid = false;
704                 if(isset($_POST['_csrf_id']) && isset($_POST['_csrf_key'])) {
705                     $_csrf_id = trim($_POST['_csrf_id']);
706                     $_csrf_key = trim($_POST['_csrf_key']);
707                     if(isset($_SESSION['_csrf']) && isset($_SESSION['_csrf'][$_csrf_id]) && isset($_SESSION['_csrf_timeout']) && isset($_SESSION['_csrf_timeout'][$_csrf_id])) {
708                         if($_SESSION['_csrf'][$_csrf_id] === $_csrf_key && $_SESSION['_csrf_timeout'] >= time()) $_csrf_valid = true;
709                     }
710                 }
711                 if($_csrf_valid !== true) {
712                     $app->log('CSRF attempt blocked. Referer: ' . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'unknown'), LOGLEVEL_WARN);
352477 713                     $errmsg = 'err_csrf_attempt_blocked';
MC 714                     $this->errorMessage .= ($api == true ? $errmsg : $this->wordbook[$errmsg]."<br />") . "\r\n";
985390 715                     unset($_POST);
MC 716                     unset($record);
717                 }
718                 
719                 if(isset($_SESSION['_csrf_timeout']) && is_array($_SESSION['_csrf_timeout'])) {
720                     $to_unset = array();
721                     foreach($_SESSION['_csrf_timeout'] as $_csrf_id => $timeout) {
722                         if($timeout < time()) $to_unset[] = $_csrf_id;
723                     }
724                     foreach($to_unset as $_csrf_id) {
c8b685 725                         $_SESSION['_csrf'][$_csrf_id] = null;
MC 726                         $_SESSION['_csrf_timeout'][$_csrf_id] = null;
985390 727                         unset($_SESSION['_csrf'][$_csrf_id]);
MC 728                         unset($_SESSION['_csrf_timeout'][$_csrf_id]);
729                     }
730                     unset($to_unset);
731                 }
732             }
733             /* CSRF PROTECTION */
734         }
735         
736         $new_record = array();
b1a6a5 737         if(is_array($record)) {
MC 738             foreach($fields as $key => $field) {
739
740                 //* Apply filter to record value
741                 if(isset($field['filters']) && is_array($field['filters'])) {
742                     $record[$key] = $this->filterField($key, (isset($record[$key]))?$record[$key]:'', $field['filters'], 'SAVE');
743                 }
744                 //* Validate record value
745                 if(isset($field['validators']) && is_array($field['validators'])) {
746                     $this->validateField($key, (isset($record[$key]))?$record[$key]:'', $field['validators']);
747                 }
748
749                 switch ($field['datatype']) {
750                 case 'VARCHAR':
751                     if(!@is_array($record[$key])) {
752                         $new_record[$key] = (isset($record[$key]))?$record[$key]:'';
753                     } else {
754                         $new_record[$key] = implode($field['separator'], $record[$key]);
755                     }
756                     break;
757                 case 'TEXT':
758                     if(!is_array($record[$key])) {
759                         $new_record[$key] = $record[$key];
760                     } else {
761                         $new_record[$key] = implode($field['separator'], $record[$key]);
762                     }
763                     break;
764                 case 'DATETSTAMP':
765                     if($record[$key] > 0) {
766                         list($tag, $monat, $jahr) = explode('.', $record[$key]);
767                         $new_record[$key] = mktime(0, 0, 0, $monat, $tag, $jahr);
768                     } else {
769                         $new_record[$key] = 0;
770                     }
771                     break;
772                 case 'DATE':
651642 773                     if($record[$key] != '' && !is_null($record[$key]) && $record[$key] != '0000-00-00') {
b1a6a5 774                         if(function_exists('date_parse_from_format')) {
MC 775                             $date_parts = date_parse_from_format($this->dateformat, $record[$key]);
86bc65 776                             $new_record[$key] = $date_parts['year'].'-'.str_pad($date_parts['month'], 2, "0", STR_PAD_LEFT).'-'.str_pad($date_parts['day'], 2, "0", STR_PAD_LEFT);
b1a6a5 777                         } else {
MC 778                             $tmp = strtotime($record[$key]);
779                             $new_record[$key] = date('Y-m-d', $tmp);
780                         }
781                     } else {
651642 782                         $new_record[$key] = null;
b1a6a5 783                     }
MC 784                     break;
785                 case 'INTEGER':
786                     $new_record[$key] = (isset($record[$key]))?$app->functions->intval($record[$key]):0;
787                     break;
788                 case 'DOUBLE':
789                     $new_record[$key] = $record[$key];
790                     break;
791                 case 'CURRENCY':
792                     $new_record[$key] = str_replace(",", ".", $record[$key]);
793                     break;
794
795                 case 'DATETIME':
43e5b6 796                     /*if (is_array($record[$key]))
b1a6a5 797                     {
MC 798                         $filtered_values = array_map(create_function('$item', 'return (int)$item;'), $record[$key]);
799                         extract($filtered_values, EXTR_PREFIX_ALL, '_dt');
800
801                         if ($_dt_day != 0 && $_dt_month != 0 && $_dt_year != 0) {
802                             $new_record[$key] = date( 'Y-m-d H:i:s', mktime($_dt_hour, $_dt_minute, $_dt_second, $_dt_month, $_dt_day, $_dt_year) );
803                         }
43e5b6 804                     } else {*/
651642 805                         if($record[$key] != '' && !is_null($record[$key]) && $record[$key] != '0000-00-00 00:00:00') {
7adc6c 806                             //$tmp = strtotime($record[$key]);
TB 807                             //$new_record[$key] = date($this->datetimeformat, $tmp);
808                             $parsed_date = date_parse_from_format($this->datetimeformat,$record[$key]);
809                             if($parsed_date['error_count'] > 0 || ($parsed_date['year'] == 1899 && $parsed_date['month'] == 12 && $parsed_date['day'] == 31)) {
810                                 // There was an error, set the date to 0
651642 811                                 $new_record[$key] = null;
7adc6c 812                             } else {
TB 813                                 // Date parsed successfully. Convert it to database format
814                                 $new_record[$key] = date( 'Y-m-d H:i:s', mktime($parsed_date['hour'], $parsed_date['minute'], $parsed_date['second'], $parsed_date['month'], $parsed_date['day'], $parsed_date['year']) );
815                             }
43e5b6 816                         } else {
651642 817                             $new_record[$key] = null;
43e5b6 818                         }
MC 819                     /*}*/
b1a6a5 820                     break;
MC 821                 }
822
823                 // The use of the field value is deprecated, use validators instead
824                 if(isset($field['regex']) && $field['regex'] != '') {
825                     // Enable that "." matches also newlines
826                     $field['regex'] .= 's';
827                     if(!preg_match($field['regex'], $record[$key])) {
828                         $errmsg = $field['errmsg'];
829                         $this->errorMessage .= ($api == true ? $errmsg : $this->wordbook[$errmsg]."<br />") . "\r\n";
830                     }
831                 }
832
833                 //* Add slashes to all records, when we encode data which shall be inserted into mysql.
834                 if($dbencode == true) $new_record[$key] = $app->db->quote($new_record[$key]);
835             }
836         }
837         return $new_record;
838     }
839
840
841     /**
842      * Rewrite the record data to be stored in the database
843      * and check values with regular expressions.
844      *
845      * @param record = Datensatz als Array
846      * @return record
847      */
848     function encode($record, $tab, $dbencode = true) {
849         global $app;
850
851         if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab is empty or does not exist (TAB: $tab).");
852         return $this->_encode($record, $tab, $dbencode, false);
853     }
854
855
856     /**
857      * process the filters for a given field.
858      *
859      * @param field_name = Name of the field
860      * @param field_value = value of the field
861      * @param filters = Array of filters
862      * @param filter_event = 'SAVE'or 'SHOW'
863      * @return record
864      */
865     function filterField($field_name, $field_value, $filters, $filter_event) {
866
867         global $app;
868         $returnval = $field_value;
869
870         //* Loop trough all filters
871         foreach($filters as $filter) {
872             if($filter['event'] == $filter_event) {
873                 switch ($filter['type']) {
874                 case 'TOLOWER':
875                     $returnval = strtolower($returnval);
876                     break;
877                 case 'TOUPPER':
878                     $returnval = strtoupper($returnval);
879                     break;
880                 case 'IDNTOASCII':
881                     $returnval = $app->functions->idn_encode($returnval);
882                     break;
883                 case 'IDNTOUTF8':
884                     $returnval = $app->functions->idn_decode($returnval);
885                     break;
61f1f5 886                 case 'TRIM':
MC 887                     $returnval = trim($returnval);
888                     break;
d22277 889                 case 'NOWHITESPACE':
MB 890                     $returnval = preg_replace('/\s+/', '', $returnval);
891                     break;
b1a6a5 892                 default:
MC 893                     $this->errorMessage .= "Unknown Filter: ".$filter['type'];
894                     break;
895                 }
896             }
897         }
898         return $returnval;
899     }
900
901
902     /**
903      * process the validators for a given field.
904      *
905      * @param field_name = Name of the field
906      * @param field_value = value of the field
907      * @param validatoors = Array of validators
908      * @return record
909      */
910     function validateField($field_name, $field_value, $validators) {
911
912         global $app;
913
914         $escape = '`';
915
916         // loop trough the validators
917         foreach($validators as $validator) {
918
919             switch ($validator['type']) {
920             case 'REGEX':
921                 $validator['regex'] .= 's';
922                 if(!preg_match($validator['regex'], $field_value)) {
923                     $errmsg = $validator['errmsg'];
924                     if(isset($this->wordbook[$errmsg])) {
925                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
926                     } else {
5bff39 927                         $this->errorMessage .= $errmsg."<br />\r\n";
M 928                     }
b1a6a5 929                 }
5bff39 930                 break;
b1a6a5 931             case 'UNIQUE':
MC 932                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
933                 if($validator['allowempty'] == 'n' || ($validator['allowempty'] == 'y' && $field_value != '')){
934                     if($this->action == 'NEW') {
2af58c 935                         $num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ?? WHERE ?? = ?", $this->formDef['db_table'], $field_name, $field_value);
b1a6a5 936                         if($num_rec["number"] > 0) {
MC 937                             $errmsg = $validator['errmsg'];
938                             if(isset($this->wordbook[$errmsg])) {
939                                 $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
940                             } else {
941                                 $this->errorMessage .= $errmsg."<br />\r\n";
942                             }
5bff39 943                         }
M 944                     } else {
2af58c 945                         $num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ?? WHERE ?? = ? AND ?? != ?", $this->formDef['db_table'], $field_name, $field_value, $this->formDef['db_table_idx'], $this->primary_id);
b1a6a5 946                         if($num_rec["number"] > 0) {
MC 947                             $errmsg = $validator['errmsg'];
948                             if(isset($this->wordbook[$errmsg])) {
949                                 $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
950                             } else {
951                                 $this->errorMessage .= $errmsg."<br />\r\n";
952                             }
5bff39 953                         }
M 954                     }
955                 }
b1a6a5 956                 break;
MC 957             case 'NOTEMPTY':
86e699 958                 if(!isset($field_value) || $field_value === '') {
b1a6a5 959                     $errmsg = $validator['errmsg'];
MC 960                     if(isset($this->wordbook[$errmsg])) {
961                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
962                     } else {
963                         $this->errorMessage .= $errmsg."<br />\r\n";
964                     }
965                 }
966                 break;
bd8b72 967             case 'ISASCII':
MC 968                 if(preg_match("/[^\x20-\x7F]/", $field_value)) {
969                     $errmsg = $validator['errmsg'];
970                     if(isset($this->wordbook[$errmsg])) {
971                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
972                     } else {
973                         $this->errorMessage .= $errmsg."<br />\r\n";
974                     }
975                 }
b1a6a5 976             case 'ISEMAIL':
a8ab61 977                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
TB 978                 if($validator['allowempty'] == 'y' && $field_value == '') {
979                     //* Do nothing
980                 } else {
981                     if(function_exists('filter_var')) {
982                         if(filter_var($field_value, FILTER_VALIDATE_EMAIL) === false) {
983                             $errmsg = $validator['errmsg'];
984                             if(isset($this->wordbook[$errmsg])) {
985                                 $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
986                             } else {
987                                 $this->errorMessage .= $errmsg."<br />\r\n";
988                             }
5bff39 989                         }
a8ab61 990                     } else $this->errorMessage .= "function filter_var missing <br />\r\n";
TB 991                 }
b1a6a5 992                 break;
MC 993             case 'ISINT':
994                 if(function_exists('filter_var') && $field_value < 2147483647) {
2d45f0 995                     //if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT, array("options" => array('min_range'=>0))) === false) {
TB 996                     if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT) === false) {
b1a6a5 997                         $errmsg = $validator['errmsg'];
MC 998                         if(isset($this->wordbook[$errmsg])) {
999                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1000                         } else {
1001                             $this->errorMessage .= $errmsg."<br />\r\n";
1002                         }
1003                     }
db2069 1004                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
FS 1005                 break;
1006             case 'ISPOSITIVE':
1007                 if(function_exists('filter_var')) {
7526d2 1008                     if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT, array("options" => array('min_range'=>1))) === false) {
b1a6a5 1009                         $errmsg = $validator['errmsg'];
MC 1010                         if(isset($this->wordbook[$errmsg])) {
1011                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1012                         } else {
1013                             $this->errorMessage .= $errmsg."<br />\r\n";
1014                         }
1015                     }
db2069 1016                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
b1a6a5 1017                 break;
fbeb11 1018             case 'V6PREFIXEND':
FS 1019                 $explode_field_value = explode(':',$field_value);
1020                 if (!$explode_field_value[count($explode_field_value)-1]=='' && $explode_field_value[count($explode_field_value)-2]!='' ) {
1021                     $errmsg = $validator['errmsg'];
1022                     if(isset($this->wordbook[$errmsg])) {
1023                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1024                     } else {
1025                         $this->errorMessage .= $errmsg."<br />\r\n";
1026                     }
1027                 }
1028                 break;
1029             case 'V6PREFIXLENGTH':
1030                 // find shortes ipv6 subnet can`t be longer
1031                 $sql_v6 = $app->db->queryOneRecord("SELECT ip_address FROM server_ip WHERE ip_type = 'IPv6' AND virtualhost = 'y' ORDER BY CHAR_LENGTH(ip_address) ASC LIMIT 0,1;");
1032                 $sql_v6_explode=explode(':',$sql_v6['ip_address']);
1033                 $explode_field_value = explode(':',$field_value);
1034                 if (count($sql_v6_explode) < count($explode_field_value) && isset($sql_v6['ip_address'])) {
1035                     $errmsg = $validator['errmsg'];
1036                     if(isset($this->wordbook[$errmsg])) {
1037                         $this->errorMessage .= $this->wordbook[$errmsg].$sql_v6[ip_address]."<br />\r\n";
1038                     } else {
1039                         $this->errorMessage .= $errmsg."<br />\r\n";
1040                     }
1041                 }
1042                 break;
b1a6a5 1043             case 'ISV6PREFIX':
fbeb11 1044                 $v6_prefix_ok=0;
FS 1045                 $explode_field_value = explode(':',$field_value);
b1a6a5 1046                 if ($explode_field_value[count($explode_field_value)-1]=='' && $explode_field_value[count($explode_field_value)-2]=='' ){
MC 1047                     if ( count($explode_field_value) <= 9 ) {
fbeb11 1048                         if (filter_var(substr($field_value,0,strlen($field_value)-2),FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) or filter_var(substr($field_value,0,strlen($field_value)-2).'::0',FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) or filter_var(substr($field_value,0,strlen($field_value)-2).':0',FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) ) {
b1a6a5 1049                             $v6_prefix_ok = 1;
MC 1050                         }
1051                     }
1052                 }
fbeb11 1053                 if($v6_prefix_ok <> 1) {
b1a6a5 1054                     $errmsg = $validator['errmsg'];
fbeb11 1055                     if(isset($this->wordbook[$errmsg])) {
FS 1056                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1057                     } else {
1058                         $this->errorMessage .= $errmsg."<br />\r\n";
1059                     }
b1a6a5 1060                 }
MC 1061                 break;
fbeb11 1062
b1a6a5 1063             case 'ISIPV4':
db2069 1064                 if(function_exists('filter_var')) {
FS 1065                     if(!filter_var($field_value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
1066                         $errmsg = $validator['errmsg'];
1067                         if(isset($this->wordbook[$errmsg])) {
1068                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1069                         } else {
1070                             $this->errorMessage .= $errmsg."<br />\r\n";
1071                         }
b1a6a5 1072                     }
db2069 1073                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
FS 1074                 break;
1075
1076             case 'ISIPV6':
1077                 if(function_exists('filter_var')) {
1078                     if(!filter_var($field_value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
1079                         $errmsg = $validator['errmsg'];
1080                         if(isset($this->wordbook[$errmsg])) {
1081                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1082                         } else {
1083                             $this->errorMessage .= $errmsg."<br />\r\n";
1084                         }
b1a6a5 1085                     }
db2069 1086                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
b1a6a5 1087                 break;
2df8c0 1088
b1a6a5 1089             case 'ISIP':
MC 1090                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
1091                 if($validator['allowempty'] == 'y' && $field_value == '') {
1092                     //* Do nothing
1093                 } else {
1094                     //* Check if its a IPv4 or IPv6 address
1095                     if(isset($validator['separator']) && $validator['separator'] != '') {
1096                         //* When the field may contain several IP addresses, split them by the char defined as separator
1097                         $field_value_array = explode($validator['separator'], $field_value);
1098                     } else {
1099                         $field_value_array[] = $field_value;
1100                     }
1101                     foreach($field_value_array as $field_value) {
1102                         $field_value = trim($field_value);
1103                         if(function_exists('filter_var')) {
1104                             if(!filter_var($field_value, FILTER_VALIDATE_IP)) {
1105                                 $errmsg = $validator['errmsg'];
1106                                 if(isset($this->wordbook[$errmsg])) {
1107                                     $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1108                                 } else {
1109                                     $this->errorMessage .= $errmsg."<br />\r\n";
1110                                 }
1111                             }
db2069 1112                         } else $this->errorMessage .= "function filter_var missing <br />\r\n";
b1a6a5 1113                     }
MC 1114                 }
1115                 break;
7adc6c 1116             
TB 1117             case 'ISDATETIME':
1118                 /* Checks a datetime value against the date format of the current language */
1119                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
1120                 if($validator['allowempty'] == 'y' && $field_value == '') {
1121                     //* Do nothing
1122                 } else {
1123                     $parsed_date = date_parse_from_format($this->datetimeformat,$field_value);
1124                     if($parsed_date['error_count'] > 0 || ($parsed_date['year'] == 1899 && $parsed_date['month'] == 12 && $parsed_date['day'] == 31)) {
1125                         $errmsg = $validator['errmsg'];
1126                         if(isset($this->wordbook[$errmsg])) {
1127                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1128                         } else {
1129                             $this->errorMessage .= $errmsg."<br />\r\n";
1130                         }
1131                     }
1132                 }
1133                 break;
1134             
b1a6a5 1135             case 'RANGE':
MC 1136                 //* Checks if the value is within the given range or above / below a value
1137                 //* Range examples: < 10 = ":10", between 2 and 10 = "2:10", above 5 = "5:".
1138                 $range_parts = explode(':', trim($validator['range']));
1139                 $ok = true;
1140                 if($range_parts[0] != '' && $field_value < $range_parts[0]) {
1141                     $ok = false;
1142                 }
1143                 if($range_parts[1] != '' && $field_value > $range_parts[1]) {
1144                     $ok = false;
1145                 }
1146                 if($ok != true) {
1147                     $errmsg = $validator['errmsg'];
1148                     if(isset($this->wordbook[$errmsg])) {
1149                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1150                     } else {
1151                         $this->errorMessage .= $errmsg."<br />\r\n";
1152                     }
1153                 }
1154                 unset($range_parts);
1155                 break;
1156             case 'CUSTOM':
1157                 // Calls a custom class to validate this record
1158                 if($validator['class'] != '' and $validator['function'] != '') {
1159                     $validator_class = $validator['class'];
1160                     $validator_function = $validator['function'];
1161                     $app->uses($validator_class);
1162                     $this->errorMessage .= $app->$validator_class->$validator_function($field_name, $field_value, $validator);
1163                 } else {
1164                     $this->errorMessage .= "Custom validator class or function is empty<br />\r\n";
1165                 }
1166                 break;
1167             default:
1168                 $this->errorMessage .= "Unknown Validator: ".$validator['type'];
1169                 break;
1170             }
5bff39 1171
M 1172
1173         }
b1a6a5 1174
MC 1175         return true;
1176     }
1177
1178     /**
1179      * Create SQL statement
1180      *
1181      * @param record = Datensatz als Array
1182      * @param action = INSERT oder UPDATE
1183      * @param primary_id
1184      * @return record
1185      */
3a11d2 1186      /* TODO: check for double quoting */
b1a6a5 1187     protected function _getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '', $api = false) {
MC 1188
1189         global $app;
1190
1191         $this->action = $action;
1192         $this->primary_id = $primary_id;
1193
1194
1195         $record = $this->encode($record, $tab, true);
1196         $sql_insert_key = '';
1197         $sql_insert_val = '';
1198         $sql_update = '';
1199
1200         if($api == true) $fields = &$this->formDef['fields'];
1201         else $fields = &$this->formDef['tabs'][$tab]['fields'];
1202
1203         // go trough all fields of the tab
1204         if(is_array($record)) {
1205             foreach($fields as $key => $field) {
1206                 // Wenn es kein leeres Passwortfeld ist
1207                 if (!($field['formtype'] == 'PASSWORD' and $record[$key] == '')) {
1208                     // Erzeuge Insert oder Update Quelltext
1209                     if($action == "INSERT") {
1210                         if($field['formtype'] == 'PASSWORD') {
1211                             $sql_insert_key .= "`$key`, ";
1212                             if ((isset($field['encryption']) && $field['encryption'] == 'CLEARTEXT') || (isset($record['_ispconfig_pw_crypted']) && $record['_ispconfig_pw_crypted'] == 1)) {
1213                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1214                             } elseif(isset($field['encryption']) && $field['encryption'] == 'CRYPT') {
1215                                 $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
1216                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1217                             } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
2af58c 1218                                 $tmp = $app->db->queryOneRecord("SELECT PASSWORD(?) as `crypted`", stripslashes($record[$key]));
b1a6a5 1219                                 $record[$key] = $tmp['crypted'];
MC 1220                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1221                             } else {
1222                                 $record[$key] = md5(stripslashes($record[$key]));
1223                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1224                             }
1225                         } elseif ($field['formtype'] == 'CHECKBOX') {
1226                             $sql_insert_key .= "`$key`, ";
1227                             if($record[$key] == '') {
1228                                 // if a checkbox is not set, we set it to the unchecked value
1229                                 $sql_insert_val .= "'".$field['value'][0]."', ";
1230                                 $record[$key] = $field['value'][0];
1231                             } else {
1232                                 $sql_insert_val .= "'".$record[$key]."', ";
1233                             }
1234                         } else {
1235                             $sql_insert_key .= "`$key`, ";
1236                             $sql_insert_val .= "'".$record[$key]."', ";
1237                         }
1238                     } else {
1239                         if($field['formtype'] == 'PASSWORD') {
1240                             if ((isset($field['encryption']) && $field['encryption'] == 'CLEARTEXT') || (isset($record['_ispconfig_pw_crypted']) && $record['_ispconfig_pw_crypted'] == 1)) {
1241                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1242                             } elseif(isset($field['encryption']) && $field['encryption'] == 'CRYPT') {
1243                                 $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
1244                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1245                             } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
2af58c 1246                                 $tmp = $app->db->queryOneRecord("SELECT PASSWORD(?) as `crypted`", stripslashes($record[$key]));
b1a6a5 1247                                 $record[$key] = $tmp['crypted'];
MC 1248                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1249                             } else {
1250                                 $record[$key] = md5(stripslashes($record[$key]));
1251                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1252                             }
1253
1254                         } elseif ($field['formtype'] == 'CHECKBOX') {
1255                             if($record[$key] == '') {
1256                                 // if a checkbox is not set, we set it to the unchecked value
1257                                 $sql_update .= "`$key` = '".$field['value'][0]."', ";
1258                                 $record[$key] = $field['value'][0];
1259                             } else {
1260                                 $sql_update .= "`$key` = '".$record[$key]."', ";
1261                             }
1262                         } else {
1263                             $sql_update .= "`$key` = '".$record[$key]."', ";
1264                         }
1265                     }
1266                 } else {
1267                     // we unset the password filed, if empty to tell the datalog function
1268                     // that the password has not been changed
1269                     unset($record[$key]);
1270                 }
1271             }
1272         }
1273
1274
1275         // Add backticks for incomplete table names
1276         if(stristr($this->formDef['db_table'], '.')) {
1277             $escape = '';
1278         } else {
1279             $escape = '`';
1280         }
1281
1282
1283         if($action == "INSERT") {
1284             if($this->formDef['auth'] == 'yes') {
1285                 // Set user and group
1286                 $sql_insert_key .= "`sys_userid`, ";
1287                 $sql_insert_val .= ($this->formDef["auth_preset"]["userid"] > 0)?"'".$this->formDef["auth_preset"]["userid"]."', ":"'".$_SESSION["s"]["user"]["userid"]."', ";
1288                 $sql_insert_key .= "`sys_groupid`, ";
1289                 $sql_insert_val .= ($this->formDef["auth_preset"]["groupid"] > 0)?"'".$this->formDef["auth_preset"]["groupid"]."', ":"'".$_SESSION["s"]["user"]["default_group"]."', ";
1290                 $sql_insert_key .= "`sys_perm_user`, ";
1291                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_user"]."', ";
1292                 $sql_insert_key .= "`sys_perm_group`, ";
1293                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_group"]."', ";
1294                 $sql_insert_key .= "`sys_perm_other`, ";
1295                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_other"]."', ";
1296             }
1297             $sql_insert_key = substr($sql_insert_key, 0, -2);
1298             $sql_insert_val = substr($sql_insert_val, 0, -2);
1299             $sql = "INSERT INTO ".$escape.$this->formDef['db_table'].$escape." ($sql_insert_key) VALUES ($sql_insert_val)";
1300         } else {
1301             if($this->formDef['auth'] == 'yes') {
1302                 if($primary_id != 0) {
1303                     if($api == true && $_SESSION["s"]["user"]["client_id"] > 0 && $_SESSION["s"]["user"]["iserid"] > 0 && $_SESSION["s"]["user"]["default_group"] > 0) {
1304                         $sql_update .= '`sys_userid` = '.$this->sys_userid.', ';
1305                         $sql_update .= '`sys_groupid` = '.$this->sys_default_group.', ';
1306                     }
1307
1308                     $sql_update = substr($sql_update, 0, -2);
1309                     $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->getAuthSQL('u')." AND ".$this->formDef['db_table_idx']." = ".$primary_id;
1310                     if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
1311                 } else {
1312                     $app->error("Primary ID fehlt!");
1313                 }
1314             } else {
1315                 if($primary_id != 0) {
1316                     $sql_update = substr($sql_update, 0, -2);
1317                     $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
1318                     if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
1319                 } else {
1320                     $app->error("Primary ID fehlt!");
1321                 }
1322             }
1323             //* return a empty string if there is nothing to update
1324             if(trim($sql_update) == '') $sql = '';
1325         }
1326
1327         return $sql;
1328     }
1329
1330
1331     /**
1332      * Create SQL statement
1333      *
1334      * @param record = Datensatz als Array
1335      * @param action = INSERT oder UPDATE
1336      * @param primary_id
1337      * @return record
1338      */
1339     function getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '') {
1340
1341         global $app;
1342
1343         // If there are no data records on the tab, return empty sql string
1344         if(count($this->formDef['tabs'][$tab]['fields']) == 0) return '';
1345
1346         // checking permissions
1347         if($this->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
1348             if($action == "INSERT") {
1349                 if(!$this->checkPerm($primary_id, 'i')) $this->errorMessage .= "Insert denied.<br />\r\n";
1350             } else {
1351                 if(!$this->checkPerm($primary_id, 'u')) $this->errorMessage .= "Update denied.<br />\r\n";
1352             }
1353         }
1354
1355         if(!is_array($this->formDef)) $app->error("Form definition not found.");
1356         if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
1357
1358         return $this->_getSQL($record, $tab, $action, $primary_id, $sql_ext_where, false);
1359     }
1360
1361
1362     /**
1363      * Debugging arrays.
1364      *
1365      * @param array_data
1366      */
1367     function dbg($array_data) {
1368
1369         echo "<pre>";
1370         print_r($array_data);
1371         echo "</pre>";
1372
1373     }
5bff39 1374
M 1375
1376     function showForm() {
b1a6a5 1377         global $app, $conf;
5bff39 1378
M 1379         if(!is_array($this->formDef)) die("Form Definition wurde nicht geladen.");
1380
b1a6a5 1381         $active_tab = $this->getNextTab();
5bff39 1382
M 1383         // go trough the tabs
1384         foreach( $this->formDef["tabs"] as $key => $tab) {
1385
1386             $tab['name'] = $key;
1387             // Translate the title of the tab
1388             $tab['title'] = $this->lng($tab['title']);
1389
1390             if($tab['name'] == $active_tab) {
1391
1392                 // If module is set, then set the template path relative to the module..
1393                 if($this->module != '') $tab["template"] = "../".$this->module."/".$tab["template"];
1394
1395                 // Generate the template if it does not exist yet.
1396
1397
1398
1399                 if(!is_file($tab["template"])) {
b1a6a5 1400                     $app->uses('tform_tpl_generator');
MC 1401                     $app->tform_tpl_generator->buildHTML($this->formDef, $tab['name']);
5bff39 1402                 }
M 1403                 $app->tpl->setVar('readonly_tab', (isset($tab['readonly']) && $tab['readonly'] == true));
b1a6a5 1404                 $app->tpl->setInclude('content_tpl', $tab["template"]);
5bff39 1405                 $tab["active"] = 1;
M 1406                 $_SESSION["s"]["form"]["tab"] = $tab['name'];
1407             } else {
b1a6a5 1408                 $tab["active"] = 0;
5bff39 1409             }
M 1410
b1a6a5 1411             // Unset unused variables.
MC 1412             unset($tab["fields"]);
1413             unset($tab["plugins"]);
5bff39 1414
M 1415             $frmTab[] = $tab;
1416         }
1417
1418         // setting form tabs
1419         $app->tpl->setLoop("formTab", $frmTab);
1420
b1a6a5 1421         // Set form action
MC 1422         $app->tpl->setVar('form_action', $this->formDef["action"]);
1423         $app->tpl->setVar('form_active_tab', $active_tab);
5bff39 1424
b1a6a5 1425         // Set form title
MC 1426         $form_hint = $this->lng($this->formDef["title"]);
1427         if($this->formDef["description"] != '') $form_hint .= '<div class="pageForm_description">'.$this->lng($this->formDef["description"]).'</div>';
1428         $app->tpl->setVar('form_hint', $form_hint);
5bff39 1429
b1a6a5 1430         // Set Wordbook for this form
5bff39 1431
b1a6a5 1432         $app->tpl->setVar($this->wordbook);
MC 1433     }
1434
1435     function getDataRecord($primary_id) {
1436         global $app;
1437         $escape = '`';
2af58c 1438         $sql = "SELECT * FROM ?? WHERE ?? = ? AND ".$this->getAuthSQL('r', $this->formDef['db_table']);
MC 1439         return $app->db->queryOneRecord($sql, $this->formDef['db_table'], $this->formDef['db_table_idx'], $primary_id);
b1a6a5 1440     }
MC 1441
1442
1443     function datalogSave($action, $primary_id, $record_old, $record_new) {
1444         global $app, $conf;
1445
1446         $app->db->datalogSave($this->formDef['db_table'], $action, $this->formDef['db_table_idx'], $primary_id, $record_old, $record_new);
1447         return true;
1448     }
1449
1450     function getAuthSQL($perm, $table = '') {
ebbe63 1451         if($_SESSION["s"]["user"]["typ"] == 'admin' || $_SESSION['s']['user']['mailuser_id'] > 0) {
b1a6a5 1452             return '1';
MC 1453         } else {
1454             if ($table != ''){
1455                 $table = ' ' . $table . '.';
1456             }
1457             $groups = ( $_SESSION["s"]["user"]["groups"] ) ? $_SESSION["s"]["user"]["groups"] : 0;
1458             $sql = '(';
1459             $sql .= "(" . $table . "sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND " . $table . "sys_perm_user like '%$perm%') OR  ";
1460             $sql .= "(" . $table . "sys_groupid IN (".$groups.") AND " . $table ."sys_perm_group like '%$perm%') OR ";
1461             $sql .= $table . "sys_perm_other like '%$perm%'";
1462             $sql .= ')';
1463
1464             return $sql;
5bff39 1465         }
b1a6a5 1466     }
5bff39 1467
M 1468 }
1469
1470 ?>