dbxapp 4.1.3
CMS, Shop, Workflows und modulare Geschäftsanwendungen
Loading...
Searching...
No Matches
dbxModules.class.php
Go to the documentation of this file.
1<?php
2namespace dbx\dbxAdmin;
3
4require_once __DIR__ . '/dbxModuleRegistry.class.php';
5require_once __DIR__ . '/dbxModuleImages.class.php';
6require_once __DIR__ . '/dbxReport_Modules.class.php';
7
8Class dbxModules {
9
11 private $moduleTexts;
12
13 private function texts() {
14 if ($this->moduleTexts) {
15 return $this->moduleTexts;
16 }
17
18 dbx()->get_system_obj('dbxForm', 'use');
19 $texts = new \dbxForm();
20 $texts->init('module-admin-texts');
21 $texts->_fd = 'dbxAdmin|module-admin';
22 $texts->load_fd_messages();
23 $texts->set_form_help_enabled(false);
24 $this->moduleTexts = $texts;
25
26 return $this->moduleTexts;
27 }
28
29 private function registry(): dbxModuleRegistry {
30 static $registry = null;
31 if (!$registry instanceof dbxModuleRegistry) {
32 $registry = new dbxModuleRegistry();
33 }
34 return $registry;
35 }
36
37 private function localizedGroupOptions(array $options): array {
38 $texts = $this->texts();
39 $builtins = array(
40 'admin' => 'group_admin',
41 'guest' => 'group_guest',
42 'member' => 'group_member',
43 '*' => 'group_all',
44 );
45 foreach ($builtins as $key => $messageKey) {
46 if (array_key_exists($key, $options)) {
47 $options[$key] = $texts->get_fd_message($messageKey);
48 }
49 }
50 return $options;
51 }
52
59 private function clientMessagesJson(): string {
60 $texts = $this->texts();
61 $keys = array(
62 'active',
63 'inactive',
64 'saving',
65 'saved',
66 'save_failed',
67 'status_save_error',
68 'no_module_images',
69 'module_preview',
70 'open_module',
71 'remove_image',
72 'run1_required',
73 'image_import_error',
74 'symbol_import_error',
75 'confirm_unavailable',
76 'image_delete_title',
77 'image_delete_question',
78 'image_delete_hint',
79 'module_delete_title',
80 'module_delete_question',
81 'module_delete_hint',
82 'delete_button',
83 'cancel_button',
84 );
85 $messages = array();
86 foreach ($keys as $key) {
87 $messages[$key] = $texts->get_fd_message($key);
88 }
89
90 $json = json_encode($messages, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
91 return dbx()->esc(is_string($json) ? $json : '{}');
92 }
93
94 private function adminHelp(): dbxAdminHelp {
95 return dbx()->get_include_obj('dbxAdminHelp');
96 }
97
98 private function tpl() {
99 return dbx()->get_system_obj('dbxTPL');
100 }
101
102 private function save_config_modul($modul, $data) {
103 return dbx()->set_config($modul, $data);
104 }
105
106 private function modul_access() {
107 $xmodul = (string)dbx()->get_modul_var('xmodul');
108 $texts = $this->texts();
109 if ($xmodul === '') {
110 return $this->tpl()->get_tpl('dbx', 'alert-warning', array('msg' => $texts->get_fd_message('no_module')));
111 }
112
113 $data = dbx()->get_config($xmodul);
114 if (!is_array($data)) {
115 $data = array();
116 }
117
118 $oForm = dbx()->get_system_obj('dbxForm');
119 $oForm->init('form-modul-access');
120 $oForm->_fd = 'dbxAdmin|module-admin';
121 $oForm->load_fd_messages();
122 $oForm->add_rep('bar_title', $texts->format_fd_message('access_title', array('module' => dbx()->esc($xmodul))));
123 $oForm->add_obj(
124 'bar_actions',
125 'obj-value',
126 '<button class="btn btn-primary btn-sm" type="submit"><i class="bi bi-save"></i> '
127 . dbx()->esc($texts->get_fd_message('action_save')) . '</button>'
128 );
129 $oForm->_data = $data;
130 $oForm->_msg_info = $texts->get_fd_message('access_info');
131
132 $oForm->add_obj('xmodul', $xmodul);
133 $oForm->add_fld(
134 'groups',
135 'multi-select',
136 options: $this->localizedGroupOptions($this->registry()->groupOptions()),
137 rules: 'array|parameter',
138 label: $texts->get_fd_message('label_groups'),
139 errormsg: $texts->get_fd_message('invalid_groups')
140 );
141
142 $this->adminHelp()->attachForm($oForm, 'modules_access');
143
144 if ($oForm->submit()) {
145 if (!$oForm->errors()) {
146 $config = dbx()->get_config($xmodul);
147 if (!is_array($config)) {
148 $config = array();
149 }
150 if (isset($oForm->_post['groups'])) {
151 $groups = $oForm->_post['groups'];
152 $config['groups'] = is_array($groups) ? implode(',', $groups) : (string)$groups;
153 }
154 $ok = $this->save_config_modul($xmodul, $config);
155 if ($ok) {
156 $oForm->_msg_success = $texts->get_fd_message('access_saved');
157 } else {
158 $oForm->_msg_error = $texts->get_fd_message('access_save_error');
159 }
160 } else {
161 $oForm->_msg_error = $texts->get_fd_message('check_input');
162 }
163 }
164
165 $content = $oForm->run();
166 return str_replace('{xmodul}', $xmodul, $content);
167 }
168
169 private function modul_help() {
170 $xmodul = trim((string)dbx()->get_modul_var('xmodul'));
171 if ($xmodul === '') {
172 return $this->tpl()->get_tpl('dbx', 'alert-warning', array('msg' => $this->texts()->get_fd_message('no_module')));
173 }
174
175 $raw = $this->registry()->inspect($xmodul);
176 $title = (string)($raw['title'] ?? $xmodul);
177 $moduleHelpHtml = $this->registry()->renderModuleHelp($xmodul, array(
178 'title' => $title,
179 'xmodul' => $xmodul,
180 ));
181
182 return $this->tpl()->get_tpl('dbxAdmin|module-help-detail', array(
183 'title' => $title,
184 'module_help_html' => $moduleHelpHtml,
185 ));
186 }
187
188 private function buildInstallHelpHtml(array $record): string {
189 if (empty($record['install_url'])) {
190 return '';
191 }
192
193 $modul = dbx()->esc((string)($record['install_modul'] ?? ''));
194 $url = dbx()->esc((string)$record['install_url']);
195 $title = dbx()->esc((string)($record['title'] ?? ''));
196
197 return '<h4>Installation</h4>'
198 . '<p>Dieses Modul stellt einen Installationsdialog bereit (<code>' . $modul . '</code>).</p>'
199 . '<p><a class="btn btn-sm btn-outline-secondary dbx-win" href="' . $url . '" data-url="' . $url . '" data-title="Installation: ' . $title . '">'
200 . '<i class="bi bi-database-gear"></i> Installation starten</a></p>';
201 }
202
203 private function formatRunCases(array $runCases): string {
204 if (!$runCases) {
205 return 'Keine Run-Aktionen erkannt';
206 }
207 return implode(', ', array_map('strval', $runCases));
208 }
209
210 private function prepareModuleRecord(array $record): array {
211 return $record;
212 }
213
214 private function images(): dbxModuleImages {
215 static $obj = null;
216 if (!$obj instanceof dbxModuleImages) {
217 $obj = new dbxModuleImages();
218 }
219 return $obj;
220 }
221
222 private function modul_images() {
223 $xmodul = (string)dbx()->get_modul_var('xmodul');
224 if ($xmodul === '') {
225 return $this->tpl()->get_tpl('dbx', 'alert-warning', array('msg' => $this->texts()->get_fd_message('no_module')));
226 }
227
228 $images = $this->images();
229 $items = $images->imageItems($xmodul);
230 $info = $this->registry()->inspect($xmodul);
232 $galleryHtml = $report->moduleImagesGalleryHtml(array(
233 'xmodul' => $xmodul,
234 'image_items' => $items,
235 'default_run1' => (string)($info['default_run1'] ?? 'run'),
236 'default_run2' => (string)($info['default_run2'] ?? ''),
237 'placeholder_url' => (string)($info['placeholder_url'] ?? ''),
238 ));
239 $previewHtml = $report->moduleImagesPreviewHtml(array(
240 'xmodul' => $xmodul,
241 'image_items' => $items,
242 'default_run1' => (string)($info['default_run1'] ?? 'run'),
243 'default_run2' => (string)($info['default_run2'] ?? ''),
244 'placeholder_url' => (string)($info['placeholder_url'] ?? ''),
245 ));
246 $targetHtml = $report->moduleImagesTargetHtml($info);
247
248 $data = array(
249 'xmodul' => dbx()->esc($xmodul),
250 'gallery_html' => $galleryHtml,
251 'images_preview_html' => $previewHtml,
252 'images_target_html' => $targetHtml,
253 'uses_run2' => (string)($info['uses_run2'] ?? '0'),
254 'placeholder_url' => dbx()->esc((string)($info['placeholder_url'] ?? '')),
255 'placeholder_alt' => dbx()->esc($this->texts()->get_fd_message('placeholder_alt')),
256 'image_count' => count($items),
257 'module_messages_json'=> $this->clientMessagesJson(),
258 'media_api_url' => dbx()->esc($this->images()->mediaApiUrl() . '&images=1&media_type=image'),
259 'images_add_url' => dbx()->esc('?dbx_modul=dbxAdmin&dbx_run1=modules&dbx_run2=modul_images_add'),
260 'images_upload_url' => dbx()->esc('?dbx_modul=dbxAdmin&dbx_run1=modules&dbx_run2=modul_images_upload'),
261 'images_remove_url' => dbx()->esc('?dbx_modul=dbxAdmin&dbx_run1=modules&dbx_run2=modul_images_remove'),
262 'media_folders_url' => dbx()->esc($this->images()->mediaFoldersApiUrl()),
263 'media_browser_forms' => dbx()->get_include_obj('dbxContentMediaForms', 'dbxContent_admin')->renderTemplates(
264 '?dbx_modul=dbxAdmin&dbx_run1=modules&dbx_run2=modul_images_upload',
265 'modules-media-upload'
266 ),
267 );
268
269 return $this->tpl()->get_tpl('dbxAdmin|form-modul-images', $data);
270 }
271
272 private function modul_image_serve() {
273 $file = trim((string)dbx()->get_modul_var('file', '', '*'));
274 $this->images()->serveFile($file);
275 }
276
277 private function modul_images_media_json() {
278 $xmodul = trim((string)dbx()->get_modul_var('xmodul', ''));
279 dbx()->json_response(array(
280 'ok' => 1,
281 'rows' => $this->images()->mediaBrowserRows($xmodul),
282 ));
283 }
284
285 private function modul_images_media_folders_json() {
286 $folders = array();
287 $dir = $this->images()->absDir();
288 if (is_dir($dir) && is_readable($dir)) {
289 $folders[] = 'mod';
290 }
291 dbx()->json_response(array(
292 'ok' => 1,
293 'success' => true,
294 'folders' => $folders,
295 'root' => 'files/mod/',
296 ));
297 }
298
299 private function modul_images_list_json() {
300 $xmodul = (string)dbx()->get_modul_var('xmodul');
301 if ($xmodul === '') {
302 dbx()->json_response(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('no_module'), 'items' => array()));
303 }
304 dbx()->json_response(array(
305 'ok' => 1,
306 'modul' => $xmodul,
307 'items' => $this->images()->imageItems($xmodul),
308 ));
309 }
310
311 private function modul_images_save_json() {
312 $payload = $this->readJsonBody();
313 $xmodul = (string)($payload['xmodul'] ?? dbx()->get_modul_var('xmodul'));
314 $files = $payload['files'] ?? array();
315 if ($xmodul === '' || !is_array($files)) {
316 dbx()->json_response(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('invalid_data')));
317 }
318 $ok = $this->images()->saveList($xmodul, $files);
319 dbx()->json_response(array(
320 'ok' => $ok ? 1 : 0,
321 'modul' => $xmodul,
322 'items' => $this->images()->imageItems($xmodul),
323 ));
324 }
325
326 private function modul_images_add_json() {
327 $payload = $this->readJsonBody();
328 $xmodul = (string)($payload['xmodul'] ?? dbx()->get_modul_var('xmodul'));
329 if ($xmodul === '') {
330 dbx()->json_response(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('no_module')));
331 }
332
333 $run1 = trim((string)($payload['dbx_run1'] ?? $payload['run1'] ?? ''));
334 $run2 = trim((string)($payload['dbx_run2'] ?? $payload['run2'] ?? ''));
335 if ($run1 === '') {
336 dbx()->json_response(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('run1_required')));
337 }
338
339 $filename = null;
340 $mediaId = (int)($payload['media_id'] ?? 0);
341 $filePath = trim((string)($payload['file_path'] ?? ''));
342
343 if ($mediaId > 0 || $filePath !== '') {
344 $filename = $this->images()->importForModul($xmodul, $mediaId, $filePath, $run1, $run2);
345 }
346
347 if ($filename === null || $filename === '') {
348 dbx()->json_response(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('image_import_error')));
349 }
350
351 dbx()->json_response(array(
352 'ok' => 1,
353 'modul' => $xmodul,
354 'filename' => $filename,
355 'items' => $this->images()->imageItems($xmodul),
356 ));
357 }
358
359 private function modul_symbol_add_json() {
360 $payload = $this->readJsonBody();
361 $xmodul = (string)($payload['xmodul'] ?? dbx()->get_modul_var('xmodul'));
362 if ($xmodul === '') {
363 dbx()->json_response(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('no_module')));
364 }
365
366 $mediaId = (int)($payload['media_id'] ?? 0);
367 $filePath = trim((string)($payload['file_path'] ?? ''));
368 if ($mediaId <= 0 && $filePath === '') {
369 dbx()->json_response(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('symbol_select_required')));
370 }
371
372 $symbol = $this->images()->importSymbolForModul($xmodul, $mediaId, $filePath);
373 if (!is_array($symbol) || empty($symbol['url'])) {
374 dbx()->json_response(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('symbol_import_error')));
375 }
376
377 dbx()->json_response(array(
378 'ok' => 1,
379 'modul' => $xmodul,
380 'symbol' => $symbol,
381 ));
382 }
383
384 private function modul_images_upload_json() {
385 $formState = dbx()->get_include_obj('dbxContentMediaForms', 'dbxContent_admin')->verify(
386 'upload',
387 '?dbx_modul=dbxAdmin&dbx_run1=modules&dbx_run2=modul_images_upload',
388 'modules-media-upload'
389 );
390 $security = is_array($formState['security'] ?? null) ? $formState['security'] : array();
391 $reply = static function(array $data) use ($security): void {
392 $data['form_security'] = $security;
393 dbx()->json_response($data);
394 };
395 if (empty($formState['submitted'])) {
396 $reply(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('form_token_invalid')));
397 }
398
399 $xmodul = trim((string)($_POST['xmodul'] ?? dbx()->get_modul_var('xmodul')));
400 $run1 = trim((string)($_POST['dbx_run1'] ?? $_POST['run1'] ?? ''));
401 $run2 = trim((string)($_POST['dbx_run2'] ?? $_POST['run2'] ?? ''));
402 if ($xmodul === '') {
403 $reply(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('no_module')));
404 }
405 if ($run1 === '') {
406 $reply(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('run1_required')));
407 }
408
409 $file = $_FILES['file'] ?? null;
410 if (!is_array($file)) {
411 $reply(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('file_missing')));
412 }
413
414 $filename = $this->images()->saveFromUpload($xmodul, $run1, $run2, $file);
415 if ($filename === null || $filename === '') {
416 $reply(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('upload_error')));
417 }
418
419 $reply(array(
420 'ok' => 1,
421 'modul' => $xmodul,
422 'filename' => $filename,
423 'items' => $this->images()->imageItems($xmodul),
424 ));
425 }
426
427 private function modul_images_remove_json() {
428 $payload = $this->readJsonBody();
429 $xmodul = (string)($payload['xmodul'] ?? dbx()->get_modul_var('xmodul'));
430 $file = (string)($payload['file'] ?? '');
431 $deleteFile = !array_key_exists('delete_file', $payload) || !empty($payload['delete_file']);
432 if ($xmodul === '' || $file === '') {
433 dbx()->json_response(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('invalid_data')));
434 }
435
436 $ok = $this->images()->removeFromList($xmodul, $file, $deleteFile);
437 dbx()->json_response(array(
438 'ok' => $ok ? 1 : 0,
439 'modul' => $xmodul,
440 'items' => $this->images()->imageItems($xmodul),
441 ));
442 }
443
444 private function modul_access_save_json() {
445 $payload = $this->readJsonBody();
446 $xmodul = trim((string)($payload['xmodul'] ?? dbx()->get_modul_var('xmodul')));
447 if ($xmodul === '') {
448 dbx()->json_response(array('ok' => 0, 'msg' => $this->texts()->get_fd_message('no_module')));
449 }
450
451 $groups = $payload['groups'] ?? array();
452 if (!is_array($groups)) {
453 $groups = preg_split('/\s*,\s*/', trim((string)$groups), -1, PREG_SPLIT_NO_EMPTY);
454 }
455 if (!is_array($groups)) {
456 $groups = array();
457 }
458
459 $allowed = array_keys($this->registry()->groupOptions());
460 $clean = array();
461 foreach ($groups as $group) {
462 $group = trim((string)$group);
463 if ($group !== '' && in_array($group, $allowed, true)) {
464 $clean[] = $group;
465 }
466 }
467 $clean = array_values(array_unique($clean));
468
469 $config = dbx()->get_config($xmodul);
470 if (!is_array($config)) {
471 $config = array();
472 }
473 $config['groups'] = implode(',', $clean);
474
475 $ok = dbx()->set_config($xmodul, $config);
476 $texts = $this->texts();
477 dbx()->json_response(array(
478 'ok' => $ok ? 1 : 0,
479 'modul' => $xmodul,
480 'groups' => $clean,
481 'msg' => $ok ? $texts->get_fd_message('access_saved') : $texts->get_fd_message('access_save_error'),
482 ));
483 }
484
485 private function modul_active_toggle_json() {
486 $texts = $this->texts();
487 $payload = $this->readJsonBody();
488 $xmodul = trim((string)($payload['xmodul'] ?? dbx()->get_modul_var('xmodul')));
489 if ($xmodul === '' || !preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $xmodul)) {
490 dbx()->json_response(array('ok' => 0, 'msg' => $texts->get_fd_message('no_module')));
491 }
492
493 $config = dbx()->get_config($xmodul);
494 if (!is_array($config)) {
495 $config = array();
496 }
497
498 $active = null;
499 if (array_key_exists('active', $payload)) {
500 $active = !empty($payload['active']) ? '1' : '0';
501 } else {
502 $current = '1';
503 if (isset($config['activ'])) {
504 $current = (string)$config['activ'] === '1' ? '1' : '0';
505 } elseif (isset($config['active'])) {
506 $current = (string)$config['active'] === '1' ? '1' : '0';
507 }
508 $active = $current === '1' ? '0' : '1';
509 }
510
511 $config['activ'] = $active;
512 $config['active'] = $active;
513 $ok = dbx()->set_config($xmodul, $config);
514 dbx()->json_response(array(
515 'ok' => $ok ? 1 : 0,
516 'modul' => $xmodul,
517 'active' => $active,
518 'active_label' => $active === '1' ? $texts->get_fd_message('active') : $texts->get_fd_message('inactive'),
519 'msg' => $ok ? $texts->get_fd_message('status_saved') : $texts->get_fd_message('status_save_error'),
520 ));
521 }
522
523 private function modul_delete_json() {
524 $texts = $this->texts();
525 $payload = $this->readJsonBody();
526 $xmodul = trim((string)($payload['xmodul'] ?? dbx()->get_modul_var('xmodul')));
527 if ($xmodul === '' || !preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $xmodul)) {
528 dbx()->json_response(array('ok' => 0, 'msg' => $texts->get_fd_message('no_module')));
529 }
530 if (!$this->registry()->canDeleteModule($xmodul)) {
531 dbx()->json_response(array('ok' => 0, 'msg' => $texts->get_fd_message('delete_not_allowed')));
532 }
533
534 $dir = dbx()->os_path(dbx()->get_base_dir() . 'dbx/modules/' . $xmodul);
535 $ok = $this->deleteModuleDirectory($dir);
536 if ($ok) {
537 if (isset($_SESSION['dbx']['config'][$xmodul])) {
538 unset($_SESSION['dbx']['config'][$xmodul]);
539 }
540 if (isset($_SESSION['dbx']['config_file'][$xmodul])) {
541 unset($_SESSION['dbx']['config_file'][$xmodul]);
542 }
543 }
544
545 dbx()->json_response(array(
546 'ok' => $ok ? 1 : 0,
547 'modul' => $xmodul,
548 'msg' => $ok ? $texts->get_fd_message('module_deleted') : $texts->get_fd_message('module_delete_error'),
549 ));
550 }
551
552 private function deleteModuleDirectory(string $dir): bool {
553 $dir = rtrim(dbx()->os_path($dir), '/\\');
554 if ($dir === '' || !is_dir($dir)) {
555 return false;
556 }
557
558 $items = new \RecursiveIteratorIterator(
559 new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS),
560 \RecursiveIteratorIterator::CHILD_FIRST
561 );
562
563 foreach ($items as $item) {
564 $path = $item->getPathname();
565 if ($item->isDir()) {
566 if (!@rmdir($path)) {
567 return false;
568 }
569 } elseif (!@unlink($path)) {
570 return false;
571 }
572 }
573
574 return @rmdir($dir);
575 }
576
577 private function readJsonBody(): array {
578 $raw = file_get_contents('php://input');
579 if (!is_string($raw) || $raw === '') {
580 return array();
581 }
582 $data = json_decode($raw, true);
583 return is_array($data) ? $data : array();
584 }
585
586 private function modul_avatar() {
587 $xmodul = (string)dbx()->get_modul_var('xmodul');
588 $texts = $this->texts();
589
590 if ($xmodul === '') {
591 return $this->tpl()->get_tpl('dbx', 'alert-warning', array('msg' => $texts->get_fd_message('no_module')));
592 }
593
594 $path = dbx()->os_path(dbx()->get_base_dir() . "dbx/modules/$xmodul/tpl/img/");
595 $url = dbx()->get_base_url() . "dbx/modules/$xmodul/tpl/img/";
596 $modul_img = 'modul.gif';
597 $path_img_ext = $path . $modul_img;
598 $url_img_ext = $url . $modul_img;
599
600 $data = array(
601 'xmodul' => $xmodul,
602 'avatar_upload' => $url_img_ext,
603 );
604
605 $oForm = dbx()->get_system_obj('dbxForm');
606 $oForm->init('dbxModules_avatar', 'form-avatar');
607 $oForm->_fd = 'dbxAdmin|module-admin';
608 $oForm->load_fd_messages();
609 $oForm->_data = $data;
610 $oForm->_msg_info = $texts->get_fd_message('avatar_info');
611 $oForm->add_rep('avatar_upload_action', $texts->get_fd_message('avatar_upload_action'));
612 $oForm->add_js_call('uploader_img', 'upload');
613
614 if (!empty($_FILES)) {
615 $oUpload = dbx()->get_system_obj('dbxUpload');
616 $oUpload->upload($_FILES['upload_file']);
617 $oUpload->allowed = array('image/*');
618 $oUpload->file_new_name_body = 'modul';
619 $oUpload->image_convert = 'gif';
620 $oUpload->file_overwrite = true;
621 $oUpload->image_resize = true;
622 $oUpload->image_x = 200;
623 $oUpload->image_y = 200;
624 $oUpload->process($path);
625 if ($oUpload->processed) {
626 $oUpload->clean();
627 $oForm->_data['avatar_upload'] = $url . $oUpload->file_dst_name;
628 $oForm->_msg_success = $texts->get_fd_message('avatar_upload_success');
629 } else {
630 $oForm->set_msg_error($texts->get_fd_message('avatar_upload_error'));
631 }
632 }
633
634 $oForm->add_fld(
635 'avatar_upload',
636 'avatar_upload',
637 rules: 'alphanum',
638 label: $texts->get_fd_message('avatar_label'),
639 data: 'msg=' . $texts->get_fd_message('avatar_help')
640 );
641 $content = $oForm->run();
642 return str_replace('{xmodul}', $xmodul, $content);
643 }
644
645 Private function report_modules() {
646 $texts = $this->texts();
647 $allModules = $this->registry()->inspectAll();
648 $moduleOptions = array('0' => $texts->get_fd_message('all_modules'));
649 foreach ($allModules as $module) {
650 $name = (string)($module['xmodul'] ?? '');
651 if ($name !== '') {
652 $moduleOptions[$name] = $name;
653 }
654 }
655
656 $activeCount = 0;
657 foreach ($allModules as $module) {
658 if ((string)($module['active'] ?? '1') === '1') {
659 $activeCount++;
660 }
661 }
662
663 $oReport = new dbxReport_Modules();
664 $oReport->init('dbxModules', 'report-modules');
665 $oReport->_fd = 'dbxAdmin|module-admin';
666 $oReport->load_fd_messages();
667 $oReport->set_form_help_enabled(false);
668 $oReport->_action = '?dbx_modul=dbxAdmin&dbx_run1=modules&dbx_run2=modul_list';
669 $oReport->_pages = true;
670 $oReport->_rrows = 20;
671 $oReport->_but_pagination = 7;
672 $oReport->_fld_id = 'rid';
673 $oReport->_create_row_select = true;
674 $oReport->_create_sel_flds = false;
675 $oReport->_data = array(
676 'dbx_rmodul' => '0',
677 'dbx_rwhere' => '',
678 'dbx_rrows' => 20,
679 'dbx_rpos' => 0,
680 );
681
682 $oReport->add_fld('dbx_rmodul', 'select-single-label', label: $texts->get_fd_message('label_module'), rules: 'parameter', options: $moduleOptions);
683 $oReport->add_fld('dbx_rwhere', 'dbx|search', label: $texts->get_fd_message('label_search'), rules: 'sqlsearch|max=80');
684 $oReport->add_fld('dbx_rrows', 'integer-label', label: $texts->get_fd_message('label_rows'), rules: 'int');
685
686 $modulFilter = $oReport->get_fld_val('dbx_rmodul', '0', 'parameter');
687 $search = $oReport->get_fld_val('dbx_rwhere', '', 'sqlsearch|max=80');
688 $rrows = (int)$oReport->get_fld_val('dbx_rrows', 20, 'int');
689 $rpos = (int)$oReport->get_fld_val('dbx_rpos', 0, 'int');
690 if ($rrows <= 0) {
691 $rrows = 20;
692 }
693
694 $filtered = $this->filterModuleRows($allModules, $modulFilter, $search);
695 $filteredCount = count($filtered);
696 if ($rpos < 0 || ($filteredCount > 0 && $rpos >= $filteredCount)) {
697 $rpos = 0;
698 }
699
700 $oReport->_rrows = $rrows;
701 $oReport->_rpos = $rpos;
702 $oReport->_rcount = $filteredCount;
703 $oReport->_rdata = $this->pageModuleRows($filtered, $rpos, $rrows);
704
705 $oReport->add_rep('module_count', count($allModules));
706 $oReport->add_rep('module_active_count', $activeCount);
707 $oReport->add_rep('module_filtered_count', $filteredCount);
708 $oReport->add_rep('bar_title', $texts->get_fd_message('bar_title'));
709 $oReport->add_rep('bar_subtitle', $texts->get_fd_message('bar_subtitle'));
710 $oReport->add_rep('action_filter', $texts->get_fd_message('action_filter'));
711 $oReport->add_rep('modules_label', $texts->get_fd_message('modules_label'));
712 $oReport->add_rep('active_count_label', $texts->get_fd_message('active_count_label'));
713 $oReport->add_rep('module_messages_json', $this->clientMessagesJson());
714 $oReport->add_rep('modimg_media_url', dbx()->esc($this->images()->mediaApiUrl() . '&images=1&media_type=image'));
715 $oReport->add_rep('modimg_upload_url', dbx()->esc('?dbx_modul=dbxAdmin&dbx_run1=modules&dbx_run2=modul_images_upload'));
716 $oReport->add_rep('modimg_mediafolders_url', dbx()->esc($this->images()->mediaFoldersApiUrl()));
717 $oReport->add_rep('modimg_mediafoldercreate_url', '');
718 $oReport->add_rep('modimg_mediafolderdelete_url', '');
719 $oReport->add_rep('modimg_deletemedia_url', '');
720 $oReport->add_rep('modimg_uploadmax', (string)(16 * 1024 * 1024));
721 $oReport->add_rep('media_browser_forms',
722 dbx()->get_include_obj('dbxContentMediaForms', 'dbxContent_admin')->renderTemplates(
723 '?dbx_modul=dbxAdmin&dbx_run1=modules&dbx_run2=modul_images_upload',
724 'modules-media-upload'
725 )
726 );
727
728 return $oReport->run();
729 }
730
731 private function filterModuleRows(array $modules, string $modulFilter, string $search): array {
732 $modulFilter = trim($modulFilter);
733 $search = strtolower(trim($search));
734 $rows = array();
735
736 foreach ($modules as $module) {
737 if (!is_array($module)) {
738 continue;
739 }
740
741 $name = (string)($module['xmodul'] ?? '');
742 if ($name === '') {
743 continue;
744 }
745
746 if ($modulFilter !== '' && $modulFilter !== '0' && $name !== $modulFilter) {
747 continue;
748 }
749
750 if ($search !== '') {
751 $ddList = $module['dd_list'] ?? array();
752 if (!is_array($ddList)) {
753 $ddList = array();
754 }
755
756 $haystack = strtolower(implode(' ', array(
757 $name,
758 (string)($module['description'] ?? ''),
759 (string)($module['default_call'] ?? ''),
760 (string)($module['groups_text'] ?? ''),
761 (string)($module['version'] ?? ''),
762 implode(' ', $ddList),
763 )));
764
765 if (strpos($haystack, $search) === false) {
766 continue;
767 }
768 }
769
770 $module['rid'] = $name;
771 $rows[] = $module;
772 }
773
774 return $rows;
775 }
776
777 private function pageModuleRows(array $modules, int $rpos, int $rrows): array {
778 if ($rpos < 0) {
779 $rpos = 0;
780 }
781 if ($rrows <= 0) {
782 $rrows = 20;
783 }
784
785 $slice = array_slice($modules, $rpos, $rrows);
786 $rows = array();
787 foreach ($slice as $module) {
788 $rows[] = $this->prepareModuleRecord($module);
789 }
790
791 return $rows;
792 }
793
794 public function modul_new() {
795 $obj = dbx()->get_include_obj('dbxWizard');
796 $run = dbx()->get_modul_var('run');
797 return $obj->run($run);
798 }
799
800 public function modul_edit() {
801 $obj = dbx()->get_include_obj('dbxWizard');
802 $run = dbx()->get_modul_var('run');
803 return $obj->run($run);
804 }
805
806 public function run() {
807 $modul = dbx()->get_modul_var('dbx_modul');
808 $action = dbx()->get_modul_var('dbx_run1');
809 $work = dbx()->get_modul_var('dbx_run2');
810 $content = "dbxAdmin->dbxModules ($work) X<br>";
811
812 switch ($work) {
813 case 'modul_list':
814 $content = $this->report_modules();
815 break;
816
817 case 'modul_avatar':
818 $content = $this->modul_avatar();
819 break;
820
821 case 'avatar_upload':
822 $content = $this->modul_avatar();
823 break;
824
825 case 'modul_new':
826 $content = $this->modul_new();
827 break;
828
829 case 'modul_edit':
830 $content = $this->modul_edit();
831 break;
832
833 case 'modul_access':
834 $content = $this->modul_access();
835 break;
836
837 case 'modul_access_save':
838 $this->modul_access_save_json();
839 break;
840
841 case 'modul_active_toggle':
842 $this->modul_active_toggle_json();
843 break;
844
845 case 'modul_delete':
846 $this->modul_delete_json();
847 break;
848
849 case 'modul_help':
850 $content = $this->modul_help();
851 break;
852
853 case 'modul_images':
854 $content = $this->modul_images();
855 break;
856
857 case 'modul_image':
858 $this->modul_image_serve();
859 break;
860
861 case 'modul_images_list':
862 $this->modul_images_list_json();
863 break;
864
865 case 'modul_images_save':
866 $this->modul_images_save_json();
867 break;
868
869 case 'modul_images_add':
870 $this->modul_images_add_json();
871 break;
872
873 case 'modul_symbol_add':
874 $this->modul_symbol_add_json();
875 break;
876
877 case 'modul_images_upload':
878 $this->modul_images_upload_json();
879 break;
880
881 case 'modul_images_remove':
882 $this->modul_images_remove_json();
883 break;
884
885 case 'modul_images_media':
886 $this->modul_images_media_json();
887 break;
888
889 case 'modul_images_media_folders':
890 $this->modul_images_media_folders_json();
891 break;
892
893 default:
894 $msg['msg'] = "Modul=($modul) Action=($action) Work=($work) is undef!";
895 $content = $this->tpl()->get_tpl('dbx', 'alert-warning', $msg);
896 }
897
898 return $content;
899 }
900}
901
902?>
Modul-Bilder unter files/mod — Dateiname: {modul}__{run1}[__{run2}].ext.
Erkennt Modul-Metadaten aus Dateisystem und PHP-Quellen (ohne manuelle Registry).
$messages
Definition config.fd.php:2
if((string)($formActionPolicy['action'] ?? '') !=='dbxAction.save'||!dbx() ->check_action_token((string)($formActionPolicy['scope'] ?? ''),(string)($formActionRoute['params']['dbx_token'] ?? ''))) $report
os_path(string $path)
Normalisiert einen Pfad fuer das aktuelle Betriebssystem.
Definition dbxApi.php:1538
get_base_dir(int $cutData=0)
Liefert das Basisverzeichnis der Installation.
Definition dbxApi.php:1507
esc($value)
Escaped einen Wert fuer HTML-Text und HTML-Attribute.
Definition dbxApi.php:2310
if($resolved !==$expectedBase . 'files/test/') $config
foreach(array('bootstrapRowColumns', 'setBootstrapColumnLayout', 'addBootstrapColumn', 'dissolveBootstrapColumns',) as $function) $keys
if(!defined( 'IMG_WEBP')) define( 'IMG_WEBP'
if( $demoId<=0) foreach(array('create_date', 'create_uid', 'update_date', 'update_uid', 'owner',) as $systemField) $items
Private report_modules()
DBX schema administration.