dbXapp 2.0
RAD, CMS, Module und Runtime-IDE fuer dbXapp
Loading...
Searching...
No Matches
dbxForm.class.php
Go to the documentation of this file.
1<?php
2
179class dbxForm extends \dbxObj {
180
183
185 public $oTPL;
186
188 public $oDB;
189
191 public $_dbx_view = '';
192
194 public $_view_sync = '';
195
197 public $_view_mode = '';
198
200 public $_mode = 'mix';
201
203 public $_ajax = true;
204
206 public $_store_mode = 'session';
207
209 public $_dbx_modul_id = 0;
210
212 public $_dbx_modul = 'modul';
213
215 public $_dbx_lng = '';
216
218 public $_dbx_design = '';
219
221 public $_dbx_action = '';
222
224 public $_dbx_work = '';
225
227 public $_dbx_page = '';
228
230 public $_rid = 0;
231
233 public $_action = '';
234
236 public $_tpl = '';
237
239 public $_fid = '';
240
242 public $_next_i = 0;
243
245 public $_dd = '';
246
248 public $_fd = '';
249
251 public $_editor_files = array();
252
255
257 public $_data = array();
258
260 public $_post = array();
261
263 public $_sys = array();
264
266 public $_obj = array();
267
269 public $_js = array();
270
272 public $_css = array();
273
275 public $_flds = array();
276
278 public $_infos = array();
279
281 public $_errors = array();
282
284 public $_warnings = array();
285
287 public $_replaces = array();
288
290 public $_general_error = '';
291
293 public $_msg_info = '#form_msg_info#';
294
296 public $_msg_success = '#form_msg_success#';
297
299 public $_msg_error = '#form_msg_error#';
300
302 public $_msg_warning = '#form_msg_warning#';
303
305 public $_tpl_form_info = 'form-alert-info';
306
308 public $_tpl_form_success = 'form-alert-success';
309
311 public $_tpl_form_error = 'form-alert-danger';
312
314 public $_tpl_form_warning = 'form-alert-warning';
315
317 public $_tpl_fld_info = 'fld-alert-info';
318
320 public $_tpl_fld_success = 'fld-alert-success';
321
323 public $_tpl_fld_error = 'fld-alert-danger';
324
326 public $_tpl_fld_warning = 'fld-alert-warning';
327
329 public $_tpl_max_try = 'form-alert-maxtry';
330
332 public $_try_reset = 120;
333
335 public $_try_max = 20;
336
338 public $_try_msg = 'Max {try_count} try. Suspend for {sec} seconds';
339
341 public $_create_flds = 1;
342
344 public $_reload_record = 1;
345
347 public $_reload_run = 0;
348
351
353 protected $_module_bar_form_actions = array();
354
356 public $_reload_suffix = '_rlo';
357
359 public $_fld_change_state = 'fld';
360
362 public $_fld_changes = -1;
363
365 public $_form_submit = -1;
366
368 public $_form_validate = -1;
369
371 public $_editor_fld = '';
372
374 public $_page_reset = 1;
375
377 public $_confirm_delete = '';
378
380 public $_confirm_copy = '';
381
383 public $_activ_id = 0;
384
386 public $_fld_id = 'id';
387
389 public $_workflow_scope = '';
390
392 public $_workflow_state = array();
393
412 public function __construct($id = '', $tpl = '') {
413 $this->oValidator = dbx()->get_system_obj('dbxValidator');
414 $this->oTPL = dbx()->get_system_obj('dbxTPL');
415 $this->oDB = dbx()->get_system_obj('dbxDB');
416
417 if (!$tpl) {
418 $tpl = $id;
419 }
420
421 if ($id) {
422 $this->init($id, $tpl);
423 }
424 }
425
439 public function __destruct() {
440 }
441
457 public function clear_sys() {
458 $this->_sys = array();
459 }
460
482 public function clear() {
483 $this->_forward_clear();
484 }
485
486
487
519 public function _forward_clear() {
520 $this->_reload_record = 0;
521 $this->_reload_run = 0;
522
523 $this->_obj = array();
524 $this->_js = array();
525 $this->_css = array();
526 $this->_flds = array();
527 $this->_infos = array();
528 $this->_errors = array();
529 $this->_warnings = array();
530 $this->_post = array();
531 $this->_sys = array();
532 $this->_data = array();
533 $this->_replaces = array();
534 $this->_module_bar_form_actions = array();
535
536 $this->_fld_changes = -1;
537 $this->_form_submit = -1;
538 $this->_form_validate = -1;
539 $this->_general_error = '';
540
541 $this->_rid = 0;
542 $this->_action = '';
543 $this->_next_i = 0;
544 $this->_fld_id = 'id';
545 $this->_callback_owner = null;
546 $this->_callback_id = '';
547 $this->_callbacks = array();
548
549 $this->_dd = '';
550 $this->_fd = '';
551 $this->_editor_files = array();
552 }
553
560 public function set_editor_class_file(string $file) {
561 $this->_editor_class_file = $file;
562 $this->add_editor_file('class', $file);
563 }
564
572 protected function add_editor_file(string $kind, string $file) {
573 $file = trim($file);
574 $kind = strtolower(trim($kind));
575
576 if ($file === '' || $kind === '') {
577 return;
578 }
579
580 $path = dbx()->editor_file_path($file);
581 $key = $kind . '|' . $path;
582 $this->_editor_files[$key] = array('kind' => $kind, 'file' => $path);
583 dbx()->register_editor_file($kind, $path);
584 }
585
592 protected function add_editor_markers(string $content): string {
593 $edit = (int) dbx()->get_system_var('dbx_edit', 0, 'int');
594
595 if (($edit >= 4 && $edit <= 8) || $edit === 9) {
596 return $content;
597 }
598
599 if ($this->_editor_class_file !== '') {
600 $this->add_editor_file('class', $this->_editor_class_file);
601 }
602
603 foreach (dbx()->get_editor_files() as $file) {
604 if (isset($file['kind'], $file['file'])) {
605 $this->add_editor_file($file['kind'], $file['file']);
606 }
607 }
608
609 if ($content === '' || !$this->_editor_files) {
610 return $content;
611 }
612
613 $markers = '';
614
615 foreach ($this->_editor_files as $file) {
616 $kind = strtolower((string) ($file['kind'] ?? ''));
617
618 // FD/DD-Marker werden pro Feld in create_fld() gesetzt.
619 if ($kind === 'fd' || $kind === 'dd') {
620 continue;
621 }
622
623 $marker = dbx()->editor_marker($file['kind'], $file['file']);
624 $needle = trim($marker);
625
626 if ($marker !== '' && strpos($content, $needle) === false && strpos($markers, $needle) === false) {
627 $markers .= $marker;
628 }
629 }
630
631 if ($markers === '') {
632 return $content;
633 }
634
635 return $markers . $content . "\n<!-- DBX-EDITOR-END -->\n";
636 }
637
638 public function set_form_callback_owner($owner): void {
639 $this->set_callback_owner($owner);
640 }
641
642 public function set_init_callback(string $callback): void {
643 $this->set_callback('init', $callback);
644 }
645
646 public function set_submit_callback(string $callback): void {
647 $this->set_callback('submit', $callback);
648 }
649
650 public function set_run_callback(string $callback): void {
651 $this->set_callback('run', $callback);
652 }
653
654
655
684 public function forward_init($fid, $tpl = '') {
685 $this->clear();
686
687 if ($tpl == '') {
688 $tpl = $fid;
689 }
690
691 $i = $this->next_i();
692
693 $this->_fid = $fid;
694 $this->set_callback_id($fid);
695 $this->_dbx_modul = dbx()->get_system_var('dbx_activ_modul', 'modul');
696 $this->_dbx_action = dbx()->get_system_var('dbx_activ_action', 'run');
697 $this->_dbx_page = dbx()->get_system_var('dbx_page', 'default');
698 $this->_dbx_design = dbx()->get_system_var('dbx_design', 'default');
699 $this->_dbx_lng = dbx()->get_system_var('dbx_lng', 'de');
700 $this->_dbx_modul_id = dbx()->get_system_var('dbx_activ_modul_id', 1);
701 $this->_tpl = $tpl;
702 $this->_data = array();
703 $this->_next_i = $i;
704 $this->_form_validate = -1;
705 $this->_form_submit = -1;
706
707
708 $init = array(
709 'fid' => $this->_fid,
710 'tpl' => $this->_tpl,
711 'i' => $this->_next_i,
712 );
713
714 $init = $this->callback('init', $init);
715
716 if (is_array($init)) {
717 if (isset($init['fid'])) $this->_fid = $init['fid'];
718 if (isset($init['tpl'])) $this->_tpl = $init['tpl'];
719 if (isset($init['i'])) $this->_next_i = $init['i'];
720 }
721
722 $this->_sys = $this->load_sysdata();
723
724 $this->load_workflow_state();
725
726 $secure_fld = $this->secure_fld_name();
727 $this->add_fld($secure_fld, 'dbx|hidden', $secure_fld, rules: 'parameter', dd: '');
728 $this->sync_secure_field($secure_fld, $this->secure_token($secure_fld));
729 $this->attachAdminHelpButton();
730 $this->add_default_search_rep();
731 }
732
733 public function add_module_bar($title, $icon = 'bi-grid', $subtitle = '') {
734 if (!isset($this->_replaces['bar_title']) || (string)$this->_replaces['bar_title'] === '') {
735 $this->add_rep('bar_title', (string)$title);
736 }
737 if (!isset($this->_replaces['bar_icon']) || (string)$this->_replaces['bar_icon'] === '') {
738 $this->add_rep('bar_icon', (string)$icon);
739 }
740 if (!isset($this->_replaces['bar_subtitle']) || (string)$this->_replaces['bar_subtitle'] === '') {
741 $this->add_rep('bar_subtitle', (string)$subtitle);
742 }
743 }
744
745 public function add_module_bar_form_actions(array $options = array()) {
746 $defaults = array(
747 'save' => true,
748 'delete' => false,
749 'reload' => true,
750 'reload_url' => '',
751 'delete_url' => '',
752 'delete_title' => 'Datensatz loeschen',
753 'delete_hint' => 'Dieser Vorgang kann nicht rueckgaengig gemacht werden.',
754 );
755 $this->_module_bar_form_actions = array_merge($defaults, $options);
756 }
757
758 public function prepare_form_shell(array $options = array()) {
759 if (!isset($this->_replaces['form_shell_class'])) {
760 $this->add_rep('form_shell_class', (string)($options['class'] ?? ''));
761 }
762 if (!isset($this->_replaces['form_class'])) {
763 $this->add_rep('form_class', (string)($options['form_class'] ?? ''));
764 }
765 if (!isset($this->_replaces['form_attrs'])) {
766 $this->add_rep('form_attrs', (string)($options['form_attrs'] ?? ''));
767 }
768 }
769
770 protected function defaultModuleBarReplaces(): array {
771 return array(
772 'bar_class' => 'dbx-module-bar',
773 'bar_title_class' => 'dbx-module-bar-titleblock',
774 'bar_actions_class' => 'dbx-module-bar-actions',
775 'bar_title' => '',
776 'bar_icon' => 'bi-grid',
777 'bar_subtitle' => '',
778 'bar_title_pre' => '',
779 'bar_title_heading_attrs' => '',
780 'bar_actions' => '',
781 'bar_extra' => '',
782 'bar_middle' => '',
783 );
784 }
785
786 protected function prepareFormFrameReplaces(int $i): void {
787 $formClass = trim((string)($this->_replaces['form_class'] ?? ''));
788 $formAttrs = trim((string)($this->_replaces['form_attrs'] ?? ''));
789 $shellClass = trim((string)($this->_replaces['form_shell_class'] ?? ''));
790 $panelClass = trim('dbxForm_wrapper ' . $shellClass);
791 $frameId = trim((string)($this->_replaces['frame_id'] ?? ''));
792 if ($frameId === '') {
793 $frameId = 'dbx_target_' . $i;
794 }
795
796 $this->add_rep('frame_id', $frameId);
797 if (trim((string)($this->_replaces['frame_panel_class'] ?? '')) === '') {
798 $this->add_rep('frame_panel_class', $panelClass);
799 }
800 $this->add_rep('frame_panel_attrs', (string)($this->_replaces['frame_panel_attrs'] ?? ''));
801 $this->add_rep('frame_subbar', '');
802 $this->add_rep('frame_body_class', '');
803 if ((string)($this->_replaces['frame_skip_form_wrap'] ?? '') !== '1') {
804 $this->add_rep('frame_form_open', '<form action="' . htmlspecialchars((string)$this->_action, ENT_QUOTES) . '" method="post" id="dbx_form_' . $i . '" class="dbxAjax' . ($formClass !== '' ? ' ' . $formClass : '') . '"' . ($formAttrs !== '' ? ' ' . $formAttrs : '') . '>');
805 $this->add_rep('frame_body_head', '<div class="row"><div class="col">{obj:form_msg}</div></div>');
806 $this->add_rep('frame_form_close', '</form>');
807 } else {
808 if (!isset($this->_replaces['frame_form_open'])) {
809 $this->add_rep('frame_form_open', '');
810 }
811 if (!isset($this->_replaces['frame_body_head'])) {
812 $this->add_rep('frame_body_head', '');
813 }
814 if (!isset($this->_replaces['frame_form_close'])) {
815 $this->add_rep('frame_form_close', '');
816 }
817 }
818 $this->add_rep('frame_body_tail', '');
819 }
820
821 protected function applyModuleBarReplaces(array $values = array()): void {
822 $defaults = array_merge($this->defaultModuleBarReplaces(), $values);
823
824 foreach ($defaults as $key => $value) {
825 $this->add_rep($key, (string) $value);
826 }
827 }
828
829 protected function buildModuleBarFormActionsHtml() {
830 if (!$this->_module_bar_form_actions) {
831 return '';
832 }
833
834 $opts = $this->_module_bar_form_actions;
835 $i = (int)$this->_next_i;
836 if ($i <= 0) {
837 $i = (int)$this->next_i();
838 }
839
840 $formId = 'dbx_form_' . $i;
841 $html = '';
842
843 if (!empty($opts['save'])) {
844 $html .= $this->get_tpl('dbx|button-bar-save', array(
845 'bar_form_id' => $formId,
846 ));
847 }
848
849 if (!empty($opts['delete']) && trim((string)($opts['delete_url'] ?? '')) !== '') {
850 $html .= $this->get_tpl('dbx|button-bar-delete', array(
851 'bar_delete_url' => htmlspecialchars((string)($opts['delete_url'] ?? ''), ENT_QUOTES),
852 'bar_delete_title' => htmlspecialchars((string)($opts['delete_title'] ?? 'Datensatz loeschen'), ENT_QUOTES),
853 'bar_delete_hint' => htmlspecialchars((string)($opts['delete_hint'] ?? ''), ENT_QUOTES),
854 ));
855 }
856
857 if (!empty($opts['reload'])) {
858 $reloadUrl = trim((string)($opts['reload_url'] ?? ''));
859 if ($reloadUrl === '') {
860 $reloadUrl = (string)$this->_action;
861 }
862
863 $html .= $this->get_tpl('dbx|button-bar-reload', array(
864 'bar_reload_url' => htmlspecialchars($reloadUrl, ENT_QUOTES),
865 ));
866 }
867
868 return $html;
869 }
870
871 protected function buildModuleBarObj() {
872 $modul = (string)dbx()->get_system_var('dbx_modul', '');
873 $isAdmin = ($modul === 'dbxAdmin' || str_ends_with($modul, '_admin'));
874 $barTitle = trim((string)($this->_replaces['bar_title'] ?? ''));
875
876 if (!$isAdmin && $barTitle === '') {
877 return;
878 }
879
880 try {
881 $help = dbx()->get_include_obj('dbxAdminHelp', 'dbxAdmin');
882 $topic = $help->resolveTopic($modul);
883
884 if ($isAdmin && $topic === '') {
885 return;
886 }
887
888 $actions = trim((string)($this->_replaces['bar_actions'] ?? ''));
889 if ($actions === '' && isset($this->_obj['bar_actions'])) {
890 $actions = (string)$this->_obj['bar_actions'];
891 }
892
893 $formActions = $this->buildModuleBarFormActionsHtml();
894 if ($formActions !== '') {
895 $actions = ($actions !== '') ? ($actions . ' ' . $formActions) : $formActions;
896 }
897
898 $title = (string)($this->_replaces['bar_title'] ?? '');
899 $icon = (string)($this->_replaces['bar_icon'] ?? 'bi-grid');
900 $subtitle = (string)($this->_replaces['bar_subtitle'] ?? '');
901
902 if ($topic !== '') {
903 $meta = $help->barMeta($topic);
904 if (is_array($meta) && $meta) {
905 if ($title === '') {
906 $title = (string)($meta['title'] ?? $topic);
907 }
908 if ($icon === '' || $icon === 'bi-grid') {
909 $icon = (string)($meta['icon'] ?? 'bi-grid');
910 }
911 if ($subtitle === '') {
912 $subtitle = (string)($meta['subtitle'] ?? '');
913 }
914 }
915 }
916
917 $helpButton = '';
918 if ($topic !== '') {
919 $helpButton = $help->button($topic);
920 } elseif (isset($this->_obj['help_button'])) {
921 $helpButton = (string)$this->_obj['help_button'];
922 }
923
924 $barClass = trim((string)($this->_replaces['bar_class'] ?? ''));
925 if ($barClass === '') {
926 $barClass = 'dbx-module-bar';
927 }
928
929 $this->applyModuleBarReplaces(array(
930 'bar_class' => $barClass,
931 'bar_title' => $title,
932 'bar_icon' => $icon !== '' ? $icon : 'bi-grid',
933 'bar_subtitle' => $subtitle,
934 'bar_actions' => $actions,
935 'bar_extra' => $helpButton,
936 ));
937 } catch (\Throwable $e) {
938 }
939 }
940
941 protected function attachAdminHelpButton($topic = '') {
942 $modul = (string)dbx()->get_system_var('dbx_modul', '');
943 if ($modul !== 'dbxAdmin' && !str_ends_with($modul, '_admin')) {
944 return;
945 }
946
947 try {
948 $help = dbx()->get_include_obj('dbxAdminHelp', 'dbxAdmin');
949 if ($topic === '') {
950 $topic = $help->resolveTopic($modul);
951 }
952 if ($topic === '') {
953 return;
954 }
955 $this->add_obj('help_button', $help->button($topic));
956
957 $barMeta = $help->barMeta($topic);
958 if (is_array($barMeta) && $barMeta) {
959 $this->add_module_bar(
960 (string)($barMeta['title'] ?? ''),
961 (string)($barMeta['icon'] ?? 'bi-grid'),
962 (string)($barMeta['subtitle'] ?? '')
963 );
964 }
965 } catch (\Throwable $e) {
966 }
967 }
968
969 private function get_token(): string {
970 try {
971 return bin2hex(random_bytes(32));
972 } catch (\Throwable $e) {
973 return hash('sha256', uniqid('', true) . '|' . mt_rand());
974 }
975 }
976
977 private function secure_fld_name(): string {
978 return '_' . (string)$this->_fid;
979 }
980
981 private function secure_token(string $fld): string {
982 if (!isset($this->_sys['_csrf']) || !is_array($this->_sys['_csrf'])) {
983 $this->_sys['_csrf'] = array();
984 }
985
986 $token = (string)($this->_sys['_csrf'][$fld] ?? $this->_sys[$fld] ?? '');
987 if (!preg_match('/^[a-f0-9]{64}$/', $token)) {
988 $token = $this->get_token();
989 }
990
991 $this->_sys['_csrf'][$fld] = $token;
992 $this->_sys[$fld] = $token;
993 $this->_data[$fld] = $token;
994
995 return $token;
996 }
997
998 private function sync_secure_field(string $fld, string $token): void {
999 $this->_sys['_csrf'][$fld] = $token;
1000 $this->_sys[$fld] = $token;
1001 $this->_data[$fld] = $token;
1002
1003 if (isset($this->_flds[$fld])) {
1004 $this->_flds[$fld]['value'] = $token;
1005 $this->_flds[$fld]['origin'] = 'csrf';
1006 $this->_flds[$fld]['verify'] = 1;
1007 $this->_flds[$fld]['error'] = 0;
1008 }
1009 }
1010
1011 private function rotate_secure_token(string $fld): void {
1012 $this->sync_secure_field($fld, $this->get_token());
1013 }
1014
1015
1031 public function url_to_array($data) {
1032 if (!is_array($data)) {
1033 $first = substr((string) $data, 0, 1);
1034
1035 if ($data && $first != '=') {
1036 if (strpos((string) $data, '=') !== false) {
1037 parse_str($data, $xdata);
1038 $data = $xdata;
1039 }
1040 }
1041 }
1042
1043 return $data;
1044 }
1045
1053 public function set_msg_info($msg) {
1054 $this->_msg_info = $msg;
1055 }
1056
1064 public function set_msg_ok($msg) {
1065 $this->_msg_success = $msg;
1066 }
1067
1075 public function set_msg_error($msg) {
1076 $this->_msg_error = $msg;
1077 }
1078
1086 public function set_msg_warning($msg) {
1087 $this->_msg_warning = $msg;
1088 }
1089
1102 public function get_fld_id($fld) {
1103 return dbx()->part_select(' name="', '"', $fld);
1104 }
1105
1123 public function add_norep($content) {
1124 $oTPL = dbx()->get_system_obj('dbxTPL');
1125 if (is_object($oTPL) && method_exists($oTPL, 'cleanup_optional_placeholders')) {
1126 $content = $oTPL->cleanup_optional_placeholders((string)$content);
1127 }
1128
1129 if (isset($_SESSION['dbx']['norep']) && is_array($_SESSION['dbx']['norep'])) {
1130 $xnorep = $_SESSION['dbx']['norep'];
1131
1132 for ($i = 0; $i < 2; $i++) {
1133 foreach ($xnorep as $id => $norep) {
1134 $xid = '[' . $id . ']';
1135 $content = str_replace($xid, $norep, $content);
1136 }
1137 }
1138 }
1139
1140 return $content;
1141 }
1142
1161 public function fast_response($response, $interpreter = 0) {
1162 if ($interpreter) {
1163 $oInterpreter = dbx()->get_system_obj('dbxInterpreter');
1164 $response = $oInterpreter->run($response);
1165 $response = $this->add_norep($response);
1166 }
1167
1168 echo $response;
1169 exit;
1170 }
1171
1187 public function get_tpl($tpl, $data = '', $type = 'htm', $i = 0) {
1188 return $this->oTPL->get_tpl($tpl, $data, $type, $i);
1189 }
1190
1206 public function obv_value($content, $id, $value) {
1207 $rep = '{obv:' . $id . '}';
1208 $val = '';
1209
1210 if (is_string($value)) {
1211 $val = htmlspecialchars($value, ENT_QUOTES);
1212 $content = str_replace($rep, $val, $content);
1213 }
1214
1215 return $content;
1216 }
1217
1236 public function merge_tpl_data($tpl, $i = 0) {
1237 $editor = dbx()->get_system_var('dbx_editor', 0, 'int');
1238
1239 if (!$i && !$editor) {
1240 $i = $this->_next_i;
1241 }
1242
1243 $replaces = array();
1244 $replaces['dbx_modul'] = $this->_dbx_modul;
1245 $replaces['dbx_run1'] = $this->_dbx_action;
1246 $replaces['dbx_page'] = $this->_dbx_page;
1247 $replaces['dbx_design'] = $this->_dbx_design;
1248 $replaces['dbx_lng'] = $this->_dbx_lng;
1249 $replaces['action'] = $this->_action;
1250 $replaces['fid'] = $this->_fid;
1251 $replaces['rid'] = $this->_rid;
1252 $replaces['self'] = dbx()->get_self_url();
1253
1254 if ($i) {
1255 $replaces['i'] = $i;
1256 }
1257
1258 return $this->oTPL->replaces($tpl, $replaces);
1259 }
1260
1278 public function merge_obj($content, $i = 0) {
1279 if (is_array($this->_obj)) {
1280 foreach ($this->_obj as $id => $obj) {
1281 $fid = '{obj:' . $id . '}';
1282 $obj = $this->oTPL->replaces($obj, $this->_replaces);
1283 $content = str_replace($fid, $obj, $content);
1284 }
1285 }
1286
1287 return $content;
1288 }
1289
1305 public function store_sysdata() {
1306 $section = $this->_fid;
1307 $modul = $this->_dbx_modul;
1308 $mode = $this->_store_mode;
1309 $value = $this->_sys;
1310 $key = 'sysdata';
1311
1312 if ($section && $mode == 'session') {
1313 dbx()->set_session_var($key, $value, $section, $modul);
1314 }
1315 }
1316
1332 public function load_sysdata() {
1333 $sysdata = array();
1334 $section = $this->_fid;
1335 $modul = $this->_dbx_modul;
1336 $key = 'sysdata';
1337 $empty = array();
1338
1339 if ($section) {
1340 $sysdata = dbx()->get_session_var($key, $empty, $section, $modul);
1341 }
1342
1343 return is_array($sysdata) ? $sysdata : array();
1344 }
1345
1362 public function get_activ_id($key = '') {
1363 if (!$key) {
1364 $key = $this->_dd;
1365 }
1366
1367 $xkey = '_activ-row_id_' . $key;
1368 return dbx()->get_remember_var($xkey, 0, 'dbx');
1369 }
1370
1379 public function set_activ_id($value, $key = '') {
1380 if (!$key) {
1381 $key = $this->_dd;
1382 }
1383
1384 $xkey = '_activ-row_id_' . $key;
1385 dbx()->set_remember_var($xkey, $value, 'dbx');
1386 }
1387
1400 public function add_rep($key, $val) {
1401 $this->_replaces[$key] = $val;
1402 }
1403
1420 public function add_js_code($javascript) {
1421 if ($javascript !== '') {
1422 $this->_js[] = $javascript;
1423 }
1424 }
1425
1446 public function add_js_call($target, $function, $args = '') {
1447 $js = $function . "('" . addslashes((string) $target) . "'";
1448
1449 if ($args !== '') {
1450 $js .= ',' . $args;
1451 }
1452
1453 $js .= ');';
1454
1455 $this->_js[] = $js;
1456 }
1457
1476 public function update_error_fld($name, $msg) {
1477 foreach ($this->_flds as $no => $fld) {
1478 if (($fld['name'] ?? '') == $name) {
1479 $fld['error'] = 1;
1480 $fld['verify'] = 1;
1481 $fld['data']['class'] = trim(($fld['data']['class'] ?? '') . ' fld-error');
1482 $fld['data']['errormsg'] = $msg;
1483 $this->_flds[$no] = $fld;
1484 break;
1485 }
1486 }
1487 }
1488
1502 public function add_fld_error($name, $msg = '') {
1503 dbx()->debug("add fld-error fld=($name) Msg=($msg)");
1504 $this->_errors[$name] = $msg;
1505 $this->update_error_fld($name, $msg);
1506 }
1507
1516 public function add_fld_warning($name, $msg = '') {
1517 $this->_warnings[$name] = $msg;
1518 }
1519
1537 private function resolve_fld_val($name, $default = '', $rules = '', $useRequest = true, $fallbackToState = true) {
1538 $stateValue = $default;
1539 $origin = 'default';
1540
1541 if (isset($this->_data[$name])) {
1542 $stateValue = $this->_data[$name];
1543 $origin = 'data';
1544 }
1545
1546 if (isset($this->_sys[$name])) {
1547 $stateValue = $this->_sys[$name];
1548 $origin = 'sys';
1549 }
1550
1551 $value = $fallbackToState ? $stateValue : $default;
1552
1553 if (!$fallbackToState) {
1554 $origin = 'default';
1555 }
1556
1557 if ($useRequest) {
1558 if (isset($_POST[$name])) {
1559 $value = $_POST[$name];
1560 $origin = 'post';
1561 } elseif (isset($_GET[$name])) {
1562 $value = $_GET[$name];
1563 $origin = 'get';
1564 }
1565 }
1566
1567 if ($value === null) {
1568 $value = '';
1569 }
1570
1571 $ok = true;
1572
1573 if ($rules) {
1574 $ok = $this->oValidator->validate($value, $rules, $name);
1575 }
1576
1577 return array(
1578 'value' => $value,
1579 'origin' => $origin,
1580 'ok' => $ok ? 1 : 0,
1581 );
1582 }
1583
1584 public function get_fld_val($name, $default = '', $rules = '', $submit = -1) {
1585 $resolved = $this->resolve_fld_val($name, $default, $rules, true, true);
1586 $value = $resolved['value'];
1587
1588 if (!$resolved['ok']) {
1589 $this->add_fld_error($name, 'f:' . $rules);
1590 $value = $default;
1591 }
1592
1593 $this->_data[$name] = $value;
1594 $this->_sys[$name] = $value;
1595
1596 if (isset($this->_flds[$name])) {
1597 $this->_flds[$name]['value'] = $value;
1598 $this->_flds[$name]['origin'] = $resolved['origin'];
1599 }
1600
1601 return $value;
1602 }
1603 public function get_fld_value($name, $default = '', $rules = '', $submit = -1) {
1604 return $this->get_fld_val($name, $default, $rules, $submit);
1605 }
1606
1616 public function get_post_data($name, $default = '', $rules = 'parameter') {
1617 $danger_value = $this->_get_post_data($name, $default);
1618
1619 if ($rules) {
1620 $ok = $this->oValidator->validate($danger_value, $rules, $name);
1621
1622 if (!$ok) {
1623 $this->add_fld_error($name, 'p:' . $rules);
1624 $danger_value = $default;
1625 }
1626 }
1627
1628 return $danger_value;
1629 }
1630
1640 public function get_post($name, $default = '', $rules = 'alphanum') {
1641 $danger_value = $this->_get_post($name, $default);
1642
1643 if ($rules) {
1644 $ok = $this->oValidator->validate($danger_value, $rules, $name);
1645
1646 if (!$ok) {
1647 $this->add_fld_error($name, 'p:' . $rules);
1648 $danger_value = $default;
1649 }
1650 }
1651
1652 return $danger_value;
1653 }
1654
1668 private function _get_post_data($name, $default = '') {
1669 $set = 0;
1670 $value = $default;
1671
1672 if (isset($_POST[$name])) {
1673 $value = $_POST[$name];
1674 $set = 1;
1675 } elseif (isset($_GET[$name])) {
1676 $value = $_GET[$name];
1677 $set = 1;
1678 }
1679
1680 if (!$set && isset($this->_data[$name])) {
1681 $value = $this->_data[$name];
1682 }
1683
1684 return $value;
1685 }
1686
1699 private function _get_post($name, $default = '') {
1700 $value = $default;
1701
1702 if (isset($_POST[$name])) {
1703 $value = $_POST[$name];
1704 } elseif (isset($_GET[$name])) {
1705 $value = $_GET[$name];
1706 }
1707
1708 return $value;
1709 }
1710
1730 public function add_obj($obj, $tpl, $data = '', $data2 = '') {
1731 if ($tpl != 'obj-value' && $tpl != 'obv-value') {
1732 $tpl = $this->get_tpl($tpl, $data);
1733 } else {
1734 if ($tpl == 'obv-value') {
1735 $tpl = htmlspecialchars((string) $data, ENT_QUOTES);
1736 }
1737
1738 if ($tpl == 'obj-value') {
1739 $tpl = $data;
1740 }
1741
1742 $tpl = $this->oTPL->replaces((string) $tpl, $data2);
1743 }
1744
1745 $tpl = str_replace('{class}', '', $tpl);
1746 $tpl = str_replace('{tooltip}', '', $tpl);
1747
1748 $this->_obj[$obj] = $tpl;
1749 }
1750
1766 public function add_action($obj, $tpl, $action = '', $data = '') {
1767 $xaction = $this->_action;
1768
1769 if ($action !== '' && $action[0] == '&') {
1770 $x_action = $xaction . $action;
1771 } else {
1772 $x_action = $action;
1773 }
1774
1775 $xdata = array();
1776 $xdata['action'] = $x_action;
1777
1778 if (is_array($data)) {
1779 $xdata = array_merge($xdata, $data);
1780 }
1781
1782 $tpl = $this->get_tpl($tpl, $xdata);
1783 $tpl = str_replace('{class}', '', $tpl);
1784 $tpl = str_replace('{tooltip}', '', $tpl);
1785
1786 $this->_obj[$obj] = $tpl;
1787 }
1788
1813 private function get_active_field_source($source = 'fd::'): string {
1814 if ($source === 'fd::') {
1815 if ($this->_fd) {
1816 return (string) $this->_fd;
1817 }
1818
1819 return (string) $this->_dd;
1820 }
1821
1822 if ($source === 'dd::') {
1823 return (string) $this->_dd;
1824 }
1825
1826 return (string) $source;
1827 }
1828
1860 private function get_fld_marker_value_from_records($value, string $var, $field_record = array(), $dd_record = array()) {
1861 if (!is_array($field_record)) {
1862 $field_record = array();
1863 }
1864
1865 if (!is_array($dd_record)) {
1866 $dd_record = array();
1867 }
1868
1869 if ($value === 'fd::') {
1870 return $field_record[$var] ?? '';
1871 }
1872
1873 if ($value === 'dd::') {
1874 return $dd_record[$var] ?? '';
1875 }
1876
1877 return $value;
1878 }
1879
1880
1881
1911 private function get_dd_fields_source(string $dd): array {
1912 $dd = trim($dd);
1913
1914 if ($dd === '' || $dd === 'dd') {
1915 return array();
1916 }
1917
1918 $mod = 'dd';
1919 $name = $dd;
1920
1921 foreach (array('cfg:', 'def:', 'mod:', 'fd:', 'dd:') as $prefix) {
1922 if (strpos($dd, $prefix) === 0) {
1923 $mod = substr($prefix, 0, -1);
1924 $name = substr($dd, strlen($prefix));
1925 break;
1926 }
1927 }
1928
1929 if ($mod === 'dd' && strpos($dd, '|') !== false) {
1930 $mod = 'fd';
1931 $name = $dd;
1932 }
1933
1934 if ($mod === 'dd') {
1935 $fields = $this->oDB->get_dd_fields($name);
1936 if (method_exists($this->oDB, 'get_dd_file')) {
1937 $this->add_editor_file('dd', $this->oDB->get_dd_file($name));
1938 }
1939 return is_array($fields) ? $fields : array();
1940 }
1941
1942 $dd_file = '';
1943
1944 switch ($mod) {
1945 case 'cfg':
1946 $dd_file = dbx_get_base_dir() . "dbx/modules/$name/cfg/config.dd.php";
1947 break;
1948
1949 case 'def':
1950 $dd_file = dbx_get_base_dir() . "dbx/modules/$name/dd/$name.dd.php";
1951 break;
1952
1953 case 'mod':
1954 $modul = dbx()->get_system_var('dbx_activ_modul', 'dbx');
1955 $dd_file = dbx_get_base_dir() . "dbx/modules/$modul/dd/$name.dd.php";
1956 break;
1957
1958 case 'fd':
1959 $fd_modul = $this->_dbx_modul ? $this->_dbx_modul : dbx()->get_system_var('dbx_activ_modul', 'dbx');
1960 $fd_name = $name;
1961
1962 if (strpos($name, '|') !== false) {
1963 $parts = explode('|', $name, 2);
1964 $fd_modul = trim($parts[0]);
1965 $fd_name = trim($parts[1]);
1966 }
1967
1968 if ($fd_modul === '') {
1969 $fd_modul = dbx()->get_system_var('dbx_activ_modul', 'dbx');
1970 }
1971
1972 $dd_file = function_exists('dbx_lng_resolve_file')
1973 ? dbx_lng_resolve_file(
1974 dbx_get_base_dir() . "dbx/modules/$fd_modul/fd/",
1975 $fd_name,
1976 'fd.php',
1977 $this->_dbx_lng,
1978 true
1979 )
1980 : dbx_get_base_dir() . "dbx/modules/$fd_modul/fd/$fd_name.fd.php";
1981 if ($dd_file === '' || !is_file($dd_file)) {
1982 $dd_file = dbx_get_base_dir() . "dbx/modules/$fd_modul/fd/$fd_name.fd.php";
1983 }
1984 break;
1985 }
1986
1987 return $this->read_dd_fields_direct($dd_file);
1988 }
1989
2019 private function read_dd_fields_direct(string $dd_file): array {
2020 $fields = array();
2021 $table = array();
2022 $indexes = array();
2023
2024 $dd_file = dbx_os_path_file($dd_file);
2025
2026 if (!file_exists($dd_file)) {
2027 return array();
2028 }
2029
2030 $real_file = realpath($dd_file);
2031 if (!$real_file) {
2032 $real_file = $dd_file;
2033 }
2034
2035 $normalized = str_replace('\\', '/', $real_file);
2036 $kind = (substr($normalized, -7) === '.fd.php') ? 'fd' : 'dd';
2037 $mtime = @filemtime($real_file);
2038 $size = @filesize($real_file);
2039 $cache_key = md5($normalized);
2040
2041 $this->add_editor_file($kind, $real_file);
2042 $runtime_cache =& $this->session_cache_section('form', 'field_source_runtime');
2043 $field_source_cache =& $this->session_cache_section('form', 'field_source');
2044
2045 if (isset($runtime_cache[$cache_key])) {
2046 $entry = $runtime_cache[$cache_key];
2047
2048 if (
2049 is_array($entry) &&
2050 ($entry['mtime'] ?? 0) === $mtime &&
2051 ($entry['size'] ?? 0) === $size &&
2052 isset($entry['fields']) &&
2053 is_array($entry['fields'])
2054 ) {
2055 return $entry['fields'];
2056 }
2057 }
2058
2059 if (
2060 !isset($field_source_cache[$cache_key]) &&
2061 isset($_SESSION['dbx']['cache']['field_source'][$cache_key]) &&
2062 is_array($_SESSION['dbx']['cache']['field_source'][$cache_key])
2063 ) {
2064 $field_source_cache[$cache_key] = $_SESSION['dbx']['cache']['field_source'][$cache_key];
2065 unset($_SESSION['dbx']['cache']['field_source'][$cache_key]);
2066 }
2067
2068 if (isset($field_source_cache[$cache_key])) {
2069 $entry = $field_source_cache[$cache_key];
2070
2071 if (
2072 is_array($entry) &&
2073 ($entry['mtime'] ?? 0) === $mtime &&
2074 ($entry['size'] ?? 0) === $size &&
2075 isset($entry['fields']) &&
2076 is_array($entry['fields'])
2077 ) {
2078 $runtime_cache[$cache_key] = $entry;
2079 return $entry['fields'];
2080 }
2081 }
2082
2083 include $real_file;
2084
2085 if (!is_array($fields)) {
2086 $fields = array();
2087 }
2088
2089 $entry = array(
2090 'path' => $normalized,
2091 'kind' => $kind,
2092 'mtime' => $mtime,
2093 'size' => $size,
2094 'fields' => $fields,
2095 );
2096
2097 $runtime_cache[$cache_key] = $entry;
2098 $field_source_cache[$cache_key] = $entry;
2099
2100 return $fields;
2101 }
2102
2116 private function get_dd_fld(array $fields, string $fld): array {
2117 foreach ($fields as $record) {
2118 if (isset($record['name']) && $record['name'] === $fld) {
2119 return $record;
2120 }
2121 }
2122
2123 return array();
2124 }
2125
2126 private function &session_cache_section(string $bereich, string $section) {
2127 if (!isset($_SESSION['dbx']) || !is_array($_SESSION['dbx'])) {
2128 $_SESSION['dbx'] = array();
2129 }
2130
2131 if (!isset($_SESSION['dbx']['cache']) || !is_array($_SESSION['dbx']['cache'])) {
2132 $_SESSION['dbx']['cache'] = array();
2133 }
2134
2135 if (!isset($_SESSION['dbx']['cache'][$bereich]) || !is_array($_SESSION['dbx']['cache'][$bereich])) {
2136 $_SESSION['dbx']['cache'][$bereich] = array();
2137 }
2138
2139 if (!isset($_SESSION['dbx']['cache'][$bereich][$section]) || !is_array($_SESSION['dbx']['cache'][$bereich][$section])) {
2140 $_SESSION['dbx']['cache'][$bereich][$section] = array();
2141 }
2142
2143 return $_SESSION['dbx']['cache'][$bereich][$section];
2144 }
2145
2169 public function get_dd(string $dd, string $fld, string $var) {
2170 if ($dd === '' || $dd === 'dd') {
2171 return '';
2172 }
2173
2174 if ($fld === '') {
2175 return '';
2176 }
2177
2178 $cache_key = md5($dd . "\0" . $fld);
2179 $field_cache =& $this->session_cache_section('form', 'runtime_field');
2180
2181 if (isset($field_cache[$cache_key]) && is_array($field_cache[$cache_key])) {
2182 $field = $field_cache[$cache_key];
2183 } else {
2184 $fields = $this->get_dd_fields_source($dd);
2185
2186 if (!is_array($fields)) {
2187 $field_cache[$cache_key] = array();
2188 return '';
2189 }
2190
2191 $field = $this->get_dd_fld($fields, $fld);
2192
2193 if (!is_array($field)) {
2194 $field = array();
2195 }
2196
2197 $field_cache[$cache_key] = $field;
2198 }
2199
2200 if (!$field) {
2201 return '';
2202 }
2203
2204 if ($var === '*') {
2205 return $field;
2206 }
2207
2208 return $field[$var] ?? '';
2209 }
2210
2232 private function sql_dd_file_exists($modul, $dd) {
2233 $modul = trim((string) $modul);
2234 $dd = trim((string) $dd);
2235
2236 if ($dd === '') {
2237 return false;
2238 }
2239
2240 if ($modul === '') {
2241 $modul = dbx()->get_system_var('dbx_activ_modul', 'dbx');
2242 }
2243
2244 $file1 = dbx_os_path_file(dbx_get_base_dir() . 'dbx/modules/' . $modul . '/dd/' . $dd . '.dd.php');
2245 $file2 = dbx_os_path_file(dbx_get_base_dir() . 'dbx/modules/dbx/dd/' . $dd . '.dd.php');
2246
2247 return file_exists($file1) || file_exists($file2);
2248 }
2249
2250 private function normalize_sql_dd_name($modul, $source) {
2251 $source = trim((string) $source);
2252
2253 if ($source === '') {
2254 return '';
2255 }
2256
2257 $candidates = array(
2258 $source,
2259 str_replace('dbx_', 'dbx', $source),
2260 str_replace(' ', '', ucwords(str_replace('_', ' ', $source))),
2261 lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $source))))
2262 );
2263
2264 foreach ($candidates as $candidate) {
2265 if ($this->sql_dd_file_exists($modul, $candidate)) {
2266 return $candidate;
2267 }
2268 }
2269
2270 return $source;
2271 }
2272
2273 private function sql_to_array($data) {
2274 $dd = '';
2275 $xkey = '';
2276 $flds = '*';
2277 $where = '';
2278 $order = '';
2279 $limit = 888;
2280 $asc_desc = 'ASC';
2281 $xdata = array();
2282 $compact_sql_syntax = false;
2283
2284 $data = str_replace('sql:', '', (string) $data);
2285 $work = explode('|', $data);
2286
2287 if (isset($work[0])) {
2288 $dd = $work[0];
2289 }
2290
2291 if (isset($work[1])) {
2292 $xkey = $work[1];
2293 }
2294
2295 if ($dd && $xkey && strpos($xkey, ',') !== false) {
2296 $sqlSource = array_map('trim', explode(',', $xkey));
2297 $dd = $this->normalize_sql_dd_name($dd, $sqlSource[0] ?? '');
2298 $xkey = $sqlSource[1] ?? 'id';
2299 $flds = $sqlSource[2] ?? $xkey;
2300 $compact_sql_syntax = true;
2301 }
2302
2303 if (isset($work[2])) {
2304 if ($compact_sql_syntax) {
2305 $where = $work[2];
2306 } else {
2307 $flds = $work[2];
2308 }
2309 }
2310
2311 if (isset($work[3])) {
2312 if ($compact_sql_syntax) {
2313 $order = $work[3];
2314 } else {
2315 $where = $work[3];
2316 }
2317 }
2318
2319 if (isset($work[4])) {
2320 if ($compact_sql_syntax) {
2321 if ((int) $work[4] > 0) {
2322 $limit = (int) $work[4];
2323 }
2324 } else {
2325 $order = $work[4];
2326 }
2327 }
2328
2329 if (!$compact_sql_syntax && isset($work[5]) && (int) $work[5] > 0) {
2330 $limit = (int) $work[5];
2331 }
2332
2333 $xdata[0] = 'Bitte auswählen';
2334
2335 if ($order && strpos($order, ' DESC') !== false) {
2336 $asc_desc = 'DESC';
2337 $order = str_replace(' DESC', '', $order);
2338 }
2339
2340 if ($order && strpos($order, ' ASC') !== false) {
2341 $asc_desc = 'ASC';
2342 $order = str_replace(' ASC', '', $order);
2343 }
2344
2345 if ($dd) {
2346 $xflds = $flds;
2347
2348 if (!$xkey) {
2349 $xkey = 'id';
2350 }
2351
2352 if (strpos(',' . $xflds . ',', ',' . $xkey . ',') === false && $xflds !== '*') {
2353 $xflds .= ',' . $xkey;
2354 }
2355
2356 $data = $this->oDB->select($dd, $where, $xflds, $order, $asc_desc, '', $limit, 0, 0);
2357
2358 if (is_array($data)) {
2359 $displayFields = ($flds === '*') ? array() : array_map('trim', explode(',', $flds));
2360
2361 foreach ($data as $record) {
2362 $value = '';
2363
2364 foreach ($record as $fld => $val) {
2365 $use = ($flds === '*') || in_array($fld, $displayFields, true);
2366
2367 if ($use) {
2368 if ($value !== '') {
2369 $value .= ' | ';
2370 }
2371
2372 $value .= $val;
2373 }
2374 }
2375
2376 if (isset($record[$xkey])) {
2377 $xdata[$record[$xkey]] = $value;
2378 }
2379 }
2380 }
2381 }
2382
2383 return $xdata;
2384 }
2385
2386
2420 public function add_flds($dd = 'fd::') {
2421 $source = $this->get_active_field_source($dd);
2422
2423 if ($source === '' || $source === 'dd') {
2424 return 0;
2425 }
2426
2427 $fields = $this->get_dd_fields_source($source);
2428
2429 if (!is_array($fields) || !$fields) {
2430 return 0;
2431 }
2432
2433 $count = 0;
2434
2435 foreach ($fields as $record) {
2436 if (!is_array($record)) {
2437 continue;
2438 }
2439
2440 if (!isset($record['name']) || trim((string) $record['name']) === '') {
2441 continue;
2442 }
2443
2444 $name = trim((string) $record['name']);
2445 $this->add_fld($name, dd: $source);
2446 $count++;
2447 }
2448
2449 return $count;
2450 }
2451
2452
2507 public function add_fld($name, $tpl = 'fd::', $label = 'fd::', $rules = 'fd::', $class = 'fd::', $data = 'fd::', $options = 'fd::', $tooltip = 'fd::', $placeholder = 'fd::', $errormsg = 'fd::', $dd = 'fd::', $remap = 'fd::') {
2508 $field_source = $this->get_active_field_source($dd);
2509 $dd_source = $this->get_active_field_source('dd::');
2510 $field_record = $field_source ? $this->get_dd($field_source, $name, '*') : array();
2511 $dd_record = $dd_source ? $this->get_dd($dd_source, $name, '*') : array();
2512 $source_data = array();
2513 $source_options = array();
2514 $dd_data = array();
2515 $dd_options = array();
2516
2517 if (is_array($field_record) && $field_record) {
2518 $source_data = $this->process_array($field_record['data'] ?? '');
2519 $source_options = $this->process_array($field_record['options'] ?? '');
2520 }
2521
2522 if (is_array($dd_record) && $dd_record) {
2523 $dd_data = $this->process_array($dd_record['data'] ?? '');
2524 $dd_options = $this->process_array($dd_record['options'] ?? '');
2525 }
2526
2527 if ($data === 'fd::' || $data === '' || $data === null) {
2528 $data = $source_data;
2529 } elseif ($data === 'dd::') {
2530 $data = $dd_data;
2531 } else {
2532 $data = $this->merge_arrays($this->process_array($data), $source_data);
2533 }
2534
2535 if ($options === 'fd::' || $options === '' || $options === null) {
2536 $options = $source_options;
2537 } elseif ($options === 'dd::') {
2538 $options = $dd_options;
2539 } else {
2540 $options = $this->merge_arrays($this->process_array($options), $source_options);
2541 }
2542
2543 if (isset($data['dd'])) {
2544 $field_source = $this->get_active_field_source($data['dd']);
2545 $field_record = $field_source ? $this->get_dd($field_source, $name, '*') : array();
2546 }
2547
2548 if ($label === 'fd::' && isset($data['label'])) {
2549 $label = $data['label'];
2550 }
2551
2552 if ($rules === 'fd::' && isset($data['rules'])) {
2553 $rules = $data['rules'];
2554 }
2555
2556 if ($class === 'fd::' && isset($data['class'])) {
2557 $class = $data['class'];
2558 }
2559
2560 if ($tooltip === 'fd::' && isset($data['tooltip'])) {
2561 $tooltip = $data['tooltip'];
2562 }
2563
2564 if ($placeholder === 'fd::' && isset($data['placeholder'])) {
2565 $placeholder = $data['placeholder'];
2566 }
2567
2568 if ($errormsg === 'fd::' && isset($data['errormsg'])) {
2569 $errormsg = $data['errormsg'];
2570 }
2571
2572 if ($remap === 'fd::' && isset($data['remap'])) {
2573 $remap = $data['remap'];
2574 }
2575
2576 $data['name'] = $name;
2577 $data['tpl'] = $this->get_fld_marker_value_from_records($tpl, 'tpl', $field_record, $dd_record);
2578 $data['label'] = $this->get_fld_marker_value_from_records($label, 'label', $field_record, $dd_record);
2579 $data['rules'] = $this->get_fld_marker_value_from_records($rules, 'rules', $field_record, $dd_record);
2580 $data['class'] = $this->get_fld_marker_value_from_records($class, 'class', $field_record, $dd_record);
2581 $data['tooltip'] = $this->get_fld_marker_value_from_records($tooltip, 'tooltip', $field_record, $dd_record);
2582 $data['placeholder'] = $this->get_fld_marker_value_from_records($placeholder, 'placeholder', $field_record, $dd_record);
2583 $data['errormsg'] = $this->get_fld_marker_value_from_records($errormsg, 'errormsg', $field_record, $dd_record);
2584 $data['remap'] = $this->get_fld_marker_value_from_records($remap, 'remap', $field_record, $dd_record);
2585
2586 $fld = array(
2587 'name' => $name,
2588 'data' => $data,
2589 'options' => $options,
2590 'label' => $data['label'],
2591 'tpl' => $data['tpl'],
2592 'rules' => $data['rules'],
2593 'remap' => $data['remap'],
2594 'value' => '',
2595 'origin' => '',
2596 'errormsg' => $data['errormsg'],
2597 'error' => 0,
2598 'changed' => 0,
2599 'verify' => 0,
2600 'dd' => $field_source,
2601 );
2602
2603 $this->_flds[$name] = $fld;
2604 $this->touch_request_state();
2605 }
2606
2620 private function process_array($input) {
2621 if (!is_array($input)) {
2622 if ($input) {
2623 $data_first = substr((string) $input, 0, 4);
2624
2625 if ($data_first === 'sql:') {
2626 $input = $this->sql_to_array($input);
2627 } else {
2628 $input = $this->url_to_array($input);
2629 }
2630 } else {
2631 $input = array();
2632 }
2633 }
2634
2635 return is_array($input) ? $input : array();
2636 }
2637
2651 private function merge_arrays($primary, $secondary) {
2652 if (!is_array($primary)) {
2653 $primary = array();
2654 }
2655
2656 if (!is_array($secondary)) {
2657 $secondary = array();
2658 }
2659
2660 foreach ($secondary as $key => $value) {
2661 if (!array_key_exists($key, $primary)) {
2662 $primary[$key] = $value;
2663 }
2664 }
2665
2666 return $primary;
2667 }
2668
2680 private function touch_request_state() {
2681 $this->_form_validate = -1;
2682 $this->_fld_changes = -1;
2683 $this->_form_submit = -1;
2684 }
2685
2686
2687
2701 public function check_fld_data($submit, $fld) {
2702 if (($fld['verify'] ?? 0)) {
2703 return $fld;
2704 }
2705
2706 $errormsg = 'Bitte Eingabe pruefen';
2707 $name = $fld['name'] ?? '';
2708 $fld_rules = $fld['rules'] ?? '';
2709
2710 if (!$submit) {
2711 $resolved = $this->resolve_fld_val($name, '', '', false, true);
2712
2713 $fld['value'] = $resolved['value'];
2714 $fld['origin'] = $resolved['origin'];
2715 $fld['changed'] = 0;
2716 $fld['error'] = 0;
2717 $fld['verify'] = 1;
2718
2719 return $fld;
2720 }
2721
2722 $old = $this->resolve_fld_val($name, '', '', false, true);
2723 $old_value = $old['value'];
2724
2725 $resolved = $this->resolve_fld_val($name, '', $fld_rules, true, false);
2726 $value = $resolved['value'];
2727 $ok = (bool) $resolved['ok'];
2728
2729 $fld['origin'] = $resolved['origin'];
2730 $fld['error'] = $ok ? 0 : 1;
2731 $fld['value'] = $value;
2732
2733 if (!empty($fld['data']['errormsg'])) {
2734 $errormsg = $fld['data']['errormsg'];
2735 }
2736
2737 if ($fld['error']) {
2738 $this->add_fld_error($name, $errormsg);
2739 $fld['data']['errormsg'] = $errormsg;
2740 }
2741
2742 $value_compare = $value;
2743
2744 if (is_array($value_compare)) {
2745 $values = '';
2746
2747 foreach ($value_compare as $keyval) {
2748 if ($values !== '') {
2749 $values .= ',';
2750 }
2751
2752 $values .= $keyval;
2753 }
2754
2755 $value_compare = $values;
2756 }
2757
2758 $change = $this->_fld_change_state;
2759
2760 if ($value_compare != $old_value || $change == '*') {
2761 $fld['changed'] = 1;
2762 } else {
2763 $fld['changed'] = 0;
2764 }
2765
2766 if (!$fld['error'] && $fld['changed']) {
2767 $this->_post[$name] = $value_compare;
2768 }
2769
2770 $fld['verify'] = 1;
2771
2772 return $fld;
2773 }
2774
2775
2788 public function check_flds_data($submit) {
2789 if ($this->_form_validate == 1) {
2790 return;
2791 }
2792
2793 $this->_post = array();
2794 $this->_errors = array();
2795 $this->_warnings = array();
2796
2797 foreach ($this->_flds as $no => $fld) {
2798 $fld = $this->check_fld_data($submit, $fld);
2799 $this->_flds[$no] = $fld;
2800 }
2801
2802 $this->_form_validate = 1;
2803 $this->_fld_changes = -1;
2804 }
2805
2821 private function evaluate_request() {
2822 if ($this->_form_validate == 1 && $this->_form_submit > -1) {
2823 dbx()->debug("dbxForm submit cached: fid=({$this->_fid}) submit=({$this->_form_submit})");
2824 return;
2825 }
2826
2827 $submit = 0;
2828 $fld = $this->secure_fld_name();
2829 $secure = $this->secure_token($fld);
2830 $posted = '';
2831 $hasPost = 0;
2832 $match = 0;
2833
2834 if ($fld !== '' && isset($_POST[$fld])) {
2835 $posted = (string)$_POST[$fld];
2836 $hasPost = 1;
2837
2838 if ($secure !== '' && hash_equals($secure, $posted)) {
2839 $submit = 1;
2840 $match = 1;
2841 }
2842 }
2843
2844 dbx()->debug(
2845 "dbxForm submit evaluate: fid=({$this->_fid}) field=($fld) post=($hasPost) match=($match) submit=($submit) sys=(" . substr($secure, 0, 8) . ") postval=(" . substr($posted, 0, 8) . ")"
2846 );
2847
2848 $this->_form_submit = $submit;
2849 $this->check_flds_data($submit);
2850
2851 if ($submit) {
2852 $this->rotate_secure_token($fld);
2853 } else {
2854 $this->sync_secure_field($fld, $secure);
2855 }
2856 }
2857
2866 public function get_form_msg($mode, $msg = '') {
2867 if (!$msg) {
2868 return '';
2869 }
2870
2871 $file = $this->_tpl_form_info;
2872 $tpl = '';
2873
2874 if ($mode == 'success') {
2875 $file = $this->_tpl_form_success;
2876 }
2877
2878 if ($mode == 'error') {
2879 $file = $this->_tpl_form_error;
2880 }
2881
2882 if ($mode == 'info') {
2883 $file = $this->_tpl_form_info;
2884 }
2885
2886 if ($mode == 'warning') {
2887 $file = $this->_tpl_form_warning;
2888 }
2889
2890 if ($file) {
2891 $tpl = $this->get_tpl($file);
2892 $tpl = str_replace('{msg}', $msg, $tpl);
2893 }
2894
2895 return str_replace('{class}', $mode, $tpl);
2896 }
2897
2906 public function get_fld_msg($mode, $msg = '') {
2907 $file = '';
2908 $tpl = '';
2909
2910 if ($mode == 'success') {
2911 $file = $this->_tpl_fld_success;
2912 }
2913
2914 if ($mode == 'error') {
2915 $file = $this->_tpl_fld_error;
2916 }
2917
2918 if ($mode == 'info') {
2919 $file = $this->_tpl_fld_info;
2920 }
2921
2922 if ($mode == 'warning') {
2923 $file = $this->_tpl_fld_warning;
2924 }
2925
2926 if ($file) {
2927 $tpl = $this->get_tpl($file);
2928 $tpl = str_replace('{msg}', $msg, $tpl);
2929 }
2930
2931 return $tpl;
2932 }
2933
2941 public function get_quartal($datum) {
2942 return '3/25';
2943 }
2944
2952 public function php_date_usr($value) {
2953 if (trim((string) $value) !== '') {
2954 $timestamp = strtotime((string) $value);
2955
2956 if ($timestamp !== false) {
2957 $value = date('d.m.Y', $timestamp);
2958 $value = substr($value, 0, 10);
2959 }
2960 }
2961
2962 return (string) $value;
2963 }
2964
2972 public function php_datetime_usr($value) {
2973 $raw = trim((string) $value);
2974
2975 if ($raw !== '') {
2976 $ms = '';
2977
2978 if (preg_match('/\.(\d+)$/', $raw, $match)) {
2979 $ms = '.' . $match[1];
2980 }
2981
2982 $timestamp = strtotime($raw);
2983
2984 if ($timestamp !== false) {
2985 if (preg_match('/^\d{2}:\d{2}(:\d{2})?(\.\d+)?$/', $raw)) {
2986 $value = date('H:i' . (substr_count($raw, ':') == 2 ? ':s' : ''), $timestamp) . $ms;
2987 } elseif (preg_match('/^\d{4}-\d{2}-\d{2}$|^\d{2}\.\d{2}\.\d{4}$/', $raw)) {
2988 $value = date('d.m.Y', $timestamp);
2989 } else {
2990 $value = date('d.m.Y H:i' . (substr_count($raw, ':') >= 2 ? ':s' : ''), $timestamp) . $ms;
2991 }
2992 }
2993 }
2994
2995 return (string) $value;
2996 }
2997
3005 public function php_date($value) {
3006 if ($value) {
3007 if ($value != 'today') {
3008 $timestamp = strtotime((string) $value);
3009 } else {
3010 $timestamp = time();
3011 }
3012
3013 $value = date('Y-m-d', $timestamp);
3014 }
3015
3016 return (string) $value;
3017 }
3018
3026 public function add_css($css = '') {
3027 if ($css) {
3028 $this->_css[] = $css;
3029 }
3030 }
3031
3042 public function forward_submit() {
3043 $this->evaluate_request();
3044 $submit = ($this->_form_submit == 1) ? 1 : 0;
3045 $submit = $this->callback('submit', $submit);
3046 $result = ($submit == 1) ? 1 : 0;
3047
3048 dbx()->debug("dbxForm submit result: fid=({$this->_fid}) result=($result)");
3049
3050 return $result;
3051 }
3052
3058 public function submit() {
3059 return $this->forward_submit();
3060 }
3061
3067 public function errors() {
3068 $this->evaluate_request();
3069
3070 if ($this->_general_error > '') {
3071 $this->_errors['general'] = 1;
3072 }
3073
3074 return count($this->_errors);
3075 }
3076
3082 public function warnings() {
3083 $this->evaluate_request();
3084 return count($this->_warnings);
3085 }
3086
3094 public function changed($changed = 0) {
3095 $this->evaluate_request();
3096
3097 if ($this->_form_submit != 1) {
3098 $this->_fld_changes = 0;
3099 return 0;
3100 }
3101
3102 if ($this->_fld_changes != -1) {
3103 return $this->_fld_changes;
3104 }
3105
3106 foreach ($this->_flds as $fld) {
3107 $changed += (int) ($fld['changed'] ?? 0);
3108 }
3109
3110 $this->_fld_changes = $changed;
3111
3112 return $changed;
3113 }
3114
3120 public function get_rid() {
3121 $empty = array();
3122 $rid = dbx()->get_modul_var('rid', -1, 'int');
3123 $dbx_view = $this->_dbx_view;
3124 $dbx_modul = $this->_dbx_modul;
3125
3126 if ($dbx_view) {
3127 $viewsys = dbx()->get_session_var($dbx_view, $empty, 'view-sys', $dbx_modul);
3128
3129 if (isset($viewsys['value'])) {
3130 $rid = $viewsys['value'];
3131 }
3132 }
3133
3134 $this->_rid = (int) $rid;
3135 $this->set_state_value('rid', (int) $rid);
3136
3137 return (int) $rid;
3138 }
3139
3147 public function view_sync($rid) {
3148 $empty = array();
3149 $dbx_view = $this->_dbx_view;
3150 $dbx_modul = $this->_dbx_modul;
3151
3152 if ($dbx_view) {
3153 $viewsys = dbx()->get_session_var($dbx_view, $empty, 'view-sys', $dbx_modul);
3154 $viewsys['value'] = $rid;
3155 dbx()->set_session_var($dbx_view, $viewsys, 'view-sys', $dbx_modul);
3156 }
3157 }
3158
3168 public function wait() {
3169 $wait = 0;
3170 $tpl = $this->_tpl;
3171
3172 if (strpos((string) $tpl, '_wait') !== false) {
3173 $wait = 1;
3174 }
3175
3176 return $wait;
3177 }
3178
3192 public function set_post($key, $val) {
3193 if ($key != 'form-dd-field') {
3194 $this->_post[$key] = $val;
3195 }
3196
3197 $this->_fld_changes = -1;
3198 }
3199
3225 public function save_post($dd, $rid, $pv = '', $reread = 1) {
3226 $ok = 0;
3227
3228 if ($rid === 'new') {
3229 $rid = 0;
3230 }
3231
3232 if (is_array($pv)) {
3233 foreach ($pv as $key => $value) {
3234 $this->_post[$key] = $value;
3235 $this->_data[$key] = $value;
3236 }
3237 }
3238
3239 if ($rid) {
3240 $this->_rid = (int) $rid;
3241 }
3242
3243 $rid = (int) $this->_rid;
3244 $post = $this->_post;
3245
3246 $this->oDB->_fld_id = $this->_fld_id;
3247 $ok = $this->oDB->save($dd, $post, $rid);
3248
3249 if (!$ok) {
3250 dbx()->debug("DB-Error=(" . $this->oDB->_error . ")\nQuery=(" . $this->oDB->_query . ")");
3251 $this->set_form_saved(false);
3252 return $ok;
3253 }
3254
3255 if (!$rid) {
3256 $rid = (int) $this->oDB->_insert_id;
3257 $this->_rid = $rid;
3258 }
3259
3260 if ($rid > 0) {
3261 $this->set_state_value('rid', $rid);
3262 }
3263
3264 if ($rid && $ok && $reread) {
3265 $new = $this->oDB->select1($dd, $rid);
3266
3267 if (is_array($new)) {
3268 foreach ($new as $key => $value) {
3269 $this->_data[$key] = $value;
3270 }
3271
3272 $this->_reload_run = 1;
3273
3274 foreach ($this->_flds as $no => $fld) {
3275 $key = $fld['name'] ?? '';
3276
3277 if ($key !== '' && array_key_exists($key, $this->_data)) {
3278 $this->_flds[$no]['value'] = $this->_data[$key];
3279 $this->_flds[$no]['origin'] = 'reload';
3280 $this->_flds[$no]['verify'] = 1;
3281 $this->_flds[$no]['error'] = 0;
3282 }
3283 }
3284 }
3285 }
3286
3287 $this->set_form_saved(true);
3288 $this->set_form_complete(true);
3289 $this->set_form_valid(true);
3290 $this->bump_form_version();
3291 $this->store_workflow_state();
3292
3293 dbx()->debug("#DD FORM-save# Tab=($dd) rid=($rid)");
3294
3295 return $ok;
3296 }
3297
3305 public function next_i($add = 1) {
3306 $i = $this->_next_i;
3307
3308 if (!$i) {
3309 $i = dbx()->next_id($add);
3310 $this->_next_i = $i;
3311 }
3312
3313 $this->add_rep('i', $i);
3314
3315 return $i;
3316 }
3317
3326 public function set_fld_val($fld_name, $fld_val) {
3327 $this->_data[$fld_name] = $fld_val;
3328 $this->_sys[$fld_name] = $fld_val;
3329
3330 if (isset($this->_flds[$fld_name])) {
3331 $this->_flds[$fld_name]['value'] = $fld_val;
3332 $this->_flds[$fld_name]['origin'] = 'set';
3333 $this->_flds[$fld_name]['verify'] = 1;
3334 }
3335 }
3336
3343 protected function add_default_search_rep(array $overrides = array()) {
3344 $this->add_rep('dbx_search', dbx()->search_html(dbx()->search_defaults(array_merge(array(
3345 'extra_attrs' => 'data-dbx="grid-search"',
3346 ), $overrides))));
3347 }
3348
3349 private function is_search_field_tpl($tpl): bool {
3350 $tpl = strtolower(trim((string) $tpl));
3351
3352 return $tpl === 'dbx|search' || $tpl === 'search' || substr($tpl, -7) === '|search';
3353 }
3354
3363 private function prepare_report_search_fld($name, &$tpl, array &$data): void {
3364 if ($name !== 'dbx_rwhere') {
3365 return;
3366 }
3367
3368 $tpl = 'dbx|search';
3369 $defaults = dbx()->search_defaults();
3370
3371 $data['label'] = '';
3372 $data['placeholder'] = $defaults['placeholder'];
3373 $data['title'] = trim((string) ($data['tooltip'] ?? '')) !== ''
3374 ? (string) $data['tooltip']
3375 : $defaults['title'];
3376 $data['input_class'] = $defaults['input_class'];
3377 $data['wrap_class'] = $defaults['wrap_class'];
3378 $data['data_role'] = $defaults['data_role'];
3379 $data['extra_attrs'] = $defaults['extra_attrs'];
3380 }
3381
3397 public function create_fld($fld, $i = 0) {
3398 if (!$i) {
3399 $i = $this->_next_i;
3400 }
3401
3402 if (!($fld['verify'] ?? 0)) {
3403 $fld = $this->check_fld_data($this->submit(), $fld);
3404 }
3405
3406 $tpl = $fld['tpl'] ?? '';
3407 $data = is_array($fld['data'] ?? null) ? $fld['data'] : array();
3408 $options = is_array($fld['options'] ?? null) ? $fld['options'] : array();
3409 $fld_value = $fld['value'] ?? '';
3410 $error = (int) ($fld['error'] ?? 0);
3411 $name = $fld['name'] ?? '';
3412
3413 if ($error) {
3414 $data['class'] = trim(($data['class'] ?? '') . ' fld-error');
3415
3416 if (!isset($data['errormsg']) || $data['errormsg'] === '') {
3417 $data['errormsg'] = 'Eingabe bitte prüfen !';
3418 }
3419 } else {
3420 $data['errormsg'] = '';
3421 }
3422
3423 if (!is_array($fld_value)) {
3424 $fld_value = htmlspecialchars((string) $fld_value, ENT_QUOTES, 'UTF-8');
3425
3426 if (!isset($data['checked']) && $fld_value !== '' && $fld_value !== '0') {
3427 $data['checked'] = 'checked';
3428 }
3429 }
3430 if (!isset($data['checked'])) {
3431 $data['checked'] = '';
3432 }
3433
3434 // dbxForm validates submitted data itself; native HTML5 required would
3435 // mark empty fields invalid before submit and can block the request.
3436 $required = '';
3437
3438 $data['required'] = $required;
3439 $data['class'] = $data['class'] ?? '';
3440 $data['style'] = $data['style'] ?? '';
3441 $data['tooltip'] = $data['tooltip'] ?? '';
3442 $data['errormsg'] = $data['errormsg'] ?? '';
3443
3444 foreach (array('placeholder') as $htmlKey) {
3445 if (isset($data[$htmlKey]) && !is_array($data[$htmlKey])) {
3446 $data[$htmlKey] = htmlspecialchars((string)$data[$htmlKey], ENT_QUOTES, 'UTF-8');
3447 }
3448 }
3449
3450 foreach (array('tooltip', 'errormsg') as $htmlAttributeKey) {
3451 if (isset($data[$htmlAttributeKey]) && !is_array($data[$htmlAttributeKey])) {
3452 $data[$htmlAttributeKey] = htmlspecialchars(str_replace('"', "'", (string)$data[$htmlAttributeKey]), ENT_QUOTES, 'UTF-8');
3453 }
3454 }
3455
3456 $this->prepare_report_search_fld($name, $tpl, $data);
3457
3458 if ($this->is_search_field_tpl($tpl)) {
3459 $tpl = dbx()->search_html(dbx()->search_defaults(array(
3460 'name' => $name,
3461 'value' => is_array($fld_value) ? '' : (string) $fld_value,
3462 'placeholder' => (string) ($data['placeholder'] ?? ''),
3463 'title' => (string) ($data['title'] ?? $data['tooltip'] ?? ''),
3464 'tooltip' => (string) ($data['tooltip'] ?? $data['title'] ?? ''),
3465 'errormsg' => (string) ($data['errormsg'] ?? ''),
3466 'class' => (string) ($data['class'] ?? ''),
3467 'input_class' => (string) ($data['input_class'] ?? ''),
3468 'wrap_class' => (string) ($data['wrap_class'] ?? ''),
3469 'wrap_style' => (string) ($data['wrap_style'] ?? ($data['style'] ?? '')),
3470 'data_role' => (string) ($data['data_role'] ?? ''),
3471 'extra_attrs' => (string) ($data['extra_attrs'] ?? ''),
3472 'label' => (string) ($data['label'] ?? ''),
3473 'style' => (string) ($data['style'] ?? ''),
3474 'i' => $i,
3475 )));
3476 } else {
3477 $tpl = $this->get_tpl($tpl, $data);
3478 }
3479
3480 if (is_array($options)) {
3481 $xoptions = '';
3482 $oid = $name . '_options';
3483 $options_vals = $fld_value;
3484
3485 if (!is_array($options_vals)) {
3486 $options_vals = explode(',', (string) $options_vals);
3487 }
3488
3489 $selected_lookup = array();
3490 foreach ($options_vals as $keyval) {
3491 $selected_lookup[(string) $keyval] = true;
3492 }
3493
3494 foreach ($options as $key => $description) {
3495 $selected = isset($selected_lookup[(string) $key]) ? 'selected' : '';
3496
3497 $xoptions .= '<option value="' . htmlspecialchars((string) $key, ENT_QUOTES, 'UTF-8') . '" ' . $selected . '>' .
3498 htmlspecialchars((string) $description, ENT_QUOTES, 'UTF-8') .
3499 "</option>\n";
3500 }
3501
3502 $tpl = str_replace('{' . $oid . '}', $xoptions, $tpl);
3503 }
3504
3505 $tpl = $this->oTPL->replaces($tpl, $this->_replaces);
3506
3507 if (!is_array($fld_value)) {
3508 $tpl = str_replace('{src}', $fld_value, $tpl);
3509 $tpl = str_replace('{value}', $fld_value, $tpl);
3510 }
3511
3512 $tpl = dbx()->norep($tpl, $i);
3513
3514 $field_markers = $this->get_field_editor_markers();
3515
3516 if ($field_markers !== '') {
3517 $tpl = $field_markers . $tpl;
3518 }
3519
3520 return $tpl;
3521 }
3522
3542 public function merge_fld_data($content, $i = 0) {
3543 $form = '';
3544 $editor = dbx()->get_system_var('dbx_editor', 0, 'int');
3545
3546 if (!$i && !$editor) {
3547 $i = $this->_next_i;
3548 }
3549
3550 foreach ($this->_flds as $fld_name => $fld) {
3551 $slot = $fld_name;
3552
3553 if (!empty($fld['remap'])) {
3554 $slot = $fld['remap'];
3555 }
3556
3557 $fid = '{obj:' . $slot . '}';
3558 $fld_content = $this->create_fld($fld, $i);
3559
3560 if (strpos($content, $fid) !== false) {
3561 $content = str_replace($fid, $fld_content, $content);
3562 } else {
3563 $form .= $fld_content . "\n";
3564 }
3565 }
3566
3567 if (strpos($content, '[dbx:form]') !== false) {
3568 $content = str_replace('[dbx:form]', $form, $content);
3569 } else {
3570 $content = str_replace('</form>', $form . '</form>', $content);
3571 }
3572
3573 return $content;
3574 }
3575
3585 public function check_try_count($submit, $errors, $allways = 1) {
3586 $content = '';
3587 $clear = 0;
3588 $reset = $this->_try_reset;
3589 $max = $this->_try_max;
3590 $msg = $this->_try_msg;
3591 $now = dbx()->timestamp();
3592 $self = dbx()->get_self_url();
3593 $ip = (string)($_SERVER['REMOTE_ADDR'] ?? '');
3594 $sys = isset($this->_sys['_try_sys']) ? $this->_sys['_try_sys'] : array();
3595
3596 if (($sys['dbx_try_ip'] ?? '') !== $ip) {
3597 $sys = array(
3598 'dbx_try_ip' => $ip,
3599 );
3600 }
3601
3602 $sys['dbx_try_count'] = $sys['dbx_try_count'] ?? 0;
3603 $sys['dbx_run_count'] = $sys['dbx_run_count'] ?? 0;
3604 $sys['dbx_try_lock'] = $sys['dbx_try_lock'] ?? 0;
3605 $sys['dbx_try_ip'] = $ip;
3606
3607 $sys['dbx_run_count']++;
3608
3609 if ($submit) {
3610 if ($errors) {
3611 $sys['dbx_try_first'] = $sys['dbx_try_first'] ?? $now;
3612 $sys['dbx_try_last'] = $now;
3613 $sys['dbx_try_count']++;
3614
3615 if ($sys['dbx_try_count'] >= $max) {
3616 if (!isset($sys['dbx_try_stop'])) {
3617 $sys['dbx_try_lock']++;
3618
3619 for ($i = 1; $i < $sys['dbx_try_lock']; $i++) {
3620 $reset = (int) ($reset * 2);
3621 }
3622
3623 $sys['dbx_try_stop'] = $now;
3624 $sys['dbx_try_run'] = dbx()->timestamp($reset);
3625 }
3626 }
3627
3628 if (isset($sys['dbx_try_run']) && $now > $sys['dbx_try_run']) {
3629 $clear = 1;
3630 }
3631 } else {
3632 $clear = 1;
3633 }
3634 }
3635
3636 if (($submit || $allways) && !$clear) {
3637 if (($sys['dbx_try_count'] ?? 0) >= $max && ($sys['dbx_try_run'] ?? 0) > 0) {
3638 $diff = dbx()->time_diff($now, $sys['dbx_try_run']);
3639
3640 if ($diff > 0) {
3641 $data = array(
3642 'sec' => (int) $diff,
3643 'self' => $self,
3644 'try_count' => $sys['dbx_try_count'],
3645 'run_count' => $sys['dbx_run_count'],
3646 );
3647 $data['msg'] = $this->oTPL->replaces((string) $msg, $data);
3648
3649 $content = $this->get_tpl($this->_tpl_max_try, $data);
3650 } else {
3651 $clear = 1;
3652 }
3653 }
3654 }
3655
3656 if ($clear) {
3657 unset($sys['dbx_try_stop'], $sys['dbx_try_run']);
3658 $sys['dbx_try_count'] = 0;
3659 }
3660
3661 $this->_sys['_try_sys'] = $sys;
3662
3663 return $content;
3664 }
3665
3683 public function forward_run() {
3684 $content = '';
3685 $editor = dbx()->get_system_var('dbx_editor', 0, 'int');
3686
3687 $this->evaluate_request();
3688
3689 $submit = $this->submit();
3690 $errors = $this->errors();
3691
3692 $content = $this->check_try_count($submit, $errors, 1);
3693
3694 if (!$content) {
3695 $i = $this->next_i();
3696 $this->_next_i = $i;
3697
3698 $this->buildModuleBarObj();
3699 $this->prepareFormFrameReplaces($i);
3700
3701 $replaces = $this->_replaces;
3702 $replaces['form-id'] = $this->_dbx_modul . '-' . $this->_fid;
3703 foreach (array('form_shell_class' => '', 'form_class' => '', 'form_attrs' => '') as $shellKey => $shellDefault) {
3704 if (!isset($replaces[$shellKey]) || (string)$replaces[$shellKey] === '') {
3705 $replaces[$shellKey] = $shellDefault;
3706 }
3707 }
3708 foreach (array('shell_panel_class' => '', 'shell_panel_attrs' => '', 'shell_body_class' => '') as $shellKey => $shellDefault) {
3709 if (!isset($replaces[$shellKey]) || (string)$replaces[$shellKey] === '') {
3710 $replaces[$shellKey] = $shellDefault;
3711 }
3712 }
3713
3714 $content = $this->get_tpl('modul|' . $this->_tpl, $replaces, 'htm', $i);
3715 $content = $this->merge_tpl_data($content, $i);
3716 $content = $this->merge_fld_data($content, $i);
3717 $content = $this->merge_obj($content, $i);
3718
3719 $form_msg = '';
3720
3721 if ($submit) {
3722 if ($this->errors()) {
3723 $form_msg = $this->get_form_msg('error', $this->_msg_error);
3724 } elseif ($this->warnings()) {
3725 $form_msg = $this->get_form_msg('warning', $this->_msg_warning);
3726 } else {
3727 $form_msg = $this->get_form_msg('success', $this->_msg_success);
3728 }
3729 } else {
3730 $form_msg = $this->get_form_msg('info', $this->_msg_info);
3731 }
3732
3733 $content = str_replace('{obj:form_msg}', $form_msg, $content);
3734
3735 $norep_ids = '';
3736
3737 if (is_array($this->_js)) {
3738 foreach ($this->_js as $javascript) {
3739 $javascript = str_replace('{i}', $this->_next_i, $javascript);
3740 $norep = '<script>' . $javascript . '</script> ';
3741 $norep_ids .= dbx()->norep($norep, $i);
3742 }
3743 }
3744
3745 $content = str_replace('[dbx:js]', $norep_ids, $content);
3746
3747 if (!$editor && $content && $i) {
3748 $content = str_replace('{i}', $i, $content);
3749 }
3750 }
3751
3752 $content = $this->callback('run', $content);
3753
3754 $this->store_sysdata();
3755 $this->store_workflow_state();
3756
3757 return $this->add_editor_markers($content);
3758 }
3759
3768 protected function resolve_fd_dd_editor_file(string $source): string {
3769 $source = trim($source);
3770
3771 if ($source === '') {
3772 return '';
3773 }
3774
3775 $mod = 'dd';
3776 $name = $source;
3777
3778 foreach (array('cfg:', 'def:', 'mod:', 'fd:', 'dd:') as $prefix) {
3779 if (strpos($source, $prefix) === 0) {
3780 $mod = substr($prefix, 0, -1);
3781 $name = substr($source, strlen($prefix));
3782 break;
3783 }
3784 }
3785
3786 if ($mod === 'dd' && strpos($source, '|') !== false) {
3787 $mod = 'fd';
3788 $name = $source;
3789 }
3790
3791 if ($mod === 'dd') {
3792 if (method_exists($this->oDB, 'get_dd_file')) {
3793 return (string) $this->oDB->get_dd_file($name);
3794 }
3795
3796 $modul = $this->_dbx_modul ? $this->_dbx_modul : dbx()->get_system_var('dbx_activ_modul', 'dbx');
3797
3798 return dbx_get_base_dir() . "dbx/modules/$modul/dd/$name.dd.php";
3799 }
3800
3801 $dd_file = '';
3802
3803 switch ($mod) {
3804 case 'cfg':
3805 $dd_file = dbx_get_base_dir() . "dbx/modules/$name/cfg/config.dd.php";
3806 break;
3807
3808 case 'def':
3809 $dd_file = dbx_get_base_dir() . "dbx/modules/$name/dd/$name.dd.php";
3810 break;
3811
3812 case 'mod':
3813 $modul = dbx()->get_system_var('dbx_activ_modul', 'dbx');
3814 $dd_file = dbx_get_base_dir() . "dbx/modules/$modul/dd/$name.dd.php";
3815 break;
3816
3817 case 'fd':
3818 $fd_modul = $this->_dbx_modul ? $this->_dbx_modul : dbx()->get_system_var('dbx_activ_modul', 'dbx');
3819 $fd_name = $name;
3820
3821 if (strpos($name, '|') !== false) {
3822 $parts = explode('|', $name, 2);
3823 $fd_modul = trim($parts[0]);
3824 $fd_name = trim($parts[1]);
3825 }
3826
3827 if ($fd_modul === '') {
3828 $fd_modul = dbx()->get_system_var('dbx_activ_modul', 'dbx');
3829 }
3830
3831 $dd_file = function_exists('dbx_lng_resolve_file')
3832 ? dbx_lng_resolve_file(
3833 dbx_get_base_dir() . "dbx/modules/$fd_modul/fd/",
3834 $fd_name,
3835 'fd.php',
3836 $this->_dbx_lng,
3837 true
3838 )
3839 : dbx_get_base_dir() . "dbx/modules/$fd_modul/fd/$fd_name.fd.php";
3840 if ($dd_file === '' || !is_file($dd_file)) {
3841 $dd_file = dbx_get_base_dir() . "dbx/modules/$fd_modul/fd/$fd_name.fd.php";
3842 }
3843 break;
3844 }
3845
3846 if ($dd_file === '') {
3847 return '';
3848 }
3849
3850 $real_file = realpath(dbx_os_path_file($dd_file));
3851
3852 return $real_file ? $real_file : $dd_file;
3853 }
3854
3860 protected function get_field_editor_markers(): string {
3861 $markers = '';
3862
3863 foreach (array('fd' => $this->_fd, 'dd' => $this->_dd) as $kind => $source) {
3864 $file = $this->resolve_fd_dd_editor_file($source);
3865
3866 if ($file === '') {
3867 continue;
3868 }
3869
3870 $marker = dbx()->editor_marker($kind, $file);
3871
3872 if ($marker !== '' && strpos($markers, trim($marker)) === false) {
3873 $markers .= $marker;
3874 }
3875 }
3876
3877 return $markers;
3878 }
3879
3888 public function init($fid, $tpl = '') {
3889 $this->forward_init($fid, $tpl);
3890 }
3891
3897 public function run() {
3898 return $this->forward_run();
3899 }
3900
3901 /* =====================================================
3902 * WORKFLOW / REMEMBER STATE
3903 * ===================================================== */
3904
3923 public function set_workflow_scope(string $scope) {
3924 $this->_workflow_scope = trim($scope);
3925 $this->load_workflow_state();
3926 }
3927
3933 public function get_workflow_scope(): string {
3934 return $this->_workflow_scope;
3935 }
3936
3944 private function normalize_state_token(string $token): string {
3945 $token = trim($token);
3946
3947 if ($token === '') {
3948 return 'undef';
3949 }
3950
3951 return preg_replace('/[^a-zA-Z0-9._-]+/', '_', $token);
3952 }
3953
3969 public function get_workflow_state_key(): string {
3970 $modul = $this->normalize_state_token((string) $this->_dbx_modul);
3971 $scope = $this->normalize_state_token((string) $this->_workflow_scope);
3972 $fid = $this->normalize_state_token((string) $this->_fid);
3973
3974 return 'dbx.form.state.' . $modul . '.' . $scope . '.' . $fid;
3975 }
3976
3982 private function get_default_workflow_state(): array {
3983 return array(
3984 'rid' => 0,
3985 'draft_id' => '',
3986 'is_complete' => 0,
3987 'is_valid' => 0,
3988 'is_locked' => 0,
3989 'is_saved' => 0,
3990 'version' => 0,
3991 'depends_on' => array(),
3992 'depends_version' => array(),
3993 );
3994 }
3995
4001 public function load_workflow_state(): array {
4002 $key = $this->get_workflow_state_key();
4003 $state = dbx()->get_remember_var($key, $this->get_default_workflow_state(), 'dbx');
4004
4005 if (!is_array($state)) {
4006 $state = $this->get_default_workflow_state();
4007 }
4008
4009 $this->_workflow_state = array_merge($this->get_default_workflow_state(), $state);
4010
4011 if ((int) ($this->_workflow_state['rid'] ?? 0) > 0 && !$this->_rid) {
4012 $this->_rid = (int) $this->_workflow_state['rid'];
4013 }
4014
4015 return $this->_workflow_state;
4016 }
4017
4023 public function store_workflow_state() {
4024 $key = $this->get_workflow_state_key();
4025 dbx()->set_remember_var($key, $this->_workflow_state, 'dbx');
4026 }
4027
4033 public function clear_workflow_state() {
4034 $this->_workflow_state = $this->get_default_workflow_state();
4035 $this->store_workflow_state();
4036 }
4037
4046 public function set_state_value(string $key, $value) {
4047 $this->_workflow_state[$key] = $value;
4048 $this->store_workflow_state();
4049 }
4050
4059 public function get_state_value(string $key, $default = null) {
4060 if (!array_key_exists($key, $this->_workflow_state)) {
4061 $this->load_workflow_state();
4062 }
4063
4064 return $this->_workflow_state[$key] ?? $default;
4065 }
4066
4080 public function get_draft_id(bool $createIfMissing = false): string {
4081 $draftId = (string) $this->get_state_value('draft_id', '');
4082
4083 if ($draftId === '' && $createIfMissing) {
4084 $draftId = $this->create_draft_id();
4085 $this->set_state_value('draft_id', $draftId);
4086 }
4087
4088 return $draftId;
4089 }
4090
4098 public function set_draft_id(string $draftId) {
4099 $this->set_state_value('draft_id', $draftId);
4100 }
4101
4107 private function create_draft_id(): string {
4108 return 'dft_' . md5($this->_dbx_modul . '|' . $this->_fid . '|' . microtime(true) . '|' . mt_rand());
4109 }
4110
4118 public function set_form_valid(bool $state) {
4119 $this->set_state_value('is_valid', $state ? 1 : 0);
4120 }
4121
4127 public function is_form_valid(): bool {
4128 return ((int) $this->get_state_value('is_valid', 0) === 1);
4129 }
4130
4138 public function set_form_complete(bool $state) {
4139 $this->set_state_value('is_complete', $state ? 1 : 0);
4140 }
4141
4147 public function is_form_complete(): bool {
4148 return ((int) $this->get_state_value('is_complete', 0) === 1);
4149 }
4150
4158 public function set_form_locked(bool $state) {
4159 $this->set_state_value('is_locked', $state ? 1 : 0);
4160 }
4161
4167 public function is_form_locked(): bool {
4168 return ((int) $this->get_state_value('is_locked', 0) === 1);
4169 }
4170
4178 public function set_form_saved(bool $state) {
4179 $this->set_state_value('is_saved', $state ? 1 : 0);
4180 }
4181
4187 public function is_form_saved(): bool {
4188 return ((int) $this->get_state_value('is_saved', 0) === 1);
4189 }
4190
4196 public function get_form_version(): int {
4197 return (int) $this->get_state_value('version', 0);
4198 }
4199
4210 public function bump_form_version(): int {
4211 $version = $this->get_form_version() + 1;
4212 $this->set_state_value('version', $version);
4213 return $version;
4214 }
4215
4229 public function set_dependencies(array $formIds) {
4230 $deps = array();
4231
4232 foreach ($formIds as $formId) {
4233 $deps[] = $this->normalize_state_token((string) $formId);
4234 }
4235
4236 $this->set_state_value('depends_on', $deps);
4237 }
4238
4251 public function remember_current_dependencies(?array $formIds = null) {
4252 if ($formIds === null) {
4253 $formIds = $this->get_state_value('depends_on', array());
4254 }
4255
4256 $versions = array();
4257
4258 foreach ($formIds as $formId) {
4259 $state = $this->get_external_form_state((string) $formId);
4260 $versions[$formId] = (int) ($state['version'] ?? 0);
4261 }
4262
4263 $this->set_state_value('depends_version', $versions);
4264 }
4265
4276 public function dependencies_are_current(): bool {
4277 $dependsOn = $this->get_state_value('depends_on', array());
4278 $dependsVersion = $this->get_state_value('depends_version', array());
4279
4280 if (!is_array($dependsOn) || !$dependsOn) {
4281 return true;
4282 }
4283
4284 foreach ($dependsOn as $formId) {
4285 $state = $this->get_external_form_state((string) $formId);
4286 $currentVersion = (int) ($state['version'] ?? 0);
4287 $savedVersion = (int) ($dependsVersion[$formId] ?? -1);
4288
4289 if ($currentVersion !== $savedVersion) {
4290 return false;
4291 }
4292
4293 if ((int) ($state['is_valid'] ?? 0) !== 1) {
4294 return false;
4295 }
4296 }
4297
4298 return true;
4299 }
4300
4308 public function get_external_form_state(string $fid): array {
4309 $modul = $this->normalize_state_token((string) $this->_dbx_modul);
4310 $scope = $this->normalize_state_token((string) $this->_workflow_scope);
4311 $fid = $this->normalize_state_token($fid);
4312
4313 $key = 'dbx.form.state.' . $modul . '.' . $scope . '.' . $fid;
4314 $state = dbx()->get_remember_var($key, $this->get_default_workflow_state(), 'dbx');
4315
4316 return is_array($state) ? $state : $this->get_default_workflow_state();
4317 }
4318
4324 public function refresh_dependency_lock(): bool {
4325 $locked = !$this->dependencies_are_current();
4326 $this->set_form_locked($locked);
4327 return $locked;
4328 }
4329}
4330
4331?>
$table['server']
Definition .dd.php:6
$indexes[]
Definition .dd.php:167
$_ajax
AJAX-fähiges Formular.
$_reload_run
1 = Reload wurde ausgeführt
load_workflow_state()
Lädt den Remember-basierten Workflow-State.
$_tpl_form_info
Template für Info-Meldungen.
get_quartal($datum)
Platzhalter-Helfer.
get_activ_id($key='')
Liefert die aktive Remember-ID des aktuellen DD-Kontexts.
clear_workflow_state()
Löscht den Workflow-State.
is_form_complete()
Gibt zurück, ob das Formular als vollständig markiert ist.
$_tpl_form_error
Template für Fehlermeldungen.
dependencies_are_current()
Prüft, ob die gespeicherten Dependency-Versionen noch aktuell sind.
view_sync($rid)
Synchronisiert eine RID in den View-State.
$_dbx_action
Aktive DBX-Aktion.
add_fld($name, $tpl='fd::', $label='fd::', $rules='fd::', $class='fd::', $data='fd::', $options='fd::', $tooltip='fd::', $placeholder='fd::', $errormsg='fd::', $dd='fd::', $remap='fd::')
Fügt ein Feld zur Formular-Definition hinzu.
$_errors
Feld-/Formfehler.
create_fld($fld, $i=0)
Erzeugt HTML für ein Feld.
$_tpl_form_warning
Template für Warnmeldungen.
forward_submit()
Gibt zurück, ob das Formular abgesendet wurde.
update_error_fld($name, $msg)
Markiert ein Feld mit Fehlerstatus.
$_tpl_fld_error
Template für Feld-Fehler.
$_fld_id
Primärschlüsselfeld.
$_action
Formular-Action.
$_create_flds
1 = Felder sollen erzeugt werden
set_draft_id(string $draftId)
Setzt die Draft-ID explizit.
$_dbx_modul
Aktives Modul.
$_general_error
Allgemeiner Fehlertext.
set_dependencies(array $formIds)
Setzt die Abhängigkeiten dieses Formulars.
$_try_max
Maximale Fehlversuche.
load_sysdata()
Lädt Sysdata des Formulars.
php_date_usr($value)
Wandelt Datumswerte in deutsches Format um.
store_workflow_state()
Speichert den Workflow-State.
$_fid
Formular-ID.
$_msg_error
Standard-Fehlertext.
__construct($id='', $tpl='')
Initialisiert Validator, TPL und DB-Service.
add_js_code($javascript)
Fügt JS-Code hinzu.
get_state_value(string $key, $default=null)
Liest einen Wert aus dem Workflow-State.
set_msg_ok($msg)
Setzt die Formular-Erfolgsmeldung.
$oValidator
Zentraler Validator.
$_infos
Info-Meldungen.
get_draft_id(bool $createIfMissing=false)
Gibt die Draft-ID zurück, optional mit automatischer Erzeugung.
init($fid, $tpl='')
Öffentliche Init-Methode.
add_editor_markers(string $content)
Fuegt passende Editor-Marker um den gerenderten Formularinhalt.
set_msg_error($msg)
Setzt die Formular-Fehlermeldung.
$_dbx_lng
Aktive Sprache.
$_next_i
Laufende Formularinstanz-ID.
set_run_callback(string $callback)
defaultModuleBarReplaces()
$_reload_transform
Historischer Reload-Transform-Flag.
$_dbx_page
Aktive Seite.
next_i($add=1)
Liefert oder erzeugt die laufende Formularinstanz-ID.
php_date($value)
Wandelt Datumswerte in DB-Format um.
buildModuleBarFormActionsHtml()
$_msg_success
Standard-Erfolgstext.
$_warnings
Warnungen.
add_module_bar($title, $icon='bi-grid', $subtitle='')
fast_response($response, $interpreter=0)
Sendet eine direkte Fast-Response.
$_editor_class_file
Modul-/Include-Class-Datei fuer den Frontend-Editor.
wait()
Historischer Wait-Check.
$_fld_change_state
Feldmodus fuer die Changed-Logik: fld oder *.
$_msg_info
Standard-Infotext.
warnings()
Gibt die Anzahl der Warnungen zurück.
$_form_submit
-1 = unbekannt, 0 = nein, 1 = ja
add_norep($content)
Ersetzt norep-Platzhalter.
store_sysdata()
Speichert Sysdata des Formulars.
add_default_search_rep(array $overrides=array())
Standard-Suchfeld fuer Grid-Toolbars ({dbx_search}).
$_workflow_scope
Workflow-Scope für Remember-State.
is_form_saved()
Gibt zurück, ob das Formular bereits gespeichert wurde.
$_tpl_form_success
Template für Erfolgsmeldungen.
merge_fld_data($content, $i=0)
Fügt Felder in den Template-Inhalt ein.
$_reload_record
1 = Datensatz nach Save neu lesen
obv_value($content, $id, $value)
Historische obv-Hilfe.
set_form_locked(bool $state)
Setzt den Lock-Status des Formulars.
$_dbx_work
Optionaler Work-Kontext.
$_data
Aktuelle Formulardaten / Record-Daten.
check_fld_data($submit, $fld)
Prüft ein einzelnes Feld und baut seinen Laufzustand auf.
add_action($obj, $tpl, $action='', $data='')
Fügt ein Objekt hinzu, dessen Action aus _action abgeleitet wird.
set_form_complete(bool $state)
Setzt den Vollständigkeitsstatus des Formulars.
$_css
CSS-Dateien oder Marker.
$_dbx_view
Optionaler View-Schlüssel.
$_js
JS-Code-Blöcke.
get_post_data($name, $default='', $rules='parameter')
Liest POST/GET-Daten mit Default-Rules parameter.
add_js_call($target, $function, $args='')
Fügt einen einfachen JS-Aufruf hinzu.
is_form_locked()
Gibt zurück, ob das Formular gesperrt ist.
merge_tpl_data($tpl, $i=0)
Führt grundlegende Form-Replaces in Templates aus.
$_editor_files
Dateien, die fuer den Frontend-Editor markiert werden.
add_fld_error($name, $msg='')
Fügt einen Feldfehler hinzu.
set_workflow_scope(string $scope)
Setzt einen Workflow-Scope.
set_init_callback(string $callback)
get_workflow_scope()
Gibt den Workflow-Scope zurück.
prepareFormFrameReplaces(int $i)
$_page_reset
Historischer Page-Reset-Flag.
set_editor_class_file(string $file)
Merkt sich die geladene Modul-/Include-Class fuer den Frontend-Editor.
is_form_valid()
Gibt zurück, ob das Formular als gültig markiert ist.
refresh_dependency_lock()
Markiert das Formular aufgrund veralteter Abhängigkeiten als gesperrt.
$oTPL
Zentrale Template-Engine.
get_tpl($tpl, $data='', $type='htm', $i=0)
Wrapper auf dbxTPL->get_tpl().
prepare_form_shell(array $options=array())
get_field_editor_markers()
Erzeugt FD-/DD-Editor-Marker direkt am Feld-Slot.
$_sys
Form-interne Zustände / Sysdata.
$_rid
Aktuelle Record-ID.
$_activ_id
Optional aktive ID.
$_dbx_modul_id
Aktive Modul-ID.
$_fld_changes
Gecachter Changed-Wert.
get_form_msg($mode, $msg='')
Gibt die Formular-Infobox zurück.
$_fd
Optionale FD-Felddefinitionsquelle.
check_flds_data($submit)
Prüft alle Felder des Formulars genau einmal pro Request-Zyklus.
$_form_validate
-1 = noch nicht ausgewertet, 1 = ausgewertet
add_fld_warning($name, $msg='')
Fügt eine Feldwarnung hinzu.
$_module_bar_form_actions
Optionen fuer Standard-Aktionen in der Modul-Bar.
$_store_mode
Aktueller Sysdata-Speichermodus.
forward_init($fid, $tpl='')
Initialisiert den Form-Kontext.
$_tpl
Template-Name.
attachAdminHelpButton($topic='')
$_dbx_design
Aktives Design.
forward_run()
Führt die Ausgabephase aus.
submit()
Öffentliche Submit-Abfrage.
$oDB
Zentraler DB-/DD-Service.
set_post($key, $val)
Setzt einen _post-Wert manuell.
get_fld_id($fld)
Extrahiert den Feldnamen aus HTML.
get_workflow_state_key()
Baut den Remember-Schlüssel für den Form-Workflow-State.
$_reload_suffix
Historischer Reload-Suffix.
add_obj($obj, $tpl, $data='', $data2='')
Fügt ein {obj:*}-Objekt hinzu.
$_tpl_fld_warning
Template für Feld-Warnung.
set_form_callback_owner($owner)
merge_obj($content, $i=0)
Ersetzt {obj:*}-Platzhalter.
add_editor_file(string $kind, string $file)
Registriert eine genutzte FD-/DD-/Class-Datei fuer Editor-Marker.
clear()
Öffentlicher Reset-Einstieg.
url_to_array($data)
Wandelt Query-/URL-Daten in ein Array um.
$_workflow_state
Remember-basierter Form-Status.
get_fld_msg($mode, $msg='')
Gibt eine Feldmeldung zurück.
$_confirm_copy
Optionaler Copy-Bestätigungstext.
get_external_form_state(string $fid)
Liest den Workflow-State eines anderen Formulars im selben Scope.
_forward_clear()
Setzt den internen Formularzustand zurück.
$_tpl_fld_info
Template für Feld-Info.
resolve_fd_dd_editor_file(string $source)
Liefert den absoluten Pfad einer FD-/DD-Quelle fuer Editor-Marker.
get_dd(string $dd, string $fld, string $var)
Liest einen Feldwert oder das ganze Feld aus einer DD-/FD-Quelle.
get_rid()
Liest die aktuelle RID, optional view-synchronisiert.
$_mode
tpl|php|mix
changed($changed=0)
Gibt die Anzahl geänderter Felder zurück.
get_fld_value($name, $default='', $rules='', $submit=-1)
$_try_msg
Sperr-Text.
set_msg_warning($msg)
Setzt die Formular-Warnmeldung.
set_form_valid(bool $state)
Setzt den Validitätsstatus des Formulars.
$_view_sync
Optionaler View-Sync-Status.
add_css($css='')
Fügt CSS hinzu.
set_form_saved(bool $state)
Setzt den Save-Status des Formulars.
set_activ_id($value, $key='')
Setzt die aktive Remember-ID des aktuellen DD-Kontexts.
run()
Öffentliche Run-Methode.
php_datetime_usr($value)
Wandelt Datums-/Zeitwerte in deutsches Format um.
errors()
Gibt die Anzahl der Fehler zurück.
add_module_bar_form_actions(array $options=array())
$_try_reset
Sekunden bis Try-Reset.
$_post
Validierte/geänderte POST-Werte.
set_fld_val($fld_name, $fld_val)
Setzt einen Feldwert direkt im Feldzustand.
__destruct()
Destruktor.
clear_sys()
Leert nur den Sysdata-Bereich.
$_confirm_delete
Optionaler Lösch-Bestätigungstext.
$_msg_warning
Standard-Warntext.
bump_form_version()
Erhöht die Formularversion um 1.
$_tpl_max_try
Template für Max-Try-Sperre.
set_state_value(string $key, $value)
Setzt einen Wert im Workflow-State.
remember_current_dependencies(?array $formIds=null)
Speichert die aktuell gültigen Versionsstände abhängiger Formulare.
check_try_count($submit, $errors, $allways=1)
Prüft Fehlversuche und baut ggf.
$_view_mode
Optionaler View-Modus.
$_flds
Felddefinitionen.
$_replaces
Allgemeine Replace-Werte.
set_submit_callback(string $callback)
add_rep($key, $val)
Fügt einen allgemeinen Replace-Wert hinzu.
$_tpl_fld_success
Template für Feld-Erfolg.
get_fld_val($name, $default='', $rules='', $submit=-1)
applyModuleBarReplaces(array $values=array())
add_flds($dd='fd::')
Fügt alle Felder der aktiven DD-/FD-Felddefinitionsquelle hinzu.
$_obj
Platzhalter-Objekte.
$_dd
Zugeordnetes DD.
save_post($dd, $rid, $pv='', $reread=1)
Speichert _post über dbxDB.
get_post($name, $default='', $rules='alphanum')
Liest POST/GET-Daten mit Default-Rules alphanum.
set_msg_info($msg)
Setzt die Formular-Info-Meldung.
$_editor_fld
Optionales Editor-Feld.
get_form_version()
Gibt die aktuelle Formularversion zurück.
Gemeinsame Basisklasse fuer dbXapp-System-, Modul- und Include-Objekte.
Definition dbxKernel.php:63
set_callback_id(string $id)
Setzt den Namenspraefix fuer konventionelle Callback-Methoden.
Definition dbxKernel.php:96
set_callback(string $event, string $callback)
Ordnet einem Event einen konkreten Methodennamen zu.
set_callback_owner($owner)
Setzt ein explizites Owner-Objekt fuer Callback-Aufrufe.
Definition dbxKernel.php:82
callback(string $event, mixed $value)
Fuehrt einen Callback aus und gibt dessen Rueckgabewert zurueck.
$fields[]
Definition config.dd.php:16
$field
Definition config.dd.php:4
dbx_os_path_file($path_file)
Definition index.php:164
exit
Definition index.php:532
if( $syncRequest)
Definition index.php:520
dbx_get_base_dir($cut_Data=0)
Definition index.php:157
$response
Definition index.php:518
DBX schema administration.
if(! $db->connect_db_server($server)) $result
$_SERVER['REQUEST_URI']
try
Definition run_job.php:204
foreach( $topics as $file=> $html)