8 private function needsCmsRuntime() {
12 private function render_frontend_view($cid, $pageContent) {
13 $tpl =
dbx()->get_system_obj(
'dbxTPL');
14 $i =
dbx()->next_id();
15 $title = $this->page_title($cid);
17 return $tpl->get_tpl(
'dbxContent|content-page-frontend', array(
18 'frame_id' =>
'dbx_content_view_' . $i,
19 'cid' => (
string)(
int)$cid,
20 'frontend_head' => $tpl->get_tpl(
'dbxContent|content-frontend-head', array(
21 'bar_title' => $title,
22 'bar_title_pre' => $this->adminEditorBarHtml($cid,
true),
23 'bar_title_heading_attrs' =>
' data-cms-page-title',
25 'page_content' => $pageContent,
29 private function treeToggleBarHtml() {
34 return dbx()->get_system_obj(
'dbxTPL')->get_tpl(
'dbxContent|content-view-bar-tree-toggle');
37 private function adminEditorBarHtml($cid = 0, $useWindow =
false) {
38 if (!
dbx()->can(
'admin')) {
42 $tpl =
dbx()->get_system_obj(
'dbxTPL');
44 if ($useWindow && $cid > 0) {
45 $url = $this->appUrl() .
'?dbx_modul=dbxContent_admin&dbx_run1=cms&cid=' . $cid;
46 return $tpl->get_tpl(
'dbxContent|content-view-bar-admin-win', array(
47 'admin_url' =>
dbx()->esc($url),
51 return $tpl->get_tpl(
'dbxContent|content-view-bar-admin');
54 private function appUrl() {
55 $script = str_replace(
'\\',
'/', (
string)(
$_SERVER[
'SCRIPT_NAME'] ??
''));
56 if ($script ===
'')
return '';
57 $dir = str_replace(
'\\',
'/', dirname($script));
58 if (
$dir ===
'.' ||
$dir ===
'/' ||
$dir ===
'\\')
return '/';
59 return rtrim(
$dir,
'/') .
'/';
62 private function moduleFrameReplaces($barTitle, $i, $panelAttrs, $barAdmin =
'', $barSubtitle =
'', $barTreeToggle =
'') {
63 $tpl =
dbx()->get_system_obj(
'dbxTPL');
66 'frame_id' =>
'dbx_content_tree_' . $i,
67 'frame_panel_class' =>
'dbx-cms dbx-cms-view dbx-content-tree-view dbxReport',
68 'frame_body_class' =>
'dbx-content-tree-body',
69 'frame_panel_attrs' => $panelAttrs,
71 'frame_form_open' =>
'',
72 'frame_form_close' =>
'',
73 'frame_body_head' =>
'',
74 'frame_body_tail' =>
'',
75 'bar_class' =>
'dbx-module-bar dbx-cms-head',
76 'bar_title_class' =>
'dbx-module-bar-titleblock',
77 'bar_actions_class' =>
'dbx-module-bar-actions flex-nowrap',
78 'bar_title' => $barTitle,
79 'bar_icon' =>
'bi-file-earmark-text',
80 'bar_subtitle' => $barSubtitle,
81 'bar_title_pre' => (
string)$barAdmin . (
string)$barTreeToggle,
82 'bar_title_heading_attrs' =>
' data-cms-page-title',
85 'bar_actions' => $tpl->get_tpl(
'dbxContent|content-view-bar-actions'),
89 private function page_title($cid) {
92 return 'Keine Seite ausgewaehlt';
95 $db =
dbx()->get_system_obj(
'dbxDB');
97 if (!is_array($row)) {
98 return 'Seite #' . $cid;
101 $title = trim((
string)($row[
'title'] ??
''));
102 return $title !==
'' ? $title : (
'Seite #' . $cid);
105 private function base_url($action, $params = array()) {
106 $url =
'?dbx_modul=dbxContent&dbx_run1=' . rawurlencode((
string)$action);
107 foreach ($params as $key => $value) {
108 $url .=
'&' . rawurlencode((
string)$key) .
'=' . rawurlencode((
string)$value);
113 private function root_id() {
114 return dbx()->get_modul_var(
'root', 0,
'int');
117 private function user_has_access($groups) {
118 $groups = trim((
string)$groups);
119 if ($groups ===
'') $groups =
'*';
120 return dbx()->can($groups);
123 private function dd_server($dd, $fallback) {
124 $db =
dbx()->get_system_obj(
'dbxDB');
125 if (method_exists(
$db,
'load_dd')) {
126 $sys =
$db->load_dd($dd);
127 $mod = $sys[
'dd_modul'] ??
'dbx';
128 $name = $sys[
'dd_name'] ??
'';
129 if ($name && isset($_SESSION[
'dbx'][
'cache'][
'dd'][$mod][$name][
'table'][
'server'])) {
130 return $_SESSION[
'dbx'][
'cache'][
'dd'][$mod][$name][
'table'][
'server'];
138 $table = preg_replace(
'/[^A-Za-z0-9_]+/',
'', (
string)
$table);
139 $name = preg_replace(
'/[^A-Za-z0-9_]+/',
'', (
string)$name);
143 if (is_array($cols)) {
144 foreach ($cols as $col) {
145 if (isset($col[
'name']) && strtolower((
string)$col[
'name']) === strtolower($name))
return;
149 $db->exec(
$server,
'ALTER TABLE ' .
$table .
' ADD COLUMN ' . $name .
' ' . $type);
152 private function ensure_tree_schema(
$db) {
153 static $done =
false;
159 $this->ensure_column(
$db, $folder_server, $folder_table,
'sorter',
"TEXT DEFAULT ''");
162 private function resolve_folder_rights(
$db, $folder_id, array $visited = array()) {
163 $folder_id = (int)$folder_id;
164 if ($folder_id <= 0)
return '*';
165 if (isset($visited[$folder_id]))
return '*';
166 $visited[$folder_id] = 1;
169 if (!is_array($row))
return '*';
171 $raw = trim((
string)($row[
'group_read'] ??
''));
172 if ($raw ===
'')
return '*';
174 $parent_id = (int)($row[
'parent_id'] ?? 0);
175 $parts = preg_split(
'/\s*,\s*/', $raw, -1, PREG_SPLIT_NO_EMPTY);
177 $uses_parent =
false;
179 foreach ($parts as $part) {
180 $part = trim((
string)$part);
181 if ($part ===
'')
continue;
182 if (strtolower($part) ===
'parent') {
190 foreach (preg_split(
'/\s*,\s*/', $this->resolve_folder_rights(
$db, $parent_id, $visited), -1, PREG_SPLIT_NO_EMPTY) as $part) {
191 $part = trim((
string)$part);
192 if ($part !==
'' && strtolower($part) !==
'parent') $out[$part] = 1;
196 return count($out) ? implode(
',', array_keys($out)) :
'*';
199 private function resolve_page_rights(
$db, array $page) {
200 return $this->resolve_folder_rights(
$db, (
int)($page[
'folder'] ?? 0));
203 private function row_html(array $node) {
204 $tpl =
dbx()->get_system_obj(
'dbxTPL');
205 $type = ($node[
'_type'] ??
'') ===
'folder' ?
'folder' :
'page';
206 $title =
dbx()->esc((
string)($node[
'_title'] ??
''));
209 '_id' => (
string)(
int)($node[
'_id'] ?? 0),
210 '_parent' => (
string)(
int)($node[
'_parent'] ?? 0),
211 'draggable_attr' =>
'',
212 'icon' => $type ===
'folder' ?
'<i class="bi bi-folder2-open"></i>' :
'<i class="bi bi-file-earmark-text"></i>',
213 'folder_id_label' =>
'',
214 'title_label' => $title,
215 'rights_label' =>
'',
217 return $tpl->get_tpl(
'dbxContent|content-tree-row', $data);
220 private function decorate_nodes(array $nodes, array &$flat) {
221 $db =
dbx()->get_system_obj(
'dbxDB');
223 foreach ($nodes as $node) {
224 if (!is_array($node))
continue;
225 $type = ($node[
'_type'] ??
'') ===
'folder' ?
'folder' :
'page';
226 $id = (int)($node[
'_id'] ?? 0);
227 if ($id <= 0)
continue;
229 if ($type ===
'folder') {
230 if (!$this->user_has_access($this->resolve_folder_rights(
$db, $id)))
continue;
231 $node[
'_children'] = $this->decorate_nodes(is_array($node[
'_children'] ??
null) ? $node[
'_children'] : array(), $flat);
232 if (!count($node[
'_children']))
continue;
235 if (!is_array($page) || (
int)($page[
'activ'] ?? 0) !== 1)
continue;
236 if (!$this->user_has_access($this->resolve_page_rights(
$db, $page)))
continue;
237 $node[
'_parent'] = (int)($page[
'folder'] ?? 0);
240 $node[
'_row_html'] = $this->row_html($node);
247 private function tree() {
248 $db =
dbx()->get_system_obj(
'dbxDB');
249 $this->ensure_tree_schema(
$db);
250 $root = $this->root_id();
251 if (
$root > 0 && !$this->user_has_access($this->resolve_folder_rights(
$db,
$root))) {
256 'count_folders' => 0,
262 'verify_access' => 0,
263 'item_where' =>
'activ = 1',
266 $nodes = $this->decorate_nodes(is_array($tree[
'nodes'] ??
null) ? $tree[
'nodes'] : array(), $flat);
271 'count_pages' => count(array_filter($flat,
function($node) {
return ($node[
'_type'] ??
'') ===
'page'; })),
272 'count_folders' => count(array_filter($flat,
function($node) {
return ($node[
'_type'] ??
'') ===
'folder'; })),
276 private function render_page($id) {
278 if ($id <= 0)
return '<div class="dbx-cms-empty">Bitte eine Seite im Content Tree waehlen.</div>';
279 $renderer =
dbx()->get_include_obj(
'dbxContentRenderer',
'dbxContent');
280 return $renderer->render($id);
283 private function render_view() {
284 $tpl =
dbx()->get_system_obj(
'dbxTPL');
285 $root = $this->root_id();
286 $cid = (int)
dbx()->get_modul_var(
'cid', 0,
'int');
287 if (!$cid) $cid = (int)
dbx()->get_modul_var(
'dbx_cid', 0,
'int');
289 $initial_content = $cid > 0
290 ? $this->render_page($cid)
291 :
'<div class="dbx-cms-empty">Bitte eine Seite im Content Tree waehlen.</div>';
293 if (!$this->needsCmsRuntime()) {
294 return $this->render_frontend_view($cid, $initial_content);
297 $i =
dbx()->next_id();
298 $dataDbx =
'lib=cms|mode=view|id=dbx_content_tree_' . $i;
300 $dataDbx .=
'|tree=' .
dbx()->esc($this->base_url(
'cms', array(
'dbx_run2' =>
'tree',
'root' =>
$root)));
302 $dataDbx .=
'|viewpage=' .
dbx()->esc($this->base_url(
'cms', array(
'dbx_run2' =>
'page',
'root' =>
$root)));
303 $dataDbx .=
'|cid=' . $cid;
305 $panelAttrs =
'data-cms-initial-page-loaded="' . ($cid > 0 ?
'1' :
'0') .
'" data-dbx="' . $dataDbx .
'"';
306 $frameTpl = $isCms ?
'content-view-frame-cms' :
'content-view-frame-content';
307 $viewFrame = $tpl->get_tpl(
'dbxContent|' . $frameTpl, array(
308 'initial_content' => $initial_content,
310 'cms_tree_search' =>
dbx()->search_html(
dbx()->search_defaults(array(
311 'title' =>
'Tree durchsuchen',
312 'extra_attrs' =>
'data-cms-search',
318 $this->moduleFrameReplaces(
319 $this->page_title($cid),
322 $this->adminEditorBarHtml(),
323 $isCms ?
'Content Tree' :
'',
324 $this->treeToggleBarHtml()
327 'frame_panel_class' =>
'dbx-cms dbx-cms-view ' . ($isCms ?
'dbx-content-tree-view' :
'dbx-content-show') .
' dbxReport',
328 'frame_body_class' => $isCms ?
'dbx-content-tree-body' :
'dbx-content-show-body',
330 'cid' => (
string)$cid,
331 'initial_loaded' => $cid > 0 ?
'1' :
'0',
332 'initial_content' => $initial_content,
333 'view_frame' => $viewFrame,
334 'tree_url' => $isCms ?
dbx()->esc($this->base_url(
'cms', array(
'dbx_run2' =>
'tree',
'root' =>
$root))) :
'',
335 'view_page_url' =>
dbx()->esc($this->base_url(
'cms', array(
'dbx_run2' =>
'page',
'root' =>
$root))),
338 return $tpl->get_tpl(
'dbxContent|content-view', $data);
341 private function tree_json() {
343 dbx()->json_response(array(
'ok' => 0,
'msg' =>
'Content Tree ist im Modus content deaktiviert.'),
true);
346 dbx()->json_response(array(
'ok' => 1) + $this->tree(),
true);
349 private function page_json() {
351 dbx()->json_response(array(
'ok' => 0,
'msg' =>
'Content Tree ist im Modus content deaktiviert.'),
true);
354 $id = (int)
dbx()->get_modul_var(
'id', 0,
'int');
355 $db =
dbx()->get_system_obj(
'dbxDB');
357 dbx()->json_response(array(
360 'title' => is_array($row) ? (
string)($row[
'title'] ??
'') :
'',
361 'html' => $this->render_page($id),
365 public function run($action =
'view') {
368 return $this->tree_json();
370 return $this->page_json();
373 return $this->render_view();
static ddFolder(string $lng='')
static ddContent(string $lng='')