dbXapp 2.0
RAD, CMS, Module und Runtime-IDE fuer dbXapp
Loading...
Searching...
No Matches
dbxApi.php
Go to the documentation of this file.
1<?php
11
12//include_once dbx_os_path_file(dbx_get_base_dir().'dbx/add_ons/sftp/vendor/autoload.php');
13//use phpseclib3\Crypt\AES;
14use \phpseclib3\Crypt\AES;
15
17
18function dbx_log_missing_entry($missing = '') {
19 return function_exists('dbx') ? (int) dbx()->log_missing($missing) : 0;
20}
21
40class dbxApi {
41
43 public array $editor_files = array();
44
46 private array $owner_stack = array();
47
49 private bool $sys_msg_running = false;
50
52 private array $timer_state = array();
53
55 private array $admin_bypass_user = array();
56
58 private bool $admin_bypass_user_loaded = false;
59
61 private bool $admin_bypass_user_loading = false;
62
72 public function push_owner($owner): void {
73 if (is_object($owner)) {
74 $this->owner_stack[] = $owner;
75 }
76 }
77
83 public function pop_owner(): void {
84 if ($this->owner_stack) {
85 array_pop($this->owner_stack);
86 }
87 }
88
98 public function set_current_owner($owner): void {
99 if (is_object($owner)) {
100 if ($this->owner_stack) {
101 $this->owner_stack[count($this->owner_stack) - 1] = $owner;
102 } else {
103 $this->owner_stack[] = $owner;
104 }
105 }
106 }
107
113 public function get_current_owner() {
114 if (!$this->owner_stack) {
115 return null;
116 }
117
118 return $this->owner_stack[count($this->owner_stack) - 1];
119 }
120
135 public function run_owner($owner, string $method = 'run', ...$args) {
136 if (!is_object($owner) || !is_callable(array($owner, $method))) {
137 return null;
138 }
139
140 $this->push_owner($owner);
141
142 try {
143 return $owner->$method(...$args);
144 } finally {
145 $this->pop_owner();
146 }
147 }
148
167 public function get_system_obj(string $class, string $use = ''): ?object {
168 global $_dbxCache;
169
170 if (!preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $class)) {
171 throw new Exception("Invalid system class name '$class'.");
172 }
173
174 if (isset($_dbxCache[$class])) {
175 return !$use ? $_dbxCache[$class] : null;
176 }
177
178 $baseClass = '\\' . $class;
179 $baseFile = dbx_os_path_file(dbx_get_base_dir() . "dbx/include/" . $class . ".class.php");
180
181 if (file_exists($baseFile)) {
182 require_once $baseFile;
183 } else {
184 $baseClass = "\\dbxUndefClass";
185 }
186
187 $myClass = $this->get_SysClassOverrideName($class);
188 $myFile = $this->ensure_SysClassOverride($class, $myClass, $baseClass);
189
190 if ($myFile && file_exists($myFile)) {
191 $this->register_editor_file('sysclass', $myFile);
192 require_once $myFile;
193 }
194
195 $myClassFull = '\\' . $myClass;
196 $createClass = class_exists($myClassFull, false) ? $myClassFull : $baseClass;
197
198 if ($use) {
199 return null;
200 }
201
202 if (class_exists($createClass)) {
203 $_dbxCache[$class] = new $createClass();
204 return $_dbxCache[$class];
205 }
206
207 throw new Exception("Klasse '$createClass' konnte nicht geladen werden.");
208 }
209
216 public function editor_file_path(string $file): string {
217 $file = str_replace('\\', '/', $file);
218 $base = str_replace('\\', '/', dbx_get_base_dir());
219
220 if (strpos($file, $base) === 0) {
221 $file = substr($file, strlen($base));
222 }
223
224 return ltrim($file, '/');
225 }
226
234 public function register_editor_file(string $kind, string $file): void {
235 $kind = strtolower(trim($kind));
236 $file = trim($file);
237
238 if ($kind === '' || $file === '') {
239 return;
240 }
241
242 $path = $this->editor_file_path($file);
243 $key = $kind . '|' . $path;
244 $this->editor_files[$key] = array('kind' => $kind, 'file' => $path);
245 }
246
252 public function get_editor_files(): array {
253 return $this->editor_files;
254 }
255
270 public function editor_marker(string $kind, string $file): string {
271 $kind = strtolower(trim($kind));
272 $mode = (int) $this->get_system_var('dbx_edit', 0, 'int');
273 $modes = array('fd' => 4, 'dd' => 5, 'class' => 6, 'sysclass' => 7, 'config' => 8);
274
275 if (!isset($modes[$kind]) || ($mode !== 9 && $mode !== $modes[$kind]) || $file === '') {
276 return '';
277 }
278
279 $path = $this->editor_file_path($file);
280 $path = str_replace('--', '-', $path);
281
282 return "\n<!-- DBX-EDITOR|$kind|$path -->\n";
283 }
284
304 public function get_modul_obj(string $class): object {
305 // Vollqualifizierten Klassennamen vorbereiten
306 $namespace_class = '\dbx\-class-\-class-';
307 $namespace_class = str_replace('-class-', $class, $namespace_class);
308
309 // Modul-ID auslesen und inkrementieren
310 $modul_id = $this->get_system_var('dbx_activ_modul_id', 0, '*');
311 $modul_id++;
312 $this->set_system_var('dbx_activ_modul_id', $modul_id);
313
314 // Modulname in System- und Modulvariablen speichern
315 $this->set_system_var('dbx_activ_modul', $class);
316 $this->set_modul_var('dbx_modul_id', $modul_id);
317 $this->set_modul_var('dbx_modul', $class);
318
319 // Admin-spezifisches Design anwenden, falls Modul ein Admin-Modul ist
320 if (stripos($class, 'admin') !== false) {
321 //$admin_design = $this->get_config('dbx', 'default_design_admin');
322 //$this->set_system_var('dbx_design', $admin_design);
323 }
324
325 // Pfad zur Klassen-Datei des Moduls berechnen
326 $modul_class_file = dbx_os_path_file(dbx_get_base_dir() . "dbx/modules/$class/$class.class.php");
327
328 // Klassen-Datei einbinden, wenn vorhanden
329 if (file_exists($modul_class_file)) {
330 $this->register_editor_file('class', $modul_class_file);
331 require_once $modul_class_file;
332 } else {
333 // Fallback-Klasse verwenden, falls die Datei fehlt
334 $namespace_class = "\\dbxUndefClass";
335 }
336
337 // Prüfen, ob die Klasse existiert, und Instanz erstellen
338 if (class_exists($namespace_class)) {
339 $object = new $namespace_class();
340 if (method_exists($object, 'set_editor_class_file')) {
341 $object->set_editor_class_file($modul_class_file);
342 }
343 $this->set_current_owner($object);
344 return $object;
345 }
346
347 // Fehler werfen, falls die Klasse nicht existiert
348 throw new Exception("Modul-Klasse '$namespace_class' konnte nicht geladen werden.");
349 }
350
371 public function get_include_obj(string $class, string $modul = '', string $use = ''): ?object {
372 // Aktuelles Modul verwenden, wenn keins angegeben wurde
373 if (!$modul) {
374 $modul = $this->get_system_var('dbx_activ_modul', 'dbx', '*');
375 }
376
377 // Systemvariable für das aktuell geladene Include setzen
378 $this->set_system_var('dbx_inc', $class);
379
380 // Vollqualifizierten Klassennamen generieren
381 $namespace_class = '\dbx\-modul-\-class-';
382 $namespace_class = str_replace('-modul-', $modul, $namespace_class);
383 $namespace_class = str_replace('-class-', $class, $namespace_class);
384
385 // Pfad zur Klassen-Datei bestimmen
386 $modul_class_file = dbx_os_path_file(dbx_get_base_dir() . "dbx/modules/$modul/include/$class.class.php");
387
388 // Klassen-Datei einbinden, wenn sie existiert
389 if (file_exists($modul_class_file)) {
390 $this->register_editor_file('class', $modul_class_file);
391 require_once $modul_class_file;
392 } else {
393 // Fallback-Klasse verwenden, falls Datei fehlt
394 $namespace_class = "\\dbxUndefClass";
395 }
396
397 // Objekt erstellen und zurückgeben, falls $use nicht gesetzt ist
398 if (!$use) {
399 if (class_exists($namespace_class)) {
400 $object = new $namespace_class();
401 if (method_exists($object, 'set_editor_class_file')) {
402 $object->set_editor_class_file($modul_class_file);
403 }
404 $this->set_current_owner($object);
405 return $object;
406 }
407
408 // Fehler werfen, falls die Klasse nicht existiert
409 throw new Exception("Klasse '$namespace_class' konnte nicht geladen werden.");
410 }
411
412 // Keine Rückgabe, wenn $use gesetzt ist
413 return null;
414 }
415
427 public function use_system_class($class) {
428 $modul_id=0;
429 $dbx_class_file=dbx_get_base_dir()."dbx/include/".$class.".class.php";
430 $dbx_class_file=dbx_os_path_file($dbx_class_file);
431
432
433 if (file_exists($dbx_class_file)) {
434 require_once $dbx_class_file;
435 }
436 }
437
455 public function get_system_var(string $varname, $default = '', string $rules = '*') {
456 // Initialisierung der Rückgabevariable
457 $value = $default;
458 $danger_value = '';
459
460 // Überprüfen, ob die Variable in der Session vorhanden ist
461 if (isset($_SESSION['dbx']['tmp'][0]['dbx'][$varname])) {
462 $danger_value = $_SESSION['dbx']['tmp'][0]['dbx'][$varname];
463 } else {
464 // Wenn nicht, nach der Variable in GET oder POST suchen
465 if (isset($_GET[$varname])) {
466 $danger_value = $_GET[$varname];
467 }
468 if (isset($_POST[$varname])) {
469 $danger_value = $_POST[$varname];
470 }
471 }
472
473 // Wenn ein Wert vorhanden und gültig ist, validieren und zurückgeben
474 if (($danger_value !== '') && ($danger_value !== null)) {
475 if (dbx_validate_var($danger_value, $rules, $varname)) {
476 $value = $danger_value;
477 }
478 }
479
480 // Rückgabe des validierten Werts oder des Standardwerts
481 return $value;
482 }
483
499 public function set_system_var(string $varname, $value) {
500 // Speichert den Wert der Systemvariable in der Session
501 $_SESSION['dbx']['tmp'][0]['dbx'][$varname] = $value;
502 }
503
520 public function get_modul_var($varname, $default = '', $rules = 'alphanum') {
521 // Standardwert initialisieren
522 $value = $default;
523
524 // Das aktive Modul und die Modul-ID holen
525 $modul = $this->get_system_var('dbx_activ_modul', 'undef', '*');
526 $mid = $this->get_system_var('dbx_activ_modul_id', 88888, '*');
527
528 // Versuchen, die Variable aus der Session zu holen
529 if (isset($_SESSION['dbx']['tmp'][$mid][$modul][$varname])) {
530 $danger_value = $_SESSION['dbx']['tmp'][$mid][$modul][$varname];
531 } else {
532 // Wenn nicht in der Session, versuche GET und POST
533 $danger_value = '';
534
535 if (isset($_GET[$varname])) {
536 $danger_value = $_GET[$varname];
537 }
538
539 if (isset($_POST[$varname])) {
540 $danger_value = $_POST[$varname];
541 }
542 }
543
544 // Wenn ein Wert vorhanden ist und er gültig ist, validiere den Wert
545 if ($danger_value !== '' && $danger_value !== null && dbx_validate_var($danger_value, $rules, $varname)) {
546 $value = $danger_value;
547 }
548
549 // Rückgabe des Werts (entweder der gefundene gültige Wert oder der Standardwert)
550 return $value;
551 }
552
556 public function get_modul_request_var($varname, $default = '', $rules = '*') {
557 return $this->get_modul_var($varname, $default, $rules);
558 }
559
577 public function set_modul_var($varname, $value = null, $check_protected = true) {
578 // Das aktive Modul und die Modul-ID holen
579 $mid = $this->get_system_var('dbx_activ_modul_id', 0, 'int');
580 $modul = $this->get_system_var('dbx_activ_modul', 'dbx', 'parameter');
581
582 // Geschützte ModulVariablen prüfen.
583 // Wichtig: Schutzliste nur aus der echten ModulVar-Session lesen,
584 // nicht ueber $this->get_modul_var(), damit GET/POST hier niemals mitreden.
585 if ($check_protected) {
586 $protected = array();
587 if (isset($_SESSION['dbx']['tmp'][$mid][$modul]['dbx_protected_modulvars'])) {
588 $protected = $_SESSION['dbx']['tmp'][$mid][$modul]['dbx_protected_modulvars'];
589 }
590 if (is_array($protected) && array_key_exists($varname, $protected)) {
591 dbx()->debug("PROTECTED ($varname)");
592 return;
593 }
594 }
595
596 // Setze den Wert in der Session
597 $_SESSION['dbx']['tmp'][$mid][$modul][$varname] = $value;
598
599 // Optional: Debugging-Informationen hinzufügen
600 // dbx_debug("dbx_set_ModulVar modul=($modul) Mod=($mid) Var=($varname) val=($value)");
601 }
602
618 public function req(string $varname, $default = '', string $rules = 'parameter') {
619 // Standardwert initialisieren
620 $value = $default;
621 $danger_value = '';
622
623 // Prüfen, ob die Variable in GET oder POST vorhanden ist
624 if (isset($_GET[$varname])) {
625 $danger_value = $_GET[$varname];
626 }
627 if (isset($_POST[$varname])) {
628 $danger_value = $_POST[$varname];
629 }
630
631 // Wenn ein Wert vorhanden ist und nicht null ist, validieren
632 if (($danger_value !== '') && ($danger_value !== null)) {
633 if (dbx_validate_var($danger_value, $rules, $varname)) {
634 $value = $danger_value;
635 }
636 }
637
638 // Rückgabe des validierten Werts oder des Standardwerts
639 return $value;
640 }
641
650 public function get(string $varname, $default = '', string $rules = 'parameter') {
651 // Standardwert initialisieren
652 $value = $default;
653
654 // Prüfen, ob die GET-Variable gesetzt ist
655 if (isset($_GET[$varname])) {
656 $danger_value = $_GET[$varname];
657
658 // Validierung des Werts
659 if (dbx_validate_var($danger_value, $rules, $varname)) {
660 $value = $danger_value;
661 }
662 }
663
664 // Rückgabe des validierten Werts oder des Standardwerts
665 return $value;
666 }
667
676 public function post(string $varname, $default = '', string $rules = 'parameter') {
677 // Standardwert initialisieren
678 $value = $default;
679
680 // Prüfen, ob die POST-Variable gesetzt ist
681 if (isset($_POST[$varname])) {
682 $danger_value = $_POST[$varname];
683
684 // Validierung des Werts
685 if (dbx_validate_var($danger_value, $rules, $varname)) {
686 $value = $danger_value;
687 }
688 }
689
690 // Rückgabe des validierten Werts oder des Standardwerts
691 return $value;
692 }
693
697 public function get_request_var(string $varname, $default = '', string $rules = 'parameter') {
698 return $this->req($varname, $default, $rules);
699 }
700
704 public function get_query_var(string $varname, $default = '', string $rules = 'parameter') {
705 return $this->get($varname, $default, $rules);
706 }
707
711 public function get_post_var(string $varname, $default = '', string $rules = 'parameter') {
712 return $this->post($varname, $default, $rules);
713 }
714
732 public function get_config(string $modul = 'dbx', string $key = '', $default = null) {
733 $moduleConfigFile = dbx_os_path_file(dbx_get_base_dir() . "dbx/modules/$modul/cfg/config.php");
734
735 if (file_exists($moduleConfigFile)) {
736 $_SESSION['dbx']['config_file'][$modul] = $moduleConfigFile;
737 $this->register_editor_file('config', $moduleConfigFile);
738 }
739
740 // Prüfen, ob die Konfiguration bereits im Session-Cache vorhanden ist
741 if (!isset($_SESSION['dbx']['config'][$modul])) {
742 $config = [];
743 $content = '';
744
745 $dir_file = $moduleConfigFile;
746 if (file_exists($dir_file)) {
747 $_SESSION['dbx']['config_file'][$modul] = $dir_file;
748 $this->register_editor_file('config', $dir_file);
749 $content = file_get_contents($dir_file);
750 }
751
752 // Wenn Inhalt vorhanden ist, diesen ausführen
753 if ($content) {
754 $clean_code = str_replace(['<?php', '?>'], '', $content);
755
756 // Benutzerdefinierte Fehlerbehandlung für eval()
757 set_error_handler(function ($errno, $errstr, $errfile, $errline) {
758 throw new Exception("Fehler in eval() Code: $errstr in Zeile $errline");
759 });
760
761 try {
762 eval($clean_code); // Führt den bereinigten Code aus
763 } catch (Exception $e) {
764 echo "Fehler: " . $e->getMessage();
765 } finally {
766 restore_error_handler(); // Fehlerbehandlung zurücksetzen
767 }
768 }
769
770 // Standardgruppe setzen, falls keine Gruppen definiert sind
771 if (!isset($config['groups'])) {
772 $config['groups'] = ['admin'];
773 } elseif (!is_array($config['groups'])) {
774 $config['groups'] = array_filter(explode(',', $config['groups']));
775 }
776
777 $fileDefaults = $this->read_module_config_defaults($modul);
778 if (is_array($fileDefaults) && count($fileDefaults)) {
779 $config = array_merge($fileDefaults, $config);
780 }
781
782 // Konfiguration im Session-Cache speichern
783 $_SESSION['dbx']['config'][$modul] = $config;
784 }
785
786 // Konfiguration aus dem Cache laden
787 $config = $_SESSION['dbx']['config'][$modul];
788
789 static $configDefaultsMerged = array();
790 if (!isset($configDefaultsMerged[$modul])) {
791 $fileDefaults = $this->read_module_config_defaults($modul);
792 if (is_array($fileDefaults) && count($fileDefaults)) {
793 $merged = array_merge($fileDefaults, $config);
794 if ($merged !== $config) {
795 $config = $merged;
796 $_SESSION['dbx']['config'][$modul] = $config;
797 }
798 }
799 $configDefaultsMerged[$modul] = 1;
800 }
801
802 // Spezifischen Schlüssel zurueckgeben, falls angegeben
803 if ($key) {
804 if (!array_key_exists($key, $config)) {
805 return $default !== null ? $default : 'undef';
806 }
807
808 $val = $config[$key];
809 if (($val === 'undef' || $val === '' || $val === null) && $default !== null) {
810 return $default;
811 }
812
813 return $val;
814 }
815
816 // Gesamte Konfiguration zurückgeben
817 return $config;
818 }
819
826 private function read_module_config_defaults(string $modul): array {
827 if ($modul === 'dbx') {
828 $dir_file = dbx_os_path_file(dbx_get_base_dir() . 'dbx/modules/dbx/cfg/config.php');
829 } else {
830 $dir_file = dbx_os_path_file(dbx_get_base_dir() . "dbx/modules/$modul/cfg/config.php");
831 }
832 if (!is_file($dir_file) || !is_readable($dir_file)) {
833 return array();
834 }
835
836 $config = array();
837 $content = file_get_contents($dir_file);
838 if (!is_string($content) || $content === '') {
839 return array();
840 }
841
842 $clean_code = str_replace(array('<?php', '?>'), '', $content);
843 set_error_handler(function ($errno, $errstr, $errfile, $errline) {
844 throw new \Exception("Fehler in config.php: $errstr in Zeile $errline");
845 });
846
847 try {
848 eval($clean_code);
849 } catch (\Exception $e) {
850 $config = array();
851 } finally {
852 restore_error_handler();
853 }
854
855 return is_array($config) ? $config : array();
856 }
857
870 public function set_config(string $modul, array $config): int {
871 $content = "<?php \n"; // PHP-Tag hinzufügen, um die Datei als ausführbaren Code zu speichern
872 $dir = dbx_get_base_dir() . "dbx/modules/$modul/cfg/";
873 if (isset($config['form-config-edit'])) unset($config['form-config-edit']);
875
876 $dir_file = dbx_os_path_file($dir . 'config.php');
878
879 // Konfigurationsarray in PHP-Code konvertieren
880 if (is_array($config)) {
881 $_SESSION['dbx']['config'][$modul] = $config; // Cache aktualisieren
882 $content .= dbx_convertArrayToPHPCode($config, '$config'); // Array in PHP-Code umwandeln
883 }
884
885 // Verzeichnis erstellen, falls es nicht existiert
886 if (!is_dir($dir)) {
887 mkdir($dir, 0700, true);
888 }
889
890 // Dateiinhalt schreiben und Erfolg prüfen
891 $ok = file_put_contents($dir_file, $content);
892 dbx()->debug("#CFG write ok=($ok) file=($dir_file)");
893 if ($ok) {
894 $_SESSION['dbx']['config_file'][$modul] = $dir_file;
895 $this->register_editor_file('config', $dir_file);
896 }
897
898
899 return $ok ?: 0; // Gibt 0 zurück, falls `file_put_contents` fehlschlägt
900 }
901
926 public function send_mail($from, $to, string $subject = '', string $body = '', string $format = 'html', $attachments = array(), array $options = array()): int {
927 $mail = $this->get_system_obj('dbxMail');
928 if (!$mail) {
929 return 0;
930 }
931
932 $mail->init();
933 $options['from'] = $from;
934
935 $format = strtolower(trim($format));
936 if ($format === 'txt') {
937 $format = 'text';
938 }
939
940 if ($format === 'html') {
941 $mail->bodyhtml($body);
942 if (isset($options['text'])) {
943 $mail->bodytext((string) $options['text']);
944 }
945 } else {
946 $mail->bodytext($body);
947 }
948
949 foreach ($this->normalize_mail_attachments($attachments) as $attachment) {
950 if (is_array($attachment)) {
951 $mail->attachfile(
952 (string) ($attachment['path'] ?? $attachment['file'] ?? ''),
953 (string) ($attachment['disposition'] ?? 'attachment'),
954 (string) ($attachment['content_type'] ?? $attachment['type'] ?? ''),
955 (string) ($attachment['cid'] ?? '')
956 );
957 } else {
958 $mail->attachfile((string) $attachment);
959 }
960 }
961
962 return (int) $mail->send($to, $subject, $options);
963 }
964
965 private function normalize_mail_attachments($attachments): array {
966 if ($attachments === null || $attachments === '') {
967 return array();
968 }
969
970 if (is_string($attachments)) {
971 return array_filter(array_map('trim', preg_split('/[;,]+/', $attachments)));
972 }
973
974 if (is_array($attachments)) {
975 if (isset($attachments['path']) || isset($attachments['file'])) {
976 return array($attachments);
977 }
978 return $attachments;
979 }
980
981 return array();
982 }
983
1000 public function get_remember_var(string $varname, $default = '', string $modul = 'modul') {
1001 // Initialisierung der Rückgabevariable
1002 $value = $default;
1003 $danger_value = '';
1004
1005 // Wenn das Modul nicht angegeben ist, den aktiven Modulnamen aus der Session holen
1006 if ($modul == 'modul') {
1007 $modul = $this->get_system_var('dbx_activ_modul', 'dbx', '*');
1008 }
1009
1010 // Überprüfen, ob die Variable in der Session unter der richtigen Modul-Sektion existiert
1011 if (isset($_SESSION['dbx']['remember'][$modul][$varname])) {
1012 $value = $_SESSION['dbx']['remember'][$modul][$varname];
1013 }
1014
1015 // Rückgabe des validierten Werts oder des Standardwerts
1016 return $value;
1017 }
1018
1035 public function set_remember_var(string $varname, $value, string $modul = 'modul') {
1036 // Wenn das Modul nicht angegeben ist, den aktiven Modulnamen aus der Session holen
1037 if ($modul == 'modul') {
1038 $modul = $this->get_system_var('dbx_activ_modul', 'dbx', '*');
1039 }
1040
1041 // Setzt den Wert der Variable in der Session unter der "remember"-Sektion
1042 $_SESSION['dbx']['remember'][$modul][$varname] = $value;
1043
1044 // Wenn das Modul 'dbx' ist, wird der Wert auch in der System-Session gespeichert
1045 if ($modul == 'dbx') {
1046 $this->set_system_var($varname, $value);
1047 }
1048 }
1049
1064 public function get_session_var($key,$default=null,$section='sys',$modul='modul') {
1065 $val=$default;
1066 if ($modul=='modul') $modul =$this->get_system_var('dbx_activ_modul' ,'dbx');
1067 if ($key != '*') {
1068 if (isset($_SESSION['dbx']['session'][$modul][$section][$key])) {
1069 $val=$_SESSION['dbx']['session'][$modul][$section][$key];
1070 }
1071 } else {
1072 if (isset($_SESSION['dbx']['session'][$modul][$section])) {
1073 $val=$_SESSION['dbx']['session'][$modul][$section];
1074 }
1075 }
1076 return $val;
1077 }
1078
1088 public function set_session_var($key,$val,$section='sys',$modul='') {
1089 if (!$modul) $modul =$this->get_system_var('dbx_activ_modul' ,'dbx');
1090 if ($key != '*') $_SESSION['dbx']['session'][$modul][$section][$key]=$val;
1091 if ($key == '*') $_SESSION['dbx']['session'][$modul][$section]=$val;
1092 }
1101 public function delete_session_var($key,$section='sys',$modul='modul') {
1102 if ($modul=='modul') $modul =$this->get_system_var('dbx_activ_modul' ,'dbx');
1103 if ($key != '*') {
1104 if (isset($_SESSION['dbx']['session'][$modul][$section][$key])) {
1105 unset($_SESSION['dbx']['session'][$modul][$section][$key]);
1106 }
1107 }
1108 if ($key == '*') {
1109 if (isset($_SESSION['dbx']['session'][$modul][$section])) {
1110 unset($_SESSION['dbx']['session'][$modul][$section]);
1111 }
1112 }
1113 if ($key == '*' && $section=='*') {
1114 if (isset($_SESSION['dbx']['session'][$modul])) {
1115 unset($_SESSION['dbx']['session'][$modul]);
1116 }
1117 }
1118 //dbx_debug("DEL Session Store Key=($key) section=($section) Modul=($modul)");
1119
1120 }
1121
1128 public function action_token(string $scope = 'global'): string {
1129 $scope = preg_replace('/[^a-zA-Z0-9_.:-]/', '', $scope) ?: 'global';
1130 $tokens = $this->get_session_var('action_tokens', array(), 'security', 'dbx');
1131 if (!is_array($tokens)) {
1132 $tokens = array();
1133 }
1134
1135 if (empty($tokens[$scope]) || !preg_match('/^[a-f0-9]{64}$/', (string)$tokens[$scope])) {
1136 $tokens[$scope] = bin2hex(random_bytes(32));
1137 $this->set_session_var('action_tokens', $tokens, 'security', 'dbx');
1138 }
1139
1140 return (string)$tokens[$scope];
1141 }
1142
1150 public function check_action_token(string $scope = 'global', string $token = ''): bool {
1151 $scope = preg_replace('/[^a-zA-Z0-9_.:-]/', '', $scope) ?: 'global';
1152 $expected = $this->action_token($scope);
1153 return $token !== '' && hash_equals($expected, $token);
1154 }
1155
1168 public function user($key='id') {
1169 $current_user = $_SESSION['dbx']['current_user'] ?? array();
1170
1171 if (defined('dbxRunAsAdmin') && (int) constant('dbxRunAsAdmin') === 1) {
1172 $current_user = $this->get_admin_bypass_user($current_user);
1173 }
1174
1175 if ($key === '*') {
1176 return $current_user;
1177 }
1178
1179 return $current_user[$key] ?? null;
1180 }
1181
1192 private function get_admin_bypass_user(array $session_user = array()): array {
1193 if ((int)($session_user['id'] ?? 0) === 1) {
1194 return $session_user;
1195 }
1196
1197 if ($this->admin_bypass_user_loaded || $this->admin_bypass_user_loading) {
1198 return $this->admin_bypass_user;
1199 }
1200
1201 $this->admin_bypass_user = array_merge($session_user, array(
1202 'id' => 1,
1203 'uname' => 'admin',
1204 'roles' => 'admin',
1205 'email' => '',
1206 'name' => 'Admin',
1207 'design' => $session_user['design'] ?? 'default',
1208 'color' => $session_user['color'] ?? 'default',
1209 'language' => $session_user['language'] ?? 'de',
1210 'edit' => $session_user['edit'] ?? 0,
1211 ));
1212 $this->admin_bypass_user_loading = true;
1213
1214 try {
1215 $session = $this->get_system_obj('dbxSession');
1216 if (is_object($session) && method_exists($session, 'get_current_user')) {
1217 $admin_user = $session->get_current_user(1);
1218 if (is_array($admin_user) && (int)($admin_user['id'] ?? 0) === 1) {
1219 $this->admin_bypass_user = $admin_user;
1220 }
1221 }
1222 } catch (\Throwable $e) {
1223 // Der sichere Admin-Fallback bleibt auch ohne verfuegbare DB erhalten.
1224 } finally {
1225 $this->admin_bypass_user_loading = false;
1226 $this->admin_bypass_user_loaded = true;
1227 }
1228
1229 return $this->admin_bypass_user;
1230 }
1231
1244 public function can($access_groups = '', $user_groups = '') {
1245 $access = 0;
1246 if (defined('dbxRunAsAdmin') && (int) constant('dbxRunAsAdmin') === 1) return 1;
1247 if ($access_groups=='*') return 1;
1248 if (!$access_groups) return 1;
1249 $current_user_groups = !$user_groups;
1250 if ($current_user_groups) $user_groups = $_SESSION['dbx']['current_user']['roles'] ?? '';
1251
1252 if (!is_array($user_groups)) $user_groups = explode(',', $user_groups);
1253 if (!is_array($access_groups)) $access_groups = explode(',', $access_groups);
1254 $user_groups = array_map('trim', $user_groups);
1255 $access_groups = array_map('trim', $access_groups);
1256
1257 if ($current_user_groups && in_array('authenticated', $access_groups, true) && (int)$this->user() > 0) {
1258 return 1;
1259 }
1260
1261 foreach ($user_groups as $role) {
1262 if ($role === 'admin') return 1; // Immer Zugriff für Admins
1263
1264 foreach ($access_groups as $group) {
1265 if ($group === '*' || $group === $role) $access = 1;
1266 if ($access) break 2; // Beide Schleifen abbrechen
1267 }
1268 }
1269
1270 return $access;
1271 }
1272
1273 public function has_group($access_groups = '', $user_groups = '') {
1274 return $this->can($access_groups, $user_groups);
1275 }
1276
1282 public function is_dbx_edit(): bool {
1283 return (int) $this->get_system_var('dbx_edit', 0, 'int') > 0;
1284 }
1285
1286
1293 public function can_modul($modul) {
1294
1295 $access=0;
1296
1297 $current_user= $_SESSION['dbx']['current_user'] ?? array();
1298 $modul_config= $this->get_config($modul);
1299 $groups =$modul_config['groups'] ?? '';
1300 $uid =$current_user['id'] ?? 0;
1301 $install=$this->get_system_var('dbx_install',0,'int');
1302
1303 if (defined('dbxRunAsAdmin') && (int) constant('dbxRunAsAdmin') === 1) {
1304 return 1;
1305 }
1306 if ((int)$uid === 1) {
1307 return 1;
1308 }
1309
1310 $access = $install ? 1 : $this->can($groups);
1311
1312 if ($access==0) $this->set_system_var('dbx_noaccess_modul',"(User=$uid Modul=$modul)");
1313 return $access;
1314 }
1315
1328 public function login($uid=0,$remember=0) {
1329 $old=$this->user();
1330 dbx()->debug("API dbx_login von ($old) Zu ($uid)");
1331 if ($uid != $old) {
1332 $oSession=$this->get_system_obj('dbxSession');
1333 $oSession->login($uid,$remember);
1334
1335 $page = $this->get_base_url();
1336 $from = $this->user('email');
1337 $fromname = $this->user('name');
1338 $subject = 'Login ('.$from.') on ('.$page.') User=('.$uid.')';
1339 $text = $subject;
1340 //$this->sys_msg('info','login',$uid,$subject,'ok');
1341 //dbx_sendMail($from,$fromname,'login@dbxapp.de',$subject,$text,'text'); // #todo
1342
1343 }
1344 }
1345
1352 public function logout($uid=0) {
1353 if (!$uid) $uid=$this->user();
1354 dbx()->debug("API dbx_logout uid=($uid)");
1355 $oSession=$this->get_system_obj('dbxSession');
1356 $oSession->logout($uid);
1357 }
1358
1364 public function get_base_url() {
1365 return $this->get_system_var('dbx_base_url','','*');
1366 }
1367
1373 public function get_self_url() {
1374 return $this->get_system_var('dbx_self_url','','*');
1375 }
1376
1383 public function get_base_dir(int $cutData = 0): string {
1384 return dbx_get_base_dir($cutData);
1385 }
1386
1392 public function get_file_dir(): string {
1393 return dbx_get_file_dir();
1394 }
1395
1402 public function os_path(string $path): string {
1403 return dbx_os_path_file($path);
1404 }
1405
1413 public function json_response(array $data, bool $withRuntime = false): void {
1414 if ($withRuntime) {
1415 $runtime = number_format($this->current_php_runtime(), 3, '.', '');
1416 $data['dbx_php_runtime'] = $runtime;
1417 $data['_dbx_runtime'] = array('php' => $runtime);
1418 $this->send_runtime_headers();
1419 }
1420
1421 if (!headers_sent()) {
1422 header('Content-Type: application/json; charset=utf-8');
1423 }
1424
1425 echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
1426 exit;
1427 }
1428
1443 public function timer($section,$info='') {
1444 global $dbx_run_timer;
1445
1446 $empty = array();
1447 $time = microtime(true);
1448 $memory = memory_get_peak_usage();
1449
1450
1451 if (!isset($dbx_run_timer[$section])) {
1452 //dbx_debug("#TIMER NEW SET");
1453 $dbx_run_timer[$section]['start_time'] =$time;
1454 $dbx_run_timer[$section]['end_time'] =-1;
1455 $dbx_run_timer[$section]['start_memory']=$memory;
1456 $dbx_run_timer[$section]['end_memory'] =-1;
1457 $dbx_run_timer[$section]['time'] =-1;
1458 $dbx_run_timer[$section]['memory'] =-1;
1459 $dbx_run_timer[$section]['info'] =$info;
1460 $this->timer_state[$section] = array(
1461 'running' => 1,
1462 'segment_start_time' => $time,
1463 'segment_start_memory' => $memory,
1464 'segments' => 0,
1465 );
1466 } else {
1467 $state = $this->timer_state[$section] ?? array();
1468 $running = (int) ($state['running'] ?? (($dbx_run_timer[$section]['end_time'] ?? -1) == -1 ? 1 : 0));
1469
1470 if ($running) {
1471 //dbx_debug("#TIMER ADD SET");
1472 $segment_start_time = (float) ($state['segment_start_time'] ?? $dbx_run_timer[$section]['start_time'] ?? $time);
1473 $segment_start_memory = (int) ($state['segment_start_memory'] ?? $dbx_run_timer[$section]['start_memory'] ?? $memory);
1474 $time_sum = max(0, (float) ($dbx_run_timer[$section]['time'] ?? 0));
1475 $memory_sum = max(0, (int) ($dbx_run_timer[$section]['memory'] ?? 0));
1476
1477 $dbx_run_timer[$section]['end_time'] = $time;
1478 $dbx_run_timer[$section]['end_memory']= $memory;
1479 $dbx_run_timer[$section]['time'] = $time_sum + max(0, $time - $segment_start_time);
1480 $dbx_run_timer[$section]['memory'] = $memory_sum + max(0, $memory - $segment_start_memory);
1481 $this->timer_state[$section] = array(
1482 'running' => 0,
1483 'segment_start_time' => $segment_start_time,
1484 'segment_start_memory' => $segment_start_memory,
1485 'segments' => (int) ($state['segments'] ?? 0) + 1,
1486 );
1487 } elseif ($info !== '') {
1488 if (($dbx_run_timer[$section]['info'] ?? '') === '') {
1489 $dbx_run_timer[$section]['info'] = $info;
1490 }
1491
1492 $dbx_run_timer[$section]['end_time'] = -1;
1493 $dbx_run_timer[$section]['end_memory'] = -1;
1494 $this->timer_state[$section] = array(
1495 'running' => 1,
1496 'segment_start_time' => $time,
1497 'segment_start_memory' => $memory,
1498 'segments' => (int) ($state['segments'] ?? 0),
1499 );
1500 }
1501 }
1502 //dbx_debug("#TIMER ($section)",$dbx_run_timer);
1503
1504 }
1505
1511 public function skin_ids(): array {
1512 return array('hell', 'gelb', 'rot', 'gruen', 'blau', 'dunkel');
1513 }
1514
1521 public function normalize_skin(string $skin = ''): string {
1522 $skin = strtolower(trim($skin));
1523
1524 $map = array(
1525 'blue' => 'blau',
1526 'blau' => 'blau',
1527 'green' => 'gruen',
1528 'gruen' => 'gruen',
1529 'grün' => 'gruen',
1530 'red' => 'rot',
1531 'rot' => 'rot',
1532 'black' => 'dunkel',
1533 'dark' => 'dunkel',
1534 'dunkel' => 'dunkel',
1535 'yellow' => 'gelb',
1536 'gelb' => 'gelb',
1537 'light' => 'hell',
1538 'hell' => 'hell',
1539 'white' => 'hell',
1540 );
1541
1542 if ($skin !== '' && isset($map[$skin])) {
1543 $skin = $map[$skin];
1544 }
1545
1546 if ($skin === '' || !in_array($skin, $this->skin_ids(), true)) {
1547 $cfg = strtolower(trim((string) $this->get_config('dbx', 'default_color', 'blau')));
1548 $skin = $map[$cfg] ?? $cfg;
1549 }
1550
1551 if (!in_array($skin, $this->skin_ids(), true)) {
1552 $skin = 'blau';
1553 }
1554
1555 return $skin;
1556 }
1557
1563 public function get_skin(): string {
1564 return $this->normalize_skin((string) $this->get_system_var('dbx_color', ''));
1565 }
1566
1572 public function get_skin_css(): string {
1573 $skin = $this->get_skin();
1574 $design = (string) $this->get_system_var('dbx_activ_design', $this->get_system_var('dbx_design', 'dbxapp'));
1575
1576 return 'dbx/design/' . $design . '/css/skin-' . $skin . '.css';
1577 }
1578
1584 public function get_skin_class(): string {
1585 $skin = $this->get_skin();
1586 $cls = 'skin-' . $skin;
1587
1588 if ($skin === 'dunkel') {
1589 $cls .= ' theme-dark';
1590 }
1591
1592 return $cls;
1593 }
1594
1600 public function load_content_cache_classes(): void {
1601 static $loaded = false;
1602 if ($loaded) {
1603 return;
1604 }
1605
1606 require_once dbx_os_path_file(dbx_get_base_dir() . 'dbx/modules/dbxContent/include/dbxContent_bootstrap_sync.php');
1607 $loaded = true;
1608 }
1609
1615 public function get_content_permalink_mode(): string {
1616 $file = $this->os_path($this->get_base_dir() . 'dbx/modules/dbxContent/include/dbxContentLng.class.php');
1617 if (is_file($file)) {
1618 require_once $file;
1619 }
1620
1621 return class_exists('\dbx\dbxContent\dbxContentLng')
1623 : 'content';
1624 }
1625
1632 public function find_executable_path(string $command): string {
1633 static $cache = array();
1634
1635 $command = trim($command);
1636 if ($command === '' || !preg_match('/^[a-zA-Z0-9_.-]+$/', $command)) {
1637 return '';
1638 }
1639
1640 if (array_key_exists($command, $cache)) {
1641 return $cache[$command];
1642 }
1643
1644 $lookup = stripos(PHP_OS_FAMILY, 'Windows') === 0
1645 ? 'where ' . $command . ' 2>NUL'
1646 : 'command -v ' . $command . ' 2>/dev/null';
1647
1648 $result = trim((string)@shell_exec($lookup));
1649 $path = $result !== '' ? strtok($result, "\r\n") : '';
1650 $cache[$command] = is_string($path) ? trim($path) : '';
1651
1652 return $cache[$command];
1653 }
1654
1661 public function log_missing($missing = '') {
1662 $missing = trim((string)$missing);
1663 if ($missing === '') {
1664 return 0;
1665 }
1666
1667 if (strlen($missing) > 250) {
1668 $missing = substr($missing, 0, 250);
1669 }
1670
1671 try {
1672 $db = $this->get_system_obj('dbxDB');
1673 if (!is_object($db)) {
1674 return 0;
1675 }
1676
1677 $uid = (int)$this->user();
1678 $rec = $db->select1('dbxMissing', array('missing' => $missing), 'id,count', 0);
1679
1680 if (is_array($rec) && (int)($rec['id'] ?? 0) > 0) {
1681 $id = (int)$rec['id'];
1682 $db->update('dbxMissing', array(
1683 'count' => ((int)($rec['count'] ?? 0)) + 1,
1684 ), $id, 0, 1, 1, 0);
1685 return $id;
1686 }
1687
1688 $ok = $db->insert('dbxMissing', array(
1689 'missing' => $missing,
1690 'count' => 1,
1691 'owner' => $uid,
1692 ), 0, 1, 1, 0);
1693
1694 return $ok ? (int)$db->get_insert_id() : 0;
1695 } catch (\Throwable $e) {
1696 if (function_exists('dbx_write_php_error_log')) {
1697 dbx_write_php_error_log(get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
1698 }
1699 }
1700
1701 return 0;
1702 }
1703
1719 public function sys_msg($status = '', $about = '', $rid = '', $why = '', $what = '') {
1720 if ($this->sys_msg_running) {
1721 return 0;
1722 }
1723
1724 $this->sys_msg_running = true;
1725
1726 try {
1727 $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
1728 $caller = $trace[1] ?? null;
1729 $file = $caller['file'] ?? '';
1730 $line = (int)($caller['line'] ?? 0);
1731
1732 $status = strtolower(trim((string)$status));
1733 if ($status === '') {
1734 $status = 'info';
1735 }
1736
1737 $level_map = array(
1738 'debug' => 5,
1739 'info' => 10,
1740 'login' => 15,
1741 'notice' => 15,
1742 'warning' => 20,
1743 'warn' => 20,
1744 'security' => 30,
1745 'error' => 40,
1746 'fatal' => 50,
1747 );
1748
1749 $level = $level_map[$status] ?? 10;
1750 if ($status === 'warn') {
1751 $status = 'warning';
1752 }
1753
1754 $sysMsgLevel = strtolower(trim((string) $this->get_config('dbx', 'sys_msg_level', 'all')));
1755 if ($sysMsgLevel === '') {
1756 $sysMsgLevel = 'all';
1757 }
1758
1759 $minLevel = 0;
1760 if ($sysMsgLevel === 'error') {
1761 $minLevel = 40;
1762 } elseif ($sysMsgLevel === 'warning' || $sysMsgLevel === 'warn') {
1763 $minLevel = 20;
1764 }
1765
1766 if ($level < $minLevel) {
1767 return 0;
1768 }
1769
1770 $modul = $this->get_modul_var('dbx_modul', $this->get_system_var('dbx_activ_modul' , 'dbx', '*'), rules: '*');
1771 $action = $this->get_modul_var('dbx_run1' , $this->get_system_var('dbx_activ_action', '' , '*'), rules: '*');
1772 $work = $this->get_modul_var('dbx_run2' , '', '*');
1773
1774 $data_json = '';
1775 if (is_array($what) || is_object($what)) {
1776 $data_json = json_encode($what, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
1777 $what_text = $data_json ?: '';
1778 } else {
1779 $what_text = (string)$what;
1780 }
1781
1782 $message_parts = array();
1783 if ((string)$about !== '') $message_parts[] = (string)$about;
1784 if ((string)$why !== '') $message_parts[] = 'why=' . (string)$why;
1785 if ($what_text !== '') $message_parts[] = 'what=' . $what_text;
1786 if ((string)$rid !== '') $message_parts[] = 'rid=' . (string)$rid;
1787 $message = implode(' | ', $message_parts);
1788
1789 $record = array(
1790 'xuser' => $this->user('id'),
1791 'level' => $level,
1792 'status' => $status,
1793 'about' => (string)$about,
1794 'rid' => (string)$rid,
1795 'why' => (string)$why,
1796 'what' => $what_text,
1797 'message' => $message,
1798 'modul' => (string)$modul,
1799 'action' => (string)$action,
1800 'work' => (string)$work,
1801 'source_file' => (string)$file,
1802 'source_line' => $line,
1803 'data_json' => $data_json,
1804 );
1805
1806 $oDB = $this->get_system_obj('dbxDB');
1807 $prevReport = (int)$oDB->_report_error;
1808 $oDB->_report_error = 0;
1809 $ok = $oDB->insert('dbxSysMsg', $record, 0, 1, 0, 0);
1810 $oDB->_report_error = $prevReport;
1811 $insertId = $ok ? $oDB->get_insert_id() : 0;
1812
1813 dbx()->debug("##SYS-MSG### ok=($ok) id=($insertId) Level=($level) Status=($status) Modul=($modul) Action=($action) Work=($work) About=($about) RID=($rid) Why=($why) What=($what_text)");
1814
1815 return (int)$insertId;
1816 } finally {
1817 $this->sys_msg_running = false;
1818 }
1819 }
1820
1832 public function norep($norep,$i=0) {
1833 $norep=str_replace("\r",'',$norep);
1834 $norep_id='norep_'.$this->next_id();
1835 $_SESSION['dbx']['norep'][$norep_id]=$norep;
1836 return '['.$norep_id.']';
1837 }
1838
1845 public function next_id(int $add = 1): int {
1846 // Aktuellen Zählerwert aus der "Remember"-Datenstruktur abrufen
1847 $i = $this->get_remember_var('dbx_next_i', 0, 'dbx');
1848
1849 // Zähler um den angegebenen Wert erhöhen
1850 $i += $add;
1851
1852 // Aktualisierten Zählerwert in die "Remember"-Datenstruktur speichern
1853 $this->set_remember_var('dbx_next_i', $i, 'dbx');
1854
1855 // Neuen Zählerwert zurückgeben
1856 return $i;
1857 }
1858
1865 public function is_modul($modul) {
1866 $retval=false;
1867 if ($modul) {
1868 $modul_class_file=dbx_get_base_dir()."dbx/modules/$modul/".$modul.".class.php";
1869 if (file_exists($modul_class_file)) $retval=true;
1870 }
1871 return $retval;
1872 }
1873
1881 public function is_design($design,$page='default') {
1882 $admin=$this->can('admin');
1883 $firstchar=substr($design,0,1);
1884 if (!$admin && $firstchar == '_') return false;
1885 if (!$admin && $firstchar == '-') return false;
1886
1887 $design_tpl=dbx_get_base_dir()."dbx/design/$design/htm/$page.htm";
1888 if (file_exists($design_tpl)) return true;
1889 if ($page != 'default') {
1890 $design_tpl=dbx_get_base_dir()."dbx/design/$design/htm/default.htm";
1891 if (file_exists($design_tpl)) return true;
1892 }
1893
1894 return false;
1895 }
1896
1904 public function redirect($redirect, $timer = 0) {
1905 $timer = ($timer * 1000);
1906 $base = $this->get_base_url();
1907 $ajax = $this->get_system_var('dbx_ajax', 0, 'int');
1908
1909 dbx()->debug("run redirect ($redirect)");
1910
1911 if (!str_contains($redirect, '://'))
1912 $redir = $base . $redirect;
1913 else
1914 $redir = $redirect;
1915
1916 dbx()->debug("#dbx_redirect Call=($redirect) redir=($redir) Ajax=($ajax) timer=($timer)");
1917
1918 $redir_js = json_encode($redir);
1919
1920 if (!$timer) {
1921 $script = "<script>window.location.replace($redir_js);</script>";
1922 } else {
1923 $script = "<script>setTimeout(function() { window.location.replace($redir_js); }, $timer);</script>";
1924 }
1925
1926 return $script;
1927 }
1928
1937 public function set_cookie_var($cookie,$key,$val) {
1938 $_SESSION['dbx']['cookie'][$cookie][$key]=$val;
1939 }
1940
1948 public function has_text($string,$find) {
1949 return strpos('~'.$string,$find);
1950 }
1951
1958 public function html($html) {
1959 return htmlentities($html, ENT_QUOTES);
1960 }
1961
1972 public function esc($value): string {
1973 return htmlspecialchars(
1974 (string)$value,
1975 ENT_QUOTES | ENT_SUBSTITUTE,
1976 'UTF-8'
1977 );
1978 }
1979
1988 public function search_defaults(array $overrides = array()): array {
1989 $defaults = array(
1990 'placeholder' => '🔍',
1991 'title' => 'Suchen',
1992 'tooltip' => '',
1993 'errormsg' => '',
1994 'input_class' => 'form-control-sm dbx-grid-search',
1995 'data_role' => 'search',
1996 'wrap_class' => '',
1997 'wrap_style' => '',
1998 'extra_attrs' => '',
1999 );
2000
2001 if (array_key_exists('placeholder', $overrides) && trim((string) $overrides['placeholder']) === '') {
2002 unset($overrides['placeholder']);
2003 }
2004
2005 return array_merge($defaults, $overrides);
2006 }
2007
2016 public function search_html(array $opts = array()): string {
2017 $opts = $this->search_defaults($opts);
2018 $i = (int) ($opts['i'] ?? 0);
2019 $name = (string) ($opts['name'] ?? '');
2020 $label = trim((string) ($opts['label'] ?? ''));
2021 $tooltip = trim((string) ($opts['tooltip'] ?? '')) !== ''
2022 ? (string) $opts['tooltip']
2023 : (string) ($opts['title'] ?? 'Suchen');
2024
2025 $data = array(
2026 'name' => $this->esc($name),
2027 'value' => $this->esc((string) ($opts['value'] ?? '')),
2028 'placeholder' => $this->esc((string) ($opts['placeholder'] ?? '🔍')),
2029 'title' => $this->esc((string) ($opts['title'] ?? 'Suchen')),
2030 'tooltip' => $this->esc($tooltip),
2031 'errormsg' => $this->esc((string) ($opts['errormsg'] ?? '')),
2032 'class' => $this->esc((string) ($opts['class'] ?? '')),
2033 'input_class' => $this->esc((string) ($opts['input_class'] ?? 'form-control-sm dbx-grid-search')),
2034 'wrap_class' => $this->esc((string) ($opts['wrap_class'] ?? '')),
2035 'wrap_style' => $this->esc((string) ($opts['wrap_style'] ?? '')),
2036 'data_role' => $this->esc((string) ($opts['data_role'] ?? 'search')),
2037 'extra_attrs' => (string) ($opts['extra_attrs'] ?? ''),
2038 );
2039
2040 $html = $this->get_system_obj('dbxTPL')->get_tpl('dbx|search', $data, 'htm', $i);
2041
2042 if ($label === '') {
2043 return $html;
2044 }
2045
2046 $fieldId = $this->esc($name !== '' ? $name . '_' . $i : 'dbx_search_' . $i);
2047 $style = $this->esc((string) ($opts['style'] ?? ''));
2048
2049 return '<div class="fld-frame dbx-search-field" style="' . $style . '">'
2050 . '<label for="' . $fieldId . '" class="control-label">' . $this->esc($label) . '</label>'
2051 . $html
2052 . '</div>';
2053 }
2054
2061 public function timestamp($add_sec=0) {
2062 list($usec, $sec) = explode(" ",microtime());
2063 $time= ((float) $usec + (float)$sec);
2064 $time= (float) ($time + ($add_sec));
2065 return $time;
2066 }
2067
2075 public function time_diff($starttime=0,$endtime=0) {
2076 if (!$starttime) $starttime=$this->timestamp();
2077 if (!$endtime) $endtime =$this->timestamp();
2078 return ($endtime-$starttime);
2079 }
2080
2089 public function part_select($vor,$nach,$part) {
2090 $leng= strlen($vor);
2091 $pos1= strpos($part, $vor);
2092
2093 if ($pos1 === false) {
2094 return '';
2095 }
2096
2097 $part= substr($part, ($pos1+$leng));
2098 $pos2= strpos($part, $nach);
2099
2100 if ($pos2 === false) {
2101 return '';
2102 }
2103
2104 $part= substr($part, 0,$pos2);
2105
2106 return $part;
2107 }
2108
2115 public function parse_url($data) {
2116 if (!is_array($data)) {
2117 $first=substr($data,0,1);
2118 if ($data && $first != '=') {
2119 if (strpos($data,'=')) {
2120 parse_str($data,$xdata);
2121 $data=$xdata;
2122 }
2123 }
2124 }
2125 return $data;
2126 }
2127
2134 public function is_int_value($value) {
2135 if (is_int($value)) return 1;
2136 if (is_string($value) && filter_var($value, FILTER_VALIDATE_INT) !== false) return 1;
2137 return 0;
2138 }
2139
2147 public function new_password($minlength, $special = '-_!') {
2148 $passwort = '';
2149 $syllabels = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' . $special;
2150 $len = strlen($syllabels) - 1;
2151
2152 // Sicherheit: Prüfen, ob Mindestlänge gültig ist
2153 if ($minlength < 1) return '';
2154
2155 // Box mit zufälligen Zeichen füllen
2156 $box = '';
2157 for ($i = 0; $i < 300; $i++) {
2158 $ch = $syllabels[mt_rand(0, $len)];
2159 if (ctype_lower($ch) && mt_rand(0, 4) == 1) {
2160 $ch = strtoupper($ch); // Etwa 20 % der Kleinbuchstaben in Großbuchstaben umwandeln
2161 }
2162 $box .= $ch;
2163 }
2164
2165 // Passwort aus der Box zusammenstellen
2166 for ($i = 0; $i < $minlength; $i++) {
2167 $passwort .= $box[mt_rand(0, 299)];
2168 }
2169
2170 return $passwort;
2171 }
2172
2179 public function debug_timer($max=0) {
2180 Global $dbx_run_timer;
2181 if (isset($dbx_run_timer['system']['time'])) {
2182 $time=$dbx_run_timer['system']['time'];
2183 if ($time > $max) {
2184 $this->debug("#RUN-TIMER",$dbx_run_timer);
2185 } else {
2186 $this->debug("dbx System run time=($time)");
2187 }
2188 }
2189 }
2190
2196 public function current_php_runtime(): float {
2197 global $dbx_run_timer;
2198
2199 if (isset($dbx_run_timer['system']['time']) && is_numeric($dbx_run_timer['system']['time']) && (float) $dbx_run_timer['system']['time'] >= 0) {
2200 return (float) $dbx_run_timer['system']['time'];
2201 }
2202
2203 if (isset($dbx_run_timer['system']['start_time']) && is_numeric($dbx_run_timer['system']['start_time'])) {
2204 return max(0.0, microtime(true) - (float) $dbx_run_timer['system']['start_time']);
2205 }
2206
2207 return 0.0;
2208 }
2209
2217 public function current_memory_bytes(): int {
2218 global $dbx_run_timer;
2219
2220 if (isset($dbx_run_timer['system']['memory']) && is_numeric($dbx_run_timer['system']['memory']) && (float) $dbx_run_timer['system']['memory'] >= 0) {
2221 return (int) round((float) $dbx_run_timer['system']['memory']);
2222 }
2223
2224 if (isset($dbx_run_timer['system']['start_memory'], $dbx_run_timer['system']['end_memory'])
2225 && is_numeric($dbx_run_timer['system']['start_memory'])
2226 && is_numeric($dbx_run_timer['system']['end_memory'])) {
2227 return max(0, (int) round((float) $dbx_run_timer['system']['end_memory'] - (float) $dbx_run_timer['system']['start_memory']));
2228 }
2229
2230 return 0;
2231 }
2232
2238 public function send_runtime_headers(): void {
2239 if (headers_sent()) {
2240 return;
2241 }
2242
2243 $runtime = $this->current_php_runtime();
2244 header('X-DBX-PHP-Runtime: ' . number_format($runtime, 3, '.', ''));
2245 header('Server-Timing: dbxphp;dur=' . number_format($runtime * 1000, 3, '.', '') . ';desc="DBX PHP Runtime"', false);
2246 }
2247
2256 public function store_performance_timer(): int {
2257 try {
2258 $file = dbx_os_path_file(dbx_get_base_dir() . 'dbx/modules/dbx/include/dbxPerformanceTimer.class.php');
2259 if (!is_file($file)) {
2260 return 0;
2261 }
2262
2263 include_once $file;
2264 if (!class_exists('dbxPerformanceTimer')) {
2265 return 0;
2266 }
2267
2268 $timer = new \dbxPerformanceTimer();
2269 if (!method_exists($timer, 'store')) {
2270 return 0;
2271 }
2272
2273 return (int) $timer->store();
2274 } catch (\Throwable $e) {
2275 if (function_exists('dbx_write_php_error_log')) {
2276 dbx_write_php_error_log(get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
2277 }
2278 return 0;
2279 }
2280 }
2281
2288 public function debug2($line) {
2289 $file = dbx_get_file_dir() . "dbxDebug2.txt";
2290 $file = dbx_os_path_file($file);
2291 file_put_contents($file, $line, FILE_APPEND);
2292 }
2293
2311 public function debug($txt, $data1 = '', $data2 = '', $data3 = '') {
2312 $activ = $this->get_remember_var('dbx_debug_activ', -1, 'dbx');
2313 if ($activ == -1) {
2314 $activ = 0;
2315 $debugActiv = dbx_get_file_dir() . "dbxDebugActiv.txt";
2316 $debugActiv = dbx_os_path_file($debugActiv);
2317 if (file_exists($debugActiv)) {
2318 $activ = 1;
2319 }
2320 $this->set_remember_var('dbx_debug_activ', $activ, 'dbx');
2321 }
2322
2323 if (!$activ) {
2324 return;
2325 }
2326
2327 $vars = '';
2328 $file = dbx_get_file_dir() . "dbxDebug.txt";
2329 $file = dbx_os_path_file($file);
2330
2331 foreach (array($data1, $data2, $data3) as $data) {
2332 if (is_array($data)) {
2333 $vars .= print_r($data, true);
2334 } else {
2335 if ($data > '') {
2336 $vars .= $data . "\n";
2337 }
2338 }
2339 }
2340
2341 $txt .= "\n" . $vars . "\n";
2342 file_put_contents($file, $txt, FILE_APPEND);
2343 }
2344
2353 private function get_SysClassOverrideName(string $class): string {
2354 if (str_starts_with($class, 'dbx')) {
2355 $suffix = substr($class, 3);
2356 return 'my' . ($suffix ?: $class);
2357 }
2358 return 'my' . $class;
2359 }
2360
2373 private function ensure_SysClassOverride(string $class, string $myClass, string $baseClass): string {
2374 if ($baseClass === "\\dbxUndefClass" || !class_exists($baseClass, false)) {
2375 return '';
2376 }
2377
2378 $moduleDir = dbx_os_path_file(dbx_get_base_dir() . 'dbx/modules/myX/');
2379 $sysDir = dbx_os_path_file($moduleDir . 'sysclass/');
2380 $file = dbx_os_path_file($sysDir . $myClass . '.class.php');
2381
2382 if (!is_dir($sysDir)) {
2383 mkdir($sysDir, 0777, true);
2384 }
2385
2386 $cfgDir = dbx_os_path_file($moduleDir . 'cfg/');
2387 if (!is_dir($cfgDir)) {
2388 mkdir($cfgDir, 0777, true);
2389 }
2390
2391 $cfgFile = dbx_os_path_file($cfgDir . 'config.php');
2392 if (!file_exists($cfgFile)) {
2393 file_put_contents($cfgFile, "<?php\n\$config['version']='1';\n\$config['activ']='1';\n\$config['groups']='*';\n");
2394 }
2395
2396 $moduleFile = dbx_os_path_file($moduleDir . 'myX.class.php');
2397 if (!file_exists($moduleFile)) {
2398 file_put_contents($moduleFile, "<?php\nnamespace dbx\\myX;\n\nclass myX {\n public function run() {\n return 'myX system module';\n }\n}\n");
2399 }
2400
2401 if (!file_exists($file)) {
2402 $content = "<?php\n";
2403 $content .= "/**\n";
2404 $content .= " * Auto-generated DBX system class override.\n";
2405 $content .= " * Requested class: $class\n";
2406 $content .= " * Override class: $myClass\n";
2407 $content .= " */\n";
2408 $content .= "class $myClass extends $class {\n";
2409 $content .= "}\n";
2410 file_put_contents($file, $content);
2411 }
2412
2413 return $file;
2414 }
2415}
2416
2430function dbx(): dbxApi {
2431 static $api = null;
2432 if ($api === null) {
2433 $api = new dbxApi();
2434 }
2435 return $api;
2436}
2437
2438
2444function ge_stichtag() {
2445 $heute = new DateTime();
2446 $grenze = new DateTime('2025-06-01');
2447 return $heute >= $grenze;
2448}
2449
2450
2458function dbx_copy_recursive($src, $dst) {
2459 $src = rtrim($src, '/\\');
2460 $dst = rtrim($dst, '/\\');
2461
2462 if (!is_dir($src)) {
2463 dbx()->debug("dbx_copy_recursive Error DIR");
2464 return 0;
2465 }
2466
2467 if (!file_exists($dst)) {
2468 if (!mkdir($dst, 0777, true)) {
2469 dbx()->debug("dbx_copy_recursive mkdir Error($dst)");
2470 return 0;
2471 }
2472 }
2473
2474 $items = scandir($src);
2475 foreach ($items as $item) {
2476 if ($item === '.' || $item === '..') {
2477 continue;
2478 }
2479
2480 $srcPath = $src . DIRECTORY_SEPARATOR . $item;
2481 $dstPath = $dst . DIRECTORY_SEPARATOR . $item;
2482
2483 if (is_dir($srcPath)) {
2484 // Rekursiv für Verzeichnisse
2485 if (!dbx_copy_recursive($srcPath, $dstPath)) {
2486 dbx()->debug("dbx_copy_recursive Error A");
2487 return 0;
2488 }
2489 } else {
2490 // Datei kopieren (überschreiben erlaubt)
2491 if (!copy($srcPath, $dstPath)) {
2492 dbx()->debug("dbx_copy_recursive Error B");
2493
2494 return 0;
2495 }
2496 }
2497 }
2498
2499 return 1;
2500}
2501
2502
2503
2504
2519function dbx_DateTime($date_time='now',$calc=0,$special='') {
2520 $timezone = 'Europe/Berlin';
2521 $offset = 0; // Offset Sommer/Winter
2522
2523 if ($date_time=='now') {
2524 $offset = (60*60*$offset);
2525 $calc=($calc + $offset);
2526 $date_time = date("Y-m-d H:i:s", (time() + $calc));
2527 } else {
2528 $offset = (60*60*$offset);
2529 $calc=($calc + $offset);
2530 $date_time = date("Y-m-d H:i:s", (strtotime($date_time) + $calc ));
2531 }
2532
2533 if ($special) {
2534 $time=strtotime($date_time);
2535 $date_time=date("Y-m-d H:i:s", strtotime($special, $time));
2536 }
2537
2538
2539 $week_start = strtotime('last Sunday', time());
2540 $week_end = strtotime('next Sunday', time());
2541
2542 $month_start = strtotime('first day of this month', time());
2543 $month_end = strtotime('last day of this month', time());
2544
2545 $year_start = strtotime('first day of January', time());
2546 $year_end = strtotime('last day of December', time());
2547
2548 //$now_date = gmdate("Y-m-d H:i:s", (time() + $calc));
2549 return $date_time;
2550}
2551
2552
2566function dbx_make_dir(string $path): int {
2567 // Prüfen, ob das Verzeichnis bereits existiert
2568 if (is_dir($path)) return 1;
2569
2570 // Versuchen, das Verzeichnis rekursiv zu erstellen
2571 if (mkdir($path, 0777, true)) {
2572 return 1; // Erfolgreich erstellt
2573 }
2574
2575 return 0; // Fehler beim Erstellen
2576}
2577
2578
2592function dbx_sendMail($from,$fromname,$to,$subject,$text,$type='html',$attach='',$archiv=0) {
2593 $from = array('email' => $from, 'name' => $fromname);
2594 return dbx()->send_mail($from, $to, (string) $subject, (string) $text, (string) $type, $attach);
2595}
2596
2597
2606function dbx_is_page($page,$design,$lng='') {
2607 $retval=false;
2608 $page_tpl=dbx_get_base_dir()."dbx/tpl/htm/$page.htm";
2609 if (file_exists($page_tpl)) $retval=true;
2610 return $retval;
2611}
2612
2613
2614
2615
2616
2617
2618
2619
2663function dbx_lng_current(): string {
2664 $lng = strtolower(trim((string) dbx()->get_system_var('dbx_lng', 'de')));
2665 return $lng !== '' ? $lng : 'de';
2666}
2667
2673function dbx_accessible_lngs(): array {
2674 $raw = dbx()->get_config('dbx', 'accessible_lng', 'de');
2675 if ($raw === 'undef' || $raw === '' || $raw === null) {
2676 $raw = 'de';
2677 }
2678 if (is_array($raw)) {
2679 $out = array();
2680 foreach ($raw as $val) {
2681 $val = strtolower(trim((string) $val));
2682 if ($val !== '' && $val !== 'undef' && preg_match('/^[a-z]{2,3}$/', $val)) {
2683 $out[] = $val;
2684 }
2685 }
2686 return count($out) ? $out : array('de');
2687 }
2688
2689 $parts = preg_split('/\s*,\s*/', (string) $raw, -1, PREG_SPLIT_NO_EMPTY);
2690 $out = array();
2691 if (is_array($parts)) {
2692 foreach ($parts as $val) {
2693 $val = strtolower(trim((string) $val));
2694 if ($val !== '' && $val !== 'undef' && preg_match('/^[a-z]{2,3}$/', $val)) {
2695 $out[] = $val;
2696 }
2697 }
2698 }
2699
2700 return count($out) ? $out : array('de');
2701}
2702
2710function dbx_lng_name(string $base, string $lng = ''): string {
2711 $base = trim($base);
2712 if ($base === '') {
2713 return '';
2714 }
2715
2716 $lng = strtolower(trim($lng !== '' ? $lng : dbx_lng_current()));
2717 if ($lng === '') {
2718 return $base;
2719 }
2720
2721 return $base . '_' . $lng;
2722}
2723
2734function dbx_lng_resolve_file(string $dir, string $name, string $ext, string $lng = '', bool $fallback = true): string {
2735 $dir = str_replace('\\', '/', $dir);
2736 if ($dir !== '' && substr($dir, -1) !== '/') {
2737 $dir .= '/';
2738 }
2739
2740 $name = strtolower(trim($name));
2741 $ext = ltrim(strtolower(trim($ext)), '.');
2742 if ($name === '' || $ext === '') {
2743 return '';
2744 }
2745
2746 $lng = strtolower(trim($lng !== '' ? $lng : dbx_lng_current()));
2747 if ($lng !== '') {
2748 $pathLng = $dir . $name . '_' . $lng . '.' . $ext;
2749 if (is_file($pathLng)) {
2750 return function_exists('dbx_os_path_file') ? dbx_os_path_file($pathLng) : $pathLng;
2751 }
2752 }
2753
2754 if (!$fallback) {
2755 return '';
2756 }
2757
2758 $pathDef = $dir . $name . '.' . $ext;
2759 if (is_file($pathDef)) {
2760 return function_exists('dbx_os_path_file') ? dbx_os_path_file($pathDef) : $pathDef;
2761 }
2762
2763 return '';
2764}
2765
2779function dbx_modul_translate($content,$modul='',$lng='') {
2780 if (!$modul) $modul=dbx()->get_system_var('dbx_activ_modul','dbx');
2781 if (!$lng) $lng=dbx()->get_system_var('dbx_lng','de');
2782 $dir_file=dbx_get_base_dir()."dbx/modules/$modul/translate.php";
2783 $dir_file=dbx_os_path_file($dir_file);
2784 if (file_exists($dir_file)) {
2785 include $dir_file;
2786 }
2787 return $content;
2788}
2789
2801function dbx_replace_first($search_str, $replacement_str, $src_str){
2802 return (false !== ($pos = strpos($src_str, $search_str))) ? substr_replace($src_str, $replacement_str, $pos, strlen($search_str)) : $src_str;
2803}
2804
2805
2818function dbx_convertArrayToPHPCode(array $array, string $prefix): string {
2819 $code = "";
2820
2821 foreach ($array as $key => $value) {
2822 // Generiere den Schlüssel (numerisch oder als String)
2823 $keyPart = is_numeric($key) ? "[$key]" : "['" . addslashes($key) . "']";
2824
2825 if (is_array($value)) {
2826 // Rekursive Verarbeitung für verschachtelte Arrays
2827 $code .= dbx_convertArrayToPHPCode($value, $prefix . $keyPart);
2828 } else {
2829 // Wert formatieren
2830 if (is_string($value)) {
2831 // Strings escapen (inklusive Backslashes)
2832 $formattedValue = "'" . addslashes($value) . "'";
2833 } elseif (is_bool($value)) {
2834 // Booleans in `true` oder `false` konvertieren
2835 $formattedValue = $value ? 'true' : 'false';
2836 } elseif ($value === null) {
2837 // `null` als Wert setzen
2838 $formattedValue = 'null';
2839 } else {
2840 // Andere Datentypen (z. B. Zahlen) direkt verwenden
2841 $formattedValue = $value;
2842 }
2843
2844 // PHP-Code-Zuweisung generieren
2845 $code .= "$prefix$keyPart = $formattedValue;\n";
2846 }
2847 }
2848
2849 return $code;
2850}
2851
2852
2895function dbx_convert_charset(string $in, string $charset, string $incharset = 'UTF-8'): string {
2896 // Nur konvertieren, wenn Zielkodierung von Eingabekodierung abweicht
2897 if ($charset !== $incharset) {
2898 // Spezielle Behandlung für deutsche Umlaute und scharfes S
2899 $umlaute = [
2900 'ä' => chr(228), 'ö' => chr(246), 'ü' => chr(252), 'ß' => chr(223),
2901 'Ä' => chr(196), 'Ö' => chr(214), 'Ü' => chr(220)
2902 ];
2903 $in = str_replace(array_keys($umlaute), array_values($umlaute), $in);
2904
2905 // Kodierung mit automatischer Erkennung der Eingabekodierung konvertieren
2906 $in = mb_convert_encoding(
2907 $in,
2908 $charset,
2909 mb_detect_encoding($in, "UTF-8, $charset, ISO-8859-1, ISO-8859-15", true)
2910 );
2911 }
2912
2913 return $in;
2914}
2915
2916
2930function dbx_add_modul(string $modul, string $action, string $work = ''): string {
2931 // Grundstruktur mit Modul und Aktion aufbauen
2932 $content = '[modul=' . $modul . ']dbx_run1=' . $action;
2933
2934 // Falls 'work' definiert ist, hinzufügen
2935 if (!empty($work)) {
2936 $content .= '&dbx_run2=' . $work;
2937 }
2938
2939 // Abschluss des Modul-Strings
2940 $content .= '[/modul]';
2941 return $content;
2942}
2943
2944
2945
2959function dbx_validate_var($danger_value, $rules = 'parameter', $varname = 'undef'): bool {
2960 // Wenn keine Validierung erforderlich ist, einfach true zurückgeben
2961 if ($rules == '*') return true;
2962 // Validator-Objekt aus dem Cache holen
2963 $oValidator = dbx()->get_system_obj('dbxValidator'); // #cache for speed
2964 // Validierung durchführen
2965 return $oValidator->validate($danger_value, $rules, $varname);
2966}
2967
2968
2969
2970
2971
3085// Session
3086
3087// Session - - - - - - - - - - - - - - - - - - - - - - - - -
3088
3094function dbx_make_seed(){
3095 list($usec, $sec) = explode(' ', microtime());
3096 return (float) $sec + ((float) $usec * 100000);
3097}
3098
3112function dbx_load_cookie($cookie) {
3113 $data=array();
3114 if (isset($_COOKIE[$cookie])) $data = json_decode($_COOKIE[$cookie], true);
3115 $_SESSION['dbx']['cookie'][$cookie]=$data;
3116}
3117
3118
3119function dbx_save_cookie($cookie,$hh=12) {
3120 $data=$_SESSION['dbx']['cookie'][$cookie];
3121 setcookie($cookie, json_encode($data), time()+3600*$hh,'/');
3122}
3123
3124function dbx_delete_cookie($cookie) {
3125 setcookie($cookie, '', time() - 3600, '/');
3126}
3127
3128
3129function dbx_get_cookie_val($cookie,$key,$default='') {
3130 $val=$default;
3131 if (isset($_SESSION['dbx']['cookie'][$cookie][$key])) {
3132 $val=$_SESSION['dbx']['cookie'][$cookie][$key];
3133 }
3134 return $val;
3135}
3136
3137
3138// Format Value
3148function dbx_get_Date($date, $io, $default = ''): string {
3149 //dbx_debug("dbx_get_Date($date) io=($io) defalut=($default)");
3150 if (!$date || $date===null) $date='';
3151 $date = trim($date);
3152
3153 // Ensure the date only contains valid characters.
3154 if (!preg_match('#^[0-9./-]+$#', $date)) {
3155 dbx()->set_system_var('dbx_validate_error', 1);
3156 return $default;
3157 }
3158
3159 // Check date length.
3160 if (strlen($date) !== 10) {
3161 dbx()->set_system_var('dbx_validate_error', 1);
3162 return $default;
3163 }
3164
3165 // Determine delimiter and split the date.
3166 $delimiter = '';
3167 if (strpos($date, '-') !== false) {
3168 $delimiter = '-';
3169 } elseif (strpos($date, '.') !== false) {
3170 $delimiter = '.';
3171 } elseif (strpos($date, '/') !== false) {
3172 $delimiter = '/';
3173 }
3174
3175 if (!$delimiter) {
3176 dbx()->set_system_var('dbx_validate_error', 1);
3177 return $default;
3178 }
3179
3180 $parts = explode($delimiter, $date);
3181
3182 // Ensure valid parts based on delimiter.
3183 if (count($parts) !== 3) {
3184 dbx()->set_system_var('dbx_validate_error', 1);
3185 return $default;
3186 }
3187
3188 [$first, $second, $third] = $parts;
3189
3190 // Determine the format (DD.MM.YYYY or YYYY-MM-DD).
3191 if ($delimiter === '-') {
3192 [$year, $month, $day] = [$first, $second, $third];
3193 } else {
3194 [$day, $month, $year] = [$first, $second, $third];
3195 }
3196
3197 // Validate the extracted date.
3198 if (!checkdate((int)$month, (int)$day, (int)$year)) {
3199 dbx()->set_system_var('dbx_validate_error', 1);
3200 return $default;
3201 }
3202
3203 // Format date based on the desired output.
3204 if ($io === 'web') {
3205 return sprintf('%02d.%02d.%04d', $day, $month, $year);
3206 } elseif ($io === 'php') {
3207 return sprintf('%04d-%02d-%02d', $year, $month, $day);
3208 }
3209
3210 // Default return in case of unsupported $io value.
3211 dbx()->set_system_var('dbx_validate_error', 1);
3212 return $default;
3213}
3214
3215
3216function dbx_get_webDate($date,$default='') {
3217 $date=dbx_get_Date($date,'web');
3218 if (!$date) $date=$default;
3219 return $date;
3220}
3221
3222function dbx_get_phpDate($date,$default='') {
3223 $date=dbx_get_Date($date,'php');
3224 if (!$date) $date=$default;
3225 return $date;
3226}
3227
3228
3229
3230function dbx_get_webDateTime($date_time,$default='') {
3231 $date=substr($date_time, 0, 10);
3232 $time=substr($date_time,11, 8);
3233 $date=dbx_get_Date($date,'web');
3234 return $date.' '.$time;
3235}
3236
3237
3238// Secure
3239
3240function dbx_is_Login() {
3241 return dbx()->user('id');
3242}
3243
3256function dbx_set_CurrentUser($key,$value) {
3257 if ($key != '*') {
3258 $_SESSION['dbx']['current_user'][$key]=$value;
3259 } else {
3260 $_SESSION['dbx']['current_user']=$value;
3261 }
3262}
3263function dbx_is_decimal($value) {
3264 if (trim($value)=='') return FALSE;
3265 $lang = strlen($value);
3266 $okcahr = '-0123456789.,';
3267 for ($i = 0; $i < $lang; $i++) {
3268 $char = $value[$i];
3269 $ok = strrpos($okcahr, $char);
3270 if ($ok === FALSE) return FALSE;
3271 }
3272 return TRUE;
3273}
3274
3275
3276
3277
3278// Time
3279
3280
3281function dbx_get_Today($days=0) {
3282 $today = getdate();
3283 $date=$today['year'].'-'.$today['mon'].'-'.$today['mday'];
3284 //return $date;
3285
3286 $date_t = strtotime($date.' UTC');
3287 return gmdate('Y-m-d',$date_t + ($days*86400));
3288
3289
3290}
3291
3292function dbx_get_Microtime() {
3293 list($usec, $sec) = explode(' ',microtime());
3294 return ((float)$usec + (float)$sec);
3295}
3296
3297// File Upload
3298
3299function dbx_upload() {
3300 $oUpload=dbx()->get_system_obj('dbxUpload');
3301
3302}
3303
3304
3305// Mail
3306
3307
3308
3309
3310
3311
3312function dbx_html2txt($txt) {
3313 $txt = dbx_html2src($txt);
3314 $txt = str_replace('<br/>',"\n", $txt );
3315 $txt = str_replace('<br>' ,"\n", $txt );
3316 return $txt;
3317}
3318
3319function dbx_txt2html($txt) {
3320 $txt = str_replace("\n",'<br/>',$txt);
3321 return $txt;
3322}
3323
3324function dbx_html2src($html_in) {
3325 $html_in=stripslashes($html_in);
3326 $html_in = str_replace ('&nbsp;' , ' ', $html_in);
3327 $html_in = str_replace ('&amp;' , '&', $html_in);
3328 $html_in = str_replace ('&quot;' , '"', $html_in);
3329 $html_in = str_replace ('&#039;' , "'", $html_in);
3330 $html_in = str_replace ('&lt;' , '<', $html_in);
3331 $html_in = str_replace ('&gt;' , '>', $html_in);
3332 $html_in = str_replace ('%7B' , '{', $html_in);
3333 $html_in = str_replace ('%7D' , '}', $html_in);
3334
3335 $html_in = str_replace ('&uuml;', 'ü', $html_in);
3336 $html_in = str_replace ('&ouml;', 'ö', $html_in);
3337 $html_in = str_replace ('&auml;', 'ä', $html_in);
3338 $html_in = str_replace ('&Uuml;', 'Ü', $html_in);
3339 $html_in = str_replace ('&Ouml;', 'Ö', $html_in);
3340 $html_in = str_replace ('&Auml;', 'Ä', $html_in);
3341
3342 return $html_in;
3343}
3344
3345
3346
3347// dbx Util
3348
3349
3350function dbx_interpreter($content) {
3351 $int=dbx()->get_system_obj('dbxInterpreter');
3352 $content=$int->run($content);
3353 return $content;
3354}
3355
3356
3357
3358// crypt / decrypt
3359
3360// use \phpseclib3\Crypt\AES; // wird am anfang gemacht.
3361
3371function dbx_decrypt($content, $xkey = '', $master = '') {
3372 try {
3373 if (!$master) {
3374 $master = dbx()->get_config('dbx', 'crypt');
3375 if (!$master) {
3376 throw new Exception("Master key is not set.");
3377 }
3378 }
3379
3380 if (!$xkey) {
3381 $xkey = 'jkgj89bz7b789345%$&8t5';
3382 }
3383
3384 $crypt_key = md5($xkey . $master);
3385 $key = substr($crypt_key, 0, 16);
3386 $iv = substr($crypt_key, -16);
3387
3388 //dbx_debug("decrypt ($xkey) ($master) Key=($key) IV=($iv)");
3389
3390 $aes = new AES('cbc');
3391 $aes->setKey($key);
3392 $aes->setIV($iv);
3393
3394 $decrypt_content = $aes->decrypt($content);
3395
3396 return $decrypt_content;
3397 } catch (Exception $e) {
3398 dbx()->debug("Decryption error: " . $e->getMessage());
3399 return false;
3400 }
3401}
3402
3412function dbx_crypt($content, $xkey = '', $master = '') {
3413 try {
3414
3415 if (!$master) {
3416 $master = dbx()->get_config('dbx', 'crypt');
3417 if (!$master) {
3418 throw new Exception("Master key is not set.");
3419 }
3420 }
3421
3422 if (!$xkey) {
3423 $xkey = 'jkgj89bz7b789345%$&8t5';
3424 }
3425
3426 $crypt_key = md5($xkey . $master);
3427 $key = substr($crypt_key, 0, 16);
3428 $iv = substr($crypt_key, -16);
3429
3430 //dbx_debug("crypt ($xkey) ($master) Key=($key) IV=($iv)");
3431
3432 $aes = new AES('cbc');
3433 $aes->setKey($key);
3434 $aes->setIV($iv);
3435
3436 $crypt_content = $aes->encrypt($content);
3437
3438 return $crypt_content;
3439 } catch (Exception $e) {
3440 dbx()->debug("Encryption error: " . $e->getMessage());
3441 return false;
3442 }
3443}
$cfg
$config['version']
Definition config.php:2
Global $_dbxCache
Definition dbxApi.php:16
dbx_log_missing_entry($missing='')
Definition dbxApi.php:18
dbx_normalize_config_for_store(array $config)
Definition index.php:261
dbx_os_path_file($path_file)
Definition index.php:164
exit
Definition index.php:532
dbx_write_php_error_log($type, $message, $file='', $line=0)
Definition index.php:81
dbx_get_file_dir()
Definition index.php:265
if( $syncRequest)
Definition index.php:520
dbx_get_base_dir($cut_Data=0)
Definition index.php:157
DBX schema administration.
if(! $db->connect_db_server($server)) $result
try
Definition run_job.php:204