Marius Burkard
2016-05-04 c3189ce6c7301c3ec17878fd3918f31d0d3cb18a
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.
7537db 834                 if($dbencode == true && !is_null($new_record[$key])) $new_record[$key] = $app->db->quote($new_record[$key]);
b1a6a5 835             }
MC 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                 }
0268a2 976                 break;
b1a6a5 977             case 'ISEMAIL':
0268a2 978                 $error = false;
a8ab61 979                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
TB 980                 if($validator['allowempty'] == 'y' && $field_value == '') {
981                     //* Do nothing
982                 } else {
983                     if(function_exists('filter_var')) {
984                         if(filter_var($field_value, FILTER_VALIDATE_EMAIL) === false) {
0268a2 985                             $error = true;
FS 986                         } else {
987                             if (!preg_match("/^[^\\+]+$/", $field_value)) { // * disallow + in local-part
988                                 $error = true;
989                             }
990                         }
991                         if ($error) {
a8ab61 992                             $errmsg = $validator['errmsg'];
TB 993                             if(isset($this->wordbook[$errmsg])) {
994                                 $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
995                             } else {
996                                 $this->errorMessage .= $errmsg."<br />\r\n";
997                             }
5bff39 998                         }
0268a2 999
a8ab61 1000                     } else $this->errorMessage .= "function filter_var missing <br />\r\n";
TB 1001                 }
0268a2 1002                 unset($error);
b1a6a5 1003                 break;
MC 1004             case 'ISINT':
1005                 if(function_exists('filter_var') && $field_value < 2147483647) {
2d45f0 1006                     //if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT, array("options" => array('min_range'=>0))) === false) {
TB 1007                     if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT) === false) {
b1a6a5 1008                         $errmsg = $validator['errmsg'];
MC 1009                         if(isset($this->wordbook[$errmsg])) {
1010                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1011                         } else {
1012                             $this->errorMessage .= $errmsg."<br />\r\n";
1013                         }
1014                     }
db2069 1015                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
FS 1016                 break;
1017             case 'ISPOSITIVE':
1018                 if(function_exists('filter_var')) {
7526d2 1019                     if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT, array("options" => array('min_range'=>1))) === false) {
b1a6a5 1020                         $errmsg = $validator['errmsg'];
MC 1021                         if(isset($this->wordbook[$errmsg])) {
1022                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1023                         } else {
1024                             $this->errorMessage .= $errmsg."<br />\r\n";
1025                         }
1026                     }
db2069 1027                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
b1a6a5 1028                 break;
fbeb11 1029             case 'V6PREFIXEND':
FS 1030                 $explode_field_value = explode(':',$field_value);
1031                 if (!$explode_field_value[count($explode_field_value)-1]=='' && $explode_field_value[count($explode_field_value)-2]!='' ) {
1032                     $errmsg = $validator['errmsg'];
1033                     if(isset($this->wordbook[$errmsg])) {
1034                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1035                     } else {
1036                         $this->errorMessage .= $errmsg."<br />\r\n";
1037                     }
1038                 }
1039                 break;
1040             case 'V6PREFIXLENGTH':
1041                 // find shortes ipv6 subnet can`t be longer
fe0bcd 1042                 $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");
fbeb11 1043                 $sql_v6_explode=explode(':',$sql_v6['ip_address']);
FS 1044                 $explode_field_value = explode(':',$field_value);
1045                 if (count($sql_v6_explode) < count($explode_field_value) && isset($sql_v6['ip_address'])) {
1046                     $errmsg = $validator['errmsg'];
1047                     if(isset($this->wordbook[$errmsg])) {
1048                         $this->errorMessage .= $this->wordbook[$errmsg].$sql_v6[ip_address]."<br />\r\n";
1049                     } else {
1050                         $this->errorMessage .= $errmsg."<br />\r\n";
1051                     }
1052                 }
1053                 break;
b1a6a5 1054             case 'ISV6PREFIX':
fbeb11 1055                 $v6_prefix_ok=0;
FS 1056                 $explode_field_value = explode(':',$field_value);
b1a6a5 1057                 if ($explode_field_value[count($explode_field_value)-1]=='' && $explode_field_value[count($explode_field_value)-2]=='' ){
MC 1058                     if ( count($explode_field_value) <= 9 ) {
fbeb11 1059                         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 1060                             $v6_prefix_ok = 1;
MC 1061                         }
1062                     }
1063                 }
fbeb11 1064                 if($v6_prefix_ok <> 1) {
b1a6a5 1065                     $errmsg = $validator['errmsg'];
fbeb11 1066                     if(isset($this->wordbook[$errmsg])) {
FS 1067                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1068                     } else {
1069                         $this->errorMessage .= $errmsg."<br />\r\n";
1070                     }
b1a6a5 1071                 }
MC 1072                 break;
fbeb11 1073
b1a6a5 1074             case 'ISIPV4':
db2069 1075                 if(function_exists('filter_var')) {
FS 1076                     if(!filter_var($field_value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
1077                         $errmsg = $validator['errmsg'];
1078                         if(isset($this->wordbook[$errmsg])) {
1079                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1080                         } else {
1081                             $this->errorMessage .= $errmsg."<br />\r\n";
1082                         }
b1a6a5 1083                     }
db2069 1084                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
FS 1085                 break;
1086
1087             case 'ISIPV6':
1088                 if(function_exists('filter_var')) {
1089                     if(!filter_var($field_value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
1090                         $errmsg = $validator['errmsg'];
1091                         if(isset($this->wordbook[$errmsg])) {
1092                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1093                         } else {
1094                             $this->errorMessage .= $errmsg."<br />\r\n";
1095                         }
b1a6a5 1096                     }
db2069 1097                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
b1a6a5 1098                 break;
2df8c0 1099
b1a6a5 1100             case 'ISIP':
MC 1101                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
1102                 if($validator['allowempty'] == 'y' && $field_value == '') {
1103                     //* Do nothing
1104                 } else {
1105                     //* Check if its a IPv4 or IPv6 address
1106                     if(isset($validator['separator']) && $validator['separator'] != '') {
1107                         //* When the field may contain several IP addresses, split them by the char defined as separator
1108                         $field_value_array = explode($validator['separator'], $field_value);
1109                     } else {
1110                         $field_value_array[] = $field_value;
1111                     }
1112                     foreach($field_value_array as $field_value) {
1113                         $field_value = trim($field_value);
1114                         if(function_exists('filter_var')) {
1115                             if(!filter_var($field_value, FILTER_VALIDATE_IP)) {
1116                                 $errmsg = $validator['errmsg'];
1117                                 if(isset($this->wordbook[$errmsg])) {
1118                                     $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1119                                 } else {
1120                                     $this->errorMessage .= $errmsg."<br />\r\n";
1121                                 }
1122                             }
db2069 1123                         } else $this->errorMessage .= "function filter_var missing <br />\r\n";
b1a6a5 1124                     }
MC 1125                 }
1126                 break;
7adc6c 1127             
TB 1128             case 'ISDATETIME':
1129                 /* Checks a datetime value against the date format of the current language */
1130                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
1131                 if($validator['allowempty'] == 'y' && $field_value == '') {
1132                     //* Do nothing
1133                 } else {
1134                     $parsed_date = date_parse_from_format($this->datetimeformat,$field_value);
1135                     if($parsed_date['error_count'] > 0 || ($parsed_date['year'] == 1899 && $parsed_date['month'] == 12 && $parsed_date['day'] == 31)) {
1136                         $errmsg = $validator['errmsg'];
1137                         if(isset($this->wordbook[$errmsg])) {
1138                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1139                         } else {
1140                             $this->errorMessage .= $errmsg."<br />\r\n";
1141                         }
1142                     }
1143                 }
1144                 break;
1145             
b1a6a5 1146             case 'RANGE':
MC 1147                 //* Checks if the value is within the given range or above / below a value
1148                 //* Range examples: < 10 = ":10", between 2 and 10 = "2:10", above 5 = "5:".
1149                 $range_parts = explode(':', trim($validator['range']));
1150                 $ok = true;
1151                 if($range_parts[0] != '' && $field_value < $range_parts[0]) {
1152                     $ok = false;
1153                 }
1154                 if($range_parts[1] != '' && $field_value > $range_parts[1]) {
1155                     $ok = false;
1156                 }
1157                 if($ok != true) {
1158                     $errmsg = $validator['errmsg'];
1159                     if(isset($this->wordbook[$errmsg])) {
1160                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1161                     } else {
1162                         $this->errorMessage .= $errmsg."<br />\r\n";
1163                     }
1164                 }
1165                 unset($range_parts);
1166                 break;
1167             case 'CUSTOM':
1168                 // Calls a custom class to validate this record
1169                 if($validator['class'] != '' and $validator['function'] != '') {
1170                     $validator_class = $validator['class'];
1171                     $validator_function = $validator['function'];
1172                     $app->uses($validator_class);
1173                     $this->errorMessage .= $app->$validator_class->$validator_function($field_name, $field_value, $validator);
1174                 } else {
1175                     $this->errorMessage .= "Custom validator class or function is empty<br />\r\n";
1176                 }
1177                 break;
1178             default:
1179                 $this->errorMessage .= "Unknown Validator: ".$validator['type'];
1180                 break;
1181             }
5bff39 1182
M 1183
1184         }
b1a6a5 1185
MC 1186         return true;
1187     }
1188
1189     /**
1190      * Create SQL statement
1191      *
1192      * @param record = Datensatz als Array
1193      * @param action = INSERT oder UPDATE
1194      * @param primary_id
1195      * @return record
1196      */
3a11d2 1197      /* TODO: check for double quoting */
b1a6a5 1198     protected function _getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '', $api = false) {
MC 1199
1200         global $app;
1201
1202         $this->action = $action;
1203         $this->primary_id = $primary_id;
1204
1205
1206         $record = $this->encode($record, $tab, true);
1207         $sql_insert_key = '';
1208         $sql_insert_val = '';
1209         $sql_update = '';
1210
1211         if($api == true) $fields = &$this->formDef['fields'];
1212         else $fields = &$this->formDef['tabs'][$tab]['fields'];
1213
1214         // go trough all fields of the tab
1215         if(is_array($record)) {
1216             foreach($fields as $key => $field) {
1217                 // Wenn es kein leeres Passwortfeld ist
1218                 if (!($field['formtype'] == 'PASSWORD' and $record[$key] == '')) {
1219                     // Erzeuge Insert oder Update Quelltext
1220                     if($action == "INSERT") {
1221                         if($field['formtype'] == 'PASSWORD') {
1222                             $sql_insert_key .= "`$key`, ";
1223                             if ((isset($field['encryption']) && $field['encryption'] == 'CLEARTEXT') || (isset($record['_ispconfig_pw_crypted']) && $record['_ispconfig_pw_crypted'] == 1)) {
1224                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1225                             } elseif(isset($field['encryption']) && $field['encryption'] == 'CRYPT') {
1226                                 $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
1227                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1228                             } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
2af58c 1229                                 $tmp = $app->db->queryOneRecord("SELECT PASSWORD(?) as `crypted`", stripslashes($record[$key]));
b1a6a5 1230                                 $record[$key] = $tmp['crypted'];
MC 1231                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1232                             } else {
1233                                 $record[$key] = md5(stripslashes($record[$key]));
1234                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1235                             }
1236                         } elseif ($field['formtype'] == 'CHECKBOX') {
1237                             $sql_insert_key .= "`$key`, ";
1238                             if($record[$key] == '') {
1239                                 // if a checkbox is not set, we set it to the unchecked value
1240                                 $sql_insert_val .= "'".$field['value'][0]."', ";
1241                                 $record[$key] = $field['value'][0];
1242                             } else {
1243                                 $sql_insert_val .= "'".$record[$key]."', ";
1244                             }
1245                         } else {
1246                             $sql_insert_key .= "`$key`, ";
7537db 1247                             $sql_insert_val .= (is_null($record[$key]) ? 'NULL' : "'".$record[$key]."'") . ", ";
b1a6a5 1248                         }
MC 1249                     } else {
1250                         if($field['formtype'] == 'PASSWORD') {
1251                             if ((isset($field['encryption']) && $field['encryption'] == 'CLEARTEXT') || (isset($record['_ispconfig_pw_crypted']) && $record['_ispconfig_pw_crypted'] == 1)) {
1252                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1253                             } elseif(isset($field['encryption']) && $field['encryption'] == 'CRYPT') {
1254                                 $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
1255                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1256                             } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
2af58c 1257                                 $tmp = $app->db->queryOneRecord("SELECT PASSWORD(?) as `crypted`", stripslashes($record[$key]));
b1a6a5 1258                                 $record[$key] = $tmp['crypted'];
MC 1259                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1260                             } else {
1261                                 $record[$key] = md5(stripslashes($record[$key]));
1262                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1263                             }
1264
1265                         } elseif ($field['formtype'] == 'CHECKBOX') {
1266                             if($record[$key] == '') {
1267                                 // if a checkbox is not set, we set it to the unchecked value
1268                                 $sql_update .= "`$key` = '".$field['value'][0]."', ";
1269                                 $record[$key] = $field['value'][0];
1270                             } else {
1271                                 $sql_update .= "`$key` = '".$record[$key]."', ";
1272                             }
1273                         } else {
7537db 1274                             $sql_update .= "`$key` = " . (is_null($record[$key]) ? 'NULL' : "'".$record[$key]."'") . ", ";
b1a6a5 1275                         }
MC 1276                     }
1277                 } else {
1278                     // we unset the password filed, if empty to tell the datalog function
1279                     // that the password has not been changed
1280                     unset($record[$key]);
1281                 }
1282             }
1283         }
1284
1285
1286         // Add backticks for incomplete table names
1287         if(stristr($this->formDef['db_table'], '.')) {
1288             $escape = '';
1289         } else {
1290             $escape = '`';
1291         }
1292
1293
1294         if($action == "INSERT") {
1295             if($this->formDef['auth'] == 'yes') {
1296                 // Set user and group
1297                 $sql_insert_key .= "`sys_userid`, ";
1298                 $sql_insert_val .= ($this->formDef["auth_preset"]["userid"] > 0)?"'".$this->formDef["auth_preset"]["userid"]."', ":"'".$_SESSION["s"]["user"]["userid"]."', ";
1299                 $sql_insert_key .= "`sys_groupid`, ";
1300                 $sql_insert_val .= ($this->formDef["auth_preset"]["groupid"] > 0)?"'".$this->formDef["auth_preset"]["groupid"]."', ":"'".$_SESSION["s"]["user"]["default_group"]."', ";
1301                 $sql_insert_key .= "`sys_perm_user`, ";
1302                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_user"]."', ";
1303                 $sql_insert_key .= "`sys_perm_group`, ";
1304                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_group"]."', ";
1305                 $sql_insert_key .= "`sys_perm_other`, ";
1306                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_other"]."', ";
1307             }
1308             $sql_insert_key = substr($sql_insert_key, 0, -2);
1309             $sql_insert_val = substr($sql_insert_val, 0, -2);
1310             $sql = "INSERT INTO ".$escape.$this->formDef['db_table'].$escape." ($sql_insert_key) VALUES ($sql_insert_val)";
1311         } else {
1312             if($this->formDef['auth'] == 'yes') {
1313                 if($primary_id != 0) {
1314                     if($api == true && $_SESSION["s"]["user"]["client_id"] > 0 && $_SESSION["s"]["user"]["iserid"] > 0 && $_SESSION["s"]["user"]["default_group"] > 0) {
1315                         $sql_update .= '`sys_userid` = '.$this->sys_userid.', ';
1316                         $sql_update .= '`sys_groupid` = '.$this->sys_default_group.', ';
1317                     }
1318
1319                     $sql_update = substr($sql_update, 0, -2);
1320                     $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->getAuthSQL('u')." AND ".$this->formDef['db_table_idx']." = ".$primary_id;
1321                     if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
1322                 } else {
1323                     $app->error("Primary ID fehlt!");
1324                 }
1325             } else {
1326                 if($primary_id != 0) {
1327                     $sql_update = substr($sql_update, 0, -2);
1328                     $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
1329                     if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
1330                 } else {
1331                     $app->error("Primary ID fehlt!");
1332                 }
1333             }
1334             //* return a empty string if there is nothing to update
1335             if(trim($sql_update) == '') $sql = '';
1336         }
1337
1338         return $sql;
1339     }
1340
1341
1342     /**
1343      * Create SQL statement
1344      *
1345      * @param record = Datensatz als Array
1346      * @param action = INSERT oder UPDATE
1347      * @param primary_id
1348      * @return record
1349      */
1350     function getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '') {
1351
1352         global $app;
1353
1354         // If there are no data records on the tab, return empty sql string
1355         if(count($this->formDef['tabs'][$tab]['fields']) == 0) return '';
1356
1357         // checking permissions
1358         if($this->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
1359             if($action == "INSERT") {
1360                 if(!$this->checkPerm($primary_id, 'i')) $this->errorMessage .= "Insert denied.<br />\r\n";
1361             } else {
1362                 if(!$this->checkPerm($primary_id, 'u')) $this->errorMessage .= "Update denied.<br />\r\n";
1363             }
1364         }
1365
1366         if(!is_array($this->formDef)) $app->error("Form definition not found.");
1367         if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
1368
1369         return $this->_getSQL($record, $tab, $action, $primary_id, $sql_ext_where, false);
1370     }
1371
1372
1373     /**
1374      * Debugging arrays.
1375      *
1376      * @param array_data
1377      */
1378     function dbg($array_data) {
1379
1380         echo "<pre>";
1381         print_r($array_data);
1382         echo "</pre>";
1383
1384     }
5bff39 1385
M 1386
1387     function showForm() {
b1a6a5 1388         global $app, $conf;
5bff39 1389
M 1390         if(!is_array($this->formDef)) die("Form Definition wurde nicht geladen.");
1391
b1a6a5 1392         $active_tab = $this->getNextTab();
5bff39 1393
M 1394         // go trough the tabs
1395         foreach( $this->formDef["tabs"] as $key => $tab) {
1396
1397             $tab['name'] = $key;
1398             // Translate the title of the tab
1399             $tab['title'] = $this->lng($tab['title']);
1400
1401             if($tab['name'] == $active_tab) {
1402
1403                 // If module is set, then set the template path relative to the module..
1404                 if($this->module != '') $tab["template"] = "../".$this->module."/".$tab["template"];
1405
1406                 // Generate the template if it does not exist yet.
1407
1408
1409
1410                 if(!is_file($tab["template"])) {
b1a6a5 1411                     $app->uses('tform_tpl_generator');
MC 1412                     $app->tform_tpl_generator->buildHTML($this->formDef, $tab['name']);
5bff39 1413                 }
M 1414                 $app->tpl->setVar('readonly_tab', (isset($tab['readonly']) && $tab['readonly'] == true));
b1a6a5 1415                 $app->tpl->setInclude('content_tpl', $tab["template"]);
5bff39 1416                 $tab["active"] = 1;
M 1417                 $_SESSION["s"]["form"]["tab"] = $tab['name'];
1418             } else {
b1a6a5 1419                 $tab["active"] = 0;
5bff39 1420             }
M 1421
b1a6a5 1422             // Unset unused variables.
MC 1423             unset($tab["fields"]);
1424             unset($tab["plugins"]);
5bff39 1425
M 1426             $frmTab[] = $tab;
1427         }
1428
1429         // setting form tabs
1430         $app->tpl->setLoop("formTab", $frmTab);
1431
b1a6a5 1432         // Set form action
MC 1433         $app->tpl->setVar('form_action', $this->formDef["action"]);
1434         $app->tpl->setVar('form_active_tab', $active_tab);
5bff39 1435
b1a6a5 1436         // Set form title
MC 1437         $form_hint = $this->lng($this->formDef["title"]);
1438         if($this->formDef["description"] != '') $form_hint .= '<div class="pageForm_description">'.$this->lng($this->formDef["description"]).'</div>';
1439         $app->tpl->setVar('form_hint', $form_hint);
5bff39 1440
b1a6a5 1441         // Set Wordbook for this form
5bff39 1442
b1a6a5 1443         $app->tpl->setVar($this->wordbook);
MC 1444     }
1445
1446     function getDataRecord($primary_id) {
1447         global $app;
1448         $escape = '`';
2af58c 1449         $sql = "SELECT * FROM ?? WHERE ?? = ? AND ".$this->getAuthSQL('r', $this->formDef['db_table']);
MC 1450         return $app->db->queryOneRecord($sql, $this->formDef['db_table'], $this->formDef['db_table_idx'], $primary_id);
b1a6a5 1451     }
MC 1452
1453
1454     function datalogSave($action, $primary_id, $record_old, $record_new) {
1455         global $app, $conf;
1456
1457         $app->db->datalogSave($this->formDef['db_table'], $action, $this->formDef['db_table_idx'], $primary_id, $record_old, $record_new);
1458         return true;
1459     }
1460
1461     function getAuthSQL($perm, $table = '') {
ebbe63 1462         if($_SESSION["s"]["user"]["typ"] == 'admin' || $_SESSION['s']['user']['mailuser_id'] > 0) {
b1a6a5 1463             return '1';
MC 1464         } else {
1465             if ($table != ''){
1466                 $table = ' ' . $table . '.';
1467             }
1468             $groups = ( $_SESSION["s"]["user"]["groups"] ) ? $_SESSION["s"]["user"]["groups"] : 0;
1469             $sql = '(';
1470             $sql .= "(" . $table . "sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND " . $table . "sys_perm_user like '%$perm%') OR  ";
1471             $sql .= "(" . $table . "sys_groupid IN (".$groups.") AND " . $table ."sys_perm_group like '%$perm%') OR ";
1472             $sql .= $table . "sys_perm_other like '%$perm%'";
1473             $sql .= ')';
1474
1475             return $sql;
5bff39 1476         }
b1a6a5 1477     }
5bff39 1478
M 1479 }
1480
1481 ?>