dbXapp 2.0
RAD, CMS, Module und Runtime-IDE fuer dbXapp
Loading...
Searching...
No Matches
dbxReport_Modules.class.php
Go to the documentation of this file.
1<?php
2namespace dbx\dbxAdmin;
3
4dbx()->use_system_class('dbxReport');
5
7
8 private $registry;
9
10 public function __construct() {
11 parent::__construct();
12 $this->registry = new dbxModuleRegistry();
13 }
14
15 public function renderCard(array $record): string {
16 $tpl = dbx()->get_system_obj('dbxTPL');
17 $record['graphic_html'] = $this->renderModuleImages($record);
18 $record['groups_html'] = $this->renderGroups($record);
19 $record['dd_html'] = $this->renderDdList($record);
20 $record['card_state_class'] = ((string)($record['active'] ?? '1') === '0') ? ' dbx-module-row-inactive' : '';
21 $record['install_button_html'] = $this->renderInstallButton($record);
22 $record['active_toggle_button_html'] = $this->renderActiveToggleButton($record);
23 $record['delete_button_html'] = $this->renderDeleteButton($record);
24 $record['actions_html'] = $tpl->get_tpl('dbxAdmin|module-card-actions', $record);
25 $record['access_inline_html'] = $this->renderAccessInline($record);
26 $record['select_html'] = $this->_create_row_select
27 ? $this->render_table_row_select($record, 'dbx-module-row-select')
28 : '';
29 return $tpl->get_tpl('dbxAdmin|module-card', $record);
30 }
31
32 public function renderDdHtml(array $record): string {
33 return $this->renderDdList($record);
34 }
35
36 public function run_body($content) {
37 $record = is_array($this->_record) ? $this->_record : array();
38 $card = $this->renderCard($record);
39 $content = (string)$content;
40
41 if (strpos($content, '[rpt:row]') !== false) {
42 $content = str_replace('[rpt:row]', $card, $content);
43 } else {
44 $content = $card;
45 }
46
47 return $this->forward_run_body($content);
48 }
49
50 public function moduleImagesTargetHtml(array $record): string {
51 return $this->buildModuleImagesTargetHtml($record);
52 }
53
54 public function moduleImagesGalleryHtml(array $record): string {
55 return $this->buildModuleImagesGalleryHtml($record);
56 }
57
58 private function renderModuleImages(array $record): string {
59 $tpl = dbx()->get_system_obj('dbxTPL');
60 $defaultRun1 = trim((string)($record['default_run1'] ?? 'run'));
61 if ($defaultRun1 === '') {
62 $defaultRun1 = 'run';
63 }
64 $defaultRun2 = trim((string)($record['default_run2'] ?? ''));
65 $record['symbol_preview_html'] = $this->buildModuleSymbolPreviewHtml($record);
66 $record['images_gallery_html'] = $this->buildModuleImagesGalleryHtml($record);
67 $record['default_run1'] = dbx()->esc($defaultRun1);
68 $record['default_run2'] = dbx()->esc($defaultRun2);
69 $record['image_count'] = (string)count($record['image_items'] ?? array());
70 $record['images_add_url'] = dbx()->esc((string)($record['images_add_url'] ?? ''));
71 $record['images_upload_url'] = dbx()->esc((string)($record['images_upload_url'] ?? ''));
72 $record['images_remove_url'] = dbx()->esc((string)($record['images_remove_url'] ?? ''));
73 $record['symbol_add_url'] = dbx()->esc((string)($record['symbol_add_url'] ?? '?dbx_modul=dbxAdmin&dbx_run1=modules&dbx_run2=modul_symbol_add'));
74 $record['symbol_media_url'] = dbx()->esc((string)($record['symbol_media_url'] ?? '?dbx_modul=dbxContent_admin&dbx_run1=cms_media&images=1&media_type=image'));
75 $record['symbol_upload_url'] = dbx()->esc((string)($record['symbol_upload_url'] ?? '?dbx_modul=dbxContent_admin&dbx_run1=cms_upload'));
76 $record['symbol_mediafolders_url'] = dbx()->esc((string)($record['symbol_mediafolders_url'] ?? '?dbx_modul=dbxContent_admin&dbx_run1=cms_media_folders'));
77 $record['symbol_mediafoldercreate_url'] = dbx()->esc((string)($record['symbol_mediafoldercreate_url'] ?? '?dbx_modul=dbxContent_admin&dbx_run1=cms_media_folder_create'));
78 $record['symbol_mediafolderdelete_url'] = dbx()->esc((string)($record['symbol_mediafolderdelete_url'] ?? '?dbx_modul=dbxContent_admin&dbx_run1=cms_media_folder_delete'));
79 $record['symbol_deletemedia_url'] = dbx()->esc((string)($record['symbol_deletemedia_url'] ?? '?dbx_modul=dbxContent_admin&dbx_run1=cms_delete_media'));
80 $record['placeholder_url'] = dbx()->esc((string)($record['placeholder_url'] ?? ''));
81 $record['placeholder_alt'] = dbx()->esc((string)($record['placeholder_alt'] ?? $this->moduleImagesPlaceholderAlt()));
82 $run1List = $this->buildModuleImagesRun1Datalist($record, $defaultRun1);
83 $record['run1_list_id'] = dbx()->esc((string)($run1List['id'] ?? ''));
84 $record['run1_options_html'] = (string)($run1List['options_html'] ?? '');
85 return $tpl->get_tpl('dbxAdmin|module-card-images', $record);
86 }
87
88 private function buildModuleImagesRun1Datalist(array $record, string $defaultRun1): array {
89 $modul = (string)($record['xmodul'] ?? 'mod');
90 $listId = 'dbx_modimg_run1_' . preg_replace('/[^a-zA-Z0-9_]/', '_', $modul);
91 $cases = $record['run_cases'] ?? array();
92 if (!is_array($cases)) {
93 $cases = array();
94 }
95 if (!$cases && $defaultRun1 !== '') {
96 $cases = array($defaultRun1);
97 }
98
99 $options = '';
100 $seen = array();
101 foreach ($cases as $run1) {
102 $run1 = trim((string)$run1);
103 if ($run1 === '' || isset($seen[$run1])) {
104 continue;
105 }
106 $seen[$run1] = 1;
107 $options .= '<option value="' . dbx()->esc($run1) . '"></option>';
108 }
109
110 return array(
111 'id' => $listId,
112 'options_html' => $options,
113 );
114 }
115
116 private function buildModuleSymbolPreviewHtml(array $record): string {
117 $modul = dbx()->esc((string)($record['xmodul'] ?? ''));
118 $url = dbx()->esc((string)($record['graphic_url'] ?? ''));
119 $alt = dbx()->esc((string)($record['graphic_alt'] ?? $modul));
120
121 if ($url !== '') {
122 return '<img src="' . $url . '" alt="' . $alt . '" class="dbx-module-symbol-img" loading="lazy">';
123 }
124
125 $placeholder = dbx()->esc($this->moduleImagesPlaceholderUrl($record));
126 if ($placeholder !== '') {
127 return '<img src="' . $placeholder . '" alt="' . dbx()->esc($this->moduleImagesPlaceholderAlt()) . '" class="dbx-module-symbol-img is-placeholder" loading="lazy">';
128 }
129
130 return '<span class="dbx-module-images-placeholder-icon" aria-hidden="true"><i class="bi bi-box-seam"></i></span>';
131 }
132
133 private function moduleImagesPlaceholderUrl(array $record): string {
134 return $this->registry->moduleImageEmptyPlaceholderUrl();
135 }
136
137 private function moduleImagesPlaceholderAlt(): string {
138 return $this->registry->moduleImageEmptyPlaceholderAlt();
139 }
140
141 private function buildModuleImagesPreviewHtml(array $record): string {
142 $modul = dbx()->esc((string)($record['xmodul'] ?? ''));
143 $items = $record['image_items'] ?? array();
144 if (is_array($items) && isset($items[0]) && is_array($items[0])) {
145 $first = $items[0];
146 $url = dbx()->esc((string)($first['url'] ?? ''));
147 $label = dbx()->esc((string)($first['label'] ?? ($first['file'] ?? $modul)));
148 if ($url !== '') {
149 return '<img src="' . $url . '" alt="' . $label . '" class="dbx-module-images-preview-img" loading="lazy">';
150 }
151 }
152
153 $placeholder = dbx()->esc($this->moduleImagesPlaceholderUrl($record));
154 if ($placeholder !== '') {
155 $alt = dbx()->esc($this->moduleImagesPlaceholderAlt());
156 return '<img src="' . $placeholder . '" alt="' . $alt . '" class="dbx-module-images-preview-img is-placeholder" loading="lazy">';
157 }
158
159 return '<span class="dbx-module-images-placeholder-icon" aria-hidden="true"><i class="bi bi-box-seam"></i></span>';
160 }
161
162 private function buildModuleImagesTargetHtml(array $record): string {
163 $modul = dbx()->esc((string)($record['xmodul'] ?? ''));
164 $defaultRun1 = trim((string)($record['default_run1'] ?? 'run'));
165 if ($defaultRun1 === '') {
166 $defaultRun1 = 'run';
167 }
168 $defaultRun2 = trim((string)($record['default_run2'] ?? ''));
169 $usesRun2 = (string)($record['uses_run2'] ?? '0') === '1';
170 $cases = $record['run_cases'] ?? array();
171 if (!is_array($cases)) {
172 $cases = array();
173 }
174 if (!$cases) {
175 $cases = array($defaultRun1);
176 }
177
178 $listId = 'dbx_modimg_run1_' . preg_replace('/[^a-zA-Z0-9_]/', '_', (string)($record['xmodul'] ?? 'mod'));
179 $options = '';
180 $seen = array();
181 foreach ($cases as $run1) {
182 $run1 = trim((string)$run1);
183 if ($run1 === '' || isset($seen[$run1])) {
184 continue;
185 }
186 $seen[$run1] = 1;
187 $selected = ($run1 === $defaultRun1) ? ' selected' : '';
188 $options .= '<option value="' . dbx()->esc($run1) . '"' . $selected . '>' . dbx()->esc($run1) . '</option>';
189 }
190
191 $run2Class = 'dbx-module-images-run2-wrap';
192 $run2Disabled = '';
193
194 $images = new dbxModuleImages();
195 $previewName = dbx()->esc($images->stemForRuns((string)($record['xmodul'] ?? ''), $defaultRun1, $defaultRun2) . '.*');
196
197 return '<div class="dbx-module-images-target">'
198 . '<label class="dbx-module-images-target-field">'
199 . '<span>dbx_run1</span>'
200 . '<input type="text" class="form-control form-control-sm dbx-module-images-run1" list="' . $listId . '" value="' . dbx()->esc($defaultRun1) . '" placeholder="z.B. form" required>'
201 . '<datalist id="' . $listId . '">' . $options . '</datalist>'
202 . '</label>'
203 . '<label class="' . $run2Class . ' dbx-module-images-target-field">'
204 . '<span>dbx_run2</span>'
205 . '<input type="text" class="form-control form-control-sm dbx-module-images-run2" value="' . dbx()->esc($defaultRun2) . '" placeholder="optional"' . $run2Disabled . '>'
206 . '</label>'
207 . '<div class="dbx-module-images-filename">'
208 . '<span>Dateiname</span>'
209 . '<code class="dbx-module-images-filename-preview" data-modul="' . $modul . '">' . $previewName . '</code>'
210 . '</div>'
211 . '</div>';
212 }
213
214 private function resolveImagePreviewRuns(array $item, array $record): array {
215 $run1 = trim((string)($item['run1'] ?? ''));
216 $run2 = trim((string)($item['run2'] ?? ''));
217
218 if ($run1 === '' || $run2 === '') {
219 $params = trim((string)($item['default_params'] ?? ''));
220 if ($params !== '') {
221 if ($run1 === '' && preg_match('/(?:^|&)dbx_run1=([^&]+)/', $params, $m)) {
222 $run1 = rawurldecode($m[1]);
223 }
224 if ($run2 === '' && preg_match('/(?:^|&)dbx_run2=([^&]+)/', $params, $m)) {
225 $run2 = rawurldecode($m[1]);
226 }
227 }
228 }
229
230 if ($run1 === '') {
231 $run1 = trim((string)($record['default_run1'] ?? ''));
232 }
233 if ($run2 === '') {
234 $run2 = trim((string)($record['default_run2'] ?? ''));
235 }
236
237 return array($run1, $run2);
238 }
239
240 private function buildModuleImagesGalleryHtml(array $record): string {
241 $items = $record['image_items'] ?? array();
242 $xmodul = (string)($record['xmodul'] ?? '');
243 if (!is_array($items) || !$items) {
244 return '<div class="dbx-module-images-empty-list text-muted small">Keine Modulbilder</div>';
245 }
246
247 $html = '';
248 foreach ($items as $i => $item) {
249 if (!is_array($item)) {
250 continue;
251 }
252 $file = dbx()->esc((string)($item['file'] ?? ''));
253 $url = dbx()->esc((string)($item['url'] ?? ''));
254 $label = dbx()->esc((string)($item['label'] ?? $file));
255 $params = trim((string)($item['default_params'] ?? ''));
256 $call = 'dbx_modul=' . rawurlencode($xmodul);
257 if ($params !== '') {
258 $call .= '&' . $params;
259 }
260 $call = dbx()->esc($call);
261 list($run1, $run2) = $this->resolveImagePreviewRuns($item, $record);
262 $run1Esc = dbx()->esc($run1);
263 $run2Esc = dbx()->esc($run2);
264 $previewUrl = dbx()->esc($this->registry->modulUrl($xmodul, $run1, $run2));
265 $previewTitle = dbx()->esc('Vorschau: ' . $xmodul);
266 $active = ($i === 0) ? ' is-active' : '';
267 $previewBtn = '';
268 if ($run1 !== '' || $params !== '') {
269 $previewBtn = '<a class="btn btn-outline-secondary btn-sm dbx-win dbx-module-images-preview" href="' . $previewUrl . '" data-url="' . $previewUrl . '" data-title="' . $previewTitle . '" data-width="88%" data-height="88%" title="Modul aufrufen"><i class="bi bi-box-arrow-up-right"></i></a>';
270 }
271 $html .= '<div class="dbx-module-images-item' . $active . '" data-file="' . $file . '" data-params="' . dbx()->esc($params) . '" data-url="' . $url . '" data-run1="' . $run1Esc . '" data-run2="' . $run2Esc . '">'
272 . '<span class="dbx-module-images-thumb">'
273 . '<img src="' . $url . '" alt="' . $label . '" loading="lazy">'
274 . '</span>'
275 . '<span class="dbx-module-images-meta">'
276 . '<code class="dbx-module-images-call">' . $call . '</code>'
277 . '<span class="dbx-module-images-file">' . $file . '</span>'
278 . '</span>'
279 . '<span class="dbx-module-images-actions">'
280 . $previewBtn
281 . '<button type="button" class="btn btn-outline-danger btn-sm dbx-module-images-remove" title="Bild entfernen"><i class="bi bi-trash"></i></button>'
282 . '</span>'
283 . '</div>';
284 }
285
286 return $html !== '' ? $html : '<div class="dbx-module-images-empty-list text-muted small">Keine Modulbilder</div>';
287 }
288
289 public function moduleImagesPreviewHtml(array $record): string {
290 return $this->buildModuleImagesPreviewHtml($record);
291 }
292
293 private function renderGraphic(array $record): string {
294 $previewUrl = dbx()->esc((string)($record['preview_url'] ?? ''));
295 $title = dbx()->esc((string)($record['title'] ?? ''));
296 $winAttrs = ' class="dbx-module-graphic dbx-win" href="' . $previewUrl . '" data-url="' . $previewUrl
297 . '" data-title="Vorschau: ' . $title . '" data-width="88%" data-height="88%" title="Modul-Vorschau oeffnen"';
298
299 $items = $record['image_items'] ?? array();
300 if (!is_array($items)) {
301 $items = array();
302 }
303
304 if ($items) {
305 $slides = '';
306 foreach ($items as $i => $item) {
307 if (!is_array($item)) {
308 continue;
309 }
310 $url = dbx()->esc((string)($item['url'] ?? ''));
311 $label = dbx()->esc((string)($item['label'] ?? ''));
312 $active = ($i === 0) ? ' is-active' : '';
313 $slides .= '<img src="' . $url . '" alt="' . $label . '" class="dbx-module-graphic-img' . $active . '" loading="lazy">';
314 }
315 if ($slides !== '') {
316 return '<a' . $winAttrs . '><div class="dbx-module-graphic-stack">' . $slides . '</div></a>';
317 }
318 }
319
320 $graphicUrl = trim((string)($record['graphic_url'] ?? ''));
321 $alt = dbx()->esc((string)($record['graphic_alt'] ?? $record['title'] ?? ''));
322
323 if ($graphicUrl !== '') {
324 $badge = trim((string)($record['graphic_badge'] ?? ''));
325 $badgeHtml = '';
326 if ($badge !== '') {
327 $badgeHtml = '<span class="dbx-module-graphic-badge">' . dbx()->esc($badge) . '</span>';
328 }
329
330 return '<a' . $winAttrs . '>'
331 . '<img src="' . dbx()->esc($graphicUrl) . '" alt="' . $alt . '" class="dbx-module-graphic-img is-active" loading="lazy">'
332 . $badgeHtml
333 . '</a>';
334 }
335
336 return '<a' . $winAttrs . '>'
337 . '<span class="dbx-module-graphic-placeholder" aria-hidden="true">'
338 . '<i class="bi bi-box-seam dbx-module-graphic-fallback-icon"></i>'
339 . '<span class="dbx-module-graphic-placeholder-label">Vorschau</span>'
340 . '</span>'
341 . '</a>';
342 }
343
344 private function renderInstallButton(array $record): string {
345 if (empty($record['install_url'])) {
346 return '';
347 }
348
349 $url = dbx()->esc((string)$record['install_url']);
350 $title = dbx()->esc((string)($record['title'] ?? ''));
351
352 return '<a class="btn btn-outline-secondary dbx-win" href="' . $url . '" data-url="' . $url . '" data-title="Installation: ' . $title . '" data-width="82%" data-height="82%" title="Modul installieren">'
353 . '<i class="bi bi-database-gear"></i> Install</a>';
354 }
355
356 private function renderActiveToggleButton(array $record): string {
357 $modul = dbx()->esc((string)($record['xmodul'] ?? ''));
358 $url = dbx()->esc((string)($record['active_toggle_url'] ?? ''));
359 if ($modul === '' || $url === '') {
360 return '';
361 }
362 $active = (string)($record['active'] ?? '1') === '1';
363 $btnClass = $active ? 'btn-success' : 'btn-outline-secondary';
364 $icon = $active ? 'bi-toggle-on' : 'bi-toggle-off';
365 $label = $active ? 'Aktiv' : 'Inaktiv';
366 $state = $active ? '1' : '0';
367
368 return '<button type="button" class="btn ' . $btnClass . ' dbx-module-active-toggle" data-modul="' . $modul
369 . '" data-active="' . $state . '" data-toggle-url="' . $url . '" title="Modul aktivieren/deaktivieren">'
370 . '<i class="bi ' . $icon . '"></i> ' . $label . '</button>';
371 }
372
373 private function renderDeleteButton(array $record): string {
374 if ((string)($record['can_delete'] ?? '0') !== '1') {
375 return '';
376 }
377 $modul = dbx()->esc((string)($record['xmodul'] ?? ''));
378 $title = dbx()->esc((string)($record['title'] ?? ''));
379 $url = dbx()->esc((string)($record['delete_url'] ?? ''));
380 if ($modul === '' || $url === '') {
381 return '';
382 }
383
384 return '<button type="button" class="btn btn-outline-danger dbx-module-delete-btn" data-modul="' . $modul
385 . '" data-delete-url="' . $url . '" data-title="' . $title . '" title="Modul komplett loeschen">'
386 . '<i class="bi bi-trash"></i> Loeschen</button>';
387 }
388
389 private function renderAccessInline(array $record): string {
390 $tpl = dbx()->get_system_obj('dbxTPL');
391 $groups = $record['groups'] ?? array();
392 if (!is_array($groups)) {
393 $groups = array();
394 }
395 $selected = array_flip($groups);
396 $options = '';
397 foreach ($this->registry->groupOptions() as $value => $label) {
398 $sel = isset($selected[$value]) ? ' selected' : '';
399 $options .= '<option value="' . dbx()->esc($value) . '"' . $sel . '>' . dbx()->esc($label) . '</option>';
400 }
401
402 $data = array(
403 'xmodul' => dbx()->esc((string)($record['xmodul'] ?? '')),
404 'access_save_url' => dbx()->esc((string)($record['access_save_url'] ?? '')),
405 'groups_options_html' => $options,
406 );
407
408 return $tpl->get_tpl('dbxAdmin|module-card-access-inline', $data);
409 }
410
411 private function renderGroups(array $record): string {
412 $groups = $record['groups'] ?? array();
413 if (!is_array($groups)) {
414 $groups = array();
415 }
416
417 $labels = $this->registry->groupOptions();
418 $html = '';
419 foreach ($groups as $group) {
420 $group = trim((string)$group);
421 if ($group === '') {
422 continue;
423 }
424 $label = $labels[$group] ?? $group;
425 $html .= '<span class="badge rounded-pill text-bg-light border">' . dbx()->esc($label) . '</span>';
426 }
427
428 if ($html === '') {
429 $html = '<span class="text-muted small">Keine Gruppe gesetzt</span>';
430 }
431
432 return $html;
433 }
434
435 private function renderDdList(array $record): string {
436 $tpl = dbx()->get_system_obj('dbxTPL');
437 $items = $record['dd_items'] ?? array();
438 if (!is_array($items) || !$items) {
439 return $tpl->get_tpl('dbxAdmin|module-card-dd-empty', $record);
440 }
441
442 $gallery = '';
443 $selectId = (string)($record['dd_select_id'] ?? '');
444 foreach ($items as $i => $item) {
445 if (!is_array($item)) {
446 continue;
447 }
448 $url = dbx()->esc((string)($item['edit_url'] ?? ''));
449 $title = dbx()->esc((string)($item['edit_title'] ?? ''));
450 $label = dbx()->esc((string)($item['label'] ?? ''));
451 $active = ($i === 0) ? ' is-active' : '';
452 $stripe = ($i % 2 === 0) ? ' odd' : ' even';
453 $gallery .= '<button type="button" class="dbx-module-dd-item' . $active . $stripe . '" role="option"'
454 . ' data-edit-url="' . $url . '" data-edit-title="' . $title . '"'
455 . ' aria-selected="' . ($i === 0 ? 'true' : 'false') . '" title="' . $title . '">'
456 . '<span class="dbx-module-dd-item-name">' . $label . '</span>'
457 . '</button>';
458 }
459
460 $record['dd_gallery_html'] = $gallery;
461 return $tpl->get_tpl('dbxAdmin|module-card-dd', $record);
462 }
463}
Erkennt Modul-Metadaten aus Dateisystem und PHP-Quellen (ohne manuelle Registry).
forward_run_body($content)
render_table_row_select(array $record, $class)
Rendert die Row-Checkbox.
if( $syncRequest)
Definition index.php:520
DBX schema administration.