379 public $_try_msg =
'Max {try_count} try. Suspend for {sec} seconds';
460 $this->oValidator =
dbx()->get_system_obj(
'dbxValidator');
461 $this->oTPL =
dbx()->get_system_obj(
'dbxTPL');
462 $this->
oDB =
dbx()->get_system_obj(
'dbxDB');
505 $this->
_sys = array();
567 $this->_reload_record = 0;
568 $this->_reload_run = 0;
570 $this->_obj = array();
571 $this->_js = array();
572 $this->_css = array();
573 $this->_flds = array();
575 $this->_infos = array();
576 $this->_errors = array();
577 $this->_validation_results = array();
578 $this->_warnings = array();
579 $this->_post = array();
580 $this->
_sys = array();
581 $this->_data = array();
582 $this->_replaces = array();
583 $this->_module_bar_form_actions = array();
584 $this->_form_help_button =
'';
585 $this->_form_help_enabled = 1;
587 $this->_fld_changes = -1;
588 $this->_form_submit = -1;
589 $this->_form_validate = -1;
590 $this->_general_error =
'';
591 $this->_msg_info =
'#form_msg_info#';
592 $this->_msg_success =
'#form_msg_success#';
593 $this->_msg_error =
'#form_msg_error#';
594 $this->_msg_warning =
'#form_msg_warning#';
599 $this->_fld_id =
'id';
600 $this->_callback_owner =
null;
601 $this->_callback_id =
'';
602 $this->_callbacks = array();
606 $this->_editor_files = array();
616 $this->_editor_class_file =
$file;
629 $kind = strtolower(trim($kind));
631 if (
$file ===
'' || $kind ===
'') {
635 $path =
dbx()->editor_file_path(
$file);
636 $key = $kind .
'|' . $path;
637 $this->_editor_files[$key] = array(
'kind' => $kind,
'file' => $path);
638 dbx()->register_editor_file($kind, $path);
648 $edit = (int)
dbx()->get_system_var(
'dbx_edit', 0,
'int');
650 if (($edit >= 4 && $edit <= 8) || $edit === 9) {
654 if ($this->_editor_class_file !==
'') {
658 foreach (
dbx()->get_editor_files() as
$file) {
664 if (
$content ===
'' || !$this->_editor_files) {
670 foreach ($this->_editor_files as
$file) {
671 $kind = strtolower((
string) (
$file[
'kind'] ??
''));
674 if ($kind ===
'fd' || $kind ===
'dd') {
678 $marker =
dbx()->editor_marker(
$file[
'kind'],
$file[
'file']);
679 $needle = trim($marker);
681 if ($marker !==
'' && strpos(
$content, $needle) ===
false && strpos($markers, $needle) ===
false) {
686 if ($markers ===
'') {
690 return $markers .
$content .
"\n<!-- DBX-EDITOR-END -->\n";
720 $trace = debug_backtrace(
721 DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS,
724 foreach ($trace as $frame) {
725 $owner = $frame[
'object'] ??
null;
733 return dbx()->get_current_owner();
788 $this->
_dbx_modul =
dbx()->get_system_var(
'dbx_activ_modul',
'modul');
789 $this->_dbx_action =
dbx()->get_system_var(
'dbx_activ_action',
'run');
790 $this->_dbx_page =
dbx()->get_system_var(
'dbx_page',
'default');
791 $this->_dbx_design =
dbx()->get_system_var(
'dbx_design',
'default');
792 $this->
_dbx_lng =
dbx()->get_system_var(
'dbx_lng',
'de');
793 $this->_dbx_modul_id =
dbx()->get_system_var(
'dbx_activ_modul_id', 1);
795 $this->_data = array();
797 $this->_form_validate = -1;
798 $this->_form_submit = -1;
802 'fid' => $this->_fid,
803 'tpl' => $this->_tpl,
804 'i' => $this->_next_i,
807 $init = $this->
callback(
'init', $init);
809 if (is_array($init)) {
810 if (isset($init[
'fid'])) $this->_fid = $init[
'fid'];
811 if (isset($init[
'tpl'])) $this->_tpl = $init[
'tpl'];
812 if (isset($init[
'i'])) $this->_next_i = $init[
'i'];
819 $secure_fld = $this->secure_fld_name();
820 $this->
add_fld($secure_fld,
'dbx|hidden', $secure_fld, rules:
'parameter', dd:
'');
821 $this->sync_secure_field($secure_fld, $this->secure_token($secure_fld));
846 if ($replace || !isset($this->_replaces[
'bar_title']) || (
string)$this->_replaces[
'bar_title'] ===
'') {
847 $this->
add_rep(
'bar_title', (
string)$title);
849 if ($replace || !isset($this->_replaces[
'bar_icon']) || (
string)$this->_replaces[
'bar_icon'] ===
'') {
850 $this->
add_rep(
'bar_icon', (
string)$icon);
852 if ($replace || !isset($this->_replaces[
'bar_subtitle']) || (
string)$this->_replaces[
'bar_subtitle'] ===
'') {
853 $this->
add_rep(
'bar_subtitle', (
string)$subtitle);
862 $this->_form_help_enabled = $enabled ? 1 : 0;
864 $this->_form_help_button =
'';
865 unset($this->_obj[
'help_button']);
877 'delete_title' =>
'Datensatz loeschen',
878 'delete_hint' =>
'Dieser Vorgang kann nicht rueckgaengig gemacht werden.',
880 $this->_module_bar_form_actions = array_merge($defaults,
$options);
884 if (!isset($this->_replaces[
'form_shell_class'])) {
887 if (!isset($this->_replaces[
'form_class'])) {
890 if (!isset($this->_replaces[
'form_attrs'])) {
897 'bar_class' =>
'dbx-module-bar',
898 'bar_title_class' =>
'dbx-module-bar-titleblock',
899 'bar_actions_class' =>
'dbx-module-bar-actions',
901 'bar_icon' =>
'bi-grid',
902 'bar_subtitle' =>
'',
903 'bar_title_pre' =>
'',
904 'bar_title_heading_attrs' =>
'',
912 $formClass = trim((string)($this->_replaces[
'form_class'] ??
''));
913 $formAttrs = trim((
string)($this->_replaces[
'form_attrs'] ??
''));
914 $shellClass = trim((
string)($this->_replaces[
'form_shell_class'] ??
''));
915 $panelClass = trim(
'dbxForm_wrapper ' . $shellClass);
916 $frameId = trim((
string)($this->_replaces[
'frame_id'] ??
''));
918 if ($frameId ===
'') {
919 $frameId =
'dbx_target_' . $i;
922 $this->add_rep(
'frame_id', $frameId);
923 if (trim((
string)($this->_replaces[
'frame_panel_class'] ??
'')) ===
'') {
924 $this->add_rep(
'frame_panel_class', $panelClass);
926 $this->add_rep(
'frame_panel_attrs', (
string)($this->_replaces[
'frame_panel_attrs'] ??
''));
927 $this->add_rep(
'frame_subbar',
'');
928 $this->add_rep(
'frame_body_class',
'');
929 if ((
string)($this->_replaces[
'frame_skip_form_wrap'] ??
'') !==
'1') {
930 $this->add_rep(
'frame_form_open',
'<form action="' . htmlspecialchars(
$formAction, ENT_QUOTES) .
'" method="post" id="dbx_form_' . $i .
'" class="dbxAjax' . (
$formClass !==
'' ?
' ' .
$formClass :
'') .
'"' . ($formAttrs !==
'' ?
' ' . $formAttrs :
'') .
'>');
931 $this->add_rep(
'frame_body_head',
'<div class="row"><div class="col">{obj:form_msg}</div></div>');
932 $this->add_rep(
'frame_form_close',
'</form>');
934 if (!isset($this->_replaces[
'frame_form_open'])) {
935 $this->add_rep(
'frame_form_open',
'');
937 if (!isset($this->_replaces[
'frame_body_head'])) {
938 $this->add_rep(
'frame_body_head',
'');
940 if (!isset($this->_replaces[
'frame_form_close'])) {
941 $this->add_rep(
'frame_form_close',
'');
944 $this->add_rep(
'frame_body_tail',
'');
950 foreach ($defaults as $key =>
$value) {
956 if (!$this->_module_bar_form_actions) {
960 $opts = $this->_module_bar_form_actions;
961 $i = (int)$this->_next_i;
963 $i = (int)$this->
next_i();
966 $formId =
'dbx_form_' . $i;
969 if (!empty($opts[
'save'])) {
971 'bar_form_id' => $formId,
975 if (!empty($opts[
'delete']) && trim((
string)($opts[
'delete_url'] ??
'')) !==
'') {
977 'bar_delete_url' => htmlspecialchars((
string)($opts[
'delete_url'] ??
''), ENT_QUOTES),
978 'bar_delete_title' => htmlspecialchars((
string)($opts[
'delete_title'] ??
'Datensatz loeschen'), ENT_QUOTES),
979 'bar_delete_hint' => htmlspecialchars((
string)($opts[
'delete_hint'] ??
''), ENT_QUOTES),
983 if (!empty($opts[
'reload'])) {
984 $reloadUrl = trim((
string)($opts[
'reload_url'] ??
''));
985 if ($reloadUrl ===
'') {
986 $reloadUrl = (string)$this->_action;
990 'bar_reload_url' => htmlspecialchars($reloadUrl, ENT_QUOTES),
998 $modul = (string)
dbx()->get_system_var(
'dbx_modul',
'');
1001 $help =
dbx()->get_include_obj(
'dbxAdminHelp',
'dbxAdmin');
1002 $topic =
$help->resolveTopic($modul);
1004 $actions = trim((
string)($this->_replaces[
'bar_actions'] ??
''));
1005 if (
$actions ===
'' && isset($this->_obj[
'bar_actions'])) {
1006 $actions = (string)$this->_obj[
'bar_actions'];
1010 if ($formActions !==
'') {
1014 $title = (string)($this->_replaces[
'bar_title'] ??
'');
1015 $icon = (string)($this->_replaces[
'bar_icon'] ??
'bi-grid');
1016 $subtitle = (string)($this->_replaces[
'bar_subtitle'] ??
'');
1023 if ($topic !==
'') {
1024 $meta =
$help->barMeta($topic);
1025 if (is_array($meta) && $meta) {
1026 if ($title ===
'') {
1027 $title = (string)($meta[
'title'] ?? $topic);
1029 if ($icon ===
'' || $icon ===
'bi-grid') {
1030 $icon = (string)($meta[
'icon'] ??
'bi-grid');
1032 if ($subtitle ===
'') {
1033 $subtitle = (string)($meta[
'subtitle'] ??
'');
1043 $metaTitle = (string)($meta[
'title'] ??
'');
1044 $metaSubtitle = (string)($meta[
'subtitle'] ??
'');
1047 ($title ===
'' || $title === $metaTitle || $title === $fdTitle)
1052 $fdSubtitle !==
'' &&
1055 $subtitle === $metaSubtitle ||
1056 $subtitle === $fdSubtitle
1059 $subtitle = $fdSubtitle;
1061 if ($fdIcon !==
'') {
1066 if ($this->_form_help_enabled) {
1067 if ($topic !==
'') {
1068 $helpButton =
$help->button($topic);
1069 } elseif (isset($this->_obj[
'help_button'])) {
1070 $helpButton = (string)$this->_obj[
'help_button'];
1072 if ($helpButton ===
'' && method_exists(
$help,
'formButton')) {
1073 $helpButton =
$help->formButton($modul, (
string)$this->_fid, $title);
1076 $this->_form_help_button = $helpButton;
1078 $barExtra = trim((
string)($this->_replaces[
'bar_extra'] ??
''));
1079 $visibleBarActions =
$actions . $barExtra;
1080 if ($helpButton !==
'' && strpos($visibleBarActions,
'bi-question-circle') ===
false) {
1081 $barExtra .= $helpButton;
1084 $barClass = trim((
string)($this->_replaces[
'bar_class'] ??
''));
1085 if ($barClass ===
'') {
1086 $barClass =
'dbx-module-bar';
1090 'bar_class' => $barClass,
1091 'bar_title' => $title,
1092 'bar_icon' => $icon !==
'' ? $icon :
'bi-grid',
1093 'bar_subtitle' => $subtitle,
1095 'bar_extra' => $barExtra,
1097 }
catch (\Throwable $e) {
1108 if (!$this->_form_help_enabled ||
$content ===
'' || $this->_form_help_button ===
'' || stripos(
$content,
'<form') === false) {
1111 if (strpos(
$content,
'bi-question-circle') !==
false
1112 || strpos(
$content,
'dbx_run1=help') !==
false) {
1116 $title = trim((
string)($this->_replaces[
'bar_title'] ??
''));
1117 if ($title ===
'') {
1118 $title = ucwords(str_replace(array(
'-',
'_',
'.'),
' ', (
string)$this->_fid));
1120 $bar = $this->get_tpl(
'dbx|form-help-bar', array(
1121 'form_help_title' => htmlspecialchars($title, ENT_QUOTES,
'UTF-8'),
1122 'form_help_icon' => htmlspecialchars((
string)($this->_replaces[
'bar_icon'] ??
'bi-ui-checks'), ENT_QUOTES,
'UTF-8'),
1123 'form_help_button' => $this->_form_help_button,
1125 if (trim($bar) ===
'') {
1129 return (
string)preg_replace_callback(
'/<form\b[^>]*>/i',
static function ($match) use ($bar) {
1130 return $match[0] . $bar;
1135 $modul = (string)
dbx()->get_system_var(
'dbx_modul',
'');
1136 if ($modul !==
'dbxAdmin' && !str_ends_with($modul,
'_admin')) {
1141 $help =
dbx()->get_include_obj(
'dbxAdminHelp',
'dbxAdmin');
1142 if ($topic ===
'') {
1143 $topic =
$help->resolveTopic($modul);
1145 if ($topic ===
'') {
1150 $barMeta =
$help->barMeta($topic);
1151 if (is_array($barMeta) && $barMeta) {
1153 (
string)($barMeta[
'title'] ??
''),
1154 (
string)($barMeta[
'icon'] ??
'bi-grid'),
1155 (
string)($barMeta[
'subtitle'] ??
'')
1158 }
catch (\Throwable $e) {
1162 private function get_token(): string {
1164 return bin2hex(random_bytes(32));
1165 }
catch (\Throwable $e) {
1166 return hash(
'sha256', uniqid(
'',
true) .
'|' . mt_rand());
1170 private function secure_fld_name(): string {
1171 return
'_' . (string)$this->_fid;
1174 private function secure_token(
string $fld): string {
1175 if (!isset($this->
_sys[
'_csrf']) || !is_array($this->
_sys[
'_csrf'])) {
1176 $this->
_sys[
'_csrf'] = array();
1179 $token = (string)($this->
_sys[
'_csrf'][$fld] ?? $this->
_sys[$fld] ??
'');
1180 if (!preg_match(
'/^[a-f0-9]{64}$/',
$token)) {
1181 $token = $this->get_token();
1186 $this->_data[$fld] =
$token;
1191 private function sync_secure_field(
string $fld,
string $token): void {
1194 $this->_data[$fld] =
$token;
1196 if (isset($this->_flds[$fld])) {
1197 $this->_flds[$fld][
'value'] =
$token;
1198 $this->_flds[$fld][
'origin'] =
'csrf';
1199 $this->_flds[$fld][
'verify'] = 1;
1200 $this->_flds[$fld][
'error'] = 0;
1204 private function rotate_secure_token(
string $fld): void {
1205 $this->sync_secure_field($fld, $this->get_token());
1219 $fld = $this->secure_fld_name();
1220 $token = $this->secure_token($fld);
1251 if (!is_array($data)) {
1252 $first = substr((
string) $data, 0, 1);
1254 if ($data &&
$first !=
'=') {
1255 if (strpos((
string) $data,
'=') !==
false) {
1256 parse_str($data, $xdata);
1273 $this->_msg_info = $msg;
1284 $this->_msg_success = $msg;
1295 $this->_msg_error = $msg;
1311 $this->_msg_error = $msg;
1312 $this->_general_error = $msg;
1323 $this->_msg_warning = $msg;
1345 return is_scalar($message) ? (string)$message : $default;
1364 array $values = array(),
1365 string $default =
''
1368 if ($message ===
'' || $values === array()) {
1372 $replacements = array();
1373 foreach ($values as $placeholder =>
$value) {
1377 $replacements[
'{' . trim((
string)$placeholder,
'{}') .
'}'] =
1381 return strtr($message, $replacements);
1408 return $this->_messages;
1410 if (strpos(
$source,
'fd:') !== 0) {
1414 $this->get_dd_fields_source(
$source);
1416 return $this->_messages;
1430 private function apply_fd_messages(array
$messages): void {
1461 return dbx()->part_select(
' name="',
'"', $fld);
1482 $oTPL =
dbx()->get_system_obj(
'dbxTPL');
1483 if (is_object(
$oTPL) && method_exists(
$oTPL,
'cleanup_optional_placeholders')) {
1490 for ($i = 0; $i < 2; $i++) {
1491 foreach ($xnorep as $id => $norep) {
1492 $xid =
'[' . $id .
']';
1521 $oInterpreter =
dbx()->get_system_obj(
'dbxInterpreter');
1546 return $this->oTPL->get_tpl(
$tpl, $data, $type, $i);
1565 $rep =
'{obv:' . $id .
'}';
1569 $val = htmlspecialchars(
$value, ENT_QUOTES);
1595 $editor =
dbx()->get_system_var(
'dbx_editor', 0,
'int');
1597 if (!$i && !$editor) {
1598 $i = $this->_next_i;
1601 $replaces = array();
1602 $replaces[
'dbx_modul'] = $this->_dbx_modul;
1603 $replaces[
'dbx_run1'] = $this->_dbx_action;
1604 $replaces[
'dbx_page'] = $this->_dbx_page;
1605 $replaces[
'dbx_design'] = $this->_dbx_design;
1606 $replaces[
'dbx_lng'] = $this->_dbx_lng;
1607 $replaces[
'action'] =
dbx()->action_url((
string)$this->_action);
1608 $replaces[
'fid'] = $this->_fid;
1609 $replaces[
'rid'] = $this->_rid;
1610 $replaces[
'self'] =
dbx()->get_self_url();
1613 $replaces[
'i'] = $i;
1616 return $this->oTPL->replaces(
$tpl, $replaces);
1637 if (is_array($this->_obj)) {
1638 foreach ($this->_obj as $id => $obj) {
1639 $fid =
'{obj:' . $id .
'}';
1640 $obj = $this->oTPL->replaces($obj, $this->_replaces);
1664 $section = $this->_fid;
1665 $modul = $this->_dbx_modul;
1666 $mode = $this->_store_mode;
1670 if ($section &&
$mode ==
'session') {
1671 dbx()->set_session_var($key,
$value, $section, $modul);
1692 $section = $this->_fid;
1693 $modul = $this->_dbx_modul;
1698 $sysdata =
dbx()->get_session_var($key, $empty, $section, $modul);
1701 return is_array($sysdata) ? $sysdata : array();
1725 $xkey =
'_activ-row_id_' . $key;
1726 return dbx()->get_remember_var($xkey, 0,
'dbx');
1742 $xkey =
'_activ-row_id_' . $key;
1743 dbx()->set_remember_var($xkey,
$value,
'dbx');
1759 $this->_replaces[$key] = $val;
1774 if ($replaces === null) {
1775 $replaces = $this->_replaces;
1778 return $this->oTPL->replaces(
1780 is_array($replaces) ? $replaces : array()
1827 $js = $function .
"('" . addslashes((
string)
$target) .
"'";
1857 foreach ($this->_flds as $no => $fld) {
1858 if (($fld[
'name'] ??
'') == $name) {
1861 $fld[
'data'][
'class'] = trim(($fld[
'data'][
'class'] ??
'') .
' fld-error');
1862 $fld[
'data'][
'errormsg'] = $msg;
1863 $this->_flds[$no] = $fld;
1883 dbx()->debug(
"add fld-error fld=($name) Msg=($msg)");
1884 $this->_errors[$name] = $msg;
1900 return $this->_validation_results;
1903 $result = $this->_validation_results[$name] ?? array();
1912 $this->_validation_results[$name] =
$result;
1925 $this->_warnings[$name] = $msg;
1945 private function resolve_fld_val($name, $default =
'',
$rules =
'', $useRequest =
true, $fallbackToState =
true) {
1946 $stateValue = $default;
1947 $origin =
'default';
1949 if (isset($this->_data[$name])) {
1950 $stateValue = $this->_data[$name];
1954 if (isset($this->
_sys[$name])) {
1955 $stateValue = $this->
_sys[$name];
1959 $value = $fallbackToState ? $stateValue : $default;
1961 if (!$fallbackToState) {
1962 $origin =
'default';
1966 if (isset(
$_POST[$name])) {
1969 } elseif (isset(
$_GET[$name])) {
1985 $this->remember_validation_result((
string)$name,
$validation);
1989 if (
$ok && preg_match(
'/(?:^|\|)trim(?:\||$)/', (
string)
$rules)) {
1996 'origin' => $origin,
1997 'ok' =>
$ok ? 1 : 0,
2003 $resolved = $this->resolve_fld_val($name, $default,
$rules,
true,
true);
2011 $this->_data[$name] =
$value;
2014 if (isset($this->_flds[$name])) {
2015 $this->_flds[$name][
'value'] =
$value;
2016 $this->_flds[$name][
'origin'] =
$resolved[
'origin'];
2035 $danger_value = $this->_get_post_data($name, $default);
2044 $danger_value = $default;
2045 } elseif (preg_match(
'/(?:^|\|)trim(?:\||$)/', (
string)
$rules)) {
2046 $danger_value =
$validation[
'normalized'] ?? $danger_value;
2050 return $danger_value;
2063 $danger_value = $this->_get_post($name, $default);
2072 $danger_value = $default;
2073 } elseif (preg_match(
'/(?:^|\|)trim(?:\||$)/', (
string)
$rules)) {
2074 $danger_value =
$validation[
'normalized'] ?? $danger_value;
2078 return $danger_value;
2094 private function _get_post_data($name, $default =
'') {
2098 if (isset(
$_POST[$name])) {
2101 } elseif (isset(
$_GET[$name])) {
2106 if (!$set && isset($this->_data[$name])) {
2107 $value = $this->_data[$name];
2125 private function _get_post($name, $default =
'') {
2128 if (isset(
$_POST[$name])) {
2130 } elseif (isset(
$_GET[$name])) {
2157 if (
$tpl !=
'obj-value' &&
$tpl !=
'obv-value') {
2160 if (
$tpl ==
'obv-value') {
2161 $tpl = htmlspecialchars((
string) $data, ENT_QUOTES);
2164 if (
$tpl ==
'obj-value') {
2168 $tpl = $this->oTPL->replaces((
string)
$tpl, $data2);
2171 $tpl = str_replace(
'{class}',
'',
$tpl);
2172 $tpl = str_replace(
'{tooltip}',
'',
$tpl);
2174 $this->_obj[$obj] =
$tpl;
2193 $xaction = $this->_action;
2195 if ($action !==
'' && $action[0] ==
'&') {
2196 $x_action = $xaction . $action;
2198 $x_action = $action;
2202 $xdata[
'action'] =
dbx()->action_url((
string)$x_action);
2204 if (is_array($data)) {
2205 $xdata = array_merge($xdata, $data);
2209 $tpl = str_replace(
'{class}',
'',
$tpl);
2210 $tpl = str_replace(
'{tooltip}',
'',
$tpl);
2212 $this->_obj[$obj] =
$tpl;
2239 private function get_active_field_source(
$source =
'fd::'): string {
2242 return (
string) $this->_fd;
2245 return (
string) $this->_dd;
2249 return (
string) $this->_dd;
2286 private function get_fld_marker_value_from_records(
$value,
string $var, $field_record = array(), $dd_record = array()) {
2287 if (!is_array($field_record)) {
2288 $field_record = array();
2291 if (!is_array($dd_record)) {
2292 $dd_record = array();
2296 return $field_record[$var] ??
'';
2300 return $dd_record[$var] ??
'';
2337 private function get_dd_fields_source(
string $dd): array {
2340 if (
$dd ===
'' ||
$dd ===
'dd') {
2347 foreach (array(
'cfg:',
'def:',
'mod:',
'fd:',
'dd:') as $prefix) {
2348 if (strpos(
$dd, $prefix) === 0) {
2349 $mod = substr($prefix, 0, -1);
2350 $name = substr(
$dd, strlen($prefix));
2355 if ($mod ===
'dd' && strpos(
$dd,
'|') !==
false) {
2360 if ($mod ===
'dd') {
2362 if (method_exists($this->
oDB,
'get_dd_file')) {
2363 $this->add_editor_file(
'dd', $this->
oDB->get_dd_file($name));
2372 $dd_file =
dbx()->get_base_dir() .
"dbx/modules/$name/cfg/config.dd.php";
2376 $dd_file =
dbx()->get_base_dir() .
"dbx/modules/$name/dd/$name.dd.php";
2380 $modul =
dbx()->get_system_var(
'dbx_activ_modul',
'dbx');
2381 $dd_file =
dbx()->get_base_dir() .
"dbx/modules/$modul/dd/$name.dd.php";
2388 if (strpos($name,
'|') !==
false) {
2389 $parts = explode(
'|', $name, 2);
2390 $fd_modul = trim($parts[0]);
2391 $fd_name = trim($parts[1]);
2394 if ($fd_modul ===
'') {
2395 $fd_modul =
dbx()->get_system_var(
'dbx_activ_modul',
'dbx');
2398 $dd_file = function_exists(
'dbx_lng_resolve_file')
2407 if ($dd_file ===
'' || !is_file($dd_file)) {
2408 $dd_file =
dbx()->get_base_dir() .
"dbx/modules/$fd_modul/fd/$fd_name.fd.php";
2413 return $this->read_dd_fields_direct($dd_file);
2445 private function read_dd_fields_direct(
string $dd_file): array {
2451 $dd_file =
dbx()->os_path($dd_file);
2453 if (!file_exists($dd_file)) {
2457 $real_file = realpath($dd_file);
2459 $real_file = $dd_file;
2463 $kind = (substr(
$normalized, -7) ===
'.fd.php') ?
'fd' :
'dd';
2464 $mtime = @filemtime($real_file);
2465 $size = @filesize($real_file);
2468 $this->add_editor_file($kind, $real_file);
2469 $runtime_cache =& $this->session_cache_section(
'form',
'field_source_runtime');
2470 $field_source_cache =& $this->session_cache_section(
'form',
'field_source');
2472 if (isset($runtime_cache[$cache_key])) {
2473 $entry = $runtime_cache[$cache_key];
2477 ($entry[
'mtime'] ?? 0) === $mtime &&
2478 ($entry[
'size'] ?? 0) === $size &&
2479 isset($entry[
'fields']) &&
2480 is_array($entry[
'fields']) &&
2481 isset($entry[
'messages']) &&
2482 is_array($entry[
'messages'])
2484 if ($kind ===
'fd') {
2485 $this->apply_fd_messages($entry[
'messages']);
2487 return $entry[
'fields'];
2492 !isset($field_source_cache[$cache_key]) &&
2493 isset(
$_SESSION[
'dbx'][
'cache'][
'field_source'][$cache_key]) &&
2494 is_array(
$_SESSION[
'dbx'][
'cache'][
'field_source'][$cache_key])
2496 $field_source_cache[$cache_key] =
$_SESSION[
'dbx'][
'cache'][
'field_source'][$cache_key];
2497 unset(
$_SESSION[
'dbx'][
'cache'][
'field_source'][$cache_key]);
2500 if (isset($field_source_cache[$cache_key])) {
2501 $entry = $field_source_cache[$cache_key];
2505 ($entry[
'mtime'] ?? 0) === $mtime &&
2506 ($entry[
'size'] ?? 0) === $size &&
2507 isset($entry[
'fields']) &&
2508 is_array($entry[
'fields']) &&
2509 isset($entry[
'messages']) &&
2510 is_array($entry[
'messages'])
2512 $runtime_cache[$cache_key] = $entry;
2513 if ($kind ===
'fd') {
2514 $this->apply_fd_messages($entry[
'messages']);
2516 return $entry[
'fields'];
2538 $runtime_cache[$cache_key] = $entry;
2539 $field_source_cache[$cache_key] = $entry;
2541 if ($kind ===
'fd') {
2561 private function get_dd_fld(array
$fields,
string $fld): array {
2563 if (isset($record[
'name']) && $record[
'name'] === $fld) {
2571 private function &session_cache_section(
string $bereich,
string $section) {
2580 if (!isset(
$_SESSION[
'dbx'][
'cache'][$bereich]) || !is_array(
$_SESSION[
'dbx'][
'cache'][$bereich])) {
2581 $_SESSION[
'dbx'][
'cache'][$bereich] = array();
2584 if (!isset(
$_SESSION[
'dbx'][
'cache'][$bereich][$section]) || !is_array(
$_SESSION[
'dbx'][
'cache'][$bereich][$section])) {
2585 $_SESSION[
'dbx'][
'cache'][$bereich][$section] = array();
2588 return $_SESSION[
'dbx'][
'cache'][$bereich][$section];
2614 public function get_dd(
string $dd,
string $fld,
string $var) {
2615 if (
$dd ===
'' ||
$dd ===
'dd') {
2623 $cache_key = md5(
$dd .
"\0" . $fld);
2624 $field_cache =& $this->session_cache_section(
'form',
'runtime_field');
2626 if (isset($field_cache[$cache_key]) && is_array($field_cache[$cache_key])) {
2627 $field = $field_cache[$cache_key];
2632 $field_cache[$cache_key] = array();
2642 $field_cache[$cache_key] =
$field;
2653 return $field[$var] ??
'';
2677 private function sql_dd_file_exists($modul,
$dd) {
2678 $modul = trim((
string) $modul);
2679 $dd = trim((
string)
$dd);
2685 if ($modul ===
'') {
2686 $modul =
dbx()->get_system_var(
'dbx_activ_modul',
'dbx');
2689 $file1 =
dbx()->os_path(
dbx()->
get_base_dir() .
'dbx/modules/' . $modul .
'/dd/' .
$dd .
'.dd.php');
2692 return file_exists($file1) || file_exists($file2);
2695 private function normalize_sql_dd_name($modul,
$source) {
2704 str_replace(
'dbx_',
'dbx',
$source),
2705 str_replace(
' ',
'', ucwords(str_replace(
'_',
' ',
$source))),
2706 lcfirst(str_replace(
' ',
'', ucwords(str_replace(
'_',
' ',
$source))))
2710 if ($this->sql_dd_file_exists($modul, $candidate)) {
2718 private function sql_to_array($data) {
2727 $compact_sql_syntax =
false;
2729 $data = str_replace(
'sql:',
'', (
string) $data);
2730 $work = explode(
'|', $data);
2732 if (isset(
$work[0])) {
2736 if (isset(
$work[1])) {
2740 if (
$dd && $xkey && strpos($xkey,
',') !==
false) {
2741 $sqlSource = array_map(
'trim', explode(
',', $xkey));
2742 $dd = $this->normalize_sql_dd_name(
$dd, $sqlSource[0] ??
'');
2743 $xkey = $sqlSource[1] ??
'id';
2744 $flds = $sqlSource[2] ?? $xkey;
2745 $compact_sql_syntax =
true;
2748 if (isset(
$work[2])) {
2749 if ($compact_sql_syntax) {
2756 if (isset(
$work[3])) {
2757 if ($compact_sql_syntax) {
2764 if (isset(
$work[4])) {
2765 if ($compact_sql_syntax) {
2766 if ((
int)
$work[4] > 0) {
2767 $limit = (int)
$work[4];
2774 if (!$compact_sql_syntax && isset(
$work[5]) && (
int)
$work[5] > 0) {
2775 $limit = (int)
$work[5];
2778 $xdata[0] =
'Bitte auswählen';
2797 if (strpos(
',' . $xflds .
',',
',' . $xkey .
',') ===
false && $xflds !==
'*') {
2798 $xflds .=
',' . $xkey;
2801 $data = $this->
oDB->select(
$dd, $where, $xflds,
$order, $asc_desc,
'', $limit, 0, 0);
2803 if (is_array($data)) {
2804 $displayFields = ($flds ===
'*') ? array() : array_map(
'trim', explode(
',', $flds));
2806 foreach ($data as $record) {
2809 foreach ($record as $fld => $val) {
2810 $use = ($flds ===
'*') || in_array($fld, $displayFields,
true);
2821 if (isset($record[$xkey])) {
2822 $xdata[$record[$xkey]] =
$value;
2866 $source = $this->get_active_field_source(
$dd);
2880 foreach (
$fields as $record) {
2881 if (!is_array($record)) {
2885 if (!isset($record[
'name']) || trim((
string) $record[
'name']) ===
'') {
2889 $name = trim((
string) $record[
'name']);
2952 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::') {
2953 $field_source = $this->get_active_field_source(
$dd);
2954 $dd_source = $this->get_active_field_source(
'dd::');
2955 $field_record = $field_source ? $this->
get_dd($field_source, $name,
'*') : array();
2956 $dd_record = $dd_source ? $this->get_dd($dd_source, $name,
'*') : array();
2957 $source_data = array();
2958 $source_options = array();
2960 $dd_options = array();
2962 if (is_array($field_record) && $field_record) {
2963 $source_data = $this->process_array($field_record[
'data'] ??
'');
2964 $source_options = $this->process_array($field_record[
'options'] ??
'');
2967 if (is_array($dd_record) && $dd_record) {
2968 $dd_data = $this->process_array($dd_record[
'data'] ??
'');
2969 $dd_options = $this->process_array($dd_record[
'options'] ??
'');
2972 if ($data ===
'fd::' || $data ===
'' || $data ===
null) {
2973 $data = $source_data;
2974 } elseif ($data ===
'dd::') {
2977 $data = $this->merge_arrays($this->process_array($data), $source_data);
2985 $options = $this->merge_arrays($this->process_array(
$options), $source_options);
2988 if (isset($data[
'dd'])) {
2989 $field_source = $this->get_active_field_source($data[
'dd']);
2990 $field_record = $field_source ? $this->get_dd($field_source, $name,
'*') : array();
2993 if ($label ===
'fd::' && isset($data[
'label'])) {
2994 $label = $data[
'label'];
2997 if (
$rules ===
'fd::' && isset($data[
'rules'])) {
3001 if (
$class ===
'fd::' && isset($data[
'class'])) {
3005 if ($tooltip ===
'fd::' && isset($data[
'tooltip'])) {
3006 $tooltip = $data[
'tooltip'];
3009 if ($placeholder ===
'fd::' && isset($data[
'placeholder'])) {
3010 $placeholder = $data[
'placeholder'];
3013 if ($errormsg ===
'fd::' && isset($data[
'errormsg'])) {
3014 $errormsg = $data[
'errormsg'];
3017 if ($remap ===
'fd::' && isset($data[
'remap'])) {
3018 $remap = $data[
'remap'];
3021 $data[
'name'] = $name;
3022 $data[
'tpl'] = $this->get_fld_marker_value_from_records(
$tpl,
'tpl', $field_record, $dd_record);
3023 $data[
'label'] = $this->get_fld_marker_value_from_records($label,
'label', $field_record, $dd_record);
3024 $data[
'rules'] = $this->get_fld_marker_value_from_records(
$rules,
'rules', $field_record, $dd_record);
3025 $data[
'class'] = $this->get_fld_marker_value_from_records(
$class,
'class', $field_record, $dd_record);
3026 $data[
'tooltip'] = $this->get_fld_marker_value_from_records($tooltip,
'tooltip', $field_record, $dd_record);
3027 $data[
'placeholder'] = $this->get_fld_marker_value_from_records($placeholder,
'placeholder', $field_record, $dd_record);
3028 $data[
'errormsg'] = $this->get_fld_marker_value_from_records($errormsg,
'errormsg', $field_record, $dd_record);
3029 $data[
'remap'] = $this->get_fld_marker_value_from_records($remap,
'remap', $field_record, $dd_record);
3035 'label' => $data[
'label'],
3036 'tpl' => $data[
'tpl'],
3037 'rules' => $data[
'rules'],
3038 'remap' => $data[
'remap'],
3041 'errormsg' => $data[
'errormsg'],
3045 'dd' => $field_source,
3048 $this->_flds[$name] = $fld;
3049 $this->touch_request_state();
3065 private function process_array(
$input) {
3068 $data_first = substr((
string)
$input, 0, 4);
3070 if ($data_first ===
'sql:') {
3096 private function merge_arrays($primary, $secondary) {
3097 if (!is_array($primary)) {
3101 if (!is_array($secondary)) {
3102 $secondary = array();
3105 foreach ($secondary as $key =>
$value) {
3106 if (!array_key_exists($key, $primary)) {
3125 private function touch_request_state() {
3126 $this->_form_validate = -1;
3127 $this->_fld_changes = -1;
3128 $this->_form_submit = -1;
3147 if (($fld[
'verify'] ?? 0)) {
3151 $errormsg =
'Bitte Eingabe pruefen';
3152 $name = $fld[
'name'] ??
'';
3153 $fld_rules = $fld[
'rules'] ??
'';
3156 $resolved = $this->resolve_fld_val($name,
'',
'',
false,
true);
3160 $fld[
'changed'] = 0;
3167 $old = $this->resolve_fld_val($name,
'',
'',
false,
true);
3168 $old_value = $old[
'value'];
3170 $resolved = $this->resolve_fld_val($name,
'', $fld_rules,
true,
false);
3178 $fld[
'error'] =
$ok ? 0 : 1;
3182 if (!empty($fld[
'data'][
'errormsg'])) {
3183 $errormsg = $fld[
'data'][
'errormsg'];
3188 if ($fld[
'error']) {
3190 $fld[
'data'][
'errormsg'] = $errormsg;
3195 if (is_array($value_compare)) {
3198 foreach ($value_compare as $keyval) {
3199 if ($values !==
'') {
3206 $value_compare = $values;
3209 $change = $this->_fld_change_state;
3211 if ($value_compare != $old_value || $change ==
'*') {
3212 $fld[
'changed'] = 1;
3214 $fld[
'changed'] = 0;
3217 if (!$fld[
'error'] && $fld[
'changed']) {
3218 $this->_post[$name] = $value_compare;
3240 if ($this->_form_validate == 1) {
3244 $this->_post = array();
3245 $this->_errors = array();
3246 $this->_warnings = array();
3248 foreach ($this->_flds as $no => $fld) {
3250 $this->_flds[$no] = $fld;
3253 $this->_form_validate = 1;
3254 $this->_fld_changes = -1;
3272 private function evaluate_request() {
3273 if ($this->_form_validate == 1 && $this->_form_submit > -1) {
3274 dbx()->debug(
"dbxForm submit cached: fid=({$this->_fid}) submit=({$this->_form_submit})");
3279 $fld = $this->secure_fld_name();
3280 $secure = $this->secure_token($fld);
3285 if ($fld !==
'' && isset(
$_POST[$fld])) {
3286 $posted = (string)
$_POST[$fld];
3289 if ($secure !==
'' && hash_equals($secure, $posted)) {
3296 "dbxForm submit evaluate: fid=({$this->_fid}) field=($fld) post=($hasPost) match=($match) submit=($submit)"
3299 $this->_form_submit = $submit;
3300 $this->check_flds_data($submit);
3303 $this->rotate_secure_token($fld);
3305 $this->sync_secure_field($fld, $secure);
3322 $file = $this->_tpl_form_info;
3325 if (
$mode ==
'success') {
3326 $file = $this->_tpl_form_success;
3329 if (
$mode ==
'error') {
3330 $file = $this->_tpl_form_error;
3333 if (
$mode ==
'info') {
3334 $file = $this->_tpl_form_info;
3337 if (
$mode ==
'warning') {
3338 $file = $this->_tpl_form_warning;
3343 $tpl = str_replace(
'{msg}', $msg,
$tpl);
3346 return str_replace(
'{class}',
$mode,
$tpl);
3361 if (
$mode ==
'success') {
3362 $file = $this->_tpl_fld_success;
3365 if (
$mode ==
'error') {
3366 $file = $this->_tpl_fld_error;
3369 if (
$mode ==
'info') {
3370 $file = $this->_tpl_fld_info;
3373 if (
$mode ==
'warning') {
3374 $file = $this->_tpl_fld_warning;
3379 $tpl = str_replace(
'{msg}', $msg,
$tpl);
3404 if (trim((
string)
$value) !==
'') {
3405 $timestamp = strtotime((
string)
$value);
3407 if ($timestamp !==
false) {
3408 $value = date(
'd.m.Y', $timestamp);
3424 $raw = trim((
string)
$value);
3429 if (preg_match(
'/\.(\d+)$/', $raw, $match)) {
3430 $ms =
'.' . $match[1];
3433 $timestamp = strtotime($raw);
3435 if ($timestamp !==
false) {
3436 if (preg_match(
'/^\d{2}:\d{2}(:\d{2})?(\.\d+)?$/', $raw)) {
3437 $value = date(
'H:i' . (substr_count($raw,
':') == 2 ?
':s' :
''), $timestamp) . $ms;
3438 } elseif (preg_match(
'/^\d{4}-\d{2}-\d{2}$|^\d{2}\.\d{2}\.\d{4}$/', $raw)) {
3439 $value = date(
'd.m.Y', $timestamp);
3441 $value = date(
'd.m.Y H:i' . (substr_count($raw,
':') >= 2 ?
':s' :
''), $timestamp) . $ms;
3459 $timestamp = strtotime((
string)
$value);
3461 $timestamp = time();
3464 $value = date(
'Y-m-d', $timestamp);
3479 $this->_css[] =
$css;
3494 $this->evaluate_request();
3495 $submit = ($this->_form_submit == 1) ? 1 : 0;
3496 $submit = $this->
callback(
'submit', $submit);
3497 $result = ($submit == 1) ? 1 : 0;
3499 dbx()->debug(
"dbxForm submit result: fid=({$this->_fid}) result=($result)");
3519 $this->evaluate_request();
3521 if ($this->_general_error >
'') {
3522 $this->_errors[
'general'] = 1;
3525 return count($this->_errors);
3534 $this->evaluate_request();
3535 return count($this->_warnings);
3546 $this->evaluate_request();
3548 if ($this->_form_submit != 1) {
3549 $this->_fld_changes = 0;
3553 if ($this->_fld_changes != -1) {
3554 return $this->_fld_changes;
3557 foreach ($this->_flds as $fld) {
3558 $changed += (int) ($fld[
'changed'] ?? 0);
3561 $this->_fld_changes = $changed;
3573 $rid =
dbx()->get_modul_var(
'rid', -1,
'int');
3574 $dbx_view = $this->_dbx_view;
3575 $dbx_modul = $this->_dbx_modul;
3578 $viewsys =
dbx()->get_session_var($dbx_view, $empty,
'view-sys', $dbx_modul);
3580 if (isset($viewsys[
'value'])) {
3581 $rid = $viewsys[
'value'];
3585 $this->
_rid = (int) $rid;
3600 $dbx_view = $this->_dbx_view;
3601 $dbx_modul = $this->_dbx_modul;
3604 $viewsys =
dbx()->get_session_var($dbx_view, $empty,
'view-sys', $dbx_modul);
3605 $viewsys[
'value'] = $rid;
3606 dbx()->set_session_var($dbx_view, $viewsys,
'view-sys', $dbx_modul);
3623 if (strpos((
string)
$tpl,
'_wait') !==
false) {
3644 if ($key !=
'form-dd-field') {
3645 $this->_post[$key] = $val;
3648 $this->_fld_changes = -1;
3679 if ($rid ===
'new') {
3683 if (is_array($pv)) {
3684 foreach ($pv as $key =>
$value) {
3685 $this->_post[$key] =
$value;
3686 $this->_data[$key] =
$value;
3691 $this->
_rid = (int) $rid;
3694 $rid = (int) $this->
_rid;
3695 $post = $this->_post;
3697 $this->
oDB->_fld_id = $this->_fld_id;
3698 $ok = $this->
oDB->save(
$dd, $post, $rid);
3701 dbx()->debug(
"DB-Error=(" . $this->
oDB->_error .
")\nQuery=(" . $this->oDB->_query .
")");
3703 if ($saveError !==
'') {
3704 $this->_msg_error = $saveError;
3706 $this->_general_error = $this->_msg_error;
3712 if ($saveSuccess !==
'') {
3713 $this->_msg_success = $saveSuccess;
3717 $rid = (int) $this->
oDB->_insert_id;
3725 if ($rid &&
$ok && $reread) {
3726 $new = $this->
oDB->select1(
$dd, $rid);
3728 if (is_array($new)) {
3729 foreach ($new as $key =>
$value) {
3730 $this->_data[$key] =
$value;
3733 $this->_reload_run = 1;
3735 foreach ($this->_flds as $no => $fld) {
3736 $key = $fld[
'name'] ??
'';
3738 if ($key !==
'' && array_key_exists($key, $this->_data)) {
3739 $this->_flds[$no][
'value'] = $this->_data[$key];
3740 $this->_flds[$no][
'origin'] =
'reload';
3741 $this->_flds[$no][
'verify'] = 1;
3742 $this->_flds[$no][
'error'] = 0;
3754 dbx()->debug(
"#DD FORM-save# Tab=($dd) rid=($rid)");
3767 $i = $this->_next_i;
3770 $i =
dbx()->next_id($add);
3771 $this->_next_i = $i;
3788 $this->_data[$fld_name] = $fld_val;
3789 $this->
_sys[$fld_name] = $fld_val;
3791 if (isset($this->_flds[$fld_name])) {
3792 $this->_flds[$fld_name][
'value'] = $fld_val;
3793 $this->_flds[$fld_name][
'origin'] =
'set';
3794 $this->_flds[$fld_name][
'verify'] = 1;
3805 $data = $this->prepare_search_tpl_data(array_merge(array(
3806 'extra_attrs' =>
'data-dbx="grid-search"',
3808 $template = trim((
string)($data[
'label'] ??
'')) ===
''
3810 :
'dbx|search-label';
3814 private function is_search_field_tpl(
$tpl): bool {
3815 $tpl = strtolower(trim((string)
$tpl));
3817 return $tpl ===
'dbx|search' ||
$tpl ===
'search' || substr(
$tpl, -7) ===
'|search';
3825 private function prepare_search_tpl_data(
3827 ?
string $name =
null,
3832 $data[
'name'] = $name !==
null ? $name : (string)($data[
'name'] ??
'');
3833 $data[
'value'] =
$value !==
null ?
$value : (string)($data[
'value'] ??
'');
3834 $data[
'i'] = $i !==
null ? $i : (int)($data[
'i'] ?? $this->_next_i);
3835 $data[
'label'] = (string)($data[
'label'] ??
'');
3836 $data[
'class'] = (string)($data[
'class'] ??
'');
3837 $data[
'style'] = (string)($data[
'style'] ??
'');
3838 if (trim((
string)($data[
'tooltip'] ??
'')) ===
'') {
3839 $data[
'tooltip'] = (string)($data[
'title'] ??
'Suchen');
3852 private function prepare_report_search_fld($name, &
$tpl, array &$data): void {
3853 if ($name !==
'dbx_rwhere') {
3857 $tpl =
'dbx|search';
3858 $defaults =
dbx()->search_defaults();
3860 $data[
'label'] =
'';
3861 $data[
'placeholder'] = $defaults[
'placeholder'];
3862 $data[
'title'] = trim((
string) ($data[
'tooltip'] ??
'')) !==
''
3863 ? (string) $data[
'tooltip']
3864 : $defaults[
'title'];
3865 $data[
'input_class'] = $defaults[
'input_class'];
3866 $data[
'wrap_class'] = $defaults[
'wrap_class'];
3867 $data[
'data_role'] = $defaults[
'data_role'];
3868 $data[
'extra_attrs'] = $defaults[
'extra_attrs'];
3888 $i = $this->_next_i;
3891 if (!($fld[
'verify'] ?? 0)) {
3895 $tpl = $fld[
'tpl'] ??
'';
3896 $data = is_array($fld[
'data'] ??
null) ? $fld[
'data'] : array();
3897 $options = is_array($fld[
'options'] ??
null) ? $fld[
'options'] : array();
3898 $fld_value = $fld[
'value'] ??
'';
3899 $error = (int) ($fld[
'error'] ?? 0);
3900 $name = $fld[
'name'] ??
'';
3903 $data[
'class'] = trim(($data[
'class'] ??
'') .
' fld-error');
3905 if (!isset($data[
'errormsg']) || $data[
'errormsg'] ===
'') {
3906 $data[
'errormsg'] =
'Eingabe bitte prüfen !';
3909 $data[
'errormsg'] =
'';
3912 if (!is_array($fld_value)) {
3913 $fld_value = htmlspecialchars((
string) $fld_value, ENT_QUOTES,
'UTF-8');
3915 if (!isset($data[
'checked']) && $fld_value !==
'' && $fld_value !==
'0') {
3916 $data[
'checked'] =
'checked';
3919 if (!isset($data[
'checked'])) {
3920 $data[
'checked'] =
'';
3928 $data[
'class'] = $data[
'class'] ??
'';
3929 $data[
'style'] = $data[
'style'] ??
'';
3930 $data[
'tooltip'] = $data[
'tooltip'] ??
'';
3931 $data[
'errormsg'] = $data[
'errormsg'] ??
'';
3933 foreach (array(
'placeholder') as $htmlKey) {
3934 if (isset($data[$htmlKey]) && !is_array($data[$htmlKey])) {
3935 $data[$htmlKey] = htmlspecialchars((
string)$data[$htmlKey], ENT_QUOTES,
'UTF-8');
3939 foreach (array(
'tooltip',
'errormsg') as $htmlAttributeKey) {
3940 if (isset($data[$htmlAttributeKey]) && !is_array($data[$htmlAttributeKey])) {
3941 $data[$htmlAttributeKey] = htmlspecialchars(str_replace(
'"',
"'", (
string)$data[$htmlAttributeKey]), ENT_QUOTES,
'UTF-8');
3945 $this->prepare_report_search_fld($name,
$tpl, $data);
3947 if ($this->is_search_field_tpl(
$tpl)) {
3948 $data = $this->prepare_search_tpl_data(
3951 is_array($fld_value) ?
'' : (
string)$fld_value,
3954 $tpl = trim((
string)($data[
'label'] ??
'')) ===
''
3956 :
'dbx|search-label';
3962 $oid = $name .
'_options';
3963 $options_vals = $fld_value;
3965 if (!is_array($options_vals)) {
3966 $options_vals = explode(
',', (
string) $options_vals);
3969 $selected_lookup = array();
3970 foreach ($options_vals as $keyval) {
3971 $selected_lookup[(string) $keyval] =
true;
3974 foreach (
$options as $key => $description) {
3975 $selected = isset($selected_lookup[(
string) $key]) ?
'selected' :
'';
3977 $xoptions .=
'<option value="' . htmlspecialchars((
string) $key, ENT_QUOTES,
'UTF-8') .
'" ' . $selected .
'>' .
3978 htmlspecialchars((
string) $description, ENT_QUOTES,
'UTF-8') .
3982 $tpl = str_replace(
'{' . $oid .
'}', $xoptions,
$tpl);
3985 $tpl = $this->oTPL->replaces(
$tpl, $this->_replaces);
3987 if (!is_array($fld_value)) {
3988 $tpl = str_replace(
'{src}', $fld_value,
$tpl);
3989 $tpl = str_replace(
'{value}', $fld_value,
$tpl);
3996 if ($field_markers !==
'') {
4024 $editor =
dbx()->get_system_var(
'dbx_editor', 0,
'int');
4026 if (!$i && !$editor) {
4027 $i = $this->_next_i;
4030 foreach ($this->_flds as $fld_name => $fld) {
4033 if (!empty($fld[
'remap'])) {
4034 $slot = $fld[
'remap'];
4037 $fid =
'{obj:' . $slot .
'}';
4040 if (strpos(
$content, $fid) !==
false) {
4043 $form .= $fld_content .
"\n";
4047 if (strpos(
$content,
'[dbx:form]') !==
false) {
4068 $reset = $this->_try_reset;
4069 $max = $this->_try_max;
4070 $msg = $this->_try_msg;
4072 $self =
dbx()->get_self_url();
4073 $ip = (string)(
$_SERVER[
'REMOTE_ADDR'] ??
'');
4074 $sys = isset($this->
_sys[
'_try_sys']) ? $this->
_sys[
'_try_sys'] : array();
4076 if ((
$sys[
'dbx_try_ip'] ??
'') !== $ip) {
4078 'dbx_try_ip' => $ip,
4082 $sys[
'dbx_try_count'] =
$sys[
'dbx_try_count'] ?? 0;
4083 $sys[
'dbx_run_count'] =
$sys[
'dbx_run_count'] ?? 0;
4084 $sys[
'dbx_try_lock'] =
$sys[
'dbx_try_lock'] ?? 0;
4085 $sys[
'dbx_try_ip'] = $ip;
4088 $lastTry = (float) (
$sys[
'dbx_try_last'] ?? 0);
4090 if ($countReset > 0 && $lastTry > 0 && (
$now - $lastTry) > $countReset) {
4092 $sys[
'dbx_try_first'],
4093 $sys[
'dbx_try_last'],
4094 $sys[
'dbx_try_stop'],
4097 $sys[
'dbx_try_count'] = 0;
4098 $sys[
'dbx_try_lock'] = 0;
4101 $sys[
'dbx_run_count']++;
4107 $sys[
'dbx_try_count']++;
4109 if (
$sys[
'dbx_try_count'] >= $max) {
4110 if (!isset(
$sys[
'dbx_try_stop'])) {
4111 $sys[
'dbx_try_lock']++;
4113 for ($i = 1; $i <
$sys[
'dbx_try_lock']; $i++) {
4114 $reset = (int) ($reset * 2);
4118 $sys[
'dbx_try_run'] =
dbx()->timestamp($reset);
4122 if (isset(
$sys[
'dbx_try_run']) &&
$now >
$sys[
'dbx_try_run']) {
4130 if (($submit || $allways) && !$clear) {
4131 if ((
$sys[
'dbx_try_count'] ?? 0) >= $max && (
$sys[
'dbx_try_run'] ?? 0) > 0) {
4132 $diff =
dbx()->time_diff(
$now,
$sys[
'dbx_try_run']);
4136 'sec' => (
int) $diff,
4138 'try_count' =>
$sys[
'dbx_try_count'],
4139 'run_count' =>
$sys[
'dbx_run_count'],
4141 $data[
'msg'] = $this->oTPL->replaces((
string) $msg, $data);
4151 unset(
$sys[
'dbx_try_stop'],
$sys[
'dbx_try_run']);
4152 $sys[
'dbx_try_count'] = 0;
4179 $editor =
dbx()->get_system_var(
'dbx_editor', 0,
'int');
4181 $this->evaluate_request();
4183 $submit = $this->
submit();
4189 $this->_next_i = $i;
4194 $replaces = $this->_replaces;
4195 $replaces[
'form-id'] = $this->
_dbx_modul .
'-' . $this->_fid;
4196 foreach (array(
'form_shell_class' =>
'',
'form_class' =>
'',
'form_attrs' =>
'') as $shellKey => $shellDefault) {
4197 if (!isset($replaces[$shellKey]) || (
string)$replaces[$shellKey] ===
'') {
4198 $replaces[$shellKey] = $shellDefault;
4201 foreach (array(
'shell_panel_class' =>
'',
'shell_panel_attrs' =>
'',
'shell_body_class' =>
'') as $shellKey => $shellDefault) {
4202 if (!isset($replaces[$shellKey]) || (
string)$replaces[$shellKey] ===
'') {
4203 $replaces[$shellKey] = $shellDefault;
4210 $templateRef = strpos((
string)$this->_tpl,
'|') !==
false
4211 ? (string)$this->_tpl
4212 :
'modul|' . $this->_tpl;
4221 if ($tryContent !==
'') {
4222 $form_msg = $tryContent;
4226 $form_msg = $this->
get_form_msg(
'error', $this->_msg_error);
4228 $form_msg = $this->
get_form_msg(
'warning', $this->_msg_warning);
4230 $form_msg = $this->
get_form_msg(
'success', $this->_msg_success);
4233 $form_msg = $this->
get_form_msg(
'info', $this->_msg_info);
4241 if (is_array($this->_js)) {
4245 $norep_ids .=
dbx()->norep($norep, $i);
4281 foreach (array(
'cfg:',
'def:',
'mod:',
'fd:',
'dd:') as $prefix) {
4282 if (strpos(
$source, $prefix) === 0) {
4283 $mod = substr($prefix, 0, -1);
4284 $name = substr(
$source, strlen($prefix));
4289 if ($mod ===
'dd' && strpos(
$source,
'|') !==
false) {
4294 if ($mod ===
'dd') {
4295 if (method_exists($this->
oDB,
'get_dd_file')) {
4296 return (
string) $this->
oDB->get_dd_file($name);
4301 return dbx()->get_base_dir() .
"dbx/modules/$modul/dd/$name.dd.php";
4308 $dd_file =
dbx()->get_base_dir() .
"dbx/modules/$name/cfg/config.dd.php";
4312 $dd_file =
dbx()->get_base_dir() .
"dbx/modules/$name/dd/$name.dd.php";
4316 $modul =
dbx()->get_system_var(
'dbx_activ_modul',
'dbx');
4317 $dd_file =
dbx()->get_base_dir() .
"dbx/modules/$modul/dd/$name.dd.php";
4324 if (strpos($name,
'|') !==
false) {
4325 $parts = explode(
'|', $name, 2);
4326 $fd_modul = trim($parts[0]);
4327 $fd_name = trim($parts[1]);
4330 if ($fd_modul ===
'') {
4331 $fd_modul =
dbx()->get_system_var(
'dbx_activ_modul',
'dbx');
4334 $dd_file = function_exists(
'dbx_lng_resolve_file')
4343 if ($dd_file ===
'' || !is_file($dd_file)) {
4344 $dd_file =
dbx()->get_base_dir() .
"dbx/modules/$fd_modul/fd/$fd_name.fd.php";
4349 if ($dd_file ===
'') {
4353 $real_file = realpath(
dbx()->
os_path($dd_file));
4355 return $real_file ? $real_file : $dd_file;
4366 foreach (array(
'fd' => $this->
_fd,
'dd' => $this->_dd) as $kind =>
$source) {
4373 $marker =
dbx()->editor_marker($kind,
$file);
4375 if ($marker !==
'' && strpos($markers, trim($marker)) ===
false) {
4376 $markers .= $marker;
4427 $this->_workflow_scope = trim(
$scope);
4437 return $this->_workflow_scope;
4447 private function normalize_state_token(
string $token): string {
4454 return preg_replace(
'/[^a-zA-Z0-9._-]+/',
'_',
$token);
4473 $modul = $this->normalize_state_token((string) $this->
_dbx_modul);
4474 $scope = $this->normalize_state_token((
string) $this->_workflow_scope);
4475 $fid = $this->normalize_state_token((
string) $this->_fid);
4477 return 'dbx.form.state.' . $modul .
'.' .
$scope .
'.' . $fid;
4485 private function get_default_workflow_state(): array {
4494 'depends_on' => array(),
4495 'depends_version' => array(),
4506 $state =
dbx()->get_remember_var($key, $this->get_default_workflow_state(),
'dbx');
4509 $state = $this->get_default_workflow_state();
4512 $this->_workflow_state = array_merge($this->get_default_workflow_state(),
$state);
4514 if ((
int) ($this->_workflow_state[
'rid'] ?? 0) > 0 && !$this->
_rid) {
4515 $this->
_rid = (int) $this->_workflow_state[
'rid'];
4518 return $this->_workflow_state;
4528 dbx()->set_remember_var($key, $this->_workflow_state,
'dbx');
4537 $this->_workflow_state = $this->get_default_workflow_state();
4550 $this->_workflow_state[$key] =
$value;
4563 if (!array_key_exists($key, $this->_workflow_state)) {
4567 return $this->_workflow_state[$key] ?? $default;
4586 if ($draftId ===
'' && $createIfMissing) {
4587 $draftId = $this->create_draft_id();
4610 private function create_draft_id(): string {
4611 return
'dft_' . md5($this->
_dbx_modul .
'|' . $this->_fid .
'|' . microtime(true) .
'|' . mt_rand());
4735 foreach ($formIds as $formId) {
4736 $deps[] = $this->normalize_state_token((
string) $formId);
4755 if ($formIds ===
null) {
4759 $versions = array();
4761 foreach ($formIds as $formId) {
4763 $versions[$formId] = (int) (
$state[
'version'] ?? 0);
4783 if (!is_array($dependsOn) || !$dependsOn) {
4787 foreach ($dependsOn as $formId) {
4788 $state = $this->get_external_form_state((
string) $formId);
4789 $currentVersion = (int) (
$state[
'version'] ?? 0);
4790 $savedVersion = (int) ($dependsVersion[$formId] ?? -1);
4792 if ($currentVersion !== $savedVersion) {
4796 if ((
int) (
$state[
'is_valid'] ?? 0) !== 1) {
4812 $modul = $this->normalize_state_token((string) $this->
_dbx_modul);
4813 $scope = $this->normalize_state_token((
string) $this->_workflow_scope);
4814 $fid = $this->normalize_state_token($fid);
4816 $key =
'dbx.form.state.' . $modul .
'.' .
$scope .
'.' . $fid;
4817 $state =
dbx()->get_remember_var($key, $this->get_default_workflow_state(),
'dbx');
4819 return is_array(
$state) ?
$state : $this->get_default_workflow_state();
Zentrale Laufzeit-API von dbXapp.
Gemeinsame Basisklasse fuer dbXapp-System-, Modul- und Include-Objekte.
set_callback_id(string $id)
Setzt den Namenspraefix fuer konventionelle Callback-Methoden.
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.
callback(string $event, mixed $value)
Fuehrt einen Callback aus und gibt dessen Rueckgabewert zurueck.
dbx()
Liefert die zentrale dbXapp-API als Singleton.
os_path(string $path)
Normalisiert einen Pfad fuer das aktuelle Betriebssystem.
get_base_dir(int $cutData=0)
Liefert das Basisverzeichnis der Installation.
search_defaults(array $overrides=array())
Standard-Optionen fuer dbx|search (wie Content-Grid).
dbx_lng_resolve_file(string $dir, string $name, string $ext, string $lng='', bool $fallback=true)
Datei mit Sprachsuffix aufloesen: name_lng.ext mit Fallback name.ext.
$_SERVER['REQUEST_METHOD']
if($stored !=='files/test/') $resolved
if(($result['name'] ?? '') !=='customer-design'||!is_dir($target)) if(substr_count( $defaultHtml, '[dbx:content]') !==1) foreach(array('[dbx:logo]', '[dbx:branding]', '[dbx:footer]') as $slot) if(( $metadata[ 'contract'] ?? '') !==\dbx\dbxDesign_admin\dbxDesignService::CONTRACT) if((dbx() ->config['dbx']['default_design_user'] ?? '') !=='customer-design') $validation
if(preg_match('/core\.js\? foreach[^"\']*v=(\d+)/', $designTemplate, $assetMatch) !== 1 || !str_contains($shopReference, 'dbxapp-Asset-Version ' . $assetMatch[1])) foreach (array( 'reference\\archive', 'provision_docs_content.php', 'dbxSelfTest') as $needle)(array('Installation'=> $installation, 'Installations-Tutorial'=> $installationTutorial, 'SelfTest'=> $selfTest) as $label=> $html)
if($web->content_permalink_redirect_target() !=='') $tpl
if(!defined( 'IMG_WEBP')) define( 'IMG_WEBP'
foreach( $valid as $email) foreach($invalid as $email) $fd
if(!is_object($db)||! $db->connect_db_server('dbx|dbxContent.db3')) $help
DBX schema administration.