Till Brehm
2016-06-29 566c28a952bf361ba9a22d7c39d5c335f6956ab2
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
566c28 565                     case 'DATE':
TB 566                         if (strtotime($val) !== false) {
567                             $dt_value = $val;
568                         } elseif ( isset($field['default']) && (strtotime($field['default']) !== false) ) {
569                             $dt_value = $field['default'];
570                         } else {
571                             $dt_value = 0;
572                         }
573
574                         $new_record[$key] = $this->_getDateHTML($key, $dt_value);
575                         break;
576                     
b1a6a5 577                     default:
MC 578                         if(isset($record[$key])) {
579                             $new_record[$key] = htmlspecialchars($record[$key]);
580                         } else {
581                             $new_record[$key] = '';
582                         }
583                     }
584                 }
585             }
586         } else {
587             // Action: NEW
588             foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
589
590                 // If Datasource is set, get the data from there
591                 if(@is_array($field['datasource'])) {
592                     if(is_array($field["value"])) {
593                         $field["value"] = $app->functions->array_merge($field["value"], $this->getDatasourceData($field, $record));
5bff39 594                     } else {
b1a6a5 595                         $field["value"] = $this->getDatasourceData($field, $record);
5bff39 596                     }
b1a6a5 597                 }
MC 598
599                 // If a limitation for the values is set
600                 if(isset($field['valuelimit']) && is_array($field["value"])) {
601                     $field["value"] = $this->applyValueLimit($field['valuelimit'], $field["value"]);
602                 }
603
604                 switch ($field['formtype']) {
605                 case 'SELECT':
606                     if(is_array($field['value'])) {
607                         $out = '';
608                         foreach($field['value'] as $k => $v) {
609                             $selected = ($k == $field["default"])?' SELECTED':'';
610                             $out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
611                         }
5bff39 612                     }
b1a6a5 613                     if(isset($out)) $new_record[$key] = $out;
MC 614                     break;
615                 case 'MULTIPLE':
616                     if(is_array($field['value'])) {
617
618                         // aufsplitten ergebnisse
619                         $vals = explode($field['separator'], $val);
620
621                         // HTML schreiben
622                         $out = '';
623                         foreach($field['value'] as $k => $v) {
624
625                             $out .= "<option value='$k'>$v</option>\r\n";
626                         }
5bff39 627                     }
b1a6a5 628                     $new_record[$key] = $out;
MC 629                     break;
630
631                 case 'PASSWORD':
632                     //$new_record[$key] = '';
633                     $new_record[$key] = htmlspecialchars($field['default']);
634                     break;
635
636                 case 'CHECKBOX':
637                     // $checked = (empty($field["default"]))?'':' CHECKED';
638                     $checked = ($field["default"] == $field['value'][1])?' CHECKED':'';
639                     $new_record[$key] = "<input name=\"".$key."\" id=\"".$key."\" value=\"".$field['value'][1]."\" type=\"checkbox\" $checked />\r\n";
640                     break;
641
642                 case 'CHECKBOXARRAY':
643                     if(is_array($field['value'])) {
644
645                         // aufsplitten ergebnisse
646                         $vals = explode($field['separator'], $field["default"]);
647
648                         // HTML schreiben
649                         $out = '';
650                         $elementNo = 0;
651                         foreach($field['value'] as $k => $v) {
652
653                             $checked = '';
654                             foreach($vals as $tvl) {
655                                 if(trim($tvl) == trim($k)) $checked = ' CHECKED';
656                             }
657                             // $out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"checkbox\" $checked /> $v</label>\r\n";
658                             $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"checkbox\" $checked /> $v</label> &nbsp;\r\n";
659                             $elementNo++;
660                         }
5bff39 661                     }
b1a6a5 662                     $new_record[$key] = $out;
MC 663                     break;
664
665                 case 'RADIO':
666                     if(is_array($field['value'])) {
667
668                         // HTML schreiben
669                         $out = '';
670                         $elementNo = 0;
671                         foreach($field['value'] as $k => $v) {
672                             $checked = ($k == $field["default"])?' CHECKED':'';
673                             //$out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
674                             $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
675                             $elementNo++;
676                         }
5bff39 677                     }
b1a6a5 678                     $new_record[$key] = $out;
MC 679                     break;
680
681                 case 'DATETIME':
682                     $dt_value = (isset($field['default'])) ? $field['default'] : 0;
683                     $display_seconds = (isset($field['display_seconds']) && $field['display_seconds'] == true) ? true : false;
684
685                     $new_record[$key] = $this->_getDateTimeHTML($key, $dt_value, $display_seconds);
686                     break;
566c28 687                 
TB 688                 case 'DATE':
689                     $dt_value = (isset($field['default'])) ? $field['default'] : 0;
690
691                     $new_record[$key] = $this->_getDateHTML($key, $dt_value);
692                     break;
b1a6a5 693
MC 694                 default:
695                     $new_record[$key] = htmlspecialchars($field['default']);
696                 }
697             }
698
699         }
700
701         if($this->debug == 1) $this->dbg($new_record);
702
703         return $new_record;
704     }
705
706     /**
707      * Rewrite the record data to be stored in the database
708      * and check values with regular expressions.
709      *
710      * @param record = Datensatz als Array
711      * @return record
712      */
713     protected function _encode($record, $tab, $dbencode = true, $api = false) {
714         global $app;
985390 715         if($api == true) {
MC 716             $fields = &$this->formDef['fields'];
717         } else {
718             $fields = &$this->formDef['tabs'][$tab]['fields'];
719             /* CSRF PROTECTION */
720             if(isset($_POST) && is_array($_POST)) {
721                 $_csrf_valid = false;
722                 if(isset($_POST['_csrf_id']) && isset($_POST['_csrf_key'])) {
723                     $_csrf_id = trim($_POST['_csrf_id']);
724                     $_csrf_key = trim($_POST['_csrf_key']);
725                     if(isset($_SESSION['_csrf']) && isset($_SESSION['_csrf'][$_csrf_id]) && isset($_SESSION['_csrf_timeout']) && isset($_SESSION['_csrf_timeout'][$_csrf_id])) {
726                         if($_SESSION['_csrf'][$_csrf_id] === $_csrf_key && $_SESSION['_csrf_timeout'] >= time()) $_csrf_valid = true;
727                     }
728                 }
729                 if($_csrf_valid !== true) {
730                     $app->log('CSRF attempt blocked. Referer: ' . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'unknown'), LOGLEVEL_WARN);
352477 731                     $errmsg = 'err_csrf_attempt_blocked';
MC 732                     $this->errorMessage .= ($api == true ? $errmsg : $this->wordbook[$errmsg]."<br />") . "\r\n";
985390 733                     unset($_POST);
MC 734                     unset($record);
735                 }
736                 
737                 if(isset($_SESSION['_csrf_timeout']) && is_array($_SESSION['_csrf_timeout'])) {
738                     $to_unset = array();
739                     foreach($_SESSION['_csrf_timeout'] as $_csrf_id => $timeout) {
740                         if($timeout < time()) $to_unset[] = $_csrf_id;
741                     }
742                     foreach($to_unset as $_csrf_id) {
c8b685 743                         $_SESSION['_csrf'][$_csrf_id] = null;
MC 744                         $_SESSION['_csrf_timeout'][$_csrf_id] = null;
985390 745                         unset($_SESSION['_csrf'][$_csrf_id]);
MC 746                         unset($_SESSION['_csrf_timeout'][$_csrf_id]);
747                     }
748                     unset($to_unset);
749                 }
750             }
751             /* CSRF PROTECTION */
752         }
753         
754         $new_record = array();
b1a6a5 755         if(is_array($record)) {
MC 756             foreach($fields as $key => $field) {
757
758                 //* Apply filter to record value
759                 if(isset($field['filters']) && is_array($field['filters'])) {
760                     $record[$key] = $this->filterField($key, (isset($record[$key]))?$record[$key]:'', $field['filters'], 'SAVE');
761                 }
762                 //* Validate record value
763                 if(isset($field['validators']) && is_array($field['validators'])) {
764                     $this->validateField($key, (isset($record[$key]))?$record[$key]:'', $field['validators']);
765                 }
766
767                 switch ($field['datatype']) {
768                 case 'VARCHAR':
769                     if(!@is_array($record[$key])) {
770                         $new_record[$key] = (isset($record[$key]))?$record[$key]:'';
771                     } else {
772                         $new_record[$key] = implode($field['separator'], $record[$key]);
773                     }
774                     break;
775                 case 'TEXT':
776                     if(!is_array($record[$key])) {
777                         $new_record[$key] = $record[$key];
778                     } else {
779                         $new_record[$key] = implode($field['separator'], $record[$key]);
780                     }
781                     break;
782                 case 'DATETSTAMP':
783                     if($record[$key] > 0) {
784                         list($tag, $monat, $jahr) = explode('.', $record[$key]);
785                         $new_record[$key] = mktime(0, 0, 0, $monat, $tag, $jahr);
786                     } else {
787                         $new_record[$key] = 0;
788                     }
789                     break;
790                 case 'DATE':
651642 791                     if($record[$key] != '' && !is_null($record[$key]) && $record[$key] != '0000-00-00') {
b1a6a5 792                         if(function_exists('date_parse_from_format')) {
MC 793                             $date_parts = date_parse_from_format($this->dateformat, $record[$key]);
86bc65 794                             $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 795                         } else {
MC 796                             $tmp = strtotime($record[$key]);
797                             $new_record[$key] = date('Y-m-d', $tmp);
798                         }
799                     } else {
651642 800                         $new_record[$key] = null;
b1a6a5 801                     }
MC 802                     break;
803                 case 'INTEGER':
804                     $new_record[$key] = (isset($record[$key]))?$app->functions->intval($record[$key]):0;
805                     break;
806                 case 'DOUBLE':
807                     $new_record[$key] = $record[$key];
808                     break;
809                 case 'CURRENCY':
810                     $new_record[$key] = str_replace(",", ".", $record[$key]);
811                     break;
812
813                 case 'DATETIME':
43e5b6 814                     /*if (is_array($record[$key]))
b1a6a5 815                     {
MC 816                         $filtered_values = array_map(create_function('$item', 'return (int)$item;'), $record[$key]);
817                         extract($filtered_values, EXTR_PREFIX_ALL, '_dt');
818
819                         if ($_dt_day != 0 && $_dt_month != 0 && $_dt_year != 0) {
820                             $new_record[$key] = date( 'Y-m-d H:i:s', mktime($_dt_hour, $_dt_minute, $_dt_second, $_dt_month, $_dt_day, $_dt_year) );
821                         }
43e5b6 822                     } else {*/
651642 823                         if($record[$key] != '' && !is_null($record[$key]) && $record[$key] != '0000-00-00 00:00:00') {
7adc6c 824                             //$tmp = strtotime($record[$key]);
TB 825                             //$new_record[$key] = date($this->datetimeformat, $tmp);
826                             $parsed_date = date_parse_from_format($this->datetimeformat,$record[$key]);
827                             if($parsed_date['error_count'] > 0 || ($parsed_date['year'] == 1899 && $parsed_date['month'] == 12 && $parsed_date['day'] == 31)) {
828                                 // There was an error, set the date to 0
651642 829                                 $new_record[$key] = null;
7adc6c 830                             } else {
TB 831                                 // Date parsed successfully. Convert it to database format
832                                 $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']) );
833                             }
43e5b6 834                         } else {
651642 835                             $new_record[$key] = null;
43e5b6 836                         }
MC 837                     /*}*/
b1a6a5 838                     break;
MC 839                 }
840
841                 // The use of the field value is deprecated, use validators instead
842                 if(isset($field['regex']) && $field['regex'] != '') {
843                     // Enable that "." matches also newlines
844                     $field['regex'] .= 's';
845                     if(!preg_match($field['regex'], $record[$key])) {
846                         $errmsg = $field['errmsg'];
847                         $this->errorMessage .= ($api == true ? $errmsg : $this->wordbook[$errmsg]."<br />") . "\r\n";
848                     }
849                 }
850
851                 //* Add slashes to all records, when we encode data which shall be inserted into mysql.
7537db 852                 if($dbencode == true && !is_null($new_record[$key])) $new_record[$key] = $app->db->quote($new_record[$key]);
b1a6a5 853             }
MC 854         }
855         return $new_record;
856     }
857
858
859     /**
860      * Rewrite the record data to be stored in the database
861      * and check values with regular expressions.
862      *
863      * @param record = Datensatz als Array
864      * @return record
865      */
866     function encode($record, $tab, $dbencode = true) {
867         global $app;
868
869         if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab is empty or does not exist (TAB: $tab).");
870         return $this->_encode($record, $tab, $dbencode, false);
871     }
872
873
874     /**
875      * process the filters for a given field.
876      *
877      * @param field_name = Name of the field
878      * @param field_value = value of the field
879      * @param filters = Array of filters
880      * @param filter_event = 'SAVE'or 'SHOW'
881      * @return record
882      */
883     function filterField($field_name, $field_value, $filters, $filter_event) {
884
885         global $app;
886         $returnval = $field_value;
887
888         //* Loop trough all filters
889         foreach($filters as $filter) {
890             if($filter['event'] == $filter_event) {
891                 switch ($filter['type']) {
892                 case 'TOLOWER':
893                     $returnval = strtolower($returnval);
894                     break;
895                 case 'TOUPPER':
896                     $returnval = strtoupper($returnval);
897                     break;
898                 case 'IDNTOASCII':
899                     $returnval = $app->functions->idn_encode($returnval);
900                     break;
901                 case 'IDNTOUTF8':
902                     $returnval = $app->functions->idn_decode($returnval);
903                     break;
61f1f5 904                 case 'TRIM':
MC 905                     $returnval = trim($returnval);
906                     break;
d22277 907                 case 'NOWHITESPACE':
MB 908                     $returnval = preg_replace('/\s+/', '', $returnval);
909                     break;
b1a6a5 910                 default:
MC 911                     $this->errorMessage .= "Unknown Filter: ".$filter['type'];
912                     break;
913                 }
914             }
915         }
916         return $returnval;
917     }
918
919
920     /**
921      * process the validators for a given field.
922      *
923      * @param field_name = Name of the field
924      * @param field_value = value of the field
925      * @param validatoors = Array of validators
926      * @return record
927      */
928     function validateField($field_name, $field_value, $validators) {
929
930         global $app;
931
932         $escape = '`';
933
934         // loop trough the validators
935         foreach($validators as $validator) {
936
937             switch ($validator['type']) {
938             case 'REGEX':
939                 $validator['regex'] .= 's';
940                 if(!preg_match($validator['regex'], $field_value)) {
941                     $errmsg = $validator['errmsg'];
942                     if(isset($this->wordbook[$errmsg])) {
943                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
944                     } else {
5bff39 945                         $this->errorMessage .= $errmsg."<br />\r\n";
M 946                     }
b1a6a5 947                 }
5bff39 948                 break;
b1a6a5 949             case 'UNIQUE':
MC 950                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
951                 if($validator['allowempty'] == 'n' || ($validator['allowempty'] == 'y' && $field_value != '')){
952                     if($this->action == 'NEW') {
2af58c 953                         $num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ?? WHERE ?? = ?", $this->formDef['db_table'], $field_name, $field_value);
b1a6a5 954                         if($num_rec["number"] > 0) {
MC 955                             $errmsg = $validator['errmsg'];
956                             if(isset($this->wordbook[$errmsg])) {
957                                 $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
958                             } else {
959                                 $this->errorMessage .= $errmsg."<br />\r\n";
960                             }
5bff39 961                         }
M 962                     } else {
2af58c 963                         $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 964                         if($num_rec["number"] > 0) {
MC 965                             $errmsg = $validator['errmsg'];
966                             if(isset($this->wordbook[$errmsg])) {
967                                 $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
968                             } else {
969                                 $this->errorMessage .= $errmsg."<br />\r\n";
970                             }
5bff39 971                         }
M 972                     }
973                 }
b1a6a5 974                 break;
MC 975             case 'NOTEMPTY':
86e699 976                 if(!isset($field_value) || $field_value === '') {
b1a6a5 977                     $errmsg = $validator['errmsg'];
MC 978                     if(isset($this->wordbook[$errmsg])) {
979                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
980                     } else {
981                         $this->errorMessage .= $errmsg."<br />\r\n";
982                     }
983                 }
984                 break;
bd8b72 985             case 'ISASCII':
MC 986                 if(preg_match("/[^\x20-\x7F]/", $field_value)) {
987                     $errmsg = $validator['errmsg'];
988                     if(isset($this->wordbook[$errmsg])) {
989                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
990                     } else {
991                         $this->errorMessage .= $errmsg."<br />\r\n";
992                     }
993                 }
0268a2 994                 break;
b1a6a5 995             case 'ISEMAIL':
0268a2 996                 $error = false;
a8ab61 997                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
TB 998                 if($validator['allowempty'] == 'y' && $field_value == '') {
999                     //* Do nothing
1000                 } else {
1001                     if(function_exists('filter_var')) {
1002                         if(filter_var($field_value, FILTER_VALIDATE_EMAIL) === false) {
0268a2 1003                             $error = true;
FS 1004                         } else {
1005                             if (!preg_match("/^[^\\+]+$/", $field_value)) { // * disallow + in local-part
1006                                 $error = true;
1007                             }
1008                         }
1009                         if ($error) {
a8ab61 1010                             $errmsg = $validator['errmsg'];
TB 1011                             if(isset($this->wordbook[$errmsg])) {
1012                                 $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1013                             } else {
1014                                 $this->errorMessage .= $errmsg."<br />\r\n";
1015                             }
5bff39 1016                         }
0268a2 1017
a8ab61 1018                     } else $this->errorMessage .= "function filter_var missing <br />\r\n";
TB 1019                 }
0268a2 1020                 unset($error);
b1a6a5 1021                 break;
MC 1022             case 'ISINT':
30aae4 1023                 if(function_exists('filter_var') && $field_value < PHP_INT_MAX) {
2d45f0 1024                     //if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT, array("options" => array('min_range'=>0))) === false) {
TB 1025                     if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT) === false) {
b1a6a5 1026                         $errmsg = $validator['errmsg'];
MC 1027                         if(isset($this->wordbook[$errmsg])) {
1028                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1029                         } else {
1030                             $this->errorMessage .= $errmsg."<br />\r\n";
1031                         }
1032                     }
db2069 1033                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
FS 1034                 break;
1035             case 'ISPOSITIVE':
1036                 if(function_exists('filter_var')) {
7526d2 1037                     if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT, array("options" => array('min_range'=>1))) === false) {
b1a6a5 1038                         $errmsg = $validator['errmsg'];
MC 1039                         if(isset($this->wordbook[$errmsg])) {
1040                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1041                         } else {
1042                             $this->errorMessage .= $errmsg."<br />\r\n";
1043                         }
1044                     }
db2069 1045                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
b1a6a5 1046                 break;
fbeb11 1047             case 'V6PREFIXEND':
FS 1048                 $explode_field_value = explode(':',$field_value);
1049                 if (!$explode_field_value[count($explode_field_value)-1]=='' && $explode_field_value[count($explode_field_value)-2]!='' ) {
1050                     $errmsg = $validator['errmsg'];
1051                     if(isset($this->wordbook[$errmsg])) {
1052                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1053                     } else {
1054                         $this->errorMessage .= $errmsg."<br />\r\n";
1055                     }
1056                 }
1057                 break;
1058             case 'V6PREFIXLENGTH':
1059                 // find shortes ipv6 subnet can`t be longer
fe0bcd 1060                 $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 1061                 $sql_v6_explode=explode(':',$sql_v6['ip_address']);
FS 1062                 $explode_field_value = explode(':',$field_value);
1063                 if (count($sql_v6_explode) < count($explode_field_value) && isset($sql_v6['ip_address'])) {
1064                     $errmsg = $validator['errmsg'];
1065                     if(isset($this->wordbook[$errmsg])) {
1066                         $this->errorMessage .= $this->wordbook[$errmsg].$sql_v6[ip_address]."<br />\r\n";
1067                     } else {
1068                         $this->errorMessage .= $errmsg."<br />\r\n";
1069                     }
1070                 }
1071                 break;
b1a6a5 1072             case 'ISV6PREFIX':
fbeb11 1073                 $v6_prefix_ok=0;
FS 1074                 $explode_field_value = explode(':',$field_value);
b1a6a5 1075                 if ($explode_field_value[count($explode_field_value)-1]=='' && $explode_field_value[count($explode_field_value)-2]=='' ){
MC 1076                     if ( count($explode_field_value) <= 9 ) {
fbeb11 1077                         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 1078                             $v6_prefix_ok = 1;
MC 1079                         }
1080                     }
1081                 }
fbeb11 1082                 if($v6_prefix_ok <> 1) {
b1a6a5 1083                     $errmsg = $validator['errmsg'];
fbeb11 1084                     if(isset($this->wordbook[$errmsg])) {
FS 1085                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1086                     } else {
1087                         $this->errorMessage .= $errmsg."<br />\r\n";
1088                     }
b1a6a5 1089                 }
MC 1090                 break;
fbeb11 1091
b1a6a5 1092             case 'ISIPV4':
db2069 1093                 if(function_exists('filter_var')) {
FS 1094                     if(!filter_var($field_value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
1095                         $errmsg = $validator['errmsg'];
1096                         if(isset($this->wordbook[$errmsg])) {
1097                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1098                         } else {
1099                             $this->errorMessage .= $errmsg."<br />\r\n";
1100                         }
b1a6a5 1101                     }
db2069 1102                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
FS 1103                 break;
1104
1105             case 'ISIPV6':
1106                 if(function_exists('filter_var')) {
1107                     if(!filter_var($field_value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
1108                         $errmsg = $validator['errmsg'];
1109                         if(isset($this->wordbook[$errmsg])) {
1110                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1111                         } else {
1112                             $this->errorMessage .= $errmsg."<br />\r\n";
1113                         }
b1a6a5 1114                     }
db2069 1115                 } else $this->errorMessage .= "function filter_var missing <br />\r\n";
b1a6a5 1116                 break;
2df8c0 1117
b1a6a5 1118             case 'ISIP':
MC 1119                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
1120                 if($validator['allowempty'] == 'y' && $field_value == '') {
1121                     //* Do nothing
1122                 } else {
1123                     //* Check if its a IPv4 or IPv6 address
1124                     if(isset($validator['separator']) && $validator['separator'] != '') {
1125                         //* When the field may contain several IP addresses, split them by the char defined as separator
1126                         $field_value_array = explode($validator['separator'], $field_value);
1127                     } else {
1128                         $field_value_array[] = $field_value;
1129                     }
1130                     foreach($field_value_array as $field_value) {
1131                         $field_value = trim($field_value);
1132                         if(function_exists('filter_var')) {
1133                             if(!filter_var($field_value, FILTER_VALIDATE_IP)) {
1134                                 $errmsg = $validator['errmsg'];
1135                                 if(isset($this->wordbook[$errmsg])) {
1136                                     $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1137                                 } else {
1138                                     $this->errorMessage .= $errmsg."<br />\r\n";
1139                                 }
1140                             }
db2069 1141                         } else $this->errorMessage .= "function filter_var missing <br />\r\n";
b1a6a5 1142                     }
MC 1143                 }
1144                 break;
7adc6c 1145             
TB 1146             case 'ISDATETIME':
1147                 /* Checks a datetime value against the date format of the current language */
1148                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
1149                 if($validator['allowempty'] == 'y' && $field_value == '') {
1150                     //* Do nothing
1151                 } else {
1152                     $parsed_date = date_parse_from_format($this->datetimeformat,$field_value);
1153                     if($parsed_date['error_count'] > 0 || ($parsed_date['year'] == 1899 && $parsed_date['month'] == 12 && $parsed_date['day'] == 31)) {
1154                         $errmsg = $validator['errmsg'];
1155                         if(isset($this->wordbook[$errmsg])) {
1156                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1157                         } else {
1158                             $this->errorMessage .= $errmsg."<br />\r\n";
1159                         }
1160                     }
1161                 }
1162                 break;
1163             
b1a6a5 1164             case 'RANGE':
MC 1165                 //* Checks if the value is within the given range or above / below a value
1166                 //* Range examples: < 10 = ":10", between 2 and 10 = "2:10", above 5 = "5:".
1167                 $range_parts = explode(':', trim($validator['range']));
1168                 $ok = true;
1169                 if($range_parts[0] != '' && $field_value < $range_parts[0]) {
1170                     $ok = false;
1171                 }
1172                 if($range_parts[1] != '' && $field_value > $range_parts[1]) {
1173                     $ok = false;
1174                 }
1175                 if($ok != true) {
1176                     $errmsg = $validator['errmsg'];
1177                     if(isset($this->wordbook[$errmsg])) {
1178                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1179                     } else {
1180                         $this->errorMessage .= $errmsg."<br />\r\n";
1181                     }
1182                 }
1183                 unset($range_parts);
1184                 break;
1185             case 'CUSTOM':
1186                 // Calls a custom class to validate this record
1187                 if($validator['class'] != '' and $validator['function'] != '') {
1188                     $validator_class = $validator['class'];
1189                     $validator_function = $validator['function'];
1190                     $app->uses($validator_class);
1191                     $this->errorMessage .= $app->$validator_class->$validator_function($field_name, $field_value, $validator);
1192                 } else {
1193                     $this->errorMessage .= "Custom validator class or function is empty<br />\r\n";
1194                 }
1195                 break;
1196             default:
1197                 $this->errorMessage .= "Unknown Validator: ".$validator['type'];
1198                 break;
1199             }
5bff39 1200
M 1201
1202         }
b1a6a5 1203
MC 1204         return true;
1205     }
1206
1207     /**
1208      * Create SQL statement
1209      *
1210      * @param record = Datensatz als Array
1211      * @param action = INSERT oder UPDATE
1212      * @param primary_id
1213      * @return record
1214      */
3a11d2 1215      /* TODO: check for double quoting */
b1a6a5 1216     protected function _getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '', $api = false) {
MC 1217
1218         global $app;
1219
1220         $this->action = $action;
1221         $this->primary_id = $primary_id;
1222
1223
1224         $record = $this->encode($record, $tab, true);
1225         $sql_insert_key = '';
1226         $sql_insert_val = '';
1227         $sql_update = '';
1228
1229         if($api == true) $fields = &$this->formDef['fields'];
1230         else $fields = &$this->formDef['tabs'][$tab]['fields'];
1231
1232         // go trough all fields of the tab
1233         if(is_array($record)) {
1234             foreach($fields as $key => $field) {
1235                 // Wenn es kein leeres Passwortfeld ist
1236                 if (!($field['formtype'] == 'PASSWORD' and $record[$key] == '')) {
1237                     // Erzeuge Insert oder Update Quelltext
1238                     if($action == "INSERT") {
1239                         if($field['formtype'] == 'PASSWORD') {
1240                             $sql_insert_key .= "`$key`, ";
1241                             if ((isset($field['encryption']) && $field['encryption'] == 'CLEARTEXT') || (isset($record['_ispconfig_pw_crypted']) && $record['_ispconfig_pw_crypted'] == 1)) {
1242                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1243                             } elseif(isset($field['encryption']) && $field['encryption'] == 'CRYPT') {
1244                                 $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
1245                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1246                             } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
2af58c 1247                                 $tmp = $app->db->queryOneRecord("SELECT PASSWORD(?) as `crypted`", stripslashes($record[$key]));
b1a6a5 1248                                 $record[$key] = $tmp['crypted'];
MC 1249                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1250                             } else {
1251                                 $record[$key] = md5(stripslashes($record[$key]));
1252                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1253                             }
1254                         } elseif ($field['formtype'] == 'CHECKBOX') {
1255                             $sql_insert_key .= "`$key`, ";
1256                             if($record[$key] == '') {
1257                                 // if a checkbox is not set, we set it to the unchecked value
1258                                 $sql_insert_val .= "'".$field['value'][0]."', ";
1259                                 $record[$key] = $field['value'][0];
1260                             } else {
1261                                 $sql_insert_val .= "'".$record[$key]."', ";
1262                             }
1263                         } else {
1264                             $sql_insert_key .= "`$key`, ";
7537db 1265                             $sql_insert_val .= (is_null($record[$key]) ? 'NULL' : "'".$record[$key]."'") . ", ";
b1a6a5 1266                         }
MC 1267                     } else {
1268                         if($field['formtype'] == 'PASSWORD') {
1269                             if ((isset($field['encryption']) && $field['encryption'] == 'CLEARTEXT') || (isset($record['_ispconfig_pw_crypted']) && $record['_ispconfig_pw_crypted'] == 1)) {
1270                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1271                             } elseif(isset($field['encryption']) && $field['encryption'] == 'CRYPT') {
1272                                 $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
1273                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1274                             } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
2af58c 1275                                 $tmp = $app->db->queryOneRecord("SELECT PASSWORD(?) as `crypted`", stripslashes($record[$key]));
b1a6a5 1276                                 $record[$key] = $tmp['crypted'];
MC 1277                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1278                             } else {
1279                                 $record[$key] = md5(stripslashes($record[$key]));
1280                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1281                             }
1282
1283                         } elseif ($field['formtype'] == 'CHECKBOX') {
1284                             if($record[$key] == '') {
1285                                 // if a checkbox is not set, we set it to the unchecked value
1286                                 $sql_update .= "`$key` = '".$field['value'][0]."', ";
1287                                 $record[$key] = $field['value'][0];
1288                             } else {
1289                                 $sql_update .= "`$key` = '".$record[$key]."', ";
1290                             }
1291                         } else {
7537db 1292                             $sql_update .= "`$key` = " . (is_null($record[$key]) ? 'NULL' : "'".$record[$key]."'") . ", ";
b1a6a5 1293                         }
MC 1294                     }
1295                 } else {
1296                     // we unset the password filed, if empty to tell the datalog function
1297                     // that the password has not been changed
1298                     unset($record[$key]);
1299                 }
1300             }
1301         }
1302
1303
1304         // Add backticks for incomplete table names
1305         if(stristr($this->formDef['db_table'], '.')) {
1306             $escape = '';
1307         } else {
1308             $escape = '`';
1309         }
1310
1311
1312         if($action == "INSERT") {
1313             if($this->formDef['auth'] == 'yes') {
1314                 // Set user and group
1315                 $sql_insert_key .= "`sys_userid`, ";
1316                 $sql_insert_val .= ($this->formDef["auth_preset"]["userid"] > 0)?"'".$this->formDef["auth_preset"]["userid"]."', ":"'".$_SESSION["s"]["user"]["userid"]."', ";
1317                 $sql_insert_key .= "`sys_groupid`, ";
1318                 $sql_insert_val .= ($this->formDef["auth_preset"]["groupid"] > 0)?"'".$this->formDef["auth_preset"]["groupid"]."', ":"'".$_SESSION["s"]["user"]["default_group"]."', ";
1319                 $sql_insert_key .= "`sys_perm_user`, ";
1320                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_user"]."', ";
1321                 $sql_insert_key .= "`sys_perm_group`, ";
1322                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_group"]."', ";
1323                 $sql_insert_key .= "`sys_perm_other`, ";
1324                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_other"]."', ";
1325             }
1326             $sql_insert_key = substr($sql_insert_key, 0, -2);
1327             $sql_insert_val = substr($sql_insert_val, 0, -2);
1328             $sql = "INSERT INTO ".$escape.$this->formDef['db_table'].$escape." ($sql_insert_key) VALUES ($sql_insert_val)";
1329         } else {
1330             if($this->formDef['auth'] == 'yes') {
1331                 if($primary_id != 0) {
1332                     if($api == true && $_SESSION["s"]["user"]["client_id"] > 0 && $_SESSION["s"]["user"]["iserid"] > 0 && $_SESSION["s"]["user"]["default_group"] > 0) {
1333                         $sql_update .= '`sys_userid` = '.$this->sys_userid.', ';
1334                         $sql_update .= '`sys_groupid` = '.$this->sys_default_group.', ';
1335                     }
1336
1337                     $sql_update = substr($sql_update, 0, -2);
1338                     $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->getAuthSQL('u')." AND ".$this->formDef['db_table_idx']." = ".$primary_id;
1339                     if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
1340                 } else {
1341                     $app->error("Primary ID fehlt!");
1342                 }
1343             } else {
1344                 if($primary_id != 0) {
1345                     $sql_update = substr($sql_update, 0, -2);
1346                     $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
1347                     if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
1348                 } else {
1349                     $app->error("Primary ID fehlt!");
1350                 }
1351             }
1352             //* return a empty string if there is nothing to update
1353             if(trim($sql_update) == '') $sql = '';
1354         }
1355
1356         return $sql;
1357     }
1358
1359
1360     /**
1361      * Create SQL statement
1362      *
1363      * @param record = Datensatz als Array
1364      * @param action = INSERT oder UPDATE
1365      * @param primary_id
1366      * @return record
1367      */
1368     function getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '') {
1369
1370         global $app;
1371
1372         // If there are no data records on the tab, return empty sql string
1373         if(count($this->formDef['tabs'][$tab]['fields']) == 0) return '';
1374
1375         // checking permissions
1376         if($this->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
1377             if($action == "INSERT") {
1378                 if(!$this->checkPerm($primary_id, 'i')) $this->errorMessage .= "Insert denied.<br />\r\n";
1379             } else {
1380                 if(!$this->checkPerm($primary_id, 'u')) $this->errorMessage .= "Update denied.<br />\r\n";
1381             }
1382         }
1383
1384         if(!is_array($this->formDef)) $app->error("Form definition not found.");
1385         if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
1386
1387         return $this->_getSQL($record, $tab, $action, $primary_id, $sql_ext_where, false);
1388     }
1389
1390
1391     /**
1392      * Debugging arrays.
1393      *
1394      * @param array_data
1395      */
1396     function dbg($array_data) {
1397
1398         echo "<pre>";
1399         print_r($array_data);
1400         echo "</pre>";
1401
1402     }
5bff39 1403
M 1404
1405     function showForm() {
b1a6a5 1406         global $app, $conf;
5bff39 1407
M 1408         if(!is_array($this->formDef)) die("Form Definition wurde nicht geladen.");
1409
b1a6a5 1410         $active_tab = $this->getNextTab();
5bff39 1411
M 1412         // go trough the tabs
1413         foreach( $this->formDef["tabs"] as $key => $tab) {
1414
1415             $tab['name'] = $key;
1416             // Translate the title of the tab
1417             $tab['title'] = $this->lng($tab['title']);
1418
1419             if($tab['name'] == $active_tab) {
1420
1421                 // If module is set, then set the template path relative to the module..
1422                 if($this->module != '') $tab["template"] = "../".$this->module."/".$tab["template"];
1423
1424                 // Generate the template if it does not exist yet.
1425
1426
1427
1428                 if(!is_file($tab["template"])) {
b1a6a5 1429                     $app->uses('tform_tpl_generator');
MC 1430                     $app->tform_tpl_generator->buildHTML($this->formDef, $tab['name']);
5bff39 1431                 }
M 1432                 $app->tpl->setVar('readonly_tab', (isset($tab['readonly']) && $tab['readonly'] == true));
b1a6a5 1433                 $app->tpl->setInclude('content_tpl', $tab["template"]);
5bff39 1434                 $tab["active"] = 1;
M 1435                 $_SESSION["s"]["form"]["tab"] = $tab['name'];
1436             } else {
b1a6a5 1437                 $tab["active"] = 0;
5bff39 1438             }
M 1439
b1a6a5 1440             // Unset unused variables.
MC 1441             unset($tab["fields"]);
1442             unset($tab["plugins"]);
5bff39 1443
M 1444             $frmTab[] = $tab;
1445         }
1446
1447         // setting form tabs
1448         $app->tpl->setLoop("formTab", $frmTab);
1449
b1a6a5 1450         // Set form action
MC 1451         $app->tpl->setVar('form_action', $this->formDef["action"]);
1452         $app->tpl->setVar('form_active_tab', $active_tab);
5bff39 1453
b1a6a5 1454         // Set form title
MC 1455         $form_hint = $this->lng($this->formDef["title"]);
1456         if($this->formDef["description"] != '') $form_hint .= '<div class="pageForm_description">'.$this->lng($this->formDef["description"]).'</div>';
1457         $app->tpl->setVar('form_hint', $form_hint);
5bff39 1458
b1a6a5 1459         // Set Wordbook for this form
5bff39 1460
b1a6a5 1461         $app->tpl->setVar($this->wordbook);
MC 1462     }
1463
1464     function getDataRecord($primary_id) {
1465         global $app;
1466         $escape = '`';
2af58c 1467         $sql = "SELECT * FROM ?? WHERE ?? = ? AND ".$this->getAuthSQL('r', $this->formDef['db_table']);
MC 1468         return $app->db->queryOneRecord($sql, $this->formDef['db_table'], $this->formDef['db_table_idx'], $primary_id);
b1a6a5 1469     }
MC 1470
1471
1472     function datalogSave($action, $primary_id, $record_old, $record_new) {
1473         global $app, $conf;
1474
1475         $app->db->datalogSave($this->formDef['db_table'], $action, $this->formDef['db_table_idx'], $primary_id, $record_old, $record_new);
1476         return true;
1477     }
1478
1479     function getAuthSQL($perm, $table = '') {
ebbe63 1480         if($_SESSION["s"]["user"]["typ"] == 'admin' || $_SESSION['s']['user']['mailuser_id'] > 0) {
b1a6a5 1481             return '1';
MC 1482         } else {
1483             if ($table != ''){
1484                 $table = ' ' . $table . '.';
1485             }
1486             $groups = ( $_SESSION["s"]["user"]["groups"] ) ? $_SESSION["s"]["user"]["groups"] : 0;
1487             $sql = '(';
1488             $sql .= "(" . $table . "sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND " . $table . "sys_perm_user like '%$perm%') OR  ";
1489             $sql .= "(" . $table . "sys_groupid IN (".$groups.") AND " . $table ."sys_perm_group like '%$perm%') OR ";
1490             $sql .= $table . "sys_perm_other like '%$perm%'";
1491             $sql .= ')';
1492
1493             return $sql;
5bff39 1494         }
b1a6a5 1495     }
5bff39 1496
M 1497 }
1498
1499 ?>