13 private $_admin_modul =
'dbxAdmin';
14 private $_fd_field =
'dbxAdmin|ddedit-field';
15 private $_texts =
null;
25 private function texts()
27 if ($this->_texts instanceof \dbxForm) {
31 dbx()->get_system_obj(
'dbxForm',
'use');
32 $this->_texts = new \dbxForm();
33 $this->_texts->set_form_help_enabled(
false);
34 $this->_texts->_fd = $this->_fd_field;
35 $this->_texts->load_fd_messages();
42 $work =
dbx()->get_modul_var(
'dbx_run2',
'');
45 case 'create_form_fd':
46 return $this->create_form_fd();
49 return $this->delete_field();
51 case 'save_field_order':
52 return $this->save_field_order();
54 case 'create_from_dd':
55 return $this->create_from_dd();
60 return $this->run_editor();
64 private function run_editor()
67 list($modul,
$fd) = $this->fd_params_from_request();
70 return $this->alert(
'warning',
$texts->get_fd_message(
'fd_module_missing'));
74 return $this->create_from_dd();
77 $model = $this->load_model($modul,
$fd);
83 array(
'fd' =>
dbx()->
esc($modul .
'|' .
$fd))
88 $instance_id = $this->instance_id($modul .
'_' .
$fd);
89 $work_target_id =
'dbx_fdedit_work_' . $instance_id;
90 $fields = array_values((array)($model[
'fields'] ?? array()));
92 ? $this->create_form_fd($modul,
$fd,
'0', $model)
93 : $this->create_form_fd($modul,
$fd,
'new', $model);
100 'work_target_id' => $work_target_id,
101 'create_from_dd_url' => $this->build_url(
'create_from_dd', $modul,
$fd),
102 'work_content' => $work_content,
103 'fields_order_report'=> $this->create_fields_order_report($modul,
$fd, $model, $work_target_id),
106 $help =
dbx()->get_include_obj(
'dbxAdminHelp',
'dbxAdmin');
107 $oTPL =
dbx()->get_system_obj(
'dbxTPL');
108 $reloadAction = $oTPL->get_tpl(
'dbx|button-bar-reload-ajax', array(
109 'bar_reload_href' =>
'?dbx_modul=dbxAdmin&dbx_run1=edit_fd&modul=' . rawurlencode($modul) .
'&fd=' . rawurlencode(
$fd),
110 'bar_reload_target' =>
'dbx_fdedit_' . $instance_id,
111 'bar_reload_replace' =>
'target',
113 $barData =
$help->moduleBarTemplateData(
'edit_fd', $reloadAction);
114 $barData[
'bar_title'] =
$texts->format_fd_message(
116 array(
'fd' =>
dbx()->
esc($modul .
'|' .
$fd))
118 $barData[
'bar_class'] =
'dbx-module-bar dbx-ddedit-head';
119 $data = array_merge($data, $barData);
121 return $oTPL->get_tpl($this->_admin_modul .
'|fdedit-frame', $data);
124 private function create_form_fd($modul =
'',
$fd =
'', $field_pos =
null, $model = array())
127 if (!$modul || !
$fd) {
128 list($modul,
$fd) = $this->fd_params_from_request();
131 if ($field_pos ===
null) {
132 $field_pos =
dbx()->get_modul_var(
'field_pos',
'new');
136 $model = $this->load_model($modul,
$fd);
142 $texts->format_fd_message(
144 array(
'fd' =>
dbx()->
esc($modul .
'|' .
$fd))
149 $fields = array_values((array)($model[
'fields'] ?? array()));
150 $is_new = ((string)$field_pos ===
'new');
153 $data = $this->default_field_record();
155 $pos = (int)$field_pos;
159 $texts->format_fd_message(
160 'fd_position_not_found',
161 array(
'position' =>
dbx()->
esc((
string)$field_pos))
168 $data[
'modul'] = $modul;
170 $data[
'field_pos'] = (string)$field_pos;
171 $data[
'old_name'] = (string)($data[
'name'] ??
'');
173 $oForm =
dbx()->get_system_obj(
'dbxForm');
174 $oForm->init(
'fdedit_field_' . $this->safe_id($modul .
'_' .
$fd .
'_' . (
string)$field_pos),
'ddedit-field-form');
175 $oForm->_fd = $this->_fd_field;
176 $oForm->load_fd_messages();
177 $oForm->_data = $data;
178 $oForm->_action = $this->build_url(
'create_form_fd', $modul,
$fd, array(
'field_pos' => (
string)$field_pos));
179 $oForm->_msg_info = $is_new
180 ? $oForm->format_fd_message(
184 : $oForm->format_fd_message(
188 (
string)($data[
'name'] ?? $field_pos)
194 if ($oForm->submit()) {
195 if (!$oForm->errors()) {
196 $field = $this->merge_record($data, $oForm->_post, $this->field_keys());
200 if (!$this->validate_field_record(
$field,
$fields, $is_new ? -1 : (
int)$field_pos, $message, $oForm)) {
201 $oForm->_msg_error = $message;
202 return $oForm->run();
207 $field_pos = count(
$fields) - 1;
213 $model[
'fields'] = array_values(
$fields);
214 $ok = $this->save_model($modul,
$fd, $model);
219 $field[
'field_pos'] = (string)$field_pos;
223 $oForm->_action = $this->build_url(
'create_form_fd', $modul,
$fd, array(
'field_pos' => (
string)$field_pos));
224 $oForm->_msg_success = $oForm->format_fd_message(
228 (
string)(
$field[
'name'] ?? $field_pos)
234 $oForm->_msg_error = $oForm->format_fd_message(
235 'fd_field_save_error',
238 (
string)(
$field[
'name'] ?? $field_pos)
245 $oForm->_msg_error = $oForm->format_fd_message(
249 (
string)($data[
'name'] ?? $field_pos)
256 $delete_url = $this->build_url(
'delete_field', $modul,
$fd, array(
'field_pos' => (
string)$field_pos));
259 '&dbx_run2=delete_field&modul={modul}&dd={dd}&field_pos={field_pos}',
265 private function create_fields_order_report($modul,
$fd, $model, $target_id =
'')
268 foreach (array_values((array)($model[
'fields'] ?? array())) as $pos =>
$field) {
273 $row = $this->field_row_defaults();
278 $row[
'modul'] = $modul;
281 $row[
'field_pos'] = (string)$pos;
282 $row[
'sort_no'] = (string)($pos + 1);
283 $row[
'target_id'] = $target_id;
284 $row[
'form_url'] = $this->build_url(
'create_form_fd', $modul,
$fd, array(
'field_pos' => (
string)$pos));
292 'count' => count(
$rows),
293 'target_id' => $target_id,
294 'new_field_url' => $this->build_url(
'create_form_fd', $modul,
$fd, array(
'field_pos' =>
'new')),
297 $oReport =
dbx()->get_system_obj(
'dbxReport');
298 $oReport->init(
'fdedit_fields_order_' . $this->safe_id($modul .
'_' .
$fd),
'fdedit-fields-order-report');
299 $oReport->_mode =
'tpl';
300 $oReport->_data = $data;
301 $oReport->_replaces = $data;
302 $oReport->_rdata =
$rows;
303 $oReport->_rcount = count(
$rows);
304 $oReport->_rrows =
'auto';
305 $oReport->_pages =
false;
307 return $oReport->run();
310 private function delete_field()
313 list($modul,
$fd) = $this->fd_params_from_request();
314 $field_pos = (int)
dbx()->get_modul_var(
'field_pos', -1);
316 $model = $this->load_model($modul,
$fd);
320 $texts->format_fd_message(
322 array(
'fd' =>
dbx()->
esc($modul .
'|' .
$fd))
327 $fields = array_values((array)($model[
'fields'] ?? array()));
328 if (!isset(
$fields[$field_pos])) {
329 return $this->alert(
'warning',
$texts->get_fd_message(
'fd_field_not_found'));
332 $name = (string)(
$fields[$field_pos][
'name'] ?? $field_pos);
334 $model[
'fields'] = array_values(
$fields);
336 if ($this->save_model($modul,
$fd, $model)) {
339 $texts->format_fd_message(
341 array(
'field' =>
dbx()->
esc($name))
348 $texts->format_fd_message(
349 'fd_field_delete_error',
350 array(
'field' =>
dbx()->
esc($name))
355 private function save_field_order()
358 list($modul,
$fd) = $this->fd_params_from_request();
359 $order = $this->parse_order(
dbx()->get_modul_var(
'order', array()));
361 $model = $this->load_model($modul,
$fd);
363 dbx()->json_response(array(
365 'msg' =>
$texts->format_fd_message(
367 array(
'fd' => $modul .
'|' .
$fd)
372 $new = $this->reorder_records(array_values((array)($model[
'fields'] ?? array())),
$order);
373 if ($new ===
false) {
374 dbx()->json_response(array(
376 'msg' =>
$texts->get_fd_message(
'fd_invalid_order'),
380 $model[
'fields'] = $new;
381 $ok = $this->save_model($modul,
$fd, $model);
383 dbx()->json_response(array(
385 'msg' =>
$texts->get_fd_message(
386 $ok ?
'fd_order_saved' :
'fd_order_save_error'
388 'count' => count($new),
401 private function create_from_dd()
404 list($modul,
$fd) = $this->fd_params_from_request();
406 $source_modul = $this->sanitize_name(
dbx()->get_modul_var(
'source_modul', $modul ?:
'dbx'));
407 $source_dd = $this->sanitize_name(
dbx()->get_modul_var(
'source_dd',
''));
408 $target_modul = $this->sanitize_name(
dbx()->get_modul_var(
'target_modul', $modul ?:
'dbx'));
409 $target_fd = $this->sanitize_name(
dbx()->get_modul_var(
'target_fd',
$fd));
410 $overwrite = (string)
dbx()->get_modul_var(
'overwrite',
'') ===
'1';
412 $oForm =
dbx()->get_system_obj(
'dbxForm');
414 'fd-create-from-dd-' . $this->safe_id($target_modul .
'-' . $target_fd),
415 'fdedit-create-from-dd'
417 $oForm->_fd = $this->_fd_field;
418 $oForm->load_fd_messages();
419 $oForm->_action =
'?dbx_modul=' . $this->_admin_modul .
420 '&dbx_run1=edit_fd&dbx_run2=create_from_dd&modul=' . rawurlencode($target_modul) .
421 '&fd=' . rawurlencode($target_fd);
424 $oForm->_data = array_merge($oForm->_data, array(
425 'source_modul' => $source_modul,
426 'source_dd' => $source_dd,
427 'target_modul' => $target_modul,
428 'target_fd' => $target_fd,
429 'overwrite' => $overwrite ? 1 : 0,
431 $oForm->_msg_info = $oForm->get_fd_message(
'create_info');
436 label: $oForm->get_fd_message(
'label_source_module'),
437 rules:
'parameter|min=1|max=64',
438 errormsg: $oForm->get_fd_message(
'error_source_module'),
444 label: $oForm->get_fd_message(
'label_source_dd'),
445 rules:
'parameter|min=1|max=64',
446 errormsg: $oForm->get_fd_message(
'error_source_dd'),
452 label: $oForm->get_fd_message(
'label_target_module'),
453 rules:
'parameter|min=1|max=64',
454 errormsg: $oForm->get_fd_message(
'error_target_module'),
460 label: $oForm->get_fd_message(
'label_target_fd'),
461 rules:
'parameter|min=1|max=64',
462 errormsg: $oForm->get_fd_message(
'error_target_fd'),
468 label: $oForm->get_fd_message(
'label_overwrite'),
473 if ($oForm->submit()) {
474 if ($oForm->errors()) {
475 $oForm->_msg_error = $oForm->get_fd_message(
'required_fields');
477 $source_modul = $this->sanitize_name($oForm->get_post(
'source_modul',
'',
'parameter|min=1|max=64'));
478 $source_dd = $this->sanitize_name($oForm->get_post(
'source_dd',
'',
'parameter|min=1|max=64'));
479 $target_modul = $this->sanitize_name($oForm->get_post(
'target_modul',
'',
'parameter|min=1|max=64'));
480 $target_fd = $this->sanitize_name($oForm->get_post(
'target_fd',
'',
'parameter|min=1|max=64'));
481 $overwrite = (int)$oForm->get_post(
'overwrite', 0,
'int') === 1;
483 if ($this->fd_file_exists($target_modul, $target_fd) && !$overwrite) {
484 $oForm->add_fld_error(
486 $oForm->get_fd_message(
'target_exists_field')
488 $oForm->_msg_error = $oForm->get_fd_message(
'target_exists');
490 $oDD =
dbx()->get_system_obj(
'dbxDD');
491 $dd_model =
$oDD->get_dd_model($source_modul .
'|' . $source_dd);
492 $fields = is_array($dd_model[
'fields'] ??
null) ? array_values($dd_model[
'fields']) : array();
495 $oForm->add_fld_error(
497 $oForm->get_fd_message(
'source_no_fields_field')
499 $oForm->_msg_error = $oForm->get_fd_message(
'source_invalid');
500 } elseif ($this->save_model($target_modul, $target_fd, array(
'fields' =>
$fields))) {
501 $url =
'?dbx_modul=' . $this->_admin_modul .
502 '&dbx_run1=edit_fd&modul=' . rawurlencode($target_modul) .
503 '&fd=' . rawurlencode($target_fd);
504 $oForm->_msg_success =
505 $oForm->format_fd_message(
508 'fd' =>
dbx()->
esc($target_modul .
'|' . $target_fd),
509 'dd' =>
dbx()->
esc($source_modul .
'|' . $source_dd),
512 '<a class="btn btn-sm btn-primary ms-2" href="' .
dbx()->esc(
$url) .
513 '">' . $oForm->get_fd_message(
'edit_fd_action') .
'</a>';
515 $oForm->_msg_error = $oForm->get_fd_message(
'fd_write_error');
516 $oForm->add_fld_error(
518 $oForm->get_fd_message(
'fd_write_field_error')
525 return $oForm->run();
528 private function load_model($modul,
$fd)
530 if (!$modul || !
$fd) {
534 $file = $this->fd_file_path($modul,
$fd);
546 'messages' => $this->normalize_fd_messages(
553 private function save_model($modul,
$fd, $model)
555 if (!$modul || !
$fd || !is_array($model)) {
559 $fields = is_array($model[
'fields'] ??
null) ? array_values($model[
'fields']) : array();
560 $messages = $this->normalize_fd_messages(
561 is_array($model[
'messages'] ??
null) ? $model[
'messages'] : array(),
564 $dir =
dbx()->get_base_dir() .
'dbx/modules/' . $modul .
'/fd/';
567 if (!is_dir(
$dir) && !mkdir(
$dir, 0775,
true)) {
571 $file = $this->fd_file_path($modul,
$fd);
572 $this->backup_fd_file($modul,
$fd);
575 $content .=
"\$messages = array();\n";
576 $content .=
"\$messages['save_success'] = "
577 . var_export(
$messages[
'save_success'],
true) .
";\n";
578 $content .=
"\$messages['save_succeass'] = \$messages['save_success'];\n";
579 $content .=
"\$messages['save_error'] = "
580 . var_export(
$messages[
'save_error'],
true) .
";\n\n";
581 foreach (
$messages as $messageKey => $messageValue) {
585 array(
'save_success',
'save_succeass',
'save_error'),
588 !is_scalar($messageValue)
592 $content .=
"\$messages[" . var_export((
string)$messageKey,
true) .
'] = '
593 . var_export((
string)$messageValue,
true) .
";\n";
605 $content .=
"\$field[" . var_export((
string)$key,
true) .
"]=" . var_export(
$value,
true) .
";\n";
607 $content .=
"\$fields[]=\$field;\n\n";
620 private function normalize_fd_messages(array
$messages,
string $fd): array
623 if (preg_match(
'/_en$/',
$fd)) {
625 } elseif (preg_match(
'/_es$/',
$fd)) {
631 'save_success' =>
'Daten wurden gespeichert',
632 'save_error' =>
'Daten konnten nicht gespeichert werden',
635 'save_success' =>
'Data was saved',
636 'save_error' =>
'Data could not be saved',
639 'save_success' =>
'Los datos se guardaron',
640 'save_error' =>
'Los datos no se pudieron guardar',
651 foreach ($defaults[$language] as $key =>
$value) {
663 private function normalize_field_for_write(
$field)
666 $oDD =
dbx()->get_system_obj(
'dbxDD');
667 if (is_object(
$oDD) && method_exists(
$oDD,
'normalize_dd_field')) {
672 foreach ($this->field_keys() as $key) {
673 if (array_key_exists($key,
$field)) {
680 private function backup_fd_file($modul,
$fd)
682 $file = $this->fd_file_path($modul,
$fd);
683 if (!is_file(
$file)) {
687 $dir = dirname(
$file) . DIRECTORY_SEPARATOR .
'_backup';
689 mkdir(
$dir, 0775,
true);
693 copy(
$file,
$dir . DIRECTORY_SEPARATOR .
$fd .
'.' . date(
'Ymd-His') .
'.fd.php');
697 private function fd_params_from_request()
699 $modul = $this->sanitize_name(
dbx()->get_modul_var(
'modul',
''));
700 $fd = $this->sanitize_name(
dbx()->get_modul_var(
'fd',
''));
703 $fd = $this->sanitize_name(
dbx()->get_modul_var(
'dd',
''));
707 $modul = $this->sanitize_name(
dbx()->get_modul_var(
'xmodul',
''));
711 $modul = $this->sanitize_name($this->get_system_var(
'dbx_activ_modul',
'dbx'));
714 return array($modul,
$fd);
717 private function fd_file_exists($modul,
$fd)
719 return is_file($this->fd_file_path($modul,
$fd));
722 private function fd_file_path($modul,
$fd)
724 $file =
dbx()->get_base_dir() .
'dbx/modules/' . $modul .
'/fd/' .
$fd .
'.fd.php';
728 private function build_url($run2, $modul,
$fd, $extra = array())
730 $url =
'?dbx_modul=' . $this->_admin_modul .
731 '&dbx_run1=edit_fd' .
732 '&dbx_run2=' . rawurlencode($run2) .
733 '&modul=' . rawurlencode($modul) .
734 '&fd=' . rawurlencode(
$fd);
736 foreach ((array)$extra as $key =>
$value) {
737 $url .=
'&' . rawurlencode((
string)$key) .
'=' . rawurlencode((
string)
$value);
743 private function get_system_var($name, $default =
'')
745 if (function_exists(
'dbx')) {
747 if (is_object($obj) && method_exists($obj,
'get_system_var')) {
748 $value = $obj->get_system_var($name);
757 private function merge_record($old, $post,
$keys)
759 $record = is_array($old) ? $old : array();
760 foreach ((array)
$keys as $key) {
761 if (array_key_exists($key, (array)$post)) {
762 $record[$key] = $this->normalize_value($post[$key]);
768 private function strip_editor_keys($record)
770 unset($record[
'modul'], $record[
'dd'], $record[
'fd'], $record[
'field_pos'], $record[
'old_name']);
774 private function normalize_value(
$value)
777 return implode(
',', array_map(
'trim',
$value));
779 return trim((
string)
$value);
782 private function parse_order($raw)
784 if (is_array($raw)) {
785 return array_values(array_map(
'intval', $raw));
788 $raw = trim((
string)$raw);
793 if (substr($raw, 0, 1) ===
'[') {
794 $decoded = json_decode($raw,
true);
795 if (is_array($decoded)) {
796 return array_values(array_map(
'intval', $decoded));
800 $parts = preg_split(
'/[|,\s;]+/', $raw);
801 return is_array($parts) ? array_values(array_map(
'intval', $parts)) : array();
804 private function reorder_records($records,
$order)
806 $records = array_values((array)$records);
817 foreach (
$order as $pos) {
819 if ($pos < 0 || $pos >=
$count || isset($seen[$pos])) {
823 $new[] = $records[$pos];
830 $name = trim((
string)(
$field[
'name'] ??
''));
831 if (!$this->is_identifier($name)) {
832 $message =
$texts->format_fd_message(
833 'fd_invalid_field_name',
834 array(
'field' =>
dbx()->
esc($name))
840 foreach (array_values((array)
$fields) as $pos => $old) {
841 if ((
int)$pos === (
int)$self_pos) {
845 $old_name = strtolower(trim((
string)($old[
'name'] ??
'')));
846 if ($old_name !==
'') {
847 $names[$old_name] = 1;
851 if (isset($names[strtolower($name)])) {
852 $message =
$texts->format_fd_message(
853 'fd_duplicate_field_name',
854 array(
'field' =>
dbx()->
esc($name))
862 private function is_identifier($name)
864 return (
bool)preg_match(
'/^[A-Za-z_][A-Za-z0-9_]*$/', (
string)$name);
867 private function sanitize_name($name)
869 $name = trim((
string)$name);
870 return preg_match(
'/^[A-Za-z0-9_-]+$/', $name) ? $name :
'';
873 private function safe_id(
$value)
875 $value = preg_replace(
'/[^A-Za-z0-9_]+/',
'_', (
string)
$value);
880 private function instance_id($seed)
882 return $this->safe_id($seed .
'_' . substr(md5((
string)$seed), 0, 6));
885 private function alert($type, $msg)
887 $type = preg_replace(
'/[^a-z]/',
'', (
string)$type);
891 return '<div class="alert alert-' . $type .
'">' . $msg .
'</div>';
894 private function field_keys()
896 $oDD =
dbx()->get_system_obj(
'dbxDD');
897 if (is_object(
$oDD) && method_exists(
$oDD,
'dd_field_schema_keys')) {
898 return array_merge(array(
'modul',
'dd',
'fd',
'field_pos',
'old_name'),
$oDD->dd_field_schema_keys());
929 private function default_field_record()
948 'tpl' =>
'text-label',
954 private function field_row_defaults()
dbx()
Liefert die zentrale dbXapp-API als Singleton.
esc($value)
Escaped einen Wert fuer HTML-Text und HTML-Attribute.
foreach(array('bootstrapRowColumns', 'setBootstrapColumnLayout', 'addBootstrapColumn', 'dissolveBootstrapColumns',) as $function) $keys
foreach( $valid as $email) foreach($invalid as $email) $fd
if(!is_object($db)||! $db->connect_db_server('dbx|dbxContent.db3')) $help