283 private $maxDepth = 10;
294 function replaces(
string $tpl, $replaces): string {
296 if (!is_array($replaces)) {
297 $replaces =
dbx()->parse_url($replaces);
300 if (!is_array($replaces) || !$replaces) {
305 foreach ($replaces as $key => $value) {
306 if (is_array($value) || is_object($value)) {
310 $map[
'{' . $key .
'}'] = (string) ($value ??
'');
313 return $map ? strtr($tpl, $map) : $tpl;
322 $tpl = str_replace(
'{dbx:base_href}',
dbx()->get_base_url(), $tpl);
323 $tpl = str_replace(
'{dbx:design}' ,
dbx()->get_system_var(
'dbx_activ_design',
dbx()->get_system_var(
'dbx_design')), $tpl);
324 $tpl = str_replace(
'{dbx:color}' ,
dbx()->get_skin(), $tpl);
325 $tpl = str_replace(
'{dbx:skin_css}' ,
dbx()->get_skin_css(), $tpl);
326 $tpl = str_replace(
'{dbx:skin_class}',
dbx()->get_skin_class(), $tpl);
327 $tpl = str_replace(
'{dbx:page}' ,
dbx()->get_system_var(
'dbx_activ_page',
dbx()->get_system_var(
'dbx_page')), $tpl);
328 $tpl = str_replace(
'{dbx:lng}' ,
dbx()->get_system_var(
'dbx_activ_lng',
dbx()->get_system_var(
'dbx_lng')), $tpl);
329 $tpl = str_replace(
'{dbx:title}' , htmlspecialchars((
string)
dbx()->get_system_var(
'dbx_title'), ENT_QUOTES,
'UTF-8'), $tpl);
330 $tpl = str_replace(
'{dbx:perma}' ,
dbx()->get_system_var(
'dbx_perma'), $tpl);
332 $meta_description = (string)
dbx()->get_system_var(
'dbx_meta_description',
'');
333 $meta_keywords = (string)
dbx()->get_system_var(
'dbx_meta_keywords',
'');
334 $canonical = (string)
dbx()->get_system_var(
'dbx_canonical',
'');
335 $robots = $this->effective_robots_meta();
336 $og_title = (string)
dbx()->get_system_var(
'dbx_og_title',
'');
337 $og_description = (string)
dbx()->get_system_var(
'dbx_og_description',
'');
338 $og_url = (string)
dbx()->get_system_var(
'dbx_og_url',
'');
339 $og_image = (string)
dbx()->get_system_var(
'dbx_og_image',
'');
341 $tpl = str_replace(
'{dbx:meta_description}', $this->seo_attr_esc($meta_description), $tpl);
342 $tpl = str_replace(
'{dbx:meta_keywords}' , $this->seo_attr_esc($meta_keywords), $tpl);
343 $tpl = str_replace(
'{dbx:canonical}' , $this->seo_attr_esc($canonical), $tpl);
344 $tpl = str_replace(
'{dbx:robots}' , $this->seo_attr_esc($robots), $tpl);
345 $tpl = str_replace(
'{dbx:og_title}' , $this->seo_attr_esc($og_title), $tpl);
346 $tpl = str_replace(
'{dbx:og_description}' , $this->seo_attr_esc($og_description), $tpl);
347 $tpl = str_replace(
'{dbx:og_url}' , $this->seo_attr_esc($og_url), $tpl);
348 $tpl = str_replace(
'{dbx:og_image}' , $this->seo_attr_esc($og_image), $tpl);
349 $tpl = str_replace(
'{dbx:head_meta}' , $this->build_head_meta_block(), $tpl);
354 private function seo_attr_esc($value): string {
355 return htmlspecialchars((string)$value, ENT_QUOTES,
'UTF-8');
358 private function build_head_meta_block(): string {
361 $description = trim((
string)
dbx()->get_system_var(
'dbx_meta_description',
''));
362 if ($description !==
'') {
363 $lines[] =
'<meta name="description" content="' . $this->seo_attr_esc($description) .
'">';
366 $keywords = trim((
string)
dbx()->get_system_var(
'dbx_meta_keywords',
''));
367 if ($keywords !==
'') {
368 $lines[] =
'<meta name="keywords" content="' . $this->seo_attr_esc($keywords) .
'">';
371 $canonical = trim((
string)
dbx()->get_system_var(
'dbx_canonical',
''));
372 if ($canonical !==
'') {
373 $lines[] =
'<link rel="canonical" href="' . $this->seo_attr_esc($canonical) .
'">';
376 $robots = $this->effective_robots_meta();
377 if ($robots !==
'') {
378 $lines[] =
'<meta name="robots" content="' . $this->seo_attr_esc($robots) .
'">';
381 $og_title = trim((
string)
dbx()->get_system_var(
'dbx_og_title',
''));
382 if ($og_title !==
'') {
383 $lines[] =
'<meta property="og:title" content="' . $this->seo_attr_esc($og_title) .
'">';
386 $og_description = trim((
string)
dbx()->get_system_var(
'dbx_og_description',
''));
387 if ($og_description !==
'') {
388 $lines[] =
'<meta property="og:description" content="' . $this->seo_attr_esc($og_description) .
'">';
391 $og_url = trim((
string)
dbx()->get_system_var(
'dbx_og_url',
''));
392 if ($og_url !==
'') {
393 $lines[] =
'<meta property="og:url" content="' . $this->seo_attr_esc($og_url) .
'">';
396 $og_image = trim((
string)
dbx()->get_system_var(
'dbx_og_image',
''));
397 if ($og_image !==
'') {
398 $lines[] =
'<meta property="og:image" content="' . $this->seo_attr_esc($og_image) .
'">';
401 if ($og_title !==
'' || $og_description !==
'' || $og_url !==
'' || $og_image !==
'') {
402 $lines[] =
'<meta property="og:type" content="website">';
405 $hreflang = (string)
dbx()->get_system_var(
'dbx_hreflang',
'');
406 if (trim($hreflang) !==
'') {
407 $lines[] = ltrim($hreflang);
410 $jsonLd = trim((
string)
dbx()->get_system_var(
'dbx_json_ld',
''));
411 if ($jsonLd !==
'') {
419 return "\n " . implode(
"\n ", $lines);
422 private function effective_robots_meta(): string {
423 $robots = trim((string)
dbx()->get_system_var(
'dbx_robots',
''));
424 if ($robots !==
'') {
428 $modul = trim((
string)
dbx()->get_request_var(
'dbx_modul',
'',
'parameter'));
429 $action = trim((
string)
dbx()->get_request_var(
'dbx_action',
'',
'parameter'));
430 $ajax = (int)
dbx()->get_system_var(
'dbx_ajax', 0,
'int');
431 $window = (int)
dbx()->get_system_var(
'dbx_window', 0,
'int');
433 if ($modul !==
'' || $action !==
'' || $ajax > 0 || $window > 0) {
434 return 'noindex,follow';
450 array(
'{bar_middle}',
'[dbx:js]'),
466 $file = strtolower($file);
467 $lng =
dbx()->get_system_var(
'dbx_lng',
'');
469 if (!isset($_SESSION[
'dbx'][
'cache'][
'tpl'])) {
470 $_SESSION[
'dbx'][
'cache'][
'tpl'] = [];
473 $cache =& $_SESSION[
'dbx'][
'cache'][
'tpl'];
476 if (isset($cache[$modul][$file][$type][$lng])) {
477 return $cache[$modul][$file][$type][$lng][
'tpl'];
482 $path = function_exists(
'dbx_lng_resolve_file')
483 ? dbx_lng_resolve_file(
$base, $file, $type,
'',
true)
487 $file_lng =
$base . $file .
'_' . $lng .
'.' . $type;
488 $file_def =
$base . $file .
'.' . $type;
490 if ($lng && file_exists($file_lng)) {
492 } elseif (file_exists($file_def)) {
498 return "<div class='alert alert-danger'>TPL ($modul/$file.$type) not found</div>";
501 $tpl = file_get_contents($path);
506 $relPath =
dbx()->editor_file_path($path);
509 $cache[$modul][$file][$type][$lng] = [
525 private function has_editor($modul, $isDesign, $edit, $path =
''): bool {
526 if ((int)
dbx()->get_system_var(
'dbx_editor', 0,
'int') > 0) {
530 if ((
string)
dbx()->get_system_var(
'dbx_page',
'') ===
'_tpledit') {
534 $isDbxModule = $this->is_dbx_template_path($path);
537 $isDbxModule = strtolower(trim((
string) $modul)) ===
'dbx';
541 case 1:
return !$isDesign && !$isDbxModule;
542 case 2:
return !$isDesign && $isDbxModule;
543 case 3:
return !$isDesign;
550 private function is_dbx_template_path($path): bool {
551 $path = strtolower(str_replace(
'\\',
'/', trim((string) $path)));
552 return strpos($path,
'dbx/modules/dbx/tpl/') === 0;
555 private function get_cached_tpl_path($modul, $file, $type): string {
556 $lng =
dbx()->get_system_var(
'dbx_lng',
'');
557 $path = $_SESSION[
'dbx'][
'cache'][
'tpl'][$modul][$file][$type][$lng][
'path'] ??
'';
560 return $path !==
'' ?
dbx()->editor_file_path($path) :
'';
567 private function add_marker($tpl, $modul, $file, $type) {
568 $path = $this->get_cached_tpl_path($modul, $file, $type);
571 dbx()->register_editor_file(
'tpl', $path);
580 if (preg_match(
'/^<t([dh])\b([^>]*)>(.*)<\/t\1>\s*$/is', $tpl, $m)) {
581 return '<t' . $m[1] . $m[2] .
'><!-- DBX-TPL-START|' . $path .
' -->'
582 . $m[3] .
'<!-- DBX-TPL-END --></t' . $m[1] .
'>';
585 return "<!-- DBX-TPL-START|$path -->" . $tpl .
"<!-- DBX-TPL-END -->";
596 private function process_inc($tpl) {
598 $allowed = [
'has_group',
'is_dbx_edit'];
600 return preg_replace_callback(
'/\[inc=([^\]]+)\](.*?)\[\/inc\]/s',
function ($m) use ($allowed) {
605 if ($cond ===
'1')
return $content;
606 if ($cond ===
'0')
return '';
609 if (preg_match(
'/(\w+)\((.*?)\)/', $cond, $f)) {
612 $args = array_map(
'trim', explode(
',', $f[2]));
617 $args = array_map(
function ($arg) {
621 (substr($arg, 0, 1) ===
"'" && substr($arg, -1) ===
"'") ||
622 (substr($arg, 0, 1) ===
'"' && substr($arg, -1) ===
'"')
624 $arg = substr($arg, 1, -1);
630 if (in_array($fn, $allowed,
true)) {
634 if (is_object($dbx) && is_callable([$dbx, $fn])) {
635 return call_user_func_array([$dbx, $fn], $args) ? $content :
'';
638 if (function_exists($fn)) {
639 return call_user_func_array($fn, $args) ? $content :
'';
656 private function process_tpl($tpl, $data, $depth) {
658 if ($depth > $this->maxDepth) {
659 return "<!-- MAX DEPTH -->";
662 return preg_replace_callback(
'/\[tpl=([^\]]+)\]/',
function ($m) use ($data, $depth) {
664 $parts = explode(
'|', $m[1], 3);
666 $modul = $this->_modul;
669 if (count($parts) > 1) {
674 $type = $parts[2] ??
'htm';
676 return $this->get_tpl($modul .
'|' . $file, $data, $type, 0, $depth + 1);
697 public function get_tpl($file, $data =
'', $type =
'htm', $i = 0, $depth = 0) {
698 if ($depth > $this->maxDepth) {
699 return "<!-- MAX DEPTH -->";
704 $parts = explode(
'|', $file);
706 if (count($parts) > 1) {
712 if ($modul ===
'modul') {
713 $modul =
dbx()->get_system_var(
'dbx_activ_modul',
'dbx');
718 $this->_modul = $modul;
721 $edit =
dbx()->get_system_var(
'dbx_edit', 0);
725 $tpl = $this->
read_tpl($modul, $file, $type);
728 $tpl = $this->
replaces($tpl, $data);
731 if (strpos($tpl,
'[inc=') !==
false) {
732 $tpl = $this->process_inc($tpl);
736 if (strpos($tpl,
'[tpl=') !==
false) {
737 $tpl = $this->process_tpl($tpl, $data, $depth);
741 $path = $this->get_cached_tpl_path($modul, $file, $type);
743 if ($edit && $this->has_editor($modul, $isDesign, $edit, $path)) {
744 $tpl = $this->add_marker($tpl, $modul, $file, $type);
767 function get_design_tpl($design, $page, $language =
'de', $type =
'htm', $repurl = 1) {
769 if (!$page) $page =
'default';
770 if (substr($page, 0, 1) ==
"_") $design =
'admin';
773 if ($design ==
'admin' || $design ==
'user') {
775 if ($design ==
'admin') $design =
$config[
'default_design_admin'];
776 if ($design ==
'user') $design =
$config[
'default_design_user'];
780 $requested_page = $page;
784 if ($requested_page !=
'default') {
785 dbx()->sys_msg(
'info',
"Page ($requested_page) not exist. Use (default)");
793 dbx()->sys_msg(
'error',
"Default page (default) not exist");
797 $home_url =
dbx()->get_base_url();
799 if ($dir_file && file_exists($dir_file)) {
804 $page_content = file_get_contents($dir_file);
806 $page_content = $this->process_inc($page_content);
809 dbx()->set_system_var(
'dbx_activ_design', $design);
810 dbx()->set_system_var(
'dbx_activ_page', $page);
811 dbx()->set_system_var(
'dbx_activ_lng', $language);
812 dbx()->register_editor_file(
'design', $dir_file);
815 if ($repurl == 1 && $type ==
'htm') {
816 $url =
"dbx/design/$design/";
817 $new_url =
'="' . $url;
818 $i =
dbx()->next_id(); $page_content = str_replace(
"<head>",
"<head>\n <base href=\"" . $home_url .
"\"/>", $page_content);
819 $page_content = str_replace(
'{base_url}', $home_url, $page_content);
820 $page_content = str_replace(
'="../', $new_url, $page_content);
821 $page_content = str_replace(
'{i}', $i, $page_content);
823 $page_content = $this->process_tpl($page_content, [], 1);
832 $edit =
dbx()->get_system_var(
'dbx_edit', 0);
834 if (
false && $edit == 4) {
837 '?dbx_modul=dbxAdmin' .
838 '&dbx_run1=_edittpl_file' .
839 '&file=' . urlencode($dir_file);
842 '<a href="' . $url .
'" class="dbx-win" ' .
843 'data-url="' . htmlspecialchars($url, ENT_QUOTES,
'UTF-8') .
'" data-title="Template bearbeiten" data-width="900" data-height="80%" ' .
849 background:rgba(0,0,0,0.7);
854 text-decoration:none;
858 $page_content = preg_replace(
860 '<body$1>' .
"\n" . $icon,
868 if ($type ==
'php') {
870 if ($dir_file && file_exists($dir_file)) {
875 return $page_content;
884 $dir_file = function_exists(
'dbx_lng_resolve_file')
885 ? dbx_lng_resolve_file(
$base, $file, $type,
'',
false)
888 if ($dir_file ===
'' && file_exists(
$base . $file .
'.' . $type)) {
889 $dir_file =
$base . $file .
'.' . $type;
901 $dir_file = function_exists(
'dbx_lng_resolve_file')
902 ? dbx_lng_resolve_file(
$base,
'default', $type,
'',
false)
905 if ($dir_file ===
'' && file_exists(
$base .
'default.' . $type)) {
906 $dir_file =
$base .
'default.' . $type;