dbxapp 4.1.3
CMS, Shop, Workflows und modulare Geschäftsanwendungen
Loading...
Searching...
No Matches
dbxWebApp.class.php
Go to the documentation of this file.
1<?php
6
26class dbxWebApp {
27
29 private const RESOURCE_MIME_TYPES = array(
30 // Styles, Skripte und Browser-Daten
31 'css' => 'text/css; charset=UTF-8',
32 'js' => 'application/javascript; charset=UTF-8',
33 'mjs' => 'application/javascript; charset=UTF-8',
34 'cjs' => 'application/javascript; charset=UTF-8',
35 'map' => 'application/json; charset=UTF-8',
36 'json' => 'application/json; charset=UTF-8',
37 'webmanifest' => 'application/manifest+json; charset=UTF-8',
38 'wasm' => 'application/wasm',
39
40 // Bilder
41 'avif' => 'image/avif',
42 'bmp' => 'image/bmp',
43 'gif' => 'image/gif',
44 'ico' => 'image/x-icon',
45 'jfif' => 'image/jpeg',
46 'jpg' => 'image/jpeg',
47 'jpeg' => 'image/jpeg',
48 'png' => 'image/png',
49 'svg' => 'image/svg+xml',
50 'svgz' => 'image/svg+xml',
51 'tif' => 'image/tiff',
52 'tiff' => 'image/tiff',
53 'webp' => 'image/webp',
54
55 // Schriften
56 'eot' => 'application/vnd.ms-fontobject',
57 'otf' => 'font/otf',
58 'ttf' => 'font/ttf',
59 'woff' => 'font/woff',
60 'woff2' => 'font/woff2',
61
62 // Dokumente und Downloads
63 'csv' => 'text/csv; charset=UTF-8',
64 'pdf' => 'application/pdf',
65 'txt' => 'text/plain; charset=UTF-8',
66 'xml' => 'application/xml; charset=UTF-8',
67 '7z' => 'application/x-7z-compressed',
68 'gz' => 'application/gzip',
69 'rar' => 'application/vnd.rar',
70 'tar' => 'application/x-tar',
71 'zip' => 'application/zip',
72 'exe' => 'application/octet-stream',
73
74 // Audio und Video
75 'aac' => 'audio/aac',
76 'flac' => 'audio/flac',
77 'm4a' => 'audio/mp4',
78 'mp3' => 'audio/mpeg',
79 'oga' => 'audio/ogg',
80 'ogg' => 'audio/ogg',
81 'opus' => 'audio/opus',
82 'wav' => 'audio/wav',
83 'avi' => 'video/x-msvideo',
84 'm4v' => 'video/mp4',
85 'mov' => 'video/quicktime',
86 'mp4' => 'video/mp4',
87 'mpeg' => 'video/mpeg',
88 'mpg' => 'video/mpeg',
89 'ogv' => 'video/ogg',
90 'webm' => 'video/webm',
91 );
92
94 private const DYNAMIC_FILE_ROUTES = array(
95 'robots.txt',
96 'sitemap.xml',
97 );
98
107 private const REPORT_ACTION_POLICIES = array(
108 'row_delete' => array('action' => 'dbxReport.row_delete', 'bind' => array('rid')),
109 'delete_tab' => array('action' => 'dbxReport.delete_tab', 'bind' => array()),
110 'multi_delete' => array('action' => 'dbxReport.multi_delete', 'bind' => array()),
111 'multi_activate' => array('action' => 'dbxReport.multi_activate', 'bind' => array()),
112 'multi_deactivate' => array('action' => 'dbxReport.multi_deactivate', 'bind' => array()),
113 'rows_delete' => array('action' => 'dbxReport.multi_delete', 'bind' => array()),
114 'rows_activate' => array('action' => 'dbxReport.multi_activate', 'bind' => array()),
115 'rows_deactivate' => array('action' => 'dbxReport.multi_deactivate', 'bind' => array()),
116 );
117
125 private const AUTOMATIC_RID_ACTIONS = array(
126 'delete' => 'dbxAction.delete',
127 'save' => 'dbxAction.save',
128 );
129
136 private $actionRouteCache = array();
137
138
152 function get_base_url(string $uri): string {
153 $base_url = dbx()->get_remember_var('base_url', 0, 'dbx');
154
155 $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
156 ? 'https://' : 'http://';
157 $host = $_SERVER['HTTP_HOST'] ?? ($_SERVER['SERVER_ADDR'] ?? 'localhost');
158 $host = preg_replace('/:\d+$/', '', (string) $host);
159
160 if ($host === 'heserver') {
161 $host = 'heserver';
162 } elseif ($host === 'localhost' || $host === '127.0.0.1') {
163 $host = 'localhost';
164 }
165
166 $port = (int) ($_SERVER['SERVER_PORT'] ?? 0);
167 $xport = ($port && $port != 80 && $port != 443) ? ":$port" : '';
168 $request_origin = $protocol . $host . $xport;
169
170 if ($base_url && $port != 4221) {
171 $cached = parse_url((string) $base_url);
172 $cached_scheme = strtolower((string) ($cached['scheme'] ?? ''));
173 $cached_host = strtolower((string) ($cached['host'] ?? ''));
174 $cached_port = (int) ($cached['port'] ?? ($cached_scheme === 'https' ? 443 : 80));
175 $cached_path = '/' . trim(str_replace('\\', '/', (string) ($cached['path'] ?? '')), '/');
176 $request_path = '/' . trim(str_replace('\\', '/', $uri), '/');
177 $request_port = $port ?: ($protocol === 'https://' ? 443 : 80);
178
179 if (
180 $cached_scheme !== rtrim($protocol, ':/') ||
181 $cached_host !== strtolower($host) ||
182 $cached_port !== $request_port ||
183 $cached_path !== $request_path
184 ) {
185 $base_url = 0;
186 }
187 }
188
189 if (!$base_url) {
190 // Erstellt die Basis-URL
191 $base_url = $request_origin . rtrim($uri, '/');
192
193 // Falls der Port 4221 ist, wird die URL aus einer Datei gelesen
194 if ($port == 4221) {
195 $base_href_file = dbx()->os_path(dbx()->get_file_dir() . 'base_href.cfg');
196
197 if (file_exists($base_href_file)) {
198 $base_url = trim(preg_replace('/[\x00-\x1F\x7F]/', '', file_get_contents($base_href_file)));
199 }
200 }
201
202 // Ersetzt Backslashes durch Slashes und sorgt für einen abschließenden Slash
203 $base_url = str_replace('\\', '/', rtrim($base_url, '\\'));
204 if (!in_array(substr($base_url, -1), ['/', '?'])) {
205 $base_url .= '/';
206 }
207
208 dbx()->set_remember_var('base_url', $base_url, 'dbx');
209 }
210
211 return $base_url;
212 }
213
214
215
216
223 function create_new_cfg($modul='dbx') {
224 if ($modul == 'dbx') {
225 $config['host']='localhost';
226 $config['name']='';
227 $config['user']='root';
228 $config['password']='';
229 $config['port']='';
230 $config['default_lng'] ='de';
231 $config['accessible_lng'] ='de,en,es';
232 $config['default_color'] ='blau';
233 $config['default_design_user'] ='lda';
234 $config['default_design_admin'] ='_admin';
235 $config['cache']=0;
236 $config['intro']=0;
237 $config['trace']=0;
238 $config['construct']=0;
239 $config['secure']='secure-key';
240 $config['ok']=0;
241
242 } else {
243 // create Modul cfg;
244 }
245 dbx()->set_config($modul,$config);
246 return $config;
247 }
248
254 function check_uri() {
255 $uri='';
256 $request = $_SERVER['REQUEST_URI'];
257
258 // Zerlege die URL in ihre Komponenten
259 $url_components = parse_url($request);
260
261 // Speichere den Pfad in $_GET mit dem Schlüssel 'dbx_request_path'
262 if (isset($url_components['path'])) {
263 $uri = $url_components['path'];
264 }
265
266 // Zerlege die Query-Parameter und speichere sie in $_GET
267 if (isset($url_components['query'])) {
268 parse_str($url_components['query'], $query_params);
269 foreach ($query_params as $key => $value) {
270 $_GET[$key] = $value;
271 }
272 }
273 return $uri;
274}
275
276
290 $url = trim(str_replace('&amp;', '&', (string) $url));
291
292 $fragment = '';
293 $hashPos = strpos($url, '#');
294 if ($hashPos !== false) {
295 $fragment = substr($url, $hashPos);
296 $url = substr($url, 0, $hashPos);
297 }
298
299 $path = $url;
300 $params = array();
301
302 if (substr($url, 0, 1) === '?') {
303 $query = substr($url, 1);
304 if ($query !== '') {
305 parse_str($query, $params);
306 }
307 return array(
308 'permalink' => '',
309 'params' => $this->normalize_route_params($params),
310 'fragment' => $fragment,
311 );
312 }
313
314 $delimPos = false;
315 foreach (array('?', '&') as $delimiter) {
316 $pos = strpos($url, $delimiter);
317 if ($pos !== false && ($delimPos === false || $pos < $delimPos)) {
318 $delimPos = $pos;
319 }
320 }
321
322 if ($delimPos !== false) {
323 $path = substr($url, 0, $delimPos);
324 $query = substr($url, $delimPos + 1);
325 if ($query !== '') {
326 parse_str($query, $params);
327 }
328 }
329
330 $path = $this->peel_glued_params_from_path($path, $params);
331
332 return array(
333 'permalink' => str_replace('\\', '/', $path),
334 'params' => $this->normalize_route_params($params),
335 'fragment' => $fragment,
336 );
337}
338
355 function build_route_url($permalink, $params = array(), $fragment = '') {
356 $permalink = str_replace('\\', '/', trim((string) $permalink));
357 $permalink = trim($permalink, '/');
358 $params = $this->normalize_route_params($params);
359
360 if ($permalink === '') {
361 if (empty($params)) {
362 return '?' . $fragment;
363 }
364 return '?' . http_build_query($params, '', '&', PHP_QUERY_RFC3986) . $fragment;
365 }
366
367 if (empty($params)) {
368 return $permalink . $fragment;
369 }
370
371 return $permalink . '?' . http_build_query($params, '', '&', PHP_QUERY_RFC3986) . $fragment;
372 }
373
392 function append_route_params($url, $params = array()) {
393 $route = $this->parse_route_url($url);
394 foreach ($params as $key => $value) {
395 $route['params'][(string) $key] = (string) $value;
396 }
397 return $this->build_route_url($route['permalink'], $route['params'], $route['fragment']);
398 }
399
410 private function effective_action_params(array $params): array {
411 $currentModul = trim((string)dbx()->get_system_var('dbx_modul', '', 'parameter'));
412 $modul = trim((string)($params['dbx_modul'] ?? ''));
413
414 if ($modul === '') {
415 $modul = $currentModul;
416 if ($modul !== '') {
417 $params['dbx_modul'] = $modul;
418 }
419 }
420
421 if ($modul === $currentModul || $currentModul === '') {
422 foreach (array('dbx_run1', 'dbx_run2', 'dbx_run3') as $key) {
423 if (!array_key_exists($key, $params) || (string)$params[$key] === '') {
424 $value = dbx()->get_system_var($key, '', 'parameter');
425 if ((string)$value !== '') {
426 $params[$key] = $value;
427 }
428 }
429 }
430 }
431
432 return $params;
433 }
434
441 private function normalize_action_scope_value($value) {
442 if (!is_array($value)) {
443 if ($value === null) {
444 return '';
445 }
446 if (is_bool($value)) {
447 return $value ? '1' : '0';
448 }
449 return (string)$value;
450 }
451
452 $normalized = array();
453 foreach ($value as $key => $item) {
454 $normalized[(string)$key] = $this->normalize_action_scope_value($item);
455 }
456 ksort($normalized, SORT_STRING);
457 return $normalized;
458 }
459
471 private function resolve_action_bindings(array $bindings, array $params): array {
472 $resolved = array();
473
474 foreach ($bindings as $key => $value) {
475 if (is_int($key)) {
476 $name = trim((string)$value);
477 if ($name === '') {
478 continue;
479 }
480 $resolved[$name] = $params[$name] ?? '';
481 continue;
482 }
483
484 $name = trim((string)$key);
485 if ($name !== '') {
486 $resolved[$name] = $value;
487 }
488 }
489
490 ksort($resolved, SORT_STRING);
491 return $resolved;
492 }
493
507 public function action_scope_for_url($url, $action, $bindings = array()): string {
508 $route = $this->parse_route_url((string)$url);
509 $params = $this->effective_action_params((array)($route['params'] ?? array()));
510 return $this->action_scope_from_params($params, (string)$action, (array)$bindings);
511 }
512
521 private function action_scope_from_params(array $params, string $action, array $bindings): string {
522 $params = $this->effective_action_params($params);
523 $route = array();
524 foreach (array('dbx_modul', 'dbx_run1', 'dbx_run2', 'dbx_run3') as $key) {
525 $route[$key] = $this->normalize_action_scope_value($params[$key] ?? '');
526 }
527
528 $payload = array(
529 'version' => '1',
530 'action' => trim($action),
531 'route' => $route,
532 'bind' => $this->normalize_action_scope_value(
533 $this->resolve_action_bindings($bindings, $params)
534 ),
535 );
536
537 $json = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
538 if (!is_string($json)) {
539 $json = serialize($payload);
540 }
541
542 return 'route-v1:' . hash('sha256', $json);
543 }
544
555 private function action_route_matches(array $match, array $params): bool {
556 foreach ($match as $key => $expected) {
557 $actual = $params[(string)$key] ?? '';
558 $allowed = is_array($expected) ? $expected : array($expected);
559 $matched = false;
560
561 foreach ($allowed as $candidate) {
562 if ((string)$candidate === '*') {
563 $matched = (string)$actual !== '';
564 } elseif ((string)$actual === (string)$candidate) {
565 $matched = true;
566 }
567
568 if ($matched) {
569 break;
570 }
571 }
572
573 if (!$matched) {
574 return false;
575 }
576 }
577
578 return true;
579 }
580
599 private function configured_action_policy(array $params): array {
600 $modul = trim((string)($params['dbx_modul'] ?? ''));
601 if ($modul === '') {
602 return array();
603 }
604
605 if (!array_key_exists($modul, $this->actionRouteCache)) {
606 $routes = dbx()->get_config($modul, 'action_routes', array());
607 $this->actionRouteCache[$modul] = is_array($routes) ? $routes : array();
608 }
609
610 $routes = $this->actionRouteCache[$modul];
611 if (!is_array($routes)) {
612 return array();
613 }
614
615 foreach ($routes as $name => $definition) {
616 if (!is_array($definition)
617 || (array_key_exists('enabled', $definition) && !$definition['enabled'])) {
618 continue;
619 }
620
621 $match = $definition['match'] ?? array();
622 if (!is_array($match) || !$match || !$this->action_route_matches($match, $params)) {
623 continue;
624 }
625
626 $policyName = trim((string)($definition['action'] ?? $name));
627 if ($policyName === '') {
628 $policyName = 'action';
629 }
630
631 return array(
632 'source' => 'module',
633 'action' => $modul . '.' . $policyName,
634 'bind' => is_array($definition['bind'] ?? null)
635 ? array_values($definition['bind'])
636 : array(),
637 'match' => $match,
638 );
639 }
640
641 return array();
642 }
643
650 private function report_action_policy(array $params): array {
651 foreach (array('dbx_do', 'dbx_run3', 'dbx_run2') as $parameter) {
652 $code = strtolower(trim((string)($params[$parameter] ?? '')));
653 if ($code === '' || !isset(self::REPORT_ACTION_POLICIES[$code])) {
654 continue;
655 }
656
657 $definition = self::REPORT_ACTION_POLICIES[$code];
658 return array(
659 'source' => 'dbxReport',
660 'action' => (string)$definition['action'],
661 'bind' => (array)$definition['bind'],
662 'match' => array($parameter => $code),
663 );
664 }
665
666 return array();
667 }
668
680 private function automatic_rid_action_policy(array $params): array {
681 if (trim((string)($params['rid'] ?? '')) === '') {
682 return array();
683 }
684
685 foreach (array('dbx_do', 'dbx_run3', 'dbx_run2', 'dbx_run1') as $parameter) {
686 $code = strtolower(trim((string)($params[$parameter] ?? '')));
687 if ($code === '') {
688 continue;
689 }
690
691 $parts = preg_split('/[^a-z0-9]+/', $code, -1, PREG_SPLIT_NO_EMPTY);
692 foreach (self::AUTOMATIC_RID_ACTIONS as $keyword => $action) {
693 if (!in_array($keyword, is_array($parts) ? $parts : array(), true)) {
694 continue;
695 }
696
697 return array(
698 'source' => 'automatic',
699 'action' => $action,
700 'bind' => array('rid'),
701 'match' => array(
702 $parameter => $code,
703 'rid' => '*',
704 ),
705 );
706 }
707 }
708
709 return array();
710 }
711
723 private function automatic_grid_action_policy(array $params): array {
724 $actions = array('save', 'insert', 'delete', 'sort', 'sync');
725 $contextBindings = array('rid', 'id', 'cid', 'iid', 'modul', 'dd', 'fd', 'xmodul');
726
727 foreach (array('dbx_run3', 'dbx_run2', 'dbx_run1') as $parameter) {
728 $code = strtolower(trim((string)($params[$parameter] ?? '')));
729 if ($code === '') {
730 continue;
731 }
732
733 $parts = preg_split('/[^a-z0-9]+/', $code, -1, PREG_SPLIT_NO_EMPTY);
734 $parts = is_array($parts) ? $parts : array();
735 $gridLike = in_array('grid', $parts, true)
736 || (isset($parts[0]) && in_array($parts[0], array('data', 'fields'), true));
737 if (!$gridLike) {
738 continue;
739 }
740
741 foreach ($actions as $action) {
742 if (!in_array($action, $parts, true)) {
743 continue;
744 }
745
746 $bindings = array();
747 foreach ($contextBindings as $binding) {
748 if (array_key_exists($binding, $params)
749 && trim((string)$params[$binding]) !== '') {
750 $bindings[] = $binding;
751 }
752 }
753
754 return array(
755 'source' => 'dbxReport',
756 'action' => 'dbxReport.grid_' . $action,
757 'bind' => $bindings,
758 'match' => array($parameter => $code),
759 );
760 }
761 }
762
763 return array();
764 }
765
777 private function resolve_action_policy(array $params): array {
778 $params = $this->effective_action_params($params);
779 $policy = $this->configured_action_policy($params);
780 if (!$policy) {
781 $policy = $this->report_action_policy($params);
782 }
783 if (!$policy) {
784 $policy = $this->automatic_grid_action_policy($params);
785 }
786 if (!$policy) {
787 $policy = $this->automatic_rid_action_policy($params);
788 }
789 if (!$policy) {
790 return array();
791 }
792
793 $policy['bindings'] = $this->resolve_action_bindings((array)$policy['bind'], $params);
794 $policy['scope'] = $this->action_scope_from_params(
795 $params,
796 (string)$policy['action'],
797 (array)$policy['bindings']
798 );
799 $policy['params'] = $params;
800 return $policy;
801 }
802
812 public function action_policy_for_url($url): array {
813 $route = $this->parse_route_url((string)$url);
814 return $this->resolve_action_policy((array)($route['params'] ?? array()));
815 }
816
822 private function current_action_request_params(): array {
823 $params = is_array($_GET ?? null) ? $_GET : array();
824 if (is_array($_POST ?? null)) {
825 $params = array_replace($params, $_POST);
826 }
827
828 foreach (array('dbx_modul', 'dbx_run1', 'dbx_run2', 'dbx_run3') as $key) {
829 $value = dbx()->get_system_var($key, '', 'parameter');
830 if ((string)$value !== '') {
831 $params[$key] = $value;
832 }
833 }
834
835 return $this->effective_action_params($params);
836 }
837
843 public function current_action_policy(): array {
844 return $this->resolve_action_policy($this->current_action_request_params());
845 }
846
857 public function current_action_request_is_valid(array $policy = array()): bool {
858 if (!$policy) {
859 $policy = $this->current_action_policy();
860 }
861 if (!$policy) {
862 return true;
863 }
864
865 $token = '';
866 if (isset($_GET['dbx_token'])) {
867 $token = (string)$_GET['dbx_token'];
868 }
869 if (isset($_POST['dbx_token'])) {
870 $token = (string)$_POST['dbx_token'];
871 }
872
873 return dbx()->check_action_token((string)($policy['scope'] ?? ''), $token);
874 }
875
883 $route = $this->parse_route_url($url);
884 if ($route['permalink'] === '') {
885 return empty($route['params'])
886 ? '?'
887 : $this->build_route_url('', $route['params']) . '&';
888 }
889
890 if (empty($route['params'])) {
891 return $route['permalink'] . '?';
892 }
893
894 return $this->build_route_url($route['permalink'], $route['params']) . '&';
895 }
896
903 function get_request_route_string($baseUri = '') {
904 $requestUri = $_SERVER['REQUEST_URI'] ?? '';
905 if ($requestUri === '') {
906 return '';
907 }
908
909 if ($baseUri === '') {
910 $baseUri = $this->get_base_uri();
911 }
912
913 $path = parse_url($requestUri, PHP_URL_PATH) ?? '';
914 $path = str_replace('\\', '/', $path);
915 $baseUri = str_replace('\\', '/', $baseUri);
916
917 if ($baseUri !== '/' && $baseUri !== '' && strpos($path, $baseUri) === 0) {
918 $path = substr($path, strlen($baseUri));
919 }
920
921 $route = ltrim($path, '/');
922 $query = parse_url($requestUri, PHP_URL_QUERY);
923
924 if ($query !== null && $query !== '') {
925 if ($route === '') {
926 return '?' . $query;
927 }
928 if (strpos($route, '?') === false && strpos($route, '&') === false) {
929 return $route . '?' . $query;
930 }
931 return $route . '&' . $query;
932 }
933
934 return $route;
935 }
936
944 function strip_unwanted_route_params($params, $unwanted = '') {
945 $remove = array_merge(
946 explode(',', (string) $unwanted),
947 $this->memory_switch_params(),
948 array('dbx_token')
949 );
950
951 foreach ($remove as $key) {
952 $key = trim($key);
953 if ($key === '') {
954 continue;
955 }
956 unset($params[$key]);
957 }
958
959 return $params;
960 }
961
969function get_self_url($permalink,$unwanted) {
970 $route = $this->parse_route_url($this->get_request_route_string($this->get_base_uri()));
971 $params = $this->strip_unwanted_route_params($route['params'], $unwanted);
972
973 if ($permalink !== '') {
974 $route['permalink'] = str_replace('\\', '/', trim((string) $permalink, '/'));
975 }
976
977 return $this->build_route_url($route['permalink'], $params, $route['fragment']);
978}
979
986 return array('dbx_edit', 'dbx_design', 'dbx_color', 'dbx_lng');
987 }
988
996 $route = $this->parse_route_url($url);
997 $route['params'] = $this->strip_unwanted_route_params($route['params']);
998 return $this->build_route_url($route['permalink'], $route['params'], $route['fragment']);
999 }
1000
1008 function peel_glued_params_from_path($path, &$params = array()) {
1009 $path = str_replace('\\', '/', (string) $path);
1010 $changed = true;
1011
1012 while ($changed) {
1013 $changed = false;
1014
1015 if (preg_match('/^(.*)[?&]([a-zA-Z_][a-zA-Z0-9_]*)=([^\/&?#]+)$/', $path, $match)) {
1016 $path = $match[1];
1017 $params[$match[2]] = rawurldecode($match[3]);
1018 $changed = true;
1019 continue;
1020 }
1021
1022 if (preg_match('/^(.*?)([a-zA-Z_][a-zA-Z0-9_]*)=([^\/&?#]+)$/', $path, $match)) {
1023 if (preg_match('/^dbx_/', $match[2]) || strpos($match[2], '_') !== false) {
1024 $path = $match[1];
1025 $params[$match[2]] = rawurldecode($match[3]);
1026 $changed = true;
1027 }
1028 }
1029 }
1030
1031 return rtrim($path, '-&?/');
1032 }
1033
1040 function normalize_route_params($params) {
1041 $normalized = array();
1042
1043 if (!is_array($params)) {
1044 return $normalized;
1045 }
1046
1047 foreach ($params as $key => $value) {
1048 if ($key === '' || $value === null) {
1049 continue;
1050 }
1051 if (is_array($value)) {
1052 $normalized[(string) $key] = implode(',', $value);
1053 } else {
1054 $normalized[(string) $key] = (string) $value;
1055 }
1056 }
1057
1058 return $normalized;
1059 }
1060
1061
1067 function get_base_uri() {
1068 // Versuche zuerst, den URI aus $_SERVER['SCRIPT_NAME'] zu holen
1069 if (!empty($_SERVER['SCRIPT_NAME'])) {
1070 $uri = $_SERVER['SCRIPT_NAME'];
1071 }
1072 // Fallback auf $_SERVER['PHP_SELF'], falls $_SERVER['SCRIPT_NAME'] nicht verfügbar ist
1073 elseif (!empty($_SERVER['PHP_SELF'])) {
1074 $uri = $_SERVER['PHP_SELF'];
1075 }
1076 // Als letzte Option, versuche den URI aus $_SERVER['REQUEST_URI'] ohne Query-Parameter
1077 elseif (!empty($_SERVER['REQUEST_URI'])) {
1078 $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
1079 }
1080 // Falls keine der Optionen verfügbar ist, gib einen leeren String zurück oder eine Fehlermeldung
1081 else {
1082 $uri = ''; // Oder ein bestimmter Wert, z.B. "/unknown" oder ein Fehlerwert
1083 }
1084
1085 // Entferne den Dateinamen, um nur das Verzeichnis zurückzugeben
1086 $uri=dirname($uri);
1087 if ($uri=='\\') $uri='/';
1088 $uri = str_replace('\\', '/', $uri);
1089 return $uri;
1090 }
1091
1092
1093
1100 function get_permalink($uri) {
1101 $route = $this->parse_route_url($this->get_request_route_string($uri));
1102 return $route['permalink'];
1103 }
1104
1105
1115 $route = $this->parse_route_url($this->get_request_route_string($this->get_base_uri()));
1116 if (!empty($route['params'])) {
1117 $_GET = array_merge($_GET, $route['params']);
1118 }
1119 }
1120
1121
1139 function check_request() {
1140 //dbx_debug("dbxApp check request");
1141 //dbx_debug('#INCOME-POST',$_POST);
1142 //dbx_debug('#INCOME-GET' ,$_GET);
1143 //dbx_debug("SERVER" ,$_SERVER);
1144
1145 // JSON-Body einlesen (z. B. von fetch)
1146 $raw = file_get_contents('php://input');
1147 $data = json_decode($raw, true);
1148
1149 // Falls gültiges JSON → $_POST damit befüllen
1150 if (is_array($data)) {
1151 $_POST = array_merge($_POST, $data);
1152 }
1153
1154
1155
1156 $pvx=array(); $gvx=array();
1157
1158
1159
1160 if (isset($_POST['dbx_get'])) { // Ajax Formular
1161 $get = $_POST['dbx_get'];
1162 $get = ltrim($get, '?');
1163 parse_str($get, $gvx);
1164 $_GET=array_merge($_GET, $gvx);
1165 unset($_POST['dbx_get']);
1166 }
1167
1168 if (isset($_POST['dbx_post'])) { // Ajax Formular
1169 $post= $_POST['dbx_post'];
1170 $post= ltrim($post, '?');
1171 parse_str($post, $pvx);
1172 $_POST=array_merge($_POST, $pvx);
1173 unset($_POST['dbx_post']);
1174 }
1175
1176 /*
1177 if (!empty($_GET)) {
1178 // Hol den ersten Schlüssel und den ersten Wert
1179 $firstKey = array_key_first($_GET);
1180 $firstValue = $_GET[$firstKey];
1181
1182 // Prüfen, ob das erste Zeichen des Schlüssels ein '?' ist
1183 if (strpos($firstKey, '?') === 0) {
1184 // Entferne den Eintrag mit dem alten Schlüssel
1185 dbx()->debug("FIX-GET Key ($firstKey)");
1186 unset($_GET[$firstKey]);
1187 // Entferne das '?' am Anfang des Schlüssels
1188 $newKey = ltrim($firstKey, '?');
1189 // Füge den Wert mit dem neuen Schlüssel hinzu
1190 $_GET[$newKey] = $firstValue;
1191 }
1192 }
1193 */
1194
1195
1196
1197
1198 $base_uri =$this->get_base_uri();
1199 $route = $this->parse_route_url($this->get_request_route_string($base_uri));
1200 if (!empty($route['params'])) {
1201 $_GET = array_merge($route['params'], $_GET);
1202 }
1203
1204 //dbx_debug('#OUT-GET POST' ,$_GET,$_POST);
1205
1206 $base_url =$this->get_base_url($base_uri);
1207 $permalink=$this->get_permalink($base_uri);
1208 $self_url =$this->get_self_url($permalink,'dbx_ajax,dbx_window,dbx_target,dbx_go');
1209 $go = dbx()->get_request_var('dbx_go' ,0,'parameter');
1210 $ajax = dbx()->get_request_var('dbx_ajax' ,0,'int');
1211 $window = dbx()->get_request_var('dbx_window',0,'int');
1212
1213
1214 dbx()->debug("#SYS Self-url=($self_url) base-Url=($base_url) base_uri=($base_uri) Perma=($permalink)");
1215
1216 //dbx_debug('#-POST',$_POST);
1217 //dbx_debug('#-GET' ,$_GET);
1218
1219
1220
1221 dbx()->set_system_var('dbx_permalink',$permalink);
1222 dbx()->set_system_var('dbx_self_url' ,$self_url);
1223 dbx()->set_system_var('dbx_base_url' ,$base_url);
1224 dbx()->set_system_var('dbx_base_uri' ,$base_uri);
1225 dbx()->set_system_var('dbx_window' ,$window);
1226 dbx()->set_system_var('dbx_ajax' ,$ajax);
1227 dbx()->set_system_var('dbx_go' ,$go);
1228
1229
1230 }
1231
1241 public function canonical_home_redirect_target(): string {
1242 $method = strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET'));
1243 if ($method !== 'GET' && $method !== 'HEAD') {
1244 return '';
1245 }
1246
1247 $permalink = strtolower(trim(
1248 str_replace('\\', '/', (string)dbx()->get_system_var('dbx_permalink', '')),
1249 '/'
1250 ));
1251 if ($permalink !== 'home') {
1252 return '';
1253 }
1254
1255 $routeKeys = array(
1256 'dbx_modul',
1257 'dbx_run1',
1258 'dbx_run2',
1259 'dbx_action',
1260 'dbx_ajax',
1261 'dbx_window',
1262 'cid',
1263 'dbx_cid',
1264 );
1265 foreach ($routeKeys as $key) {
1266 if (trim((string)dbx()->get_request_var($key, '', '*')) !== '') {
1267 return '';
1268 }
1269 }
1270
1271 return rtrim((string)dbx()->get_base_url(), '/') . '/';
1272 }
1273
1279 public function apply_canonical_home_redirect(): bool {
1281 if ($target === '' || headers_sent()) {
1282 return false;
1283 }
1284
1285 header('Location: ' . $target, true, 301);
1286 return true;
1287 }
1288
1298 public function content_permalink_redirect_target(): string {
1299 $method = strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET'));
1300 if ($method !== 'GET' && $method !== 'HEAD') {
1301 return '';
1302 }
1303
1304 foreach (array(
1305 'dbx_modul', 'dbx_run1', 'dbx_run2', 'dbx_run3', 'dbx_action',
1306 'dbx_do', 'action', 'dbx_ajax', 'dbx_window', 'cid', 'dbx_cid',
1307 ) as $key) {
1308 if (trim((string)dbx()->get_request_var($key, '', '*')) !== '') {
1309 return '';
1310 }
1311 }
1312
1313 $permalink = strtolower(trim(
1314 str_replace('\\', '/', (string)dbx()->get_system_var('dbx_permalink', '')),
1315 '/'
1316 ));
1317 if ($permalink === '' || $permalink === 'home') {
1318 return '';
1319 }
1320
1321 $lng = strtolower(trim((string)dbx()->get_system_var('dbx_lng', 'de')));
1322 if (!preg_match('/^[a-z]{2,3}$/', $lng)) {
1323 return '';
1324 }
1325
1326 $redirects = dbx()->get_config('dbxContent', 'permalink_redirects', array());
1327 $redirects = is_array($redirects) && is_array($redirects[$lng] ?? null)
1328 ? $redirects[$lng]
1329 : array();
1330 if (!array_key_exists($permalink, $redirects)) {
1331 return '';
1332 }
1333
1334 $target = strtolower(trim((string)$redirects[$permalink]));
1335 if ($target === '' || $target === '/') {
1336 return rtrim((string)dbx()->get_base_url(), '/') . '/';
1337 }
1338 $target = trim($target, '/');
1339 if (!preg_match('/^[a-z0-9]+(?:-[a-z0-9]+)*$/', $target)) {
1340 return '';
1341 }
1342
1343 return rtrim((string)dbx()->get_base_url(), '/') . '/' . $target;
1344 }
1345
1351 public function apply_content_permalink_redirect(): bool {
1353 if ($target === '' || headers_sent()) {
1354 return false;
1355 }
1356
1357 header('Location: ' . $target, true, 301);
1358 return true;
1359 }
1360
1361
1368 function get_is_resorce($ext) {
1369 $ext = strtolower(ltrim(trim((string)$ext), '.'));
1370 return isset(self::RESOURCE_MIME_TYPES[$ext]) ? 1 : 0;
1371 }
1372
1374 private function get_resource_extension($permalink): string {
1375 $path = str_replace('\\', '/', rawurldecode((string)$permalink));
1376 return strtolower((string)pathinfo($path, PATHINFO_EXTENSION));
1377 }
1378
1380 private function is_dynamic_file_route($permalink): bool {
1381 $route = strtolower(trim(str_replace('\\', '/', rawurldecode((string)$permalink)), '/'));
1382 return in_array($route, self::DYNAMIC_FILE_ROUTES, true);
1383 }
1384
1391 private function has_internal_resource_referer(): bool {
1392 $referer = trim((string)($_SERVER['HTTP_REFERER'] ?? ''));
1393 if ($referer === '') {
1394 return false;
1395 }
1396
1397 $refererHost = (string)(parse_url($referer, PHP_URL_HOST) ?? '');
1398 $requestAuthority = trim((string)($_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? ''));
1399 $requestHost = (string)(parse_url('http://' . $requestAuthority, PHP_URL_HOST) ?? '');
1400
1401 $normalize = static function (string $host): string {
1402 $host = rtrim(strtolower(trim($host)), '.');
1403 return str_starts_with($host, 'www.') ? substr($host, 4) : $host;
1404 };
1405
1406 $refererHost = $normalize($refererHost);
1407 $requestHost = $normalize($requestHost);
1408 return $refererHost !== '' && $requestHost !== '' && hash_equals($requestHost, $refererHost);
1409 }
1410
1420 private function get_resource_file($permalink) {
1421 $path = str_replace('\\', '/', rawurldecode((string) $permalink));
1422 $path = ltrim($path, '/');
1423
1424 if ($path === '' || strpos($path, "\0") !== false) {
1425 return '';
1426 }
1427
1428 $parts = explode('/', $path);
1429 foreach ($parts as $part) {
1430 if ($part === '..') {
1431 return '';
1432 }
1433 }
1434
1435 // Safari und einige Crawler fragen diese Standardnamen auch ohne expliziten
1436 // Link ab. Das vorhandene Favicon ist die kanonische lokale Quelle.
1437 if (preg_match('/^apple-touch-icon(?:-precomposed)?(?:-\d+x\d+)?\.png$/i', $path)) {
1438 $path = 'favicon.png';
1439 $parts = array($path);
1440 }
1441
1442 $base = realpath(dbx()->get_base_dir());
1443 if (!$base) {
1444 return '';
1445 }
1446
1447 $file = realpath($base . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $parts));
1448 if (!$file || !is_file($file)) {
1449 return '';
1450 }
1451
1452 $baseCheck = rtrim(str_replace('\\', '/', strtolower($base)), '/') . '/';
1453 $fileCheck = str_replace('\\', '/', strtolower($file));
1454
1455 if (strpos($fileCheck, $baseCheck) !== 0) {
1456 return '';
1457 }
1458
1459 return $file;
1460 }
1461
1468 private function get_resource_mime($ext) {
1469 $ext = strtolower(ltrim(trim((string)$ext), '.'));
1470 return self::RESOURCE_MIME_TYPES[$ext] ?? 'application/octet-stream';
1471 }
1472
1480 private function send_resource_file($file, $ext) {
1481 if (headers_sent()) {
1482 return;
1483 }
1484
1485 header('Content-Type: ' . $this->get_resource_mime($ext));
1486 header('X-Content-Type-Options: nosniff');
1487 header('Cache-Control: public, max-age=3600');
1488 header('Content-Length: ' . (string)filesize($file));
1489
1490 if (strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET')) !== 'HEAD') {
1491 readfile($file);
1492 }
1493 exit;
1494 }
1495
1496
1497
1503 function check_config() {
1504 $config=dbx()->get_config('dbx');
1505 if (!is_array($config)) {
1506 $config=$this->create_new_cfg('dbx');
1507 } else {
1508 if (!isset($config['ok'])) $config=$this->create_new_cfg('dbx');
1509 }
1510
1511 $install = (int)($config['install'] ?? 1);
1512 $ok = (int)($config['ok'] ?? 0);
1513 $timezone = trim((string)($config['timezone'] ?? 'Europe/Berlin'));
1514 if ($timezone !== '' && in_array($timezone, timezone_identifiers_list(), true)) {
1515 date_default_timezone_set($timezone);
1516 }
1517
1518 dbx()->set_system_var('dbx_install', $install);
1519 dbx()->set_system_var('dbx_construct', (int)($config['construct'] ?? 0));
1520 if (!$ok) {
1521 dbx()->set_system_var('dbx_install', 1);
1522 }
1523 }
1524
1525
1526
1535 function check_missing(): bool {
1536 // Der Wert wurde bereits von check_request() aus dem Request-Pfad
1537 // abgeleitet. Hier nicht erneut als "parameter+/" filtern, weil sonst
1538 // gueltige URL-Kodierung wie %2E (Punkt) verloren geht.
1539 $permalink=dbx()->get_system_var('dbx_permalink','','*');
1540
1541 if (trim((string)$permalink) === '' || $this->is_dynamic_file_route($permalink)) {
1542 return false;
1543 }
1544
1545 $ext = $this->get_resource_extension($permalink);
1546 if (!$this->get_is_resorce($ext)) {
1547 return false;
1548 }
1549
1550 $resourceFile = $this->get_resource_file($permalink);
1551 if ($resourceFile) {
1552 dbx()->debug("## resource exists, not missing ($permalink) file=($resourceFile)");
1553 $this->send_resource_file($resourceFile, $ext);
1554 return false;
1555 }
1556
1557 http_response_code(404);
1558 header('X-Content-Type-Options: nosniff');
1559 header('Cache-Control: no-store');
1560
1561 dbx()->debug("## check missing ($permalink)");
1562 $ok = 0;
1563 if ($this->has_internal_resource_referer()) {
1564 $ok = dbx()->log_missing($permalink);
1565 } else {
1566 dbx()->debug("## missing resource not logged: no internal referer ($permalink)");
1567 }
1568 dbx()->debug("#MISSING# ($permalink) Ext=($ext) ok=($ok)");
1569 return true;
1570 }
1571
1579 public function check_remember() {
1580 // #Session switch values
1581 //$page =dbx()->get_remember_var('dbx_page' ,'default','dbx');
1582 $design=dbx()->get_remember_var('dbx_design','user' ,'dbx');
1583 $edit =dbx()->get_remember_var('dbx_edit' ,0 ,'dbx');
1584 $lng =dbx()->get_remember_var('dbx_lng' ,'de' ,'dbx');
1585 $defaultColor = dbx()->normalize_skin(
1586 (string)dbx()->get_config('dbx', 'default_color', 'blau'),
1587 (string)$design
1588 );
1589 $color = dbx()->get_remember_var('dbx_color', $defaultColor, 'dbx');
1590
1591 //$page =dbx()->get_request_var('dbx_page' ,$page);
1592 $design=dbx()->get_request_var('dbx_design',$design);
1593 $edit =dbx()->get_request_var('dbx_edit' ,$edit);
1594 $lng =dbx()->get_request_var('dbx_lng' ,$lng);
1595 $color = dbx()->normalize_skin(
1596 (string)dbx()->get_request_var('dbx_color', $color),
1597 (string)$design
1598 );
1599
1600 // Kompatibilitaet fuer vor der Umbenennung gespeicherte Designwerte und
1601 // alte Links: fleurop wurde in flowers umbenannt.
1602 if (strtolower(trim((string)$design)) === 'fleurop') {
1603 $design = 'flowers';
1604 }
1605
1606 //dbx()->set_remember_var('dbx_page' ,$page ,'dbx');
1607 dbx()->set_remember_var('dbx_design',$design,'dbx');
1608 dbx()->set_remember_var('dbx_edit' ,$edit ,'dbx');
1609 dbx()->set_remember_var('dbx_lng' ,$lng ,'dbx');
1610 dbx()->set_remember_var('dbx_color' ,$color ,'dbx');
1611
1612 dbx()->set_system_var('dbx_design', $design);
1613 dbx()->set_system_var('dbx_edit' , $edit);
1614 dbx()->set_system_var('dbx_lng' , $lng);
1615 dbx()->set_system_var('dbx_color' , $color);
1616 dbx()->set_system_var('dbx_last_editor_tpl_paths', array());
1617
1618 }
1619
1625 private function get_content_permalink_mode(): string {
1626 return dbx()->get_content_permalink_mode();
1627 }
1628
1634 private function get_content_root(): int {
1635 $requestRoot = dbx()->get_request_var('root', '', 'int');
1636
1637 if ($requestRoot !== '') {
1638 return (int) $requestRoot;
1639 }
1640
1641 $configRoot = dbx()->get_config('dbxContent', 'root');
1642 if ($configRoot === 'undef' || $configRoot === '') {
1643 return 0;
1644 }
1645
1646 return (int) $configRoot;
1647 }
1648
1656 private function set_content_route(int $cid, string $source = ''): void {
1657 if ($cid <= 0) {
1658 return;
1659 }
1660
1662 $root = $this->get_content_root();
1663
1664 dbx()->set_system_var('dbx_modul', 'dbxContent');
1665 dbx()->set_system_var('dbx_cid', $cid);
1666 dbx()->set_system_var('cid', $cid);
1667 dbx()->set_system_var('dbx_content_route_cid', $cid);
1668 $source = (string) $source;
1669 $cacheableContentRoute = str_starts_with($source, 'permalink-');
1670 dbx()->set_system_var('dbx_content_permalink_request', $cacheableContentRoute ? 1 : 0);
1671
1672 if ($mode === 'cms') {
1673 dbx()->set_system_var('dbx_run1', 'cms');
1674 dbx()->set_system_var('dbx_run2', 'show');
1675 dbx()->set_system_var('root', $root);
1676 } else {
1677 dbx()->set_system_var('dbx_run1', 'show');
1678 }
1679
1680 dbx()->debug("#PERMALINK set dbxContent mode=($mode) root=($root) cid=($cid) source=($source)");
1681 }
1682
1688 private function get_home_content_cid(): int {
1690
1691 return \dbx\dbxContent\dbxContentHome::resolveCid();
1692 }
1693
1699 private function load_content_cache_classes(): void {
1701 }
1702
1716 public function check_perma() {
1717 $cid=0; $home=0;
1718 $permalink= dbx()->get_system_var('dbx_permalink');
1719 dbx()->set_system_var('dbx_content_permalink_request', 0);
1720 dbx()->set_system_var('dbx_content_route_cid', 0);
1721 dbx()->debug("check perma ($permalink)");
1722
1723 if ($permalink =='undef') $permalink='';
1724 if ($permalink =='/') $permalink='';
1725
1726
1727 $lng=dbx()->get_system_var('dbx_lng','de');
1728
1729 $modul = dbx()->get_request_var('dbx_modul');
1730 $action = dbx()->get_request_var('dbx_run1');
1731 $hasExplicitRoute = ($modul !== '' && $action !== '');
1732
1733 if ($hasExplicitRoute) {
1734 dbx()->set_system_var('dbx_modul', $modul);
1735 dbx()->set_system_var('dbx_run1', $action);
1736 dbx()->set_system_var('dbx_run2', dbx()->get_request_var('dbx_run2', '', 'parameter'));
1737 dbx()->set_system_var('root', dbx()->get_request_var('root', '', 'int'));
1738 }
1739
1740 $requestCid = (int) dbx()->get_request_var('cid', 0, 'int');
1741 if (!$requestCid) $requestCid = (int) dbx()->get_request_var('dbx_cid', 0, 'int');
1742
1743 if ($hasExplicitRoute) {
1744 dbx()->set_system_var('dbx_cid', $requestCid);
1745 dbx()->set_system_var('cid', $requestCid);
1746 return;
1747 }
1748
1749 if ($requestCid > 0 && (!$modul || !$action || $modul === 'dbxHome')) {
1750 $this->set_content_route($requestCid, 'request-cid');
1751 return;
1752 }
1753
1754 if (!$permalink && !$modul) $home=1;
1755 if ( $modul=='dbxHome') $home=1;
1756 if ($permalink === 'home' && !$modul) $home=1;
1757
1758
1759 if ($home) {
1760 $homeCid = $this->get_home_content_cid();
1761 if ($homeCid > 0) {
1762 $homeSource = 'dbxHome-config';
1763 if ($permalink === 'home') {
1764 $homeSource = 'permalink-home';
1765 } elseif (!$modul) {
1766 $homeSource = 'permalink-root';
1767 }
1768 $this->set_content_route($homeCid, $homeSource);
1769 return;
1770 }
1771 dbx()->set_system_var('dbx_modul' ,'dbxContent');
1772 dbx()->set_system_var('dbx_run1','show');
1773 dbx()->set_system_var('dbx_run2','');
1774 dbx()->set_system_var('dbx_cid', 0);
1775 dbx()->set_system_var('cid', 0);
1776 dbx()->set_system_var('dbx_design','user');
1777 return;
1778 }
1779
1780 if ($permalink =='admin') {
1781 dbx()->set_system_var('dbx_modul','dbxAdmin');
1782 dbx()->set_system_var('dbx_run1','run');
1783 dbx()->set_system_var('dbx_design','admin');
1784 return;
1785 }
1786
1787 if ($permalink === 'sitemap.xml' || $permalink === 'sitemap') {
1788 dbx()->set_system_var('dbx_modul', 'dbxContent');
1789 dbx()->set_system_var('dbx_run1', 'sitemap');
1790 return;
1791 }
1792
1793 if ($permalink === 'robots.txt') {
1794 dbx()->set_system_var('dbx_modul', 'dbxContent');
1795 dbx()->set_system_var('dbx_run1', 'robots');
1796 return;
1797 }
1798
1799
1800
1801
1802 $check_perma=dbx()->get_config('dbx','permalink');
1803 if ($permalink > ' ' && $check_perma) {
1804 //$permalink=strtolower($permalink);
1805 dbx()->debug("##Permalink## ($permalink) Lng=($lng) check content#");
1806 $permalink=trim((string)$permalink, '/');
1807
1810 if (!is_array($resolved) || (int)($resolved['activ'] ?? 0) !== 1) {
1811 // Sprachspezifische Permalinks tragen ihre Sprache bereits eindeutig
1812 // in der Content-Tabelle. Dadurch bleiben saubere URLs ohne
1813 // dbx_lng-Query auch fuer Suchmaschinen direkt erreichbar.
1814 $accessibleLngs = function_exists('dbx_accessible_lngs')
1816 : array($lng);
1817 foreach ($accessibleLngs as $candidateLng) {
1818 $candidateLng = strtolower(trim((string)$candidateLng));
1819 if ($candidateLng === '' || $candidateLng === $lng) {
1820 continue;
1821 }
1823 $permalink,
1824 $candidateLng
1825 );
1826 if (!is_array($candidate) || (int)($candidate['activ'] ?? 0) !== 1) {
1827 continue;
1828 }
1829
1830 $lng = $candidateLng;
1831 $resolved = $candidate;
1832 dbx()->set_remember_var('dbx_lng', $lng, 'dbx');
1833 dbx()->set_system_var('dbx_lng', $lng);
1834 dbx()->debug("##Permalink## Sprache aus sauberer URL erkannt: ($lng)");
1835 break;
1836 }
1837 }
1838 if (is_array($resolved) && (int)($resolved['activ'] ?? 0) === 1) {
1839 $cid = (int)($resolved['cid'] ?? 0);
1840 if ($cid > 0) {
1841 $this->set_content_route($cid, 'permalink-content');
1842 return;
1843 }
1844 }
1845
1846 // Die Home-Seite bleibt als kompatible Darstellung erhalten. Der
1847 // angeforderte Permalink darf dabei weder umgeschrieben noch als
1848 // erfolgreicher Inhalt (Soft-404) ausgeliefert/gecached werden.
1849 $homeCid = $this->get_home_content_cid();
1850 if ($homeCid > 0) {
1851 http_response_code(404);
1852 dbx()->set_system_var('dbx_content_not_found', 1);
1853 $this->set_content_route($homeCid, 'permalink-home-fallback');
1854 dbx()->debug("#PERMALINK not found -> HTTP 404 with /home content permalink=($permalink) cid=($homeCid)");
1855 return;
1856 }
1857
1858 http_response_code(404);
1859 dbx()->set_system_var('dbx_content_not_found', 1);
1860 dbx()->set_system_var('dbx_modul', 'dbxContent');
1861 dbx()->set_system_var('dbx_run1', 'show');
1862 dbx()->set_system_var('dbx_run2', '');
1863 dbx()->set_system_var('dbx_cid', 0);
1864 dbx()->set_system_var('cid', 0);
1865 dbx()->debug("#PERMALINK not found and no /home content configured permalink=($permalink)");
1866 return;
1867 }
1868 }
1869
1875 public function check_modul() {
1876 $modul=dbx()->get_system_var('dbx_modul');
1877 if (!dbx()->is_modul($modul)) $modul='dbxHome';
1878 dbx()->set_system_var('dbx_modul',$modul);
1879 }
1880
1881
1891 public function check_design() {
1892 $admin =dbx()->can('admin');
1893 $config=dbx()->get_config('dbx');
1894 $user_default = (string)($config['default_design_user'] ?? 'dbxapp');
1895 $admin_default= (string)($config['default_design_admin'] ?? 'dbxapp');
1896 $construct = (int)($config['construct'] ?? 0);
1897 $install = (int)($config['install'] ?? 1);
1898 $intro = (int) ($config['intro'] ?? 0);
1899 $ok = (int) ($config['ok'] ?? 0);
1900
1901 $design = dbx()->get_remember_var('dbx_design',$user_default,'dbx');
1902 if (strtolower(trim((string)$design)) === 'fleurop') {
1903 $design = 'flowers';
1904 dbx()->set_remember_var('dbx_design', $design, 'dbx');
1905 }
1906 //$page = dbx()->get_remember_var('dbx_page' , 'default' ,'dbx');
1907 $page = dbx()->get_system_var('dbx_page' , 'default');
1908 $modul = dbx()->get_system_var('dbx_modul');
1909 $admin_modul = dbx()->has_text($modul,'_admin');
1910
1911
1912 if (!dbx()->is_design($design)) {
1913 $design='user';
1914 } else {
1915 if (!$admin && $design=='admin') $design='user';
1916 if ( $admin && $admin_modul) $design='admin';
1917 }
1918
1919
1920 $ajax = (int) dbx()->get_system_var('dbx_ajax', 0, 'int');
1921 if ($intro && $ok && !$ajax) {
1922 $introShown = (int) dbx()->get_session_var('intro_shown', 0, 'ui', 'dbx');
1923 $requestModul = trim((string) dbx()->get_request_var('dbx_modul', '', 'parameter'));
1924 if (!$introShown && $requestModul === '') {
1925 $design = $user_default;
1926 $modul = 'dbxHome';
1927 $page = 'intro';
1928 dbx()->set_session_var('intro_shown', 1, 'ui', 'dbx');
1929 }
1930 }
1931
1932 if (!$modul) {
1933 $design=$user_default;
1934 $modul='dbxHome';
1935 $page='home';
1936 $action='run';
1937 }
1938
1939 if ($install || !$ok) {
1940 dbx()->set_system_var('dbx_install', 1);
1941 $modul = 'dbxSetup';
1942 // Der Installer verwendet bewusst ein festes, datenbankunabhaengiges
1943 // Design. So kann eine defekte oder noch nicht konfigurierte
1944 // Kundendesign-Auswahl den Erststart nicht blockieren.
1945 $design = 'dbxapp';
1946 $page = 'install';
1947 dbx()->set_system_var('dbx_run1', 'install');
1948 }
1949
1950 if ($design=='admin') $design=$admin_default;
1951 if ($design=='user') $design=$user_default;
1952
1953 dbx()->set_system_var('dbx_modul' ,$modul);
1954 dbx()->set_system_var('dbx_design' ,$design);
1955 dbx()->set_system_var('dbx_page' ,$page);
1956 $ajax=dbx()->get_system_var('dbx_ajax',0);
1957
1958 //dbx_debug("##->check-design##=($design) Modul=($modul)Page=($page) Intro($intro) Ajax=($ajax)");
1959}
1960
1961
1967 public function check_lng() {
1968 $config=dbx()->get_config('dbx');
1969 $lng_default =$config['default_lng'];
1970 $lng_accessible=$config['accessible_lng'];
1971 $lng=dbx()->get_system_var('dbx_lng',dbx()->get_remember_var('dbx_lng',$lng_default,'dbx'));
1972 if ($lng != $lng_default) {
1973 $ok=0;
1974 if (!is_array($lng_accessible)) $lng_accessible = explode(",", $lng_accessible);
1975 foreach ($lng_accessible as $no => $val) {
1976 if ($lng == $val) $ok=1;
1977 }
1978 if (!$ok) $lng=$lng_default;
1979 }
1980 dbx()->set_remember_var('dbx_lng',$lng,'dbx');
1981 dbx()->set_system_var('dbx_lng', $lng);
1982 }
1983
1991 public function translate($content,$lng=''){
1992 if (!$lng) $lng=dbx()->get_system_var('dbx_lng','de');
1993 $dir_file=dbx()->get_base_dir().'dbx/translate.php';
1994 if (file_exists($dir_file)) {
1995 include $dir_file;
1996 }
1997 return $content;
1998 }
1999
2000
2001
2002
2009 public function del_add_css($content) {
2010 $css_content='';
2011 if (isset($_SESSION['dbx']['add_css'])) {
2012 $xcss=$_SESSION['dbx']['add_css'];
2013 if (is_array($xcss)) {
2014 foreach ($xcss as $no => $css) { $css_content.=$css."\n"; }
2015 }
2016 }
2017 $content = (str_replace('[dbx:add_css]',$css_content,$content));
2018 return $content;
2019 }
2020
2027 public function del_add_js($content) {
2028 $js_content='';
2029 if (isset($_SESSION['dbx']['add_js'])) {
2030 $xjs=$_SESSION['dbx']['add_js'];
2031 if (is_array($xjs)) {
2032 foreach ($xjs as $no => $js) { $js_content.=$js."\n"; }
2033 }
2034 }
2035 $content = (str_replace('[dbx:add_js]',$js_content,$content));
2036 return $content;
2037 }
2038
2039
2040
2047 public function out_filter($content) {
2048 include dbx()->get_base_dir().'dbx/out_filter.php';
2049 return $content;
2050 }
2051
2052
2059 public function add_norep($content) {
2060 $oTPL = dbx()->get_system_obj('dbxTPL');
2061 if (is_object($oTPL) && method_exists($oTPL, 'cleanup_optional_placeholders')) {
2062 $content = $oTPL->cleanup_optional_placeholders((string)$content);
2063 }
2064
2065 if (isset($_SESSION['dbx']['norep'])) {
2066 $xnorep=$_SESSION['dbx']['norep'];
2067 if (is_array($xnorep)) {
2068 for($i=0; $i < 2; $i++) { // noreps can include noraps
2069 foreach ($xnorep as $id => $norep) {
2070 $xid= '['.$id.']';
2071 $content = str_replace($xid,$norep,$content);
2072 }
2073 }
2074 }
2075 }
2076 return $content;
2077 }
2078
2079
2080 function get_session_rec($fld,$default='') {
2081 $value=$default;
2082 if ($fld != '*') {
2083 if (isset($_SESSION['dbx']['record'][$fld])) {
2084 $value=$_SESSION['dbx']['record'][$fld];
2085 }
2086 } else {
2087 $value=$_SESSION['dbx']['record'];
2088 }
2089 return $value;
2090 }
2091
2092 function design_load($modul_content) {
2093 $ajax =dbx()->get_system_var('dbx_ajax');
2094 $window=dbx()->get_system_var('dbx_window');
2095
2096 $design=dbx()->get_system_var('dbx_activ_design',dbx()->get_system_var('dbx_design'));
2097 $page =dbx()->get_system_var('dbx_activ_page' ,dbx()->get_system_var('dbx_page'));
2098 $lng =dbx()->get_system_var('dbx_activ_lng' ,dbx()->get_system_var('dbx_lng'));
2099
2100 //dbx_debug ("##DBX-CAll AJAX=($ajax) Get Ajax=($get_ajax) POST/GET",$_POST,$_GET);
2101
2102 if (!$ajax) {
2103 if ($window) $page='_window';
2104 $oTPL=dbx()->get_system_obj('dbxTPL');
2105 $content=$oTPL->get_design_tpl($design,$page,$lng,'htm',1);
2106
2107 if (defined('dbxRunAsAdmin') && (int) constant('dbxRunAsAdmin') === 1) {
2108 $admin_bypass_alert=$oTPL->get_tpl('dbx|alert-warning', array(
2109 'msg' => 'Admin Bypass ist aktiv'
2110 ));
2111 $modul_content=$admin_bypass_alert.'<br>'.$modul_content;
2112 }
2113
2114 $content = (str_replace("[dbx:content]",$modul_content,$content));
2115 } else {
2116 $content=$modul_content;
2117 }
2118 return $content;
2119 }
2120
2122 $edit = (int) dbx()->get_system_var('dbx_edit', 0, 'int');
2123
2124 if (($edit < 4 || $edit > 8) && $edit !== 9) {
2125 return $content;
2126 }
2127
2128 $all_files = dbx()->get_editor_files();
2129 $files = array();
2130
2131 foreach ($all_files as $file) {
2132 if (!isset($file['kind'], $file['file'])) {
2133 continue;
2134 }
2135
2136 if ($edit == 4 && $file['kind'] !== 'fd') {
2137 continue;
2138 }
2139
2140 if ($edit == 5 && $file['kind'] !== 'dd') {
2141 continue;
2142 }
2143
2144 if ($edit == 6 && $file['kind'] !== 'class') {
2145 continue;
2146 }
2147
2148 if ($edit == 7 && $file['kind'] !== 'sysclass') {
2149 continue;
2150 }
2151
2152 if ($edit == 8 && $file['kind'] !== 'config') {
2153 continue;
2154 }
2155
2156 $key = $file['kind'] . '|' . $file['file'];
2157 $files[$key] = $file;
2158 }
2159
2160 $payload = array(
2161 'mode' => $edit,
2162 'files' => array_values($files),
2163 );
2164
2165 $json = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
2166
2167 if (!$json) {
2168 return $content;
2169 }
2170
2171 $data = '<script type="application/json" class="dbx-editor-files-data">' .
2172 htmlspecialchars($json, ENT_NOQUOTES, 'UTF-8') .
2173 '</script>';
2174
2175 if (strpos($content, '</body>') !== false) {
2176 return str_replace('</body>', $data . "\n</body>", $content);
2177 }
2178
2179 return $data . $content;
2180 }
2181
2182 private function render_editor_files_menu($edit, $files) {
2183 if (!is_array($files) || !count($files)) {
2184 return '';
2185 }
2186
2187 $title = 'Editor Dateien';
2188 if ($edit == 4) $title = 'FD Dateien';
2189 if ($edit == 5) $title = 'DD Dateien';
2190 if ($edit == 6) $title = 'Modul PHP Dateien';
2191 if ($edit == 7) $title = 'myX SysClass Dateien';
2192 if ($edit == 8) $title = 'Config Dateien';
2193 if ($edit == 9) $title = 'Alle Editor Dateien';
2194
2195 $html = '<div id="dbxEditorFilesMenu" class="dbx-editor-files-menu" ';
2196 $html .= 'style="display:none;">';
2197 $html .= '<button type="button" class="dbx-editor-files-count" title="' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '" ';
2198 $html .= 'onclick="this.parentElement.classList.toggle(\'is-open\')" ';
2199 $html .= 'style="display:inline-flex;align-items:center;gap:6px;min-height:30px;padding:4px 8px;border:1px solid rgba(0,0,0,.18);border-radius:4px;background:#212529;color:#fff;box-shadow:0 4px 12px rgba(0,0,0,.18);">';
2200 $html .= '<i class="bi bi-pencil-square"></i><span>' . count($files) . '</span></button>';
2201 $html .= '<div class="dbx-editor-files-list" style="max-height:min(520px,calc(100vh - 96px));overflow:auto;padding:8px;border:1px solid rgba(0,0,0,.16);border-radius:4px;background:#fff;color:#212529;box-shadow:0 10px 28px rgba(0,0,0,.2);">';
2202 $html .= '<div class="dbx-editor-files-title" style="padding:4px 6px;font-weight:600;color:#495057;">' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '</div>';
2203
2204 foreach ($files as $file) {
2205 if (!isset($file['file'])) {
2206 continue;
2207 }
2208
2209 $path = $file['file'];
2210 $kind = isset($file['kind']) ? (string)$file['kind'] : '';
2211 $url = $this->editor_file_url($kind, $path);
2212 $label = $this->short_editor_file_label($path);
2213
2214 $html .= '<a href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '" ';
2215 $html .= 'data-url="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '" data-title="' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '" ';
2216 $html .= 'style="display:grid;grid-template-columns:22px minmax(0,1fr);align-items:center;gap:6px;padding:5px 6px;border-radius:4px;color:#212529;text-decoration:none;" class="dbx-win">';
2217 $html .= '<i class="bi bi-filetype-php"></i>';
2218 $html .= '<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">' . htmlspecialchars($label, ENT_QUOTES, 'UTF-8') . '</span>';
2219 $html .= '</a>';
2220 }
2221
2222 $html .= '</div>';
2223 $html .= '</div>';
2224
2225 return $html;
2226 }
2227
2228 private function short_editor_file_label($path) {
2229 $path = str_replace('\\', '/', $path);
2230 $prefix = 'dbx/modules/';
2231
2232 if (strpos($path, $prefix) === 0) {
2233 return substr($path, strlen($prefix));
2234 }
2235
2236 return $path;
2237 }
2238
2239 private function editor_file_url($kind, $path) {
2240 $kind = strtolower(trim((string)$kind));
2241 $path = str_replace('\\', '/', (string)$path);
2242
2243 if ($kind === 'dd' && preg_match('#^dbx/modules/([^/]+)/dd/([^/]+)\.dd\.php$#', $path, $m)) {
2244 return '?dbx_modul=dbxAdmin&dbx_run1=edit_dd&modul=' . rawurlencode($m[1]) . '&dd=' . rawurlencode($m[2]);
2245 }
2246
2247 if ($kind === 'fd' && preg_match('#^dbx/modules/([^/]+)/fd/([^/]+)\.fd\.php$#', $path, $m)) {
2248 return '?dbx_modul=dbxAdmin&dbx_run1=edit_fd&modul=' . rawurlencode($m[1]) . '&fd=' . rawurlencode($m[2]);
2249 }
2250
2251 return '?dbx_modul=dbxEditor&dbx_run1=edit&file=' . rawurlencode($path);
2252 }
2253
2264 private function reject_action_request(array $policy): string {
2265 http_response_code(403);
2266
2267 $action = (string)($policy['action'] ?? 'action');
2268 $params = (array)($policy['params'] ?? array());
2269 $modul = (string)($params['dbx_modul'] ?? dbx()->get_system_var('dbx_modul', '', 'parameter'));
2270
2271 try {
2272 dbx()->sys_msg(
2273 'security',
2274 'Action-Token abgewiesen',
2275 $action,
2276 'ungueltiger oder fehlender dbx_token',
2277 array(
2278 'modul' => $modul,
2279 'bindings' => (array)($policy['bindings'] ?? array()),
2280 'source' => (string)($policy['source'] ?? ''),
2281 )
2282 );
2283 } catch (Throwable $e) {
2284 dbx()->debug('Action-Token-Ablehnung konnte nicht protokolliert werden: ' . $e->getMessage());
2285 }
2286
2287 $message = 'Die Aktion wurde aus Sicherheitsgründen nicht ausgeführt. Bitte laden Sie die Ausgangsseite neu und verwenden Sie den dort angebotenen Aktionslink.';
2288 $api = (int)dbx()->get_system_var('dbx_api', 0, 'int') === 1;
2289
2290 if ($api) {
2291 if (!headers_sent()) {
2292 header('Content-Type: application/json; charset=UTF-8');
2293 }
2294 return (string)json_encode(array(
2295 'ok' => false,
2296 'status' => 403,
2297 'error' => 'invalid_action_token',
2298 'message' => $message,
2299 ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
2300 }
2301
2302 $tpl = dbx()->get_system_obj('dbxTPL');
2303 return $tpl->get_tpl('dbx|alert-warning', array('msg' => $message));
2304 }
2305
2306 // - - - - - - - - - - - - - - - - - - - - -
2307
2308 function run() {
2309 $content='';
2310 $uid =dbx()->user();
2311 $self =dbx()->get_self_url();
2312 $design = dbx()->get_system_var('dbx_design');
2313 $page = dbx()->get_system_var('dbx_page');
2314 $lng = dbx()->get_system_var('dbx_lng');
2315 $edit = dbx()->get_system_var('dbx_edit');
2316 $color = dbx()->get_system_var('dbx_color');
2317 $modul = dbx()->get_system_var('dbx_modul');
2318 $action = dbx()->get_system_var('dbx_run1');
2319 $api = dbx()->get_system_var('dbx_api');
2320 $cid = dbx()->get_system_var('dbx_cid',0);
2321 $run2 = dbx()->get_system_var('dbx_run2','');
2322 $root = dbx()->get_system_var('root','');
2323 $install= dbx()->get_system_var('dbx_install',0);
2324
2325 //$oInterpreter = dbx()->get_system_obj('dbxInterpreter');
2326
2327 // Ein Request-Parameter darf niemals eine Benutzeridentitaet erzeugen.
2328 // API-Endpunkte verwenden dieselbe Modul- und Rechtepruefung wie jeder
2329 // andere Request; eine erforderliche Anmeldung muss explizit erfolgen.
2330
2331 //dbx_debug("#WebApp run-> Design=($design) Page=($page) Modul=($modul) Action=($action) Api=($api) Install=($install) User=($uid) Lng=($lng) Self=($self)");
2332
2333
2334 if ($modul) {
2335 $access=dbx()->can_modul($modul);
2336 if (!$access) {
2337 $perma=dbx()->get_system_var('dbx_permalink');
2338 if ( $perma && !$uid) dbx()->set_remember_var('dbx_redir_after_login',$perma,'dbx');
2339 if (!$perma && !$uid) dbx()->set_remember_var('dbx_redir_after_login',"?dbx_modul=$modul&dbx_run1=$action",'dbx');
2340
2341 $content='[modul=dbxLogin]dbx_run1=login[/modul]';
2342 }
2343 if ($access) {
2344
2345 dbx()->set_system_var('dbx_master_modul' , $modul); // use 4 session
2346 dbx()->set_system_var('dbx_master_action',$action); // use 4 session
2347 dbx()->set_system_var('dbx_activ_modul' , $modul); // use 4 session
2348 dbx()->set_system_var('dbx_activ_action' ,$action); // use 4 session
2349
2350 $actionPolicy = $this->current_action_policy();
2351 if ($actionPolicy && !$this->current_action_request_is_valid($actionPolicy)) {
2352 $content = $this->reject_action_request($actionPolicy);
2353 } else {
2354 $dbxModul=dbx()->get_modul_obj($modul);
2355 $mid=dbx()->get_system_var('dbx_activ_modul_id',0,'*');
2356
2357 dbx()->set_system_var('dbx_activ_modul_id',$mid);
2358 dbx()->set_modul_var('dbx_modul_id',$mid);
2359 dbx()->set_modul_var('dbx_modul' ,$modul);
2360 dbx()->set_modul_var('dbx_run1' ,$action);
2361 if ($run2 !== '') dbx()->set_modul_var('dbx_run2', $run2);
2362 dbx()->set_modul_var('dbx_cid' ,$cid); // come from permalink check()
2363 if ($cid) dbx()->set_modul_var('cid', $cid);
2364 if ($root !== '') dbx()->set_modul_var('root', $root);
2365
2366 $content=dbx()->run_owner($dbxModul);
2367 }
2368
2369
2370 if ($api) dbx()->set_system_var('dbx_page','api');
2371
2372 }
2373
2374 }
2375 $mid=dbx()->get_system_var('dbx_activ_modul_id');
2376 $go =dbx()->get_system_var('dbx_go',0,'parameter');
2377 if ($go) {
2378 $js ='$(document).ready(function() { ';
2379 $js.= "dbxGoTo('$go');";
2380 $js.=' } );';
2381 $js.="\n";
2382 $content.="<br><script>$js</script><div id=dbx_end></div>";
2383 }
2384 //dbx_debug("#WebApp load-> Modul=($modul) Action=($action) Access=($access) Modul-id=($mid) go =($go)");
2385
2386 return $content;
2387 }
2388
2389
2390} // class
Bereitet den aktuellen HTTP-Request fuer dbXapp vor.
get_is_resorce($ext)
Prueft, ob eine Dateiendung als direkt auslieferbare Ressource gilt.
action_policy_for_url($url)
Liefert die Action-Policy einer URL.
normalize_self_url($url)
Bereinigt eine Self-/Menu-URL von Memory-Schaltern in Pfad und Query.
build_route_url($permalink, $params=array(), $fragment='')
Baut eine kanonische Route-URL aus Permalink, Query-Parametern und Fragment.
current_action_request_is_valid(array $policy=array())
Prueft den Action-Token des aktuellen Requests ohne Modulcode auszufuehren.
check_remember()
Uebernimmt persistente UI-/Systemwerte aus Remember in den Request.
check_lng()
Prueft und speichert die aktive Sprache.
check_modul()
Prueft das aktive Modul und setzt bei fehlendem Modul dbxHome.
translate($content, $lng='')
Wendet die globale dbx/translate.php auf Inhalt an.
memory_switch_params()
Liefert die Remember-/Memory-Schalter, die nicht in Permalinks haengen duerfen.
design_load($modul_content)
check_config()
Stellt die zentrale dbx-Konfiguration sicher.
get_base_uri()
Liefert das Basisverzeichnis des Entry Points als URI.
apply_canonical_home_redirect()
Sendet den kanonischen Startseiten-Redirect, sofern er fuer den Request gilt.
peel_glued_params_from_path($path, &$params=array())
Entfernt angeklebte Query-Parameter aus einem Permalink-Pfad.
check_missing()
Behandelt fehlende statische Ressourcen.
add_editor_files_data($content)
current_action_policy()
Liefert die automatisch erkannte Policy des aktuellen Requests.
apply_content_permalink_redirect()
Sendet eine konfigurierte permanente Content-Weiterleitung.
action_scope_for_url($url, $action, $bindings=array())
Baut den kanonischen Scope einer Link-Aktion.
canonical_home_redirect_target()
Ermittelt das 301-Ziel fuer den historischen Startseiten-Permalink.
create_new_cfg($modul='dbx')
Erstellt eine minimale Default-Konfiguration fuer ein Modul.
check_request()
Normalisiert den aktuellen HTTP-Request fuer den Kernel.
get_session_rec($fld, $default='')
normalize_route_params($params)
Normalisiert Query-Parameter auf string-Werte.
content_permalink_redirect_target()
Liefert das Ziel einer sprachabhängigen Content-Weiterleitung.
append_route_params($url, $params=array())
Haengt Parameter an eine vorhandene Route-URL an.
setRequestUriToGet()
Spiegelt Query-Parameter aus REQUEST_URI nach $_GET.
add_norep($content)
Setzt geschuetzte norep-Platzhalter am Ende wieder ein.
get_base_url(string $uri)
Ermittelt die Basis-URL des Servers und gibt sie zurück.
strip_unwanted_route_params($params, $unwanted='')
Entfernt unerwuenschte Parameter aus einem Param-Array.
check_perma()
Loest Permalink, Home, Admin und explizite Modulrouten auf.
del_add_css($content)
Ersetzt [dbx:add_css] durch im Request gesammelte CSS-Fragmente.
get_permalink($uri)
Ermittelt den Permalink-Anteil hinter der Basis-URI.
parse_route_url($url)
Parst Permalink- und Standard-URLs in Pfad + Query-Parameter.
route_param_prefix($url)
Prefix fuer Template-Links wie {self}dbx_design=desktop.
check_design()
Bestimmt das aktive Design fuer den Request.
check_uri()
Zerlegt REQUEST_URI in Pfad und Query-Parameter.
out_filter($content)
Fuehrt den zentralen Ausgabe-Filter aus.
get_self_url($permalink, $unwanted)
Baut die aktuelle Self-URL ohne unerwuenschte DBX-Steuerparameter.
del_add_js($content)
Ersetzt [dbx:add_js] durch im Request gesammelte JS-Fragmente.
get_request_route_string($baseUri='')
Liefert den Routen-Teil des aktuellen Requests (Permalink + Query).
if((int)( $admin[ 'id'] ?? 0)<=0) if(!dbx() ->patch_local_config('dbxLogin', array('register'=> '0'))) $binding
is_modul($modul)
Prueft, ob ein Modulverzeichnis existiert.
Definition dbxApi.php:2201
dbx()
Liefert die zentrale dbXapp-API als Singleton.
Definition dbxApi.php:2805
get_base_dir(int $cutData=0)
Liefert das Basisverzeichnis der Installation.
Definition dbxApi.php:1507
get_file_dir()
Liefert das files/-Verzeichnis der Installation.
Definition dbxApi.php:1524
is_design($design, $page='default')
Prueft, ob ein Design fuer die angegebene Seite existiert.
Definition dbxApi.php:2217
parse_url($data)
Zerlegt URL-/Parameterdaten in einen Array.
Definition dbxApi.php:2416
get_self_url()
Liefert die Self-URL des aktuellen Requests.
Definition dbxApi.php:1497
dbx_accessible_lngs()
Konfigurierte Sprachen aus dbx-Config.
Definition dbxApi.php:3048
get_content_permalink_mode()
Liefert den Permalink-Modus von dbxContent (content oder cms).
Definition dbxApi.php:1913
load_content_cache_classes()
Laedt die Content-Cache-Klassen einmalig fuer Frontend, CMS und Admin.
Definition dbxApi.php:1898
get_base_url()
Liefert die Basis-URL des aktuellen Requests.
Definition dbxApi.php:1488
get_remember_var(string $varname, $default='', string $modul='modul')
Liest einen Remember-Wert.
Definition dbxApi.php:1014
$_SERVER['REQUEST_METHOD']
if($stored !=='files/test/') $resolved
if($resolved !==$expectedBase . 'files/test/') $config
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)
foreach( $iterator as $file) if(! $groups) $expected
if($web->content_permalink_redirect_target() !=='') $tpl
if(trim($second) !=='second') $design
if(trim($first) !=='first') $cached
if(!defined( 'IMG_WEBP')) define( 'IMG_WEBP'
exit
Definition index.php:146
DBX schema administration.
if($cinematic===''||!str_contains($cinematic, 'data-dbx-cinema')) $page