Marius Cramer
2015-06-05 e5c68a10633302896a8562f17577f015b3506c84
commit | author | age
2dadd2 1 <?php
T 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
992797 10     * Redistributions of source code must retain the above copyright notice,
MC 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.
2dadd2 18
T 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 /**
7fe908 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
2dadd2 61
T 62 class tform {
63
7fe908 64     /**
MC 65      * Definition of the database table (array)
66      * @var tableDef
67      */
68     var $tableDef;
2dadd2 69
7fe908 70     /**
MC 71      * Private
72      * @var action
73      */
74     var $action;
2dadd2 75
7fe908 76     /**
MC 77      * Table name (String)
78      * @var table_name
79      */
80     var $table_name;
2dadd2 81
7fe908 82     /**
MC 83      * Debug Variable
84      * @var debug
85      */
86     var $debug = 0;
2dadd2 87
7fe908 88     /**
MC 89      * name of the primary field of the database table (string)
90      * @var table_index
91      */
92     var $table_index;
2dadd2 93
7fe908 94     /**
MC 95      * contains the error messages
96      * @var errorMessage
97      */
98     var $errorMessage = '';
2dadd2 99
7fe908 100     var $dateformat = "d.m.Y";
MC 101     var $formDef = array();
102     var $wordbook;
103     var $module;
104     var $primary_id;
105     var $diffrec = array();
2dadd2 106
7fe908 107     /**
MC 108      * Loading of the table definition
109      *
110      * @param file: path to the form definition file
111      * @return true
112      */
113     /*
992797 114         function loadTableDef($file) {
MC 115                 global $app,$conf;
2dadd2 116
992797 117                 include_once($file);
MC 118                 $this->tableDef = $table;
119                 $this->table_name = $table_name;
120                 $this->table_index = $table_index;
121                 return true;
122         }
123         */
2dadd2 124
7fe908 125     function loadFormDef($file, $module = '') {
MC 126         global $app, $conf;
2dadd2 127
7fe908 128         include $file;
MC 129         $this->formDef = $form;
2dadd2 130
7fe908 131         $this->module = $module;
MC 132         $wb = array();
b5a0dc 133
82e2a2 134         include ISPC_ROOT_PATH.'/lib/lang/'.$_SESSION['s']['language'].'.lng';
2dadd2 135
7fe908 136         if(is_array($wb)) $wb_global = $wb;
2dadd2 137
7fe908 138         if($module == '') {
MC 139             $lng_file = "lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng";
140             if(!file_exists($lng_file)) $lng_file = "lib/lang/en_".$this->formDef["name"].".lng";
141             include $lng_file;
142         } else {
143             $lng_file = "../$module/lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng";
144             if(!file_exists($lng_file)) $lng_file = "../$module/lib/lang/en_".$this->formDef["name"].".lng";
145             include $lng_file;
d5473b 146         }
7fe908 147
MC 148         if(is_array($wb_global)) {
7b3516 149             $wb = $app->functions->array_merge($wb_global, $wb);
7fe908 150         }
MC 151         if(isset($wb_global)) unset($wb_global);
152
153         $this->wordbook = $wb;
154
155         $this->dateformat = $app->lng('conf_format_dateshort');
156
157         return true;
158     }
159
160     /**
161      * Converts the data in the array to human readable format
162      * Datatype conversion e.g. to show the data in lists
163      *
164      * @param record
165      * @return record
166      */
167     function decode($record, $tab) {
168         global $conf, $app;
169         if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab does not exist or the tab is empty (TAB: $tab).");
170         $new_record = '';
171         $table_idx = $this->formDef['db_table_idx'];
172         if(isset($record[$table_idx])) $new_record[$table_idx] = $app->functions->intval($record[$table_idx ]);
173
174         if(is_array($record)) {
175             foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
176
177                 //* Apply filter to record value.
178                 if(isset($field['filters']) && is_array($field['filters'])) {
179                     $record[$key] = $this->filterField($key, (isset($record[$key]))?$record[$key]:'', $field['filters'], 'SHOW');
180                 }
181
182                 switch ($field['datatype']) {
183                 case 'VARCHAR':
184                     $new_record[$key] = $record[$key];
185                     break;
186
187                 case 'TEXT':
188                     $new_record[$key] = $record[$key];
189                     break;
190
191                 case 'DATETSTAMP':
192                     if($record[$key] > 0) {
193                         $new_record[$key] = date($this->dateformat, $record[$key]);
194                     }
195                     break;
196
197                 case 'DATE':
198                     if($record[$key] != '' && $record[$key] != '0000-00-00') {
199                         $tmp = explode('-', $record[$key]);
200                         $new_record[$key] = date($this->dateformat, mktime(0, 0, 0, $tmp[1]  , $tmp[2], $tmp[0]));
201                     }
202                     break;
203
204                 case 'INTEGER':
205                     $new_record[$key] = $app->functions->intval($record[$key]);
206                     break;
207
208                 case 'DOUBLE':
209                     $new_record[$key] = $record[$key];
210                     break;
211
212                 case 'CURRENCY':
213                     $new_record[$key] = $app->functions->currency_format($record[$key]);
214                     break;
215
216                 default:
217                     $new_record[$key] = $record[$key];
2dadd2 218                 }
T 219             }
7fe908 220
MC 221         }
222
223         return $new_record;
224     }
225
226
227     /**
228      * Get the key => value array of a form filled from a datasource definitiom
229      *
230      * @param field = array with field definition
231      * @param record = Dataset as array
232      * @return key => value array for the value field of a form
233      */
234     function getDatasourceData($field, $record) {
235         global $app;
236
237         $values = array();
238
239         if($field["datasource"]["type"] == 'SQL') {
240
241             // Preparing SQL string. We will replace some
242             // common placeholders
243             $querystring = $field["datasource"]["querystring"];
244             $querystring = str_replace("{USERID}", $_SESSION["s"]["user"]["userid"], $querystring);
245             $querystring = str_replace("{GROUPID}", $_SESSION["s"]["user"]["default_group"], $querystring);
246             $querystring = str_replace("{GROUPS}", $_SESSION["s"]["user"]["groups"], $querystring);
247             $table_idx = $this->formDef['db_table_idx'];
248
249             $tmp_recordid = (isset($record[$table_idx]))?$record[$table_idx]:0;
250             $querystring = str_replace("{RECORDID}", $tmp_recordid, $querystring);
251             unset($tmp_recordid);
252
253             $querystring = str_replace("{AUTHSQL}", $this->getAuthSQL('r'), $querystring);
b509d0 254             //$querystring = preg_replace_callback('@{AUTHSQL::(.+?)}@', "self::table_auth_sql", $querystring);
TB 255             //*Used the ld form to be compatible with php < 5.3
256             $querystring = preg_replace_callback('@{AUTHSQL::(.+?)}@', create_function('$matches','global $app; $tmp = $app->tform->getAuthSQL("r", $matches[1]); return $tmp;'), $querystring);
7fe908 257
MC 258             // Getting the records
259             $tmp_records = $app->db->queryAllRecords($querystring);
260             if($app->db->errorMessage != '') die($app->db->errorMessage);
261             if(is_array($tmp_records)) {
262                 $key_field = $field["datasource"]["keyfield"];
263                 $value_field = $field["datasource"]["valuefield"];
264                 foreach($tmp_records as $tmp_rec) {
265                     $tmp_id = $tmp_rec[$key_field];
266                     $values[$tmp_id] = $tmp_rec[$value_field];
267                 }
268             }
269         }
270
271         if($field["datasource"]["type"] == 'CUSTOM') {
272             // Calls a custom class to validate this record
273             if($field["datasource"]['class'] != '' and $field["datasource"]['function'] != '') {
274                 $datasource_class = $field["datasource"]['class'];
275                 $datasource_function = $field["datasource"]['function'];
276                 $app->uses($datasource_class);
277                 $values = $app->$datasource_class->$datasource_function($field, $record);
278             } else {
279                 $this->errorMessage .= "Custom datasource class or function is empty<br />\r\n";
280             }
281         }
282
283         if(isset($field['filters']) && is_array($field['filters'])) {
284             $new_values = array();
285             foreach($values as $index => $value) {
286                 $new_index = $this->filterField($index, $index, $field['filters'], 'SHOW');
287                 $new_values[$new_index] = $this->filterField($index, (isset($values[$index]))?$values[$index]:'', $field['filters'], 'SHOW');
288             }
289             $values = $new_values;
290             unset($new_values);
291             unset($new_index);
292         }
293
294         return $values;
295
296     }
b509d0 297     
TB 298     /*
7fe908 299     function table_auth_sql($matches){
MC 300         return $this->getAuthSQL('r', $matches[1]);
301     }
b509d0 302     */
7fe908 303
MC 304     //* If the parameter 'valuelimit' is set
305     function applyValueLimit($limit, $values) {
306
307         global $app;
308
309         $limit_parts = explode(':', $limit);
310
311         //* values are limited to a comma separated list
312         if($limit_parts[0] == 'list') {
313             $allowed = explode(',', $limit_parts[1]);
314         }
315
316         //* values are limited to a field in the client settings
317         if($limit_parts[0] == 'client') {
318             if($_SESSION["s"]["user"]["typ"] == 'admin') {
319                 return $values;
320             } else {
321                 $client_group_id = $_SESSION["s"]["user"]["default_group"];
322                 $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");
323                 $allowed = explode(',', $client['lm']);
324             }
325         }
326
327         //* values are limited to a field in the reseller settings
328         if($limit_parts[0] == 'reseller') {
329             if($_SESSION["s"]["user"]["typ"] == 'admin') {
330                 return $values;
331             } else {
332                 //* Get the limits of the client that is currently logged in
333                 $client_group_id = $_SESSION["s"]["user"]["default_group"];
334                 $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");
335                 //echo "SELECT parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id";
336                 //* If the client belongs to a reseller, we will check against the reseller Limit too
337                 if($client['parent_client_id'] != 0) {
338
339                     //* first we need to know the groups of this reseller
340                     $tmp = $app->db->queryOneRecord("SELECT userid, groups FROM sys_user WHERE client_id = ".$client['parent_client_id']);
341                     $reseller_groups = $tmp["groups"];
342                     $reseller_userid = $tmp["userid"];
343
344                     // Get the limits of the reseller of the logged in client
67c4b3 345                     $client_group_id = $_SESSION["s"]["user"]["default_group"];
7fe908 346                     $reseller = $app->db->queryOneRecord("SELECT ".$limit_parts[1]." as lm FROM client WHERE client_id = ".$client['parent_client_id']);
MC 347                     $allowed = explode(',', $reseller['lm']);
348                 } else {
349                     return $values;
350                 }
351             } // end if admin
352         } // end if reseller
353
354         //* values are limited to a field in the system settings
355         if($limit_parts[0] == 'system') {
356             $app->uses('getconf');
357             $tmp_conf = $app->getconf->get_global_config($limit_parts[1]);
358             $tmp_key = $limit_parts[2];
359             $allowed = $tmp_conf[$tmp_key];
360         }
361
362         $values_new = array();
363         foreach($values as $key => $val) {
364             if(in_array($key, $allowed)) $values_new[$key] = $val;
365         }
366
367         return $values_new;
368     }
369
370
371     /**
372      * Prepare the data record to show the data in a form.
373      *
374      * @param record = Datensatz als Array
375      * @param action = NEW oder EDIT
376      * @return record
377      */
378     function getHTML($record, $tab, $action = 'NEW') {
379
380         global $app;
381
382         $this->action = $action;
383
384         if(!is_array($this->formDef)) $app->error("No form definition found.");
385         if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
582cbf 386         
MC 387         /* CSRF PROTECTION */
388         // generate csrf protection id and key
5af0cf 389         /*$_csrf_id = uniqid($this->formDef['name'] . '_');
582cbf 390         $_csrf_value = sha1(uniqid(microtime(true), true));
MC 391         if(!isset($_SESSION['_csrf'])) $_SESSION['_csrf'] = array();
392         if(!isset($_SESSION['_csrf_timeout'])) $_SESSION['_csrf_timeout'] = array();
393         $_SESSION['_csrf'][$_csrf_id] = $_csrf_value;
394         $_SESSION['_csrf_timeout'][$_csrf_id] = time() + 3600; // timeout hash in 1 hour
5af0cf 395         */
TB 396         $csrf_token = $app->auth->csrf_token_get($this->formDef['name']);
397         $_csrf_id = $csrf_token['csrf_id'];
398         $_csrf_value = $csrf_token['csrf_key'];
399         
582cbf 400         $this->formDef['tabs'][$tab]['fields']['_csrf_id'] = array(
MC 401             'datatype' => 'VARCHAR',
402             'formtype' => 'TEXT',
403             'default' => $_csrf_id,
404             'value' => $_csrf_id
405         );
406         $this->formDef['tabs'][$tab]['fields']['_csrf_key'] = array(
407             'datatype' => 'VARCHAR',
408             'formtype' => 'TEXT',
409             'default' => $_csrf_value,
410             'value' => $_csrf_value
411         );
412         $record['_csrf_id'] = $_csrf_id;
413         $record['_csrf_key'] = $_csrf_value;
414         /* CSRF PROTECTION */
415         
7fe908 416         $new_record = array();
MC 417         if($action == 'EDIT') {
418             $record = $this->decode($record, $tab);
419             if(is_array($record)) {
420                 foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
421
422                     if(isset($record[$key])) {
423                         $val = $record[$key];
67c4b3 424                     } else {
7fe908 425                         $val = '';
67c4b3 426                     }
2dadd2 427
7fe908 428                     // If Datasource is set, get the data from there
MC 429                     if(isset($field['datasource']) && is_array($field['datasource'])) {
430                         if(is_array($field["value"])) {
431                             //$field["value"] = array_merge($field["value"],$this->getDatasourceData($field, $record));
432                             $field["value"] = $app->functions->array_merge($field["value"], $this->getDatasourceData($field, $record));
433                         } else {
434                             $field["value"] = $this->getDatasourceData($field, $record);
435                         }
436                     }
2dadd2 437
7fe908 438                     // If a limitation for the values is set
MC 439                     if(isset($field['valuelimit']) && is_array($field["value"])) {
440                         $field["value"] = $this->applyValueLimit($field['valuelimit'], $field["value"]);
441                     }
2dadd2 442
7fe908 443                     switch ($field['formtype']) {
MC 444                     case 'SELECT':
445                         $out = '';
446                         if(is_array($field['value'])) {
447                             foreach($field['value'] as $k => $v) {
448                                 $selected = ($k == $val)?' SELECTED':'';
449                                 if(!empty($this->wordbook[$v]))
450                                     $v = $this->wordbook[$v];
451                                 $out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
452                             }
453                         }
454                         $new_record[$key] = $out;
455                         break;
456                     case 'MULTIPLE':
457                         if(is_array($field['value'])) {
2dadd2 458
7fe908 459                             // Split
MC 460                             $vals = explode($field['separator'], $val);
2dadd2 461
7fe908 462                             // write HTML
MC 463                             $out = '';
464                             foreach($field['value'] as $k => $v) {
2dadd2 465
7fe908 466                                 $selected = '';
MC 467                                 foreach($vals as $tvl) {
468                                     if(trim($tvl) == trim($k)) $selected = ' SELECTED';
2dadd2 469                                 }
T 470
7fe908 471                                 $out .= "<option value='$k'$selected>$v</option>\r\n";
MC 472                             }
473                         }
474                         $new_record[$key] = $out;
475                         break;
2dadd2 476
7fe908 477                     case 'PASSWORD':
MC 478                         $new_record[$key] = '';
479                         break;
2dadd2 480
7fe908 481                     case 'CHECKBOX':
MC 482                         $checked = ($val == $field['value'][1])?' CHECKED':'';
483                         $new_record[$key] = "<input name=\"".$key."\" id=\"".$key."\" value=\"".$field['value'][1]."\" type=\"checkbox\" $checked />\r\n";
484                         break;
2dadd2 485
7fe908 486                     case 'CHECKBOXARRAY':
MC 487                         if(is_array($field['value'])) {
2dadd2 488
7fe908 489                             // aufsplitten ergebnisse
MC 490                             $vals = explode($field['separator'], $val);
2dadd2 491
7fe908 492                             // HTML schreiben
MC 493                             $out = '';
494                             $elementNo = 0;
495                             foreach($field['value'] as $k => $v) {
2dadd2 496
7fe908 497                                 $checked = '';
MC 498                                 foreach($vals as $tvl) {
499                                     if(trim($tvl) == trim($k)) $checked = ' CHECKED';
d370bb 500                                 }
7fe908 501                                 // $out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"checkbox\" $checked /> $v</label>\r\n";
MC 502                                 $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"checkbox\" $checked /> $v</label><br/>\r\n";
503                                 $elementNo++;
504                             }
505                         }
506                         $new_record[$key] = $out;
507                         break;
2dadd2 508
7fe908 509                     case 'RADIO':
MC 510                         if(is_array($field['value'])) {
2dadd2 511
7fe908 512                             // HTML schreiben
MC 513                             $out = '';
514                             $elementNo = 0;
515                             foreach($field['value'] as $k => $v) {
516                                 $checked = ($k == $val)?' CHECKED':'';
517                                 //$out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
518                                 $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"radio\" $checked/> $v </label>\r\n";
519                                 $elementNo++;
520                             }
521                         }
522                         $new_record[$key] = $out;
523                         break;
2332b2 524
7fe908 525                     case 'DATETIME':
MC 526                         if (strtotime($val) !== false) {
527                             $dt_value = $val;
528                         } elseif ( isset($field['default']) && (strtotime($field['default']) !== false) ) {
529                             $dt_value = $field['default'];
530                         } else {
531                             $dt_value = 0;
532                         }
d370bb 533
7fe908 534                         $display_seconds = (isset($field['display_seconds']) && $field['display_seconds'] == true) ? true : false;
MC 535
536                         $new_record[$key] = $this->_getDateTimeHTML($key, $dt_value, $display_seconds);
d370bb 537                         break;
7fe908 538
MC 539                     default:
540                         if(isset($record[$key])) {
541                             $new_record[$key] = htmlspecialchars($record[$key]);
542                         } else {
543                             $new_record[$key] = '';
544                         }
d370bb 545                     }
T 546                 }
547             }
7fe908 548         } else {
MC 549             // Action: NEW
550             foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
2dadd2 551
7fe908 552                 // If Datasource is set, get the data from there
MC 553                 if(@is_array($field['datasource'])) {
554                     if(is_array($field["value"])) {
555                         $field["value"] = $app->functions->array_merge($field["value"], $this->getDatasourceData($field, $record));
556                     } else {
557                         $field["value"] = $this->getDatasourceData($field, $record);
558                     }
559                 }
2dadd2 560
7fe908 561                 // If a limitation for the values is set
MC 562                 if(isset($field['valuelimit']) && is_array($field["value"])) {
563                     $field["value"] = $this->applyValueLimit($field['valuelimit'], $field["value"]);
564                 }
2dadd2 565
7fe908 566                 switch ($field['formtype']) {
MC 567                 case 'SELECT':
568                     if(is_array($field['value'])) {
569                         $out = '';
570                         foreach($field['value'] as $k => $v) {
571                             $selected = ($k == $field["default"])?' SELECTED':'';
572                             $out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
573                         }
574                     }
575                     if(isset($out)) $new_record[$key] = $out;
576                     break;
577                 case 'MULTIPLE':
578                     if(is_array($field['value'])) {
2dadd2 579
7fe908 580                         // aufsplitten ergebnisse
MC 581                         $vals = explode($field['separator'], $val);
582
583                         // HTML schreiben
584                         $out = '';
585                         foreach($field['value'] as $k => $v) {
586
587                             $out .= "<option value='$k'>$v</option>\r\n";
588                         }
589                     }
590                     $new_record[$key] = $out;
591                     break;
592
593                 case 'PASSWORD':
594                     //$new_record[$key] = '';
595                     $new_record[$key] = htmlspecialchars($field['default']);
596                     break;
597
598                 case 'CHECKBOX':
599                     // $checked = (empty($field["default"]))?'':' CHECKED';
600                     $checked = ($field["default"] == $field['value'][1])?' CHECKED':'';
601                     $new_record[$key] = "<input name=\"".$key."\" id=\"".$key."\" value=\"".$field['value'][1]."\" type=\"checkbox\" $checked />\r\n";
602                     break;
603
604                 case 'CHECKBOXARRAY':
605                     if(is_array($field['value'])) {
606
607                         // aufsplitten ergebnisse
608                         $vals = explode($field['separator'], $field["default"]);
609
610                         // HTML schreiben
611                         $out = '';
612                         $elementNo = 0;
613                         foreach($field['value'] as $k => $v) {
614
615                             $checked = '';
616                             foreach($vals as $tvl) {
617                                 if(trim($tvl) == trim($k)) $checked = ' CHECKED';
618                             }
619                             // $out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"checkbox\" $checked /> $v</label>\r\n";
620                             $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"checkbox\" $checked /> $v</label> &nbsp;\r\n";
621                             $elementNo++;
622                         }
623                     }
624                     $new_record[$key] = $out;
625                     break;
626
627                 case 'RADIO':
628                     if(is_array($field['value'])) {
629
630                         // HTML schreiben
631                         $out = '';
632                         $elementNo = 0;
633                         foreach($field['value'] as $k => $v) {
634                             $checked = ($k == $field["default"])?' CHECKED':'';
635                             //$out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
636                             $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
637                             $elementNo++;
638                         }
639                     }
640                     $new_record[$key] = $out;
641                     break;
642
643                 case 'DATETIME':
644                     $dt_value = (isset($field['default'])) ? $field['default'] : 0;
645                     $display_seconds = (isset($field['display_seconds']) && $field['display_seconds'] == true) ? true : false;
646
647                     $new_record[$key] = $this->_getDateTimeHTML($key, $dt_value, $display_seconds);
648                     break;
649
650                 default:
651                     $new_record[$key] = htmlspecialchars($field['default']);
652                 }
653             }
654
655         }
656
657         if($this->debug == 1) $this->dbg($new_record);
658
659         return $new_record;
660     }
661
662
663     /**
664      * Rewrite the record data to be stored in the database
665      * and check values with regular expressions.
666      *
667      * @param record = Datensatz als Array
668      * @return record
669      */
670     function encode($record, $tab, $dbencode = true) {
671         global $app;
672
673         if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab is empty or does not exist (TAB: $tab).");
674         //$this->errorMessage = '';
582cbf 675         
MC 676         /* CSRF PROTECTION */
5af0cf 677         
582cbf 678         if(isset($_POST) && is_array($_POST)) {
MC 679             $_csrf_valid = false;
680             if(isset($_POST['_csrf_id']) && isset($_POST['_csrf_key'])) {
681                 $_csrf_id = trim($_POST['_csrf_id']);
682                 $_csrf_key = trim($_POST['_csrf_key']);
683                 if(isset($_SESSION['_csrf']) && isset($_SESSION['_csrf'][$_csrf_id]) && isset($_SESSION['_csrf_timeout']) && isset($_SESSION['_csrf_timeout'][$_csrf_id])) {
684                     if($_SESSION['_csrf'][$_csrf_id] === $_csrf_key && $_SESSION['_csrf_timeout'] >= time()) $_csrf_valid = true;
685                 }
686             }
687             if($_csrf_valid !== true) {
688                 $app->log('CSRF attempt blocked. Referer: ' . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'unknown'), LOGLEVEL_WARN);
e8f943 689                 $errmsg = 'err_csrf_attempt_blocked';
MC 690                 $this->errorMessage .= ($api == true ? $errmsg : $this->wordbook[$errmsg]."<br />") . "\r\n";
582cbf 691                 unset($_POST);
MC 692                 unset($record);
693             }
694             
695             if(isset($_SESSION['_csrf_timeout']) && is_array($_SESSION['_csrf_timeout'])) {
696                 $to_unset = array();
697                 foreach($_SESSION['_csrf_timeout'] as $_csrf_id => $timeout) {
698                     if($timeout < time()) $to_unset[] = $_csrf_id;
699                 }
700                 foreach($to_unset as $_csrf_id) {
f3cc2c 701                     $_SESSION['_csrf'][$_csrf_id] = null;
MC 702                     $_SESSION['_csrf_timeout'][$_csrf_id] = null;
582cbf 703                     unset($_SESSION['_csrf'][$_csrf_id]);
MC 704                     unset($_SESSION['_csrf_timeout'][$_csrf_id]);
705                 }
706                 unset($to_unset);
707             }
708         }
709         /* CSRF PROTECTION */
710         
711         $new_record = array();
7fe908 712         if(is_array($record)) {
MC 713             foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
714
715                 //* Apply filter to record value
716                 if(isset($field['filters']) && is_array($field['filters'])) {
717                     $record[$key] = $this->filterField($key, (isset($record[$key]))?$record[$key]:'', $field['filters'], 'SAVE');
718                 }
719                 //* Validate record value
720                 if(isset($field['validators']) && is_array($field['validators'])) {
721                     $this->validateField($key, (isset($record[$key]))?$record[$key]:'', $field['validators']);
722                 }
723
724                 switch ($field['datatype']) {
725                 case 'VARCHAR':
726                     if(!@is_array($record[$key])) {
727                         $new_record[$key] = (isset($record[$key]))?$record[$key]:'';
728                     } else {
729                         $new_record[$key] = implode($field['separator'], $record[$key]);
730                     }
731                     break;
732                 case 'TEXT':
733                     if(!is_array($record[$key])) {
734                         $new_record[$key] = $record[$key];
735                     } else {
736                         $new_record[$key] = implode($field['separator'], $record[$key]);
737                     }
738                     break;
739                 case 'DATETSTAMP':
740                     if($record[$key] > 0) {
741                         list($tag, $monat, $jahr) = explode('.', $record[$key]);
742                         $new_record[$key] = mktime(0, 0, 0, $monat, $tag, $jahr);
743                     } else {
744                         $new_record[$key] = 0;
745                     }
746                     break;
747                 case 'DATE':
748                     if($record[$key] != '' && $record[$key] != '0000-00-00') {
749                         if(function_exists('date_parse_from_format')) {
750                             $date_parts = date_parse_from_format($this->dateformat, $record[$key]);
751                             //list($tag,$monat,$jahr) = explode('.',$record[$key]);
752                             $new_record[$key] = $date_parts['year'].'-'.$date_parts['month'].'-'.$date_parts['day'];
753                             //$tmp = strptime($record[$key],$this->dateformat);
754                             //$new_record[$key] = ($tmp['tm_year']+1900).'-'.($tmp['tm_mon']+1).'-'.$tmp['tm_mday'];
755                         } else {
756                             //$tmp = strptime($record[$key],$this->dateformat);
757                             //$new_record[$key] = ($tmp['tm_year']+1900).'-'.($tmp['tm_mon']+1).'-'.$tmp['tm_mday'];
758                             $tmp = strtotime($record[$key]);
759                             $new_record[$key] = date('Y-m-d', $tmp);
760                         }
761                     } else {
762                         $new_record[$key] = '0000-00-00';
763                     }
764                     break;
765                 case 'INTEGER':
766                     $new_record[$key] = (isset($record[$key]))?$app->functions->intval($record[$key]):0;
767                     //if($new_record[$key] != $record[$key]) $new_record[$key] = $field['default'];
768                     //if($key == 'refresh') die($record[$key]);
769                     break;
770                 case 'DOUBLE':
771                     $new_record[$key] = $record[$key];
772                     break;
773                 case 'CURRENCY':
774                     $new_record[$key] = str_replace(",", ".", $record[$key]);
775                     break;
776
777                 case 'DATETIME':
778                     if (is_array($record[$key]))
779                     {
780                         $filtered_values = array_map(create_function('$item', 'return (int)$item;'), $record[$key]);
781                         extract($filtered_values, EXTR_PREFIX_ALL, '_dt');
782
783                         if ($_dt_day != 0 && $_dt_month != 0 && $_dt_year != 0) {
784                             $new_record[$key] = date( 'Y-m-d H:i:s', mktime($_dt_hour, $_dt_minute, $_dt_second, $_dt_month, $_dt_day, $_dt_year) );
785                         }
786                     }
787                     break;
788                 }
789
790                 // The use of the field value is deprecated, use validators instead
791                 if(isset($field['regex']) && $field['regex'] != '') {
792                     // Enable that "." matches also newlines
793                     $field['regex'] .= 's';
794                     if(!preg_match($field['regex'], $record[$key])) {
795                         $errmsg = $field['errmsg'];
796                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
797                     }
798                 }
799
800                 //* Add slashes to all records, when we encode data which shall be inserted into mysql.
801                 if($dbencode == true) $new_record[$key] = $app->db->quote($new_record[$key]);
802             }
803         }
804         return $new_record;
805     }
806
807
808
809
810
811     /**
812      * process the filters for a given field.
813      *
814      * @param field_name = Name of the field
815      * @param field_value = value of the field
816      * @param filters = Array of filters
817      * @param filter_event = 'SAVE'or 'SHOW'
818      * @return record
819      */
820     function filterField($field_name, $field_value, $filters, $filter_event) {
821
822         global $app;
823         $returnval = $field_value;
824
825         //* Loop trough all filters
826         foreach($filters as $filter) {
827             if($filter['event'] == $filter_event) {
828                 switch ($filter['type']) {
829                 case 'TOLOWER':
830                     $returnval = strtolower($returnval);
831                     break;
832                 case 'TOUPPER':
833                     $returnval = strtoupper($returnval);
834                     break;
835                 case 'IDNTOASCII':
836                     $returnval = $app->functions->idn_encode($returnval);
837                     break;
838                 case 'IDNTOUTF8':
839                     $returnval = $app->functions->idn_decode($returnval);
840                     break;
841                 default:
842                     $this->errorMessage .= "Unknown Filter: ".$filter['type'];
843                     break;
844                 }
845             }
846         }
847         return $returnval;
848     }
849
850
851     /**
852      * process the validators for a given field.
853      *
854      * @param field_name = Name of the field
855      * @param field_value = value of the field
856      * @param validatoors = Array of validators
857      * @return record
858      */
859     function validateField($field_name, $field_value, $validators) {
860
861         global $app;
862
863         $escape = '`';
864
865         // loop trough the validators
866         foreach($validators as $validator) {
867
868             switch ($validator['type']) {
869             case 'REGEX':
870                 $validator['regex'] .= 's';
871                 if(!preg_match($validator['regex'], $field_value)) {
872                     $errmsg = $validator['errmsg'];
873                     if(isset($this->wordbook[$errmsg])) {
874                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
875                     } else {
876                         $this->errorMessage .= $errmsg."<br />\r\n";
877                     }
878                 }
879                 break;
880             case 'UNIQUE':
881                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
882                 if($validator['allowempty'] == 'n' || ($validator['allowempty'] == 'y' && $field_value != '')){
883                     if($this->action == 'NEW') {
884                         $num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ".$escape.$this->formDef['db_table'].$escape. " WHERE $field_name = '".$app->db->quote($field_value)."'");
885                         if($num_rec["number"] > 0) {
886                             $errmsg = $validator['errmsg'];
887                             if(isset($this->wordbook[$errmsg])) {
888                                 $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
889                             } else {
890                                 $this->errorMessage .= $errmsg."<br />\r\n";
891                             }
892                         }
893                     } else {
894                         $num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ".$escape.$this->formDef['db_table'].$escape. " WHERE $field_name = '".$app->db->quote($field_value)."' AND ".$this->formDef['db_table_idx']." != ".$this->primary_id);
895                         if($num_rec["number"] > 0) {
896                             $errmsg = $validator['errmsg'];
897                             if(isset($this->wordbook[$errmsg])) {
898                                 $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
899                             } else {
900                                 $this->errorMessage .= $errmsg."<br />\r\n";
901                             }
902                         }
903                     }
904                 }
905                 break;
906             case 'NOTEMPTY':
907                 if(empty($field_value)) {
908                     $errmsg = $validator['errmsg'];
909                     if(isset($this->wordbook[$errmsg])) {
910                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
911                     } else {
912                         $this->errorMessage .= $errmsg."<br />\r\n";
913                     }
914                 }
915                 break;
0bfbaa 916             case 'ISASCII':
MC 917                 if(preg_match("/[^\x20-\x7F]/", $field_value)) {
918                     $errmsg = $validator['errmsg'];
919                     if(isset($this->wordbook[$errmsg])) {
920                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
921                     } else {
922                         $this->errorMessage .= $errmsg."<br />\r\n";
923                     }
924                 }
7fe908 925             case 'ISEMAIL':
MC 926                 if(function_exists('filter_var')) {
927                     if(filter_var($field_value, FILTER_VALIDATE_EMAIL) === false) {
928                         $errmsg = $validator['errmsg'];
929                         if(isset($this->wordbook[$errmsg])) {
930                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
931                         } else {
932                             $this->errorMessage .= $errmsg."<br />\r\n";
933                         }
934                     }
935                 } else {
936                     if(!preg_match("/^\w+[\w\.\-\+]*\w{0,}@\w+[\w.-]*\w+\.[a-zA-Z0-9\-]{2,30}$/i", $field_value)) {
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                         }
943                     }
944                 }
945                 break;
946             case 'ISINT':
947                 if(function_exists('filter_var') && $field_value < 2147483647) {
948                     if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT) === false) {
949                         $errmsg = $validator['errmsg'];
950                         if(isset($this->wordbook[$errmsg])) {
951                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
952                         } else {
953                             $this->errorMessage .= $errmsg."<br />\r\n";
954                         }
955                     }
956                 } else {
957                     $tmpval = $app->functions->intval($field_value);
958                     if($tmpval === 0 and !empty($field_value)) {
959                         $errmsg = $validator['errmsg'];
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                 }
967                 break;
968             case 'ISPOSITIVE':
969                 if(!is_numeric($field_value) || $field_value <= 0){
970                     $errmsg = $validator['errmsg'];
971                     if(isset($this->wordbook[$errmsg])) {
972                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
973                     } else {
974                         $this->errorMessage .= $errmsg."<br />\r\n";
975                     }
976                 }
977                 break;
992797 978                 /*
146783 979                 case 'ISV6PREFIX':
MC 980                     $v6_prefix_ok = 0;
981                     $explode_field_value = explode(':',$field_value);
982                     if ($explode_field_value[count($explode_field_value)-1]=='' && $explode_field_value[count($explode_field_value)-2]=='' ){
983                             if ( count($explode_field_value) <= 9 ) {
984                                     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) ) {
985                                             $v6_prefix_ok = 1;
986                                     }
987                             }
7fe908 988                     } else {
MC 989                         $v6_prefix_ok = 2;
146783 990                     }
MC 991                     // check subnet against defined server-ipv6
992                     $sql_v6 = $app->db->queryOneRecord("SELECT ip_address FROM server_ip WHERE ip_type = 'IPv6' AND virtualhost = 'y' LIMIT 0,1");
993                     $sql_v6_explode=explode(':',$sql_v6['ip_address']);
7fe908 994                     if ( count($sql_v6_explode) < count($explode_field_value) && isset($sql_v6['ip_address']) )  {
MC 995                         $v6_prefix_ok = 3;
146783 996                     }
7fe908 997                     if($v6_prefix_ok == 0) {
MC 998                         $errmsg = $validator['errmsg'];
146783 999                     }
7fe908 1000                     if($v6_prefix_ok == 2) {
MC 1001                         $errmsg = 'IPv6 Prefix must end with ::';
146783 1002                     }
7fe908 1003                     if($v6_prefix_ok == 3) {
MC 1004                         $errmsg = 'IPv6 Prefix too long (according to Server IP Addresses)';
146783 1005                     }
MC 1006                     if($v6_prefix_ok <> 1){
7fe908 1007                         $this->errorMessage .= $errmsg."<br />\r\n";
146783 1008                     }
30fc1b 1009                 break;
146783 1010                 */
7fe908 1011             case 'ISIPV4':
MC 1012                 $vip=1;
1013                 if(preg_match("/^[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}$/", $field_value)){
1014                     $groups=explode(".", $field_value);
1015                     foreach($groups as $group){
1016                         if($group<0 or $group>255)
1017                             $vip=0;
2dadd2 1018                     }
7fe908 1019                 }else{$vip=0;}
MC 1020                 if($vip==0) {
1021                     $errmsg = $validator['errmsg'];
1022                     if(isset($this->wordbook[$errmsg])) {
1023                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1024                     } else {
1025                         $this->errorMessage .= $errmsg."<br />\r\n";
1026                     }
1027                 }
1028                 break;
1029             case 'ISIP':
1030                 if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
1031                 if($validator['allowempty'] == 'y' && $field_value == '') {
1032                     //* Do nothing
1033                 } else {
1034                     //* Check if its a IPv4 or IPv6 address
1035                     if(isset($validator['separator']) && $validator['separator'] != '') {
1036                         //* When the field may contain several IP addresses, split them by the char defined as separator
1037                         $field_value_array = explode($validator['separator'], $field_value);
1038                     } else {
1039                         $field_value_array[] = $field_value;
1040                     }
1041                     foreach($field_value_array as $field_value) {
1042                         $field_value = trim($field_value);
1043                         if(function_exists('filter_var')) {
1044                             if(!filter_var($field_value, FILTER_VALIDATE_IP)) {
1045                                 $errmsg = $validator['errmsg'];
1046                                 if(isset($this->wordbook[$errmsg])) {
1047                                     $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1048                                 } else {
1049                                     $this->errorMessage .= $errmsg."<br />\r\n";
1050                                 }
1051                             }
1052                         } else {
1053                             //* Check content with regex, if we use php < 5.2
1054                             $ip_ok = 0;
1055                             if(preg_match("/^(\:\:([a-f0-9]{1,4}\:){0,6}?[a-f0-9]{0,4}|[a-f0-9]{1,4}(\:[a-f0-9]{1,4}){0,6}?\:\:|[a-f0-9]{1,4}(\:[a-f0-9]{1,4}){1,6}?\:\:([a-f0-9]{1,4}\:){1,6}?[a-f0-9]{1,4})(\/\d{1,3})?$/i", $field_value)){
1056                                 $ip_ok = 1;
1057                             }
1058                             if(preg_match("/^[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}$/", $field_value)){
1059                                 $ip_ok = 1;
1060                             }
1061                             if($ip_ok == 0) {
1062                                 $errmsg = $validator['errmsg'];
1063                                 if(isset($this->wordbook[$errmsg])) {
1064                                     $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1065                                 } else {
1066                                     $this->errorMessage .= $errmsg."<br />\r\n";
1067                                 }
1068                             }
1069                         }
1070                     }
1071                 }
1072                 break;
1073             case 'RANGE':
1074                 //* Checks if the value is within the given range or above / below a value
1075                 //* Range examples: < 10 = ":10", between 2 and 10 = "2:10", above 5 = "5:".
1076                 $range_parts = explode(':', trim($validator['range']));
1077                 $ok = true;
1078                 if($range_parts[0] != '' && $field_value < $range_parts[0]) {
1079                     $ok = false;
1080                 }
1081                 if($range_parts[1] != '' && $field_value > $range_parts[1]) {
1082                     $ok = false;
1083                 }
1084                 if($ok != true) {
1085                     $errmsg = $validator['errmsg'];
1086                     if(isset($this->wordbook[$errmsg])) {
1087                         $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
1088                     } else {
1089                         $this->errorMessage .= $errmsg."<br />\r\n";
1090                     }
1091                 }
1092                 unset($range_parts);
1093                 break;
1094             case 'CUSTOM':
1095                 // Calls a custom class to validate this record
1096                 if($validator['class'] != '' and $validator['function'] != '') {
1097                     $validator_class = $validator['class'];
1098                     $validator_function = $validator['function'];
1099                     $app->uses($validator_class);
1100                     $this->errorMessage .= $app->$validator_class->$validator_function($field_name, $field_value, $validator);
1101                 } else {
1102                     $this->errorMessage .= "Custom validator class or function is empty<br />\r\n";
1103                 }
1104                 break;
1105             default:
1106                 $this->errorMessage .= "Unknown Validator: ".$validator['type'];
1107                 break;
1108             }
2dadd2 1109
T 1110
7fe908 1111         }
2dadd2 1112
7fe908 1113         return true;
MC 1114     }
2dadd2 1115
T 1116
7fe908 1117     /**
MC 1118      * Create SQL statement
1119      *
1120      * @param record = Datensatz als Array
1121      * @param action = INSERT oder UPDATE
1122      * @param primary_id
1123      * @return record
1124      */
1125     function getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '') {
2dadd2 1126
7fe908 1127         global $app;
35509d 1128         
TB 1129         $primary_id = $app->functions->intval($primary_id);
7fe908 1130
MC 1131         // If there are no data records on the tab, return empty sql string
1132         if(count($this->formDef['tabs'][$tab]['fields']) == 0) return '';
1133
1134         // checking permissions
1135         if($this->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
1136             if($action == "INSERT") {
1137                 if(!$this->checkPerm($primary_id, 'i')) $this->errorMessage .= "Insert denied.<br />\r\n";
1138             } else {
1139                 if(!$this->checkPerm($primary_id, 'u')) $this->errorMessage .= "Update denied.<br />\r\n";
1140             }
1141         }
1142
1143         $this->action = $action;
1144         $this->primary_id = $primary_id;
1145
1146         $record = $this->encode($record, $tab, true);
1147         $sql_insert_key = '';
1148         $sql_insert_val = '';
1149         $sql_update = '';
1150
1151         if(!is_array($this->formDef)) $app->error("Form definition not found.");
1152         if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
1153
1154         // go trough all fields of the tab
1155         if(is_array($record)) {
1156             foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
1157                 // Wenn es kein leeres Passwortfeld ist
1158                 if (!($field['formtype'] == 'PASSWORD' and $record[$key] == '')) {
1159                     // Erzeuge Insert oder Update Quelltext
1160                     if($action == "INSERT") {
1161                         if($field['formtype'] == 'PASSWORD') {
1162                             $sql_insert_key .= "`$key`, ";
1163                             if($field['encryption'] == 'CRYPT') {
1164                                 $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
1165                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1166                             } elseif ($field['encryption'] == 'MYSQL') {
1167                                 $tmp = $app->db->queryOneRecord("SELECT PASSWORD('".$app->db->quote(stripslashes($record[$key]))."') as `crypted`");
1168                                 $record[$key] = $tmp['crypted'];
1169                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1170                             } elseif ($field['encryption'] == 'CLEARTEXT') {
1171                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1172                             } else {
1173                                 $record[$key] = md5(stripslashes($record[$key]));
1174                                 $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
1175                             }
1176
1177                         } elseif ($field['formtype'] == 'CHECKBOX') {
1178                             $sql_insert_key .= "`$key`, ";
1179                             if($record[$key] == '') {
1180                                 // if a checkbox is not set, we set it to the unchecked value
1181                                 $sql_insert_val .= "'".$field['value'][0]."', ";
1182                                 $record[$key] = $field['value'][0];
1183                             } else {
1184                                 $sql_insert_val .= "'".$record[$key]."', ";
1185                             }
1186                         } else {
1187                             $sql_insert_key .= "`$key`, ";
1188                             $sql_insert_val .= "'".$record[$key]."', ";
1189                         }
1190                     } else {
1191                         if($field['formtype'] == 'PASSWORD') {
1192                             if(isset($field['encryption']) && $field['encryption'] == 'CRYPT') {
1193                                 $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
1194                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1195                             } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
1196                                 $tmp = $app->db->queryOneRecord("SELECT PASSWORD('".$app->db->quote(stripslashes($record[$key]))."') as `crypted`");
1197                                 $record[$key] = $tmp['crypted'];
1198                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1199                             } elseif (isset($field['encryption']) && $field['encryption'] == 'CLEARTEXT') {
1200                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1201                             } else {
1202                                 $record[$key] = md5(stripslashes($record[$key]));
1203                                 $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
1204                             }
1205
1206                         } elseif ($field['formtype'] == 'CHECKBOX') {
1207                             if($record[$key] == '') {
1208                                 // if a checkbox is not set, we set it to the unchecked value
1209                                 $sql_update .= "`$key` = '".$field['value'][0]."', ";
1210                                 $record[$key] = $field['value'][0];
1211                             } else {
1212                                 $sql_update .= "`$key` = '".$record[$key]."', ";
1213                             }
1214                         } else {
1215                             $sql_update .= "`$key` = '".$record[$key]."', ";
1216                         }
1217                     }
1218                 } else {
1219                     // we unset the password filed, if empty to tell the datalog function
1220                     // that the password has not been changed
1221                     unset($record[$key]);
1222                 }
1223             }
1224         }
1225
1226
1227         // Add backticks for incomplete table names
1228         if(stristr($this->formDef['db_table'], '.')) {
1229             $escape = '';
1230         } else {
1231             $escape = '`';
1232         }
1233
1234
1235         if($action == "INSERT") {
1236             if($this->formDef['auth'] == 'yes') {
1237                 // Set user and group
1238                 $sql_insert_key .= "`sys_userid`, ";
1239                 $sql_insert_val .= ($this->formDef["auth_preset"]["userid"] > 0)?"'".$this->formDef["auth_preset"]["userid"]."', ":"'".$_SESSION["s"]["user"]["userid"]."', ";
1240                 $sql_insert_key .= "`sys_groupid`, ";
1241                 $sql_insert_val .= ($this->formDef["auth_preset"]["groupid"] > 0)?"'".$this->formDef["auth_preset"]["groupid"]."', ":"'".$_SESSION["s"]["user"]["default_group"]."', ";
1242                 $sql_insert_key .= "`sys_perm_user`, ";
1243                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_user"]."', ";
1244                 $sql_insert_key .= "`sys_perm_group`, ";
1245                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_group"]."', ";
1246                 $sql_insert_key .= "`sys_perm_other`, ";
1247                 $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_other"]."', ";
1248             }
1249             $sql_insert_key = substr($sql_insert_key, 0, -2);
1250             $sql_insert_val = substr($sql_insert_val, 0, -2);
1251             $sql = "INSERT INTO ".$escape.$this->formDef['db_table'].$escape." ($sql_insert_key) VALUES ($sql_insert_val)";
1252         } else {
1253             if($this->formDef['auth'] == 'yes') {
1254                 if($primary_id != 0) {
1255                     $sql_update = substr($sql_update, 0, -2);
1256                     $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->getAuthSQL('u')." AND ".$this->formDef['db_table_idx']." = ".$primary_id;
1257                     if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
1258                 } else {
1259                     $app->error("Primary ID fehlt!");
1260                 }
1261             } else {
1262                 if($primary_id != 0) {
1263                     $sql_update = substr($sql_update, 0, -2);
1264                     $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
1265                     if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
1266                 } else {
1267                     $app->error("Primary ID fehlt!");
1268                 }
1269             }
1270             //* return a empty string if there is nothing to update
1271             if(trim($sql_update) == '') $sql = '';
1272         }
1273
1274         return $sql;
1275     }
1276
1277
1278     /**
1279      * Debugging arrays.
1280      *
1281      * @param array_data
1282      */
1283     function dbg($array_data) {
1284
1285         echo "<pre>";
1286         print_r($array_data);
1287         echo "</pre>";
1288
1289     }
1290
1291
1292     function showForm() {
1293         global $app, $conf;
1294
1295         if(!is_array($this->formDef)) die("Form Definition wurde nicht geladen.");
1296
1297         $active_tab = $this->getNextTab();
1298
1299         // go trough the tabs
1300         foreach( $this->formDef["tabs"] as $key => $tab) {
1301
1302             $tab['name'] = $key;
40dd9f 1303             // Translate the title of the tab
T 1304             $tab['title'] = $this->lng($tab['title']);
2dadd2 1305
7fe908 1306             if($tab['name'] == $active_tab) {
2dadd2 1307
7fe908 1308                 // If module is set, then set the template path relative to the module..
MC 1309                 if($this->module != '') $tab["template"] = "../".$this->module."/".$tab["template"];
2dadd2 1310
7fe908 1311                 // Generate the template if it does not exist yet.
2dadd2 1312
T 1313
1314
7fe908 1315                 if(!is_file($tab["template"])) {
MC 1316                     $app->uses('tform_tpl_generator');
1317                     $app->tform_tpl_generator->buildHTML($this->formDef, $tab['name']);
2dadd2 1318                 }
7fe908 1319                 $app->tpl->setVar('readonly_tab', (isset($tab['readonly']) && $tab['readonly'] == true));
MC 1320                 $app->tpl->setInclude('content_tpl', $tab["template"]);
1321                 $tab["active"] = 1;
1322                 $_SESSION["s"]["form"]["tab"] = $tab['name'];
1323             } else {
1324                 $tab["active"] = 0;
1325             }
2dadd2 1326
7fe908 1327             // Unset unused variables.
MC 1328             unset($tab["fields"]);
1329             unset($tab["plugins"]);
1330
1331             $frmTab[] = $tab;
1332         }
1333
1334         // setting form tabs
1335         $app->tpl->setLoop("formTab", $frmTab);
1336
1337         // Set form action
1338         $app->tpl->setVar('form_action', $this->formDef["action"]);
1339         $app->tpl->setVar('form_active_tab', $active_tab);
1340
1341         // Set form title
1342         $form_hint = $this->lng($this->formDef["title"]);
1343         if($this->formDef["description"] != '') $form_hint .= '<div class="pageForm_description">'.$this->lng($this->formDef["description"]).'</div>';
1344         $app->tpl->setVar('form_hint', $form_hint);
1345
1346         // Set Wordbook for this form
1347
1348         $app->tpl->setVar($this->wordbook);
1349     }
1350
1351     function getDataRecord($primary_id) {
1352         global $app;
1353         $escape = '`';
35509d 1354         $primary_id = $app->functions->intval($primary_id);
7fe908 1355         $sql = "SELECT * FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id." AND ".$this->getAuthSQL('r', $this->formDef['db_table']);
MC 1356         return $app->db->queryOneRecord($sql);
1357     }
1358
1359
1360     function datalogSave($action, $primary_id, $record_old, $record_new) {
1361         global $app, $conf;
1362
1363         $app->db->datalogSave($this->formDef['db_table'], $action, $this->formDef['db_table_idx'], $primary_id, $record_old, $record_new);
1364         return true;
1365     }
1366
1367     function getAuthSQL($perm, $table = '') {
35509d 1368         global $app;
TB 1369         
1370         $perm = $app->db->quote($perm);
1371         $table = $app->db->quote($table);
1372         
f798aa 1373         if($_SESSION["s"]["user"]["typ"] == 'admin' || $_SESSION['s']['user']['mailuser_id'] > 0) {
7fe908 1374             return '1';
MC 1375         } else {
1376             if ($table != ''){
1377                 $table = ' ' . $table . '.';
1378             }
1379             $groups = ( $_SESSION["s"]["user"]["groups"] ) ? $_SESSION["s"]["user"]["groups"] : 0;
1380             $sql = '(';
1381             $sql .= "(" . $table . "sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND " . $table . "sys_perm_user like '%$perm%') OR  ";
1382             $sql .= "(" . $table . "sys_groupid IN (".$groups.") AND " . $table ."sys_perm_group like '%$perm%') OR ";
1383             $sql .= $table . "sys_perm_other like '%$perm%'";
1384             $sql .= ')';
1385
1386             return $sql;
1387         }
1388     }
1389
1390     /*
992797 1391         This function checks if a user has the parmissions $perm for the data record with the ID $record_id
MC 1392         If record_id = 0, the the permissions are tested against the defaults of the form file.
1393         */
7fe908 1394     function checkPerm($record_id, $perm) {
MC 1395         global $app;
2dadd2 1396
35509d 1397         $record_id = $app->functions->intval($record_id);
7fe908 1398         if($record_id > 0) {
2dadd2 1399             // Add backticks for incomplete table names.
7fe908 1400             if(stristr($this->formDef['db_table'], '.')) {
MC 1401                 $escape = '';
1402             } else {
1403                 $escape = '`';
1404             }
1405
1406             $sql = "SELECT ".$this->formDef['db_table_idx']." FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$record_id." AND ".$this->getAuthSQL($perm);
1407             if($record = $app->db->queryOneRecord($sql)) {
2dadd2 1408                 return true;
T 1409             } else {
1410                 return false;
1411             }
7fe908 1412         } else {
MC 1413             $result = false;
1414             if(@$this->formDef["auth_preset"]["userid"] == $_SESSION["s"]["user"]["userid"] && stristr($perm, $this->formDef["auth_preset"]["perm_user"])) $result = true;
1415             if(@$this->formDef["auth_preset"]["groupid"] == $_SESSION["s"]["user"]["groupid"] && stristr($perm, $this->formDef["auth_preset"]["perm_group"])) $result = true;
1416             if(@stristr($this->formDef["auth_preset"]["perm_other"], $perm)) $result = true;
1417
1418             // if preset == 0, everyone can insert a record of this type
1419             if($this->formDef["auth_preset"]["userid"] == 0 and $this->formDef["auth_preset"]["groupid"] == 0 and (@stristr($this->formDef["auth_preset"]["perm_user"], $perm) or @stristr($this->formDef["auth_preset"]["perm_group"], $perm))) $result = true;
1420
1421             return $result;
1422
2dadd2 1423         }
7fe908 1424
MC 1425     }
1426
1427     function getNextTab() {
1428         // Which tab is shown
1429         if($this->errorMessage == '') {
1430             // If there is no error
1431             if(isset($_REQUEST["next_tab"]) && $_REQUEST["next_tab"] != '') {
1432                 // If the next tab is known
1433                 $active_tab = $_REQUEST["next_tab"];
1434             } else {
1435                 // else use the default tab
1436                 $active_tab = $this->formDef['tab_default'];
1437             }
1438         } else {
1439             // Show the same tab again in case of an error
1440             $active_tab = $_SESSION["s"]["form"]["tab"];
1441         }
1442
1443         return $active_tab;
1444     }
1445
1446     function getCurrentTab() {
1447         return $_SESSION["s"]["form"]["tab"];
1448     }
1449
1450     function isReadonlyTab($tab, $primary_id) {
1451         global $app, $conf;
1452
1453         // Add backticks for incomplete table names.
1454         if(stristr($this->formDef['db_table'], '.')) {
1455             $escape = '';
1456         } else {
1457             $escape = '`';
1458         }
1459
1460         $sql = "SELECT sys_userid FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
1461         $record = $app->db->queryOneRecord($sql);
1462
1463         // return true if the readonly flag of the form is set and the current loggedin user is not the owner of the record.
1464         if(isset($this->formDef['tabs'][$tab]['readonly']) && $this->formDef['tabs'][$tab]['readonly'] == true && $record['sys_userid'] != $_SESSION["s"]["user"]["userid"]) {
1465             return true;
1466         } else {
1467             return false;
1468         }
1469     }
1470
1471
1472     // translation function for forms, tries the form wordbook first and if this fails, it tries the global wordbook
1473     function lng($msg) {
1474         global $app, $conf;
1475
1476         if(isset($this->wordbook[$msg])) {
1477             return $this->wordbook[$msg];
1478         } else {
1479             return $app->lng($msg);
1480         }
1481
1482     }
1483
1484     function checkClientLimit($limit_name, $sql_where = '') {
1485         global $app;
1486
1487         $check_passed = true;
1488         $limit_name = $app->db->quote($limit_name);
1489         if($limit_name == '') $app->error('Limit name missing in function checkClientLimit.');
1490
1491         // Get the limits of the client that is currently logged in
35509d 1492         $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
7fe908 1493         $client = $app->db->queryOneRecord("SELECT $limit_name as number, parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
MC 1494
1495         // Check if the user may add another item
1496         if($client["number"] >= 0) {
1497             $sql = "SELECT count(".$this->formDef['db_table_idx'].") as number FROM ".$this->formDef['db_table']." WHERE ".$this->getAuthSQL('u');
1498             if($sql_where != '') $sql .= ' and '.$sql_where;
1499             $tmp = $app->db->queryOneRecord($sql);
1500             if($tmp["number"] >= $client["number"]) $check_passed = false;
1501         }
1502
1503         return $check_passed;
1504     }
1505
1506     function checkResellerLimit($limit_name, $sql_where = '') {
1507         global $app;
1508
1509         $check_passed = true;
1510         $limit_name = $app->db->quote($limit_name);
1511         if($limit_name == '') $app->error('Limit name missing in function checkClientLimit.');
1512
1513         // Get the limits of the client that is currently logged in
35509d 1514         $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
7fe908 1515         $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");
MC 1516
1517         //* If the client belongs to a reseller, we will check against the reseller Limit too
1518         if($client['parent_client_id'] != 0) {
1519
1520             //* first we need to know the groups of this reseller
1521             $tmp = $app->db->queryOneRecord("SELECT userid, groups FROM sys_user WHERE client_id = ".$client['parent_client_id']);
1522             $reseller_groups = $tmp["groups"];
1523             $reseller_userid = $tmp["userid"];
1524
1525             // Get the limits of the reseller of the logged in client
3cebc3 1526             $client_group_id = $_SESSION["s"]["user"]["default_group"];
7fe908 1527             $reseller = $app->db->queryOneRecord("SELECT $limit_name as number FROM client WHERE client_id = ".$client['parent_client_id']);
MC 1528
3cebc3 1529             // Check if the user may add another item
7fe908 1530             if($reseller["number"] >= 0) {
MC 1531                 $sql = "SELECT count(".$this->formDef['db_table_idx'].") as number FROM ".$this->formDef['db_table']." WHERE (sys_groupid IN (".$reseller_groups.") or sys_userid = ".$reseller_userid.")";
3cebc3 1532                 if($sql_where != '') $sql .= ' and '.$sql_where;
T 1533                 $tmp = $app->db->queryOneRecord($sql);
7fe908 1534                 if($tmp["number"] >= $reseller["number"]) $check_passed = false;
3cebc3 1535             }
T 1536         }
7fe908 1537
MC 1538         return $check_passed;
1539     }
1540
1541     //* get the difference record of two arrays
1542     function getDiffRecord($record_old, $record_new) {
1543
1544         if(is_array($record_new) && count($record_new) > 0) {
11b3da 1545             foreach($record_new as $key => $val) {
T 1546                 if(@$record_old[$key] != $val) {
1547                     // Record has changed
7fe908 1548                     $diffrec[$key] = array( 'old' => @$record_old[$key],
MC 1549                         'new' => $val);
11b3da 1550                 }
7fe908 1551             }
MC 1552         } elseif(is_array($record_old)) {
1553             foreach($record_old as $key => $val) {
1554                 if($record_new[$key] != $val) {
1555                     // Record has changed
1556                     $diffrec[$key] = array( 'new' => $record_new[$key],
1557                         'old' => $val);
11b3da 1558                 }
7fe908 1559             }
11b3da 1560         }
7fe908 1561         return $diffrec;
2dadd2 1562
7fe908 1563     }
MC 1564
1565
1566
1567
1568
1569     /**
1570      * Generate HTML for DATETIME fields.
1571      *
1572      * @access private
1573      * @param string $form_element Name of the form element.
1574      * @param string $default_value Selected value for fields.
1575      * @param bool $display_secons Include seconds selection.
1576      * @return string HTML
1577      */
1578     function _getDateTimeHTML($form_element, $default_value, $display_seconds=false)
1579     {
eebe76 1580         $_datetime = ($default_value && $default_value != '0000-00-00 00:00:00' ? strtotime($default_value) : false);
7fe908 1581         $_showdate = ($_datetime === false) ? false : true;
MC 1582
1583         $dselect = array('day', 'month', 'year', 'hour', 'minute');
1584         if ($display_seconds === true) {
1585             $dselect[] = 'second';
1586         }
1587
1588         $out = '';
1589
1590         foreach ($dselect as $dt_element)
1591         {
1592             $dt_options = array();
1593             $dt_space = 1;
1594
1595             switch ($dt_element) {
1596             case 'day':
1597                 for ($i = 1; $i <= 31; $i++) {
1598                     $dt_options[] = array('name' =>  sprintf('%02d', $i),
1599                         'value' => sprintf('%d', $i));
75ae20 1600                 }
7fe908 1601                 $selected_value = date('d', $_datetime);
MC 1602                 break;
1603
1604             case 'month':
1605                 for ($i = 1; $i <= 12; $i++) {
1606                     $dt_options[] = array('name' => strftime('%b', mktime(0, 0, 0, $i, 1, 2000)),
1607                         'value' => strftime('%m', mktime(0, 0, 0, $i, 1, 2000)));
1608                 }
1609                 $selected_value = date('n', $_datetime);
1610                 break;
1611
1612             case 'year':
1613                 $start_year = strftime("%Y");
1614                 $years = range((int)$start_year, (int)($start_year+3));
1615
1616                 foreach ($years as $year) {
1617                     $dt_options[] = array('name' => $year,
1618                         'value' => $year);
1619                 }
1620                 $selected_value = date('Y', $_datetime);
1621                 $dt_space = 2;
1622                 break;
1623
1624             case 'hour':
1625                 foreach(range(0, 23) as $hour) {
1626                     $dt_options[] = array('name' =>  sprintf('%02d', $hour),
1627                         'value' => sprintf('%d', $hour));
1628                 }
1629                 $selected_value = date('G', $_datetime);
1630                 break;
1631
1632             case 'minute':
1633                 foreach(range(0, 59) as $minute) {
1634                     if (($minute % 5) == 0) {
1635                         $dt_options[] = array('name' =>  sprintf('%02d', $minute),
1636                             'value' => sprintf('%d', $minute));
75ae20 1637                     }
W 1638                 }
7fe908 1639                 $selected_value = (int)floor(date('i', $_datetime));
MC 1640                 break;
1641
1642             case 'second':
1643                 foreach(range(0, 59) as $second) {
1644                     $dt_options[] = array('name' =>  sprintf('%02d', $second),
1645                         'value' => sprintf('%d', $second));
1646                 }
1647                 $selected_value = (int)floor(date('s', $_datetime));
1648                 break;
75ae20 1649             }
7fe908 1650
MC 1651             $out .= "<select name=\"".$form_element."[$dt_element]\" id=\"".$form_element."_$dt_element\" class=\"selectInput\" style=\"width: auto; float: none;\">";
1652             if (!$_showdate) {
1653                 $out .= "<option value=\"-\" selected=\"selected\">--</option>" . PHP_EOL;
1654             } else {
1655                 $out .= "<option value=\"-\">--</option>" . PHP_EOL;
1656             }
1657
1658             foreach ($dt_options as $dt_opt) {
1659                 if ( $_showdate && ($selected_value == $dt_opt['value']) ) {
1660                     $out .= "<option value=\"{$dt_opt['value']}\" selected=\"selected\">{$dt_opt['name']}</option>" . PHP_EOL;
1661                 } else {
1662                     $out .= "<option value=\"{$dt_opt['value']}\">{$dt_opt['name']}</option>" . PHP_EOL;
1663                 }
1664             }
1665
1666             $out .= '</select>' . str_repeat('&nbsp;', $dt_space);
75ae20 1667         }
7fe908 1668
MC 1669         return $out;
1670     }
1671
2dadd2 1672 }
T 1673
d7ef36 1674 ?>