dbxapp 4.1.3
CMS, Shop, Workflows und modulare Geschäftsanwendungen
Loading...
Searching...
No Matches
dbxReport.class.php
Go to the documentation of this file.
1<?php
2
3require_once 'dbxForm.class.php';
4
145class dbxReport extends dbxForm {
146
148 protected $_report_state_flds = array(
149 'dbx_rpos' => array('default' => 0, 'rules' => 'int'),
150 );
151
153 protected $_table_render_tpl_cache = array();
154
156 public $_ajax = 1;
157
159 public $_mode = 'table';
160
162 public $_current_page = 0;
163
165 public $_current_report_ln = 0;
166
168 public $_current_page_ln = 0;
169
171 public $_first_page_lines = 9999;
172
174 public $_next_page_lines = 9999;
175
177 public $_fld_haeder = '';
178
180 public $_haeder_report = '';
181
183 public $_footer_report = '';
184
186 public $_haeder_page = '';
187
189 public $_footer_page = '';
190
192 public $_haeder_next_page = '';
193
195 public $_footer_next_page = '';
196
198 public $_page_break = '<div class="page-break printMe"> </div><br>';
199
201 public $_haeder = '';
202
204 public $_body = '';
205
207 public $_footer = '';
208
210 public $_record = array();
211
213 public $_rdata = array();
214
216 public $_rdata_inline = false;
217
219 public $_body_inline = '';
220
222 public $_rcount = 0;
223
225 public $_count_all = -1;
226
228 public $_rpos = 0;
229
231 public $_rrows = 20;
232
234 public $_rwhere_placeholder = '#search_for#';
235
237 public $_pages = 0;
238
240 public $_pagelink = '';
241
243 public $_auto_flds = '';
244
246 public $_auto_mode = '';
247
249 public $_rflds = '';
250
252 public $_tpl_pagination = 'dbx|pagination';
253
255 public $_but_pagination = 3;
256
258 public $_add_action = '';
259
261 public $_create_sel_flds = 0;
262
264 public $_create_row_select = 0;
265
267 public $_create_row_edit = 0;
268
270 public $_create_row_copy = 0;
271
273 public $_create_row_delete = 0;
274
276 public $_create_row_download = 0;
277
279 public $_create_row_show = 0;
280
282 public $_create_row_export = 0;
283
285 public $_create_row_import = 0;
286
288 public $_create_row_undo = 0;
289
291 public $_create_row_print = 0;
292
294 public $_rpt_format = array();
295
297 public $_options_rsort = array();
298
300 public $_options_rrows = array();
301
303 public $_options_rdesc = array();
304
306 public $_options_rselect = array();
307
309 public $_tabel_tpls = array();
310
312 public $_table_col_count = 0;
313
315 public $_multi_page_select = 0;
316
318 public $_multi_select_work = '';
319
321 protected $_report_multi_actions = array();
322
324 public $_table_buttons = 'left';
325
335 public $_data_table = 0;
336
338 public $_scroll_table = 0;
339
341 public $_class_haeder = array();
342
344 public $_style_haeder = array();
345
347 public $_class_body = array();
348
350 public $_count_selects = -1;
351
353 public $_msg_confirm_delete = 'Datensatz löschen ?';
354
356 public $_msg_confirm_delete_tab = 'Datenbank-Tabelle wirklich leeren ?';
357
359 public $_msg_confirm_copy = 'Datensatz kopieren ?';
360
362 public $_delete_tab_dd = '';
363
365 public $_delete_tab_label = 'Tabelle leeren';
366
376 protected $_delete_tab_label_from_fd = false;
377
378
379 /* =====================================================
380 * GRID / TABULURATOR SUPPORT
381 * ===================================================== */
382
384 public $_grid_read_url = '';
385
387 public $_grid_save_url = '';
388
390 public $_grid_delete_url = '';
391
393 public $_grid_insert_url = '';
394
396 public $_grid_sort_url = '';
397
399 public $_grid_sync_url = '';
400
402 public $_grid_print_url = '';
403
405 public $_grid_export_url = '';
406
408 public $_grid_schema = '';
409
411 public $_grid_id = '';
412
414 public $_grid_cols = '';
415
417 public $_grid_layout = 'fitColumns';
418
420 public $_grid_headerfilter = 1;
421
423 public $_grid_headersort = 1;
424
426 public $_grid_allow_delete = 1;
427
429 public $_grid_allow_edit = 1;
430
432 public $_grid_allow_insert = 1;
433
435 public $_grid_synctime = '2';
436
453 public function clear() {
454 $this->_forward_clear();
455
456 $this->_mode = 'table';
457 $this->_current_page = 0;
458 $this->_current_report_ln = 0;
459 $this->_current_page_ln = 0;
460 $this->_first_page_lines = 9999;
461 $this->_next_page_lines = 9999;
462
463 $this->_fld_haeder = '';
464
465 $this->_haeder_report = '';
466 $this->_footer_report = '';
467 $this->_haeder_page = '';
468 $this->_footer_page = '';
469 $this->_haeder_next_page = '';
470 $this->_footer_next_page = '';
471
472 $this->_haeder = '';
473 $this->_body = '';
474 $this->_footer = '';
475
476 $this->_record = array();
477 $this->_callback_owner = null;
478 $this->_callback_id = '';
479 $this->_callbacks = array();
480 $this->_rdata = array();
481 $this->_rdata_inline = false;
482 $this->_body_inline = '';
483
484 $this->_rcount = 0;
485 $this->_count_all = -1;
486 $this->_rpos = 0;
487 $this->_rrows = 20;
488 $this->_pages = 0;
489 $this->_pagelink = '';
490
491 $this->_auto_flds = '';
492 $this->_auto_mode = '';
493 $this->_rflds = '';
494
495 $this->_add_action = '';
496
497 $this->_create_sel_flds = 0;
498 $this->_create_row_select = 0;
499 $this->_create_row_edit = 0;
500 $this->_create_row_copy = 0;
501 $this->_create_row_delete = 0;
502 $this->_create_row_download = 0;
503 $this->_create_row_show = 0;
504 $this->_create_row_export = 0;
505 $this->_create_row_import = 0;
506 $this->_create_row_undo = 0;
507 $this->_create_row_print = 0;
508
509 $this->_rpt_format = array();
510
511
512 $this->_table_col_count = 0;
513 $this->_multi_page_select = 0;
514 $this->_multi_select_work = '';
515 $this->_report_multi_actions = array();
516 $this->_table_buttons = 'left';
517 $this->_table_render_tpl_cache = array();
518
519 $this->_data_table = 0;
520 $this->_scroll_table = 0;
521
522 $this->_style_haeder = array();
523 $this->_class_haeder = array();
524 $this->_class_body = array();
525
526 $this->_count_selects = -1;
527
528 $this->_msg_confirm_delete = 'Datensatz löschen ?';
529 $this->_msg_confirm_delete_tab = 'Datenbank-Tabelle wirklich leeren ?';
530 $this->_msg_confirm_copy = 'Datensatz kopieren ?';
531
532 $this->_delete_tab_dd = '';
533 $this->_delete_tab_label = 'Tabelle leeren';
534 $this->_delete_tab_label_from_fd = false;
535
536 $this->_grid_read_url = '';
537 $this->_grid_save_url = '';
538 $this->_grid_delete_url = '';
539 $this->_grid_insert_url = '';
540 $this->_grid_sort_url = '';
541 $this->_grid_sync_url = '';
542 $this->_grid_print_url = '';
543 $this->_grid_export_url = '';
544 $this->_grid_schema = '';
545 $this->_grid_id = '';
546 $this->_grid_cols = '';
547 $this->_grid_layout = 'fitColumns';
548 $this->_grid_headerfilter = 1;
549 $this->_grid_headersort = 1;
550 $this->_grid_allow_delete = 1;
551 $this->_grid_allow_edit = 1;
552 $this->_grid_allow_insert = 1;
553 $this->_grid_synctime = '2';
554
555 $table = array();
556
557 $table['tpl_haeder_col'] = 'table_haeder_col';
558 $table['tpl_haeder_select'] = 'table_haeder_select';
559 $table['tpl_haeder_delte'] = 'table_haeder_delete';
560 $table['tpl_haeder_expand'] = 'table_haeder_expand';
561 $table['tpl_haeder_expander'] = 'table_haeder_expander';
562 $table['tpl_haeder_edit'] = 'table_haeder_edit';
563 $table['tpl_haeder_copy'] = 'table_haeder_copy';
564 $table['tpl_haeder_undo'] = 'table_haeder_undo';
565 $table['tpl_haeder_show'] = 'table_haeder_show';
566 $table['tpl_haeder_import'] = 'table_haeder_import';
567 $table['tpl_haeder_export'] = 'table_haeder_export';
568 $table['tpl_haeder_download'] = 'table_haeder_download';
569 $table['tpl_haeder_print'] = 'table_haeder_print';
570
571 $table['tpl_row_col'] = 'table_row_col';
572 $table['tpl_row_select'] = 'table_row_select';
573 $table['tpl_row_expand'] = 'table_row_expand';
574 $table['tpl_row_expander'] = 'table_row_expander';
575 $table['tpl_row_edit'] = 'table_row_edit';
576 $table['tpl_row_copy'] = 'table_row_copy';
577 $table['tpl_row_delete'] = 'table_row_delete';
578 $table['tpl_row_save'] = 'table_row_save';
579 $table['tpl_row_undo'] = 'table_row_undo';
580 $table['tpl_row_show'] = 'table_row_show';
581 $table['tpl_row_export'] = 'table_row_export';
582 $table['tpl_row_import'] = 'table_row_import';
583 $table['tpl_row_download'] = 'table_row_download';
584 $table['tpl_row_print'] = 'table_row_print';
585
586 if ($this->_multi_page_select) {
587 $table['tpl_haeder_select'] = 'table_haeder_select-multi';
588 $table['tpl_row_select'] = 'table_row_select-multi';
589 }
590
591 $this->_tabel_tpls = $table;
592 }
593
602 public function set_tabel_tpl($tid, $tpl) {
603 $this->_tabel_tpls[$tid] = $tpl;
604 }
605
606
607
608
618 protected function get_report_action_url() {
619 if ($this->_action) {
620 return $this->_action;
621 }
622
623 $modul = $this->_dbx_modul;
624 $run1 = $this->_dbx_action;
625 $run2 = $this->_dbx_work;
626
627 if (!$run1) {
628 $run1 = dbx()->get_modul_var('dbx_run1', 0);
629 }
630
631 if (!$run2) {
632 $run2 = dbx()->get_modul_var('dbx_run2', 0);
633 }
634
635 $url = '?dbx_modul=' . $modul;
636
637 if ($run1) {
638 $url .= '&dbx_run1=' . $run1;
639 }
640
641 if ($run2) {
642 $url .= '&dbx_run2=' . $run2;
643 }
644
645 return $url;
646 }
647
658 public function enable_delete_tab($dd, $label = null) {
659 $this->_delete_tab_dd = (string) $dd;
660 $this->_delete_tab_label_from_fd = $label === null || $label === '';
661 if (!$this->_delete_tab_label_from_fd) {
662 $this->_delete_tab_label = (string) $label;
663 }
664
665 if (!$this->_dd && $this->_delete_tab_dd) {
666 $this->_dd = $this->_delete_tab_dd;
667 }
668
669 // Der Report besitzt alle Informationen fuer die Aktion bereits
670 // zentral. Ein zuvor manuell gesetzter Delete-Tab-Button wird bewusst
671 // ersetzt, damit alte Module ohne eigene Tokenlogik sicher weiterlaufen.
672 $this->add_rep('bar_actions', $this->get_delete_tab_button());
673 }
674
680 protected function get_delete_tab_button() {
681 if (!$this->_delete_tab_dd) {
682 return '';
683 }
684
685 $action = $this->get_report_action_url();
686
687 if ($action) {
688 $webApp = dbx()->get_system_obj('dbxWebApp');
689 $action = $webApp->append_route_params($action, array(
690 'dbx_do' => 'delete_tab',
691 ));
692 $action = dbx()->action_url($action);
693 }
694
695 $label = $this->_delete_tab_label_from_fd
696 ? $this->get_fd_message(
697 'delete_tab_label',
698 'Tabelle leeren'
699 )
701 $title = $this->get_fd_message(
702 'delete_tab_title',
703 $label
704 );
705 $confirm = $this->get_fd_message(
706 'delete_tab_confirm',
707 $this->_msg_confirm_delete_tab
708 );
709 $tooltip = $this->get_fd_message(
710 'delete_tab_tooltip',
711 $title
712 );
713
714 $data = array(
715 'action' => $action,
716 'label' => $label,
717 'title' => $title,
718 'confirm' => $confirm,
719 'class' => 'btn-danger',
720 'tooltip' => $tooltip,
721 );
722
723 $tpl = $this->get_tpl('dbx|action_button_delete_tab', $data);
724
725 return $tpl;
726 }
727
735 protected function merge_db_placeholders($content) {
736 $content = str_replace('{db:delete_tab}', $this->get_delete_tab_button(), $content);
737
738 return $content;
739 }
740
748 protected function normalize_multi_select_key($rid) {
749 if ($rid === null) {
750 return '';
751 }
752
753 $rid = trim((string) $rid);
754
755 if ($rid === '') {
756 return '';
757 }
758
759 return $rid;
760 }
761
777 protected function get_record_rid($record, $default = -1) {
778 if (!is_array($record)) {
779 return $default;
780 }
781
782 if ($this->_fld_id && array_key_exists($this->_fld_id, $record)) {
783 return $record[$this->_fld_id];
784 }
785
786 if (array_key_exists('rid', $record)) {
787 return $record['rid'];
788 }
789
790 if (array_key_exists('id', $record)) {
791 return $record['id'];
792 }
793
794 if (array_key_exists('recnum', $record)) {
795 return $record['recnum'];
796 }
797
798 return $default;
799 }
800
801 public function get_record(): array {
802 if (!is_array($this->_record)) {
803 return array();
804 }
805
806 return $this->_record;
807 }
808
809 public function set_record(array $record): void {
810 $this->_record = $record;
811 }
812
813 public function get_record_val(string $name, mixed $default = null): mixed {
814 if (!is_array($this->_record)) {
815 return $default;
816 }
817
818 if (array_key_exists($name, $this->_record)) {
819 return $this->_record[$name];
820 }
821
822 return $default;
823 }
824
825 public function set_record_val(string $name, mixed $value): void {
826 if (!is_array($this->_record)) {
827 $this->_record = array();
828 }
829
830 $this->_record[$name] = $value;
831 }
832
833 public function set_callback_owner($owner): void {
834 if (is_object($owner)) {
835 $this->_callback_owner = $owner;
836 }
837 }
838
839 public function set_report_header_callback(string $callback): void {
840 $this->set_callback('report_header', $callback);
841 }
842
843 public function set_page_header_callback(string $callback): void {
844 $this->set_callback('page_header', $callback);
845 }
846
847 public function set_header_callback(string $callback): void {
848 $this->set_callback('header', $callback);
849 }
850
851 public function set_body_callback(string $callback): void {
852 $this->set_callback('body', $callback);
853 }
854
855 public function set_footer_callback(string $callback): void {
856 $this->set_callback('footer', $callback);
857 }
858
859 public function set_page_footer_callback(string $callback): void {
860 $this->set_callback('page_footer', $callback);
861 }
862
863 public function set_report_footer_callback(string $callback): void {
864 $this->set_callback('report_footer', $callback);
865 }
866
867 public function set_next_record_callback(string $callback): void {
868 $this->set_callback('next_record', $callback);
869 }
870
878 protected function get_record_select_key($record) {
879 if (is_array($record) && array_key_exists('id', $record)) {
880 return $this->normalize_multi_select_key($record['id']);
881 }
882
883 $rid = $this->get_record_rid($record, '');
884
885 return $this->normalize_multi_select_key($rid);
886 }
887
902 protected function parse_multi_select_ids($raw) {
903 $ids = array();
904
905 if (is_array($raw)) {
906 foreach ($raw as $value) {
907 $key = $this->normalize_multi_select_key($value);
908
909 if ($key !== '') {
910 $ids[$key] = 1;
911 }
912 }
913
914 return array_keys($ids);
915 }
916
917 $raw = trim((string) $raw);
918
919 if ($raw === '') {
920 return array();
921 }
922
923 if ($raw[0] === '[') {
924 $decoded = json_decode($raw, true);
925
926 if (is_array($decoded)) {
927 return $this->parse_multi_select_ids($decoded);
928 }
929 }
930
931 $parts = preg_split('/[|,\s;]+/', $raw);
932
933 if (!is_array($parts)) {
934 return array();
935 }
936
937 foreach ($parts as $value) {
938 $key = $this->normalize_multi_select_key($value);
939
940 if ($key !== '') {
941 $ids[$key] = 1;
942 }
943 }
944
945 return array_keys($ids);
946 }
947
955 public function set_multi_select_ids(array $ids) {
956 $selects = $this->get_multi_selects();
957
958 foreach ($ids as $rid) {
959 $key = $this->normalize_multi_select_key($rid);
960
961 if ($key !== '') {
962 $selects[$key] = 1;
963 }
964 }
965
966 $this->set_multi_selects($selects);
967 }
968
976 public function del_multi_select_ids(array $ids) {
977 $selects = $this->get_multi_selects();
978
979 foreach ($ids as $rid) {
980 $key = $this->normalize_multi_select_key($rid);
981
982 if ($key !== '' && isset($selects[$key])) {
983 unset($selects[$key]);
984 }
985 }
986
987 $this->set_multi_selects($selects);
988 }
989
996 $ids = array();
997
998 if (!is_array($this->_rdata)) {
999 return array();
1000 }
1001
1002 foreach ($this->_rdata as $record) {
1003 $key = $this->get_record_select_key($record);
1004
1005 if ($key !== '') {
1006 $ids[$key] = 1;
1007 }
1008 }
1009
1010 return array_keys($ids);
1011 }
1012
1020 public function get_visible_multi_select_state(array $visibleIds = array()) {
1021 if (!$visibleIds) {
1022 $visibleIds = $this->get_visible_multi_select_ids();
1023 }
1024
1025 $selects = $this->get_multi_selects();
1026 $selectedVisible = array();
1027
1028 foreach ($visibleIds as $rid) {
1029 $key = $this->normalize_multi_select_key($rid);
1030
1031 if ($key !== '' && isset($selects[$key])) {
1032 $selectedVisible[] = $key;
1033 }
1034 }
1035
1036 $visibleCount = count($visibleIds);
1037 $selectedCount = count($selectedVisible);
1038 $headerState = 'none';
1039
1040 if ($visibleCount > 0 && $selectedCount === $visibleCount) {
1041 $headerState = 'all';
1042 } elseif ($selectedCount > 0) {
1043 $headerState = 'partial';
1044 }
1045
1046 return array(
1047 'visible_ids' => array_values($visibleIds),
1048 'selected_ids_visible' => array_values($selectedVisible),
1049 'visible_count' => $visibleCount,
1050 'selected_count' => $selectedCount,
1051 'header_state' => $headerState,
1052 'header_checked' => ($headerState === 'all') ? 1 : 0,
1053 );
1054 }
1055
1064 protected function send_multi_select_json_response(array $visibleIds = array(), $dbx_do = '') {
1065 $quick = dbx()->get_modul_var('dbx_select_quick', 1, 'int');
1066
1067 if ($quick) {
1068 http_response_code(204);
1069 if (function_exists('session_write_close')) {
1070 session_write_close();
1071 }
1072 exit;
1073 }
1074
1075 $state = $this->get_visible_multi_select_state($visibleIds);
1076
1077 $response = array(
1078 'ok' => 1,
1079 'dbx_do' => $dbx_do,
1080 'count_selects' => $this->get_count_selects(),
1081 'visible_ids' => $state['visible_ids'],
1082 'selected_ids_visible' => $state['selected_ids_visible'],
1083 'visible_count' => $state['visible_count'],
1084 'visible_selected_count' => $state['selected_count'],
1085 'header_state' => $state['header_state'],
1086 );
1087
1088 header('Content-Type: application/json; charset=utf-8');
1089 echo json_encode($response, JSON_UNESCAPED_UNICODE);
1090 if (function_exists('session_write_close')) {
1091 session_write_close();
1092 }
1093 exit;
1094 }
1095
1096
1097
1098
1099
1107 public function check_is_multiselect($rid) {
1108 $checked = '';
1109 $key = $this->normalize_multi_select_key($rid);
1110 $selects = $this->get_multi_selects();
1111
1112 if ($key !== '' && isset($selects[$key])) {
1113 $checked = 'checked="checked"';
1114 }
1115
1116 return $checked;
1117 }
1118
1126 public function set_multi_select($rid) {
1127 $selects = $this->get_multi_selects();
1128
1129 if ($rid == '*') {
1130 foreach ($this->_rdata as $record) {
1131 $key = $this->get_record_select_key($record);
1132
1133 if ($key !== '') {
1134 $selects[$key] = 1;
1135 }
1136 }
1137 } else {
1138 $key = $this->normalize_multi_select_key($rid);
1139
1140 if ($key !== '') {
1141 $selects[$key] = 1;
1142 }
1143 }
1144
1145 $this->set_multi_selects($selects);
1146 }
1147
1155 public function del_multi_select($rid) {
1156 $selects = $this->get_multi_selects();
1157
1158 if ($rid != '*') {
1159 $key = $this->normalize_multi_select_key($rid);
1160
1161 if ($key !== '' && isset($selects[$key])) {
1162 unset($selects[$key]);
1163 }
1164 } else {
1165 $selects = array();
1166 }
1167
1168 $this->set_multi_selects($selects);
1169 }
1170
1178 public function set_multi_selects($selects) {
1179 $normalized = array();
1180 $modul = $this->_dbx_modul ;
1181 $modul_key = $modul . '-rpt-' . $this->_fid;
1182 if (is_array($selects)) {
1183 foreach ($selects as $rid => $value) {
1184 $key = $this->normalize_multi_select_key($rid);
1185
1186 if ($key !== '') {
1187 $normalized[$key] = 1;
1188 }
1189 }
1190 }
1191 dbx()->set_remember_var('multi_select', $normalized, $modul_key);
1192 $this->_count_selects = -1;
1193 }
1194
1202 public function del_multi_selects($id) {
1203 if ($id == '*') {
1204 $this->set_multi_selects(array());
1205 return;
1206 }
1207
1208 $ids = $this->get_multi_selects();
1209 $key = $this->normalize_multi_select_key($id);
1210
1211 if ($key !== '' && isset($ids[$key])) {
1212 unset($ids[$key]);
1213 }
1214
1215 $this->set_multi_selects($ids);
1216 }
1217
1223 public function get_multi_selects(): array {
1224 $modul = $this->_dbx_modul ;
1225 $modul_key = $modul . '-rpt-' . $this->_fid;
1226 $selects = dbx()->get_remember_var('multi_select', array(), $modul_key);
1227
1228 if (!is_array($selects)) {
1229 $selects = array();
1230 }
1231
1232 $normalized = array();
1233
1234 foreach ($selects as $rid => $value) {
1235 $xkey = $this->normalize_multi_select_key($rid);
1236
1237 if ($xkey !== '') {
1238 $normalized[$xkey] = 1;
1239 }
1240 }
1241
1242 return $normalized;
1243 }
1244
1250 public function get_count_selects() {
1251 $count = $this->_count_selects;
1252
1253 if ($count == -1) {
1254 $selects = $this->get_multi_selects();
1255 $count = is_array($selects) ? count($selects) : 0;
1256 $this->_count_selects = $count;
1257 }
1258
1259 return $count;
1260 }
1261
1279 public function del_selected($rid = 0) {
1280 $count = 0;
1281
1282 if ($rid == '*') {
1283 $count = count($this->get_multi_selects());
1284 $this->del_multi_select('*');
1285 return $count;
1286 }
1287
1288 $key = $this->normalize_multi_select_key($rid);
1289
1290 if ($key === '') {
1291 return 0;
1292 }
1293
1294 $selects = $this->get_multi_selects();
1295
1296 if (isset($selects[$key])) {
1297 unset($selects[$key]);
1298 $this->set_multi_selects($selects);
1299 $count = 1;
1300 }
1301
1302 return $count;
1303 }
1304
1312 public function add_rwhere_select($rwhere) {
1313 $selects = $this->get_multi_selects();
1314 $fld_id = $this->_fld_id ? $this->_fld_id : 'id';
1315
1316 if (!is_array($selects) || !count($selects)) {
1317 if ($rwhere > '') {
1318 $rwhere .= ' and (1=0)';
1319 }
1320
1321 if ($rwhere == '') {
1322 $rwhere .= '1=0';
1323 }
1324
1325 return $rwhere;
1326 }
1327
1328 $values = array();
1329
1330 foreach ($selects as $id => $sel) {
1331 $key = $this->normalize_multi_select_key($id);
1332
1333 if ($key === '') {
1334 continue;
1335 }
1336
1337 if (preg_match('/^-?\d+$/', $key)) {
1338 $values[] = (string) ((int) $key);
1339 } else {
1340 $values[] = "'" . addslashes($key) . "'";
1341 }
1342 }
1343
1344 if (!count($values)) {
1345 if ($rwhere > '') {
1346 $rwhere .= ' and (1=0)';
1347 }
1348
1349 if ($rwhere == '') {
1350 $rwhere .= '1=0';
1351 }
1352
1353 return $rwhere;
1354 }
1355
1356 $selectWhere = $fld_id . ' IN (' . implode(',', $values) . ')';
1357
1358 if ($rwhere > '') {
1359 $rwhere .= ' and (' . $selectWhere . ')';
1360 } else {
1361 $rwhere = $selectWhere;
1362 }
1363
1364 return $rwhere;
1365 }
1366
1376 public function add_rwhere_search($sql, $suchWert, $feldListe) {
1377 if ($suchWert === null) {
1378 $suchWert = '';
1379 }
1380
1381 $suchWert = str_replace(array('\'', '"', '\\', '%'), '', $suchWert);
1382 $suchWert = filter_var($suchWert, FILTER_SANITIZE_SPECIAL_CHARS);
1383
1384 $datum = DateTime::createFromFormat('d.m.Y', $suchWert);
1385
1386 if ($datum && $datum->format('d.m.Y') === $suchWert) {
1387 $suchWert = $datum->format('Y-m-d');
1388 }
1389
1390 $felder = explode(',', $feldListe);
1391 $sql .= ' AND (';
1392 $bedingungen = array();
1393
1394 foreach ($felder as $feld) {
1395 $feld = trim($feld);
1396
1397 if ($feld === '') {
1398 continue;
1399 }
1400
1401 $bedingungen[] = "$feld LIKE '$suchWert%'";
1402 }
1403
1404 $sql .= implode(' OR ', $bedingungen);
1405 $sql .= ')';
1406
1407 return $sql;
1408 }
1409
1422 public function set_form_selects() {
1423 $dbx_do = dbx()->get_modul_var('dbx_do', '', 'parameter');
1424 $ajax = dbx()->get_system_var('dbx_ajax', 0, 'int');
1425
1426 if ($dbx_do === 'selection_state') {
1427 $idsRaw = dbx()->get_modul_var('dbx_select_ids', '', '*');
1428 $visibleRaw = dbx()->get_modul_var('dbx_select_visible_ids', '', '*');
1429 $selected = $this->parse_multi_select_ids($idsRaw);
1430 $visibleIds = $this->parse_multi_select_ids($visibleRaw);
1431
1432 if (!$visibleIds) {
1433 $visibleIds = $selected;
1434 }
1435
1436 $selectedMap = array_flip($selected);
1437
1438 foreach ($visibleIds as $rid) {
1439 if (isset($selectedMap[$rid])) {
1440 $this->set_multi_select($rid);
1441 } else {
1442 $this->del_multi_select($rid);
1443 }
1444 }
1445
1446 if ($ajax) {
1447 $this->send_multi_select_json_response($visibleIds, $dbx_do);
1448 }
1449
1450 return 'handled';
1451 }
1452
1453 if ($dbx_do === 'row_select') {
1454 $state = dbx()->get_modul_var('dbx_select_state', 0, 'int');
1455 $rid = dbx()->get_modul_var('rid', '', 'parameter+.');
1456 $selectId = dbx()->get_modul_var('dbx_select_id', '', 'parameter+.');
1457 $visibleIds = dbx()->get_modul_var('dbx_select_visible_ids', '', '*');
1458
1459 if ($selectId !== '') {
1460 $rid = $selectId;
1461 }
1462
1463 $rid = $this->normalize_multi_select_key($rid);
1464
1465 if ($rid !== '') {
1466 if ($state) {
1467 $this->set_multi_select($rid);
1468 } else {
1469 $this->del_multi_select($rid);
1470 }
1471 }
1472
1473 if ($ajax) {
1475 $this->parse_multi_select_ids($visibleIds),
1476 $dbx_do
1477 );
1478 }
1479
1480 return 'handled';
1481 }
1482
1483 if ($dbx_do === 'rows_select') {
1484 $state = dbx()->get_modul_var('dbx_select_state', 0, 'int');
1485 $idsRaw = dbx()->get_modul_var('dbx_select_ids', '', '*');
1486 $visibleRaw = dbx()->get_modul_var('dbx_select_visible_ids', '', '*');
1487 $ids = $this->parse_multi_select_ids($idsRaw);
1488 $visibleIds = $this->parse_multi_select_ids($visibleRaw);
1489
1490 if (!$visibleIds) {
1491 $visibleIds = $ids;
1492 }
1493
1494 if ($state) {
1495 $this->set_multi_select_ids($ids);
1496 } else {
1497 $this->del_multi_select_ids($ids);
1498 }
1499
1500 if ($ajax) {
1501 $this->send_multi_select_json_response($visibleIds, $dbx_do);
1502 }
1503
1504 return 'handled';
1505 }
1506
1507 if ($dbx_do === 'clear_selects') {
1508 $this->set_multi_selects(array());
1509
1510 if ($ajax) {
1511 $this->send_multi_select_json_response(array(), $dbx_do);
1512 }
1513
1514 return 'handled';
1515 }
1516
1517 return 0;
1518 }
1519
1528 public function rpt_format($key, $value) {
1529 $reform = $this->get_report_format($key);
1530
1531 if ($reform == 'php-date-usr' || $reform == 'date') {
1532 $value = $this->php_date_usr($value);
1533 }
1534
1535 if (
1536 $reform == 'php-datetime-usr' ||
1537 $reform == 'date_time' ||
1538 $reform == 'datetime' ||
1539 $reform == 'datetime_ms'
1540 ) {
1541 $value = $this->php_datetime_usr($value);
1542 }
1543
1544 if ($reform == 'html-chars') {
1545 $value = htmlspecialchars((string) $value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
1546 }
1547
1548 if ($value === null) {
1549 $value = '';
1550 }
1551
1552 return $value;
1553 }
1554
1562 protected function get_report_format($key) {
1563 $format = $this->_rpt_format;
1564 $reform = '';
1565
1566 if (is_array($format)) {
1567 if (isset($format[$key])) {
1568 $reform = $format[$key];
1569 }
1570 } else {
1571 $reform = $format;
1572 }
1573
1574 if ($reform === '') {
1575 $reform = $this->get_auto_report_format($key);
1576 }
1577
1578 return (string) $reform;
1579 }
1580
1588 protected function report_cell_allows_html($key) {
1589 $format = strtolower(trim($this->get_report_format($key)));
1590
1591 return in_array($format, array('html', 'raw-html', 'raw', 'tpl', 'template'), true);
1592 }
1593
1606 protected function render_report_cell_value($key, $value) {
1607 if ($value === null) {
1608 return '';
1609 }
1610
1611 return (string) $value;
1612 }
1613
1625 protected function get_auto_report_format($key) {
1626 static $cache = array();
1627
1628 if (!$this->_dd || !$key) {
1629 return '';
1630 }
1631
1632 $dd = (string) $this->_dd;
1633 $key = (string) $key;
1634 $cacheKey = $dd . '|' . $key;
1635
1636 if (array_key_exists($cacheKey, $cache)) {
1637 return $cache[$cacheKey];
1638 }
1639
1640 $format = '';
1641 $convert = strtolower(trim((string) $this->get_dd($dd, $key, 'convert')));
1642
1643 if (in_array($convert, array('date', 'php-date-usr'), true)) {
1644 $format = 'php-date-usr';
1645 $cache[$cacheKey] = $format;
1646 return $format;
1647 }
1648
1649 if (in_array($convert, array('date_time', 'datetime', 'datetime_ms', 'php-datetime-usr'), true)) {
1650 $format = 'php-datetime-usr';
1651 $cache[$cacheKey] = $format;
1652 return $format;
1653 }
1654
1655 $type = strtolower(trim((string) $this->get_dd($dd, $key, 'type')));
1656
1657 if ($type == 'date') {
1658 $format = 'php-date-usr';
1659 $cache[$cacheKey] = $format;
1660 return $format;
1661 }
1662
1663 if (in_array($type, array('datetime', 'date_time', 'datetime_ms', 'timestamp'), true)) {
1664 $format = 'php-datetime-usr';
1665 $cache[$cacheKey] = $format;
1666 return $format;
1667 }
1668
1669 $cache[$cacheKey] = '';
1670
1671 return '';
1672 }
1673
1686 public function rpt_merge_obj($content) {
1687 $count_select = $this->get_count_selects();
1688 $count_cols = $this->_table_col_count;
1689 $label_colspan = max(1, $count_cols - 1);
1690 $page = $this->_current_page;
1691 $page_break = $this->_page_break;
1692
1693 $content = str_replace('{rpt:count_sel}', $count_select, $content);
1694 $content = str_replace('{rpt:col_count}', $count_cols, $content);
1695 $content = str_replace('{rpt:colspan}', $label_colspan, $content);
1696 $content = str_replace('{rpt:page}', $page, $content);
1697 $content = str_replace('{rpt:pagebrak}', $page_break, $content);
1698
1699 if (is_array($this->_obj)) {
1700 foreach ($this->_obj as $key => $value) {
1701 $xkey = '{obj:' . $key . '}';
1702
1703 if ($value === null) {
1704 $value = '';
1705 }
1706
1707 $content = str_replace($xkey, $value, $content);
1708 }
1709 }
1710
1711 return $this->replaces($content);
1712 }
1713
1715 return $this->rpt_merge_obj($content);
1716 }
1717
1719 return $this->rpt_merge_obj($content);
1720 }
1721
1723 return $this->rpt_merge_obj($content);
1724 }
1725
1726 public function run_report_haeder($content) {
1727 $content = ($this->_fid != 'pagination') ? $this->callback('report_header', $content) : $content;
1728 return $this->forward_run_report_haeder($content);
1729 }
1730
1731 public function run_page_haeder($content) {
1732 $content = ($this->_fid != 'pagination') ? $this->callback('page_header', $content) : $content;
1733 return $this->forward_run_page_haeder($content);
1734 }
1735
1736 public function run_page_footer($content) {
1737 $content = ($this->_fid != 'pagination') ? $this->callback('page_footer', $content) : $content;
1738 return $this->forward_run_page_footer($content);
1739 }
1740
1742 return $this->rpt_merge_obj($content);
1743 }
1744
1745 public function run_report_footer($content) {
1746 $content = ($this->_fid != 'pagination') ? $this->callback('report_footer', $content) : $content;
1747 return $this->forward_run_report_footer($content);
1748 }
1749
1750 public function run_haeder($content) {
1751 $content = ($this->_fid != 'pagination') ? $this->callback('header', $content) : $content;
1752 return $this->forward_run_haeder($content);
1753 }
1754
1755 public function run_body($content) {
1756 $content = ($this->_fid != 'pagination') ? $this->callback('body', $content) : $content;
1757 return $this->forward_run_body($content);
1758 }
1759
1760 public function run_footer($content) {
1761 $content = ($this->_fid != 'pagination') ? $this->callback('footer', $content) : $content;
1762 return $this->forward_run_footer($content);
1763 }
1764
1765 public function forward_run_haeder($content) {
1766 return $this->rpt_merge_obj($content);
1767 }
1768
1769 public function forward_get_footer_page() {
1770 $footer = $this->_footer_next_page;
1771 $footer .= $this->_footer_page;
1772 $footer = $this->rpt_merge_obj($footer);
1773
1774 return $footer;
1775 }
1776
1777 public function forward_get_haeder_page() {
1778 $haeder = $this->_haeder_page;
1779 $haeder .= $this->_haeder_next_page;
1780 $haeder = $this->get_report_haeder($haeder);
1781 $haeder = $this->rpt_merge_obj($haeder);
1782
1783 return $haeder;
1784 }
1785
1786 public function get_footer_page() {
1787 return $this->forward_get_footer_page();
1788 }
1789
1790 public function get_haeder_page() {
1791 return $this->forward_get_haeder_page();
1792 }
1793
1801 private function get_class_body($xkey) {
1802 $class = $xkey;
1803
1804 if (isset($this->_class_body[$xkey])) {
1805 $class = $this->_class_body[$xkey];
1806 }
1807
1808 return $class;
1809 }
1810
1811 public function forward_run_body($content) {
1812 $page_footer = '';
1813 $page_haeder = '';
1814 $rpt = $this->_fid;
1815
1816 if ($rpt != 'pagination') {
1817 $this->_current_report_ln++;
1818 $this->_current_page_ln++;
1819
1820 $pn = $this->_current_page;
1821 $ln = $this->_current_page_ln;
1822
1823 if ($pn == 1) {
1824 $max = $this->_first_page_lines;
1825 } else {
1826 $max = $this->_next_page_lines;
1827 }
1828
1829 if ($ln > $max) {
1830 $page_footer = $this->get_footer_page();
1831 $this->_current_page_ln = 1;
1832 $page_haeder = $this->get_haeder_page();
1833 }
1834
1836 }
1837
1838 return $page_footer . $page_haeder . $content;
1839 }
1840
1841 public function forward_run_footer($content) {
1842 return $this->rpt_merge_obj($content);
1843 }
1844
1845 public function set_class_haeder($key, $class = '') {
1846 if (!$class) {
1847 $class = 'th-' . $key;
1848 }
1849
1850 $this->_class_haeder[$key] = $class;
1851 }
1852
1853 private function get_class_haeder($key) {
1854 $class = '';
1855
1856 if (is_array($this->_class_haeder)) {
1857 if (isset($this->_class_haeder[$key])) {
1858 $class = $this->_class_haeder[$key];
1859 }
1860 }
1861
1862 if (!$class) {
1863 $class = 'th-' . $key;
1864 }
1865
1866 return $class;
1867 }
1868
1869 public function set_style_haeder($key, $style) {
1870 $this->_style_haeder[$key] = $style;
1871 }
1872
1873 private function get_style_haeder($key) {
1874 $style = '';
1875
1876 if (is_array($this->_style_haeder)) {
1877 if (isset($this->_style_haeder[$key])) {
1878 $style = $this->_style_haeder[$key];
1879 }
1880 }
1881
1882 return $style;
1883 }
1884
1893 protected function get_table_action_definitions() {
1894 return array(
1895 array(
1896 'type' => 'expander',
1897 'enabled' => (bool) $this->_data_table,
1898 'header_tpl' => 'tpl_haeder_expander',
1899 'row_tpl' => 'tpl_row_expander',
1900 ),
1901 array(
1902 'type' => 'edit',
1903 'enabled' => (bool) $this->_create_row_edit,
1904 'header_tpl' => 'tpl_haeder_edit',
1905 'row_tpl' => 'tpl_row_edit',
1906 ),
1907 array(
1908 'type' => 'copy',
1909 'enabled' => (bool) $this->_create_row_copy,
1910 'header_tpl' => 'tpl_haeder_copy',
1911 'row_tpl' => 'tpl_row_copy',
1912 ),
1913 array(
1914 'type' => 'show',
1915 'enabled' => (bool) $this->_create_row_show,
1916 'header_tpl' => 'tpl_haeder_show',
1917 'row_tpl' => 'tpl_row_show',
1918 ),
1919 array(
1920 'type' => 'export',
1921 'enabled' => (bool) $this->_create_row_export,
1922 'header_tpl' => 'tpl_haeder_export',
1923 'row_tpl' => 'tpl_row_export',
1924 ),
1925 array(
1926 'type' => 'import',
1927 'enabled' => (bool) $this->_create_row_import,
1928 'header_tpl' => 'tpl_haeder_import',
1929 'row_tpl' => 'tpl_row_import',
1930 ),
1931 array(
1932 'type' => 'download',
1933 'enabled' => (bool) $this->_create_row_download,
1934 'header_tpl' => 'tpl_haeder_download',
1935 'row_tpl' => 'tpl_row_download',
1936 ),
1937 array(
1938 'type' => 'delete',
1939 'enabled' => (bool) $this->_create_row_delete,
1940 'header_tpl' => 'tpl_haeder_delte',
1941 'row_tpl' => 'tpl_row_delete',
1942 ),
1943 array(
1944 'type' => 'print',
1945 'enabled' => (bool) $this->_create_row_print,
1946 'header_tpl' => 'tpl_haeder_print',
1947 'row_tpl' => 'tpl_row_print',
1948 ),
1949 );
1950 }
1951
1952 protected function render_simple_table_tpl($file, array $data) {
1953 if (!isset($this->_table_render_tpl_cache[$file])) {
1954 $this->_table_render_tpl_cache[$file] = $this->get_tpl($file, array());
1955 }
1956
1957 return $this->oTPL->replaces($this->_table_render_tpl_cache[$file], $data);
1958 }
1959
1966 $html = '';
1967 $count = 0;
1968
1969 foreach ($this->get_table_action_definitions() as $def) {
1970 if (!$def['enabled']) {
1971 continue;
1972 }
1973
1974 $file = $this->_tabel_tpls[$def['header_tpl']];
1975 $tpl = $this->render_simple_table_tpl($file, array(
1976 'name' => 'ID',
1977 'class' => 'no-sort',
1978 ));
1979
1980 $html .= $tpl . "\n";
1981 $count++;
1982 }
1983
1984 return array(
1985 'html' => $html,
1986 'count' => $count,
1987 );
1988 }
1989
1998 protected function get_table_row_action_data($type, array $record) {
1999 $rid = $this->get_record_rid($record, -1);
2000 $dat = array(
2001 'rid' => $rid,
2002 'value' => $rid,
2003 'action' => $this->get_report_action_url(),
2004 'class' => 'no-sort',
2005 'tooltip' => '',
2006 );
2007
2008 if ($type === 'download') {
2009 $dat['href_dir_file'] = dbx()->get_modul_var('href_dir_file', '', '*');
2010 }
2011
2012 if ($type === 'copy') {
2013 $dat['confirm'] = $this->_msg_confirm_copy;
2014 }
2015
2016 if ($type === 'delete') {
2017 $dat['confirm'] = $this->_msg_confirm_delete;
2018 }
2019
2020 if ($this->_fid != 'pagination') {
2021 $data = array(
2022 'type' => $type,
2023 'record' => $record,
2024 'data' => $dat,
2025 );
2026
2027 $data = $this->callback('row_action_data', $data);
2028
2029 if (is_array($data) && isset($data['data']) && is_array($data['data'])) {
2030 $dat = $data['data'];
2031 }
2032 }
2033
2034 if ($type === 'delete') {
2035 $webApp = dbx()->get_system_obj('dbxWebApp');
2036 $deleteRid = (int)($dat['rid'] ?? $rid);
2037 $deleteParams = array(
2038 'dbx_do' => 'row_delete',
2039 'rid' => $deleteRid,
2040 );
2041
2042 $action = trim((string)($dat['action'] ?? ''));
2043 if ($action !== '' && $action !== '#' && stripos($action, 'javascript:') !== 0) {
2044 $action = $webApp->append_route_params($action, $deleteParams);
2045 $dat['action'] = dbx()->action_url($action);
2046 }
2047
2048 // Spezialisierte Row-Templates verwenden teilweise delete_url
2049 // statt action. Auch diese Variante wird zentral normalisiert.
2050 $deleteUrl = trim((string)($dat['delete_url'] ?? ''));
2051 if ($deleteUrl !== '' && $deleteUrl !== '#' && stripos($deleteUrl, 'javascript:') !== 0) {
2052 $deleteUrl = $webApp->append_route_params($deleteUrl, $deleteParams);
2053 $dat['delete_url'] = dbx()->action_url($deleteUrl);
2054 }
2055 }
2056
2057 return $dat;
2058 }
2059
2067 protected function render_table_row_action_block(array $record) {
2068 $html = '';
2069
2070 foreach ($this->get_table_action_definitions() as $def) {
2071 if (!$def['enabled']) {
2072 continue;
2073 }
2074
2075 $file = $this->_tabel_tpls[$def['row_tpl']];
2076 $dat = $this->get_table_row_action_data($def['type'], $record);
2077 $tpl = $this->render_simple_table_tpl($file, $dat);
2078
2079 $html .= $tpl . "\n";
2080 }
2081
2082 return $html;
2083 }
2084
2095 protected function render_table_header_select(array $auto_flds, $fld_id, $class, array $select_state) {
2096 $file = $this->_tabel_tpls['tpl_haeder_select'];
2097 $name = isset($auto_flds[$fld_id]) ? $auto_flds[$fld_id] : 'xID';
2098 $checked = '';
2099
2100 if (!empty($select_state['header_checked'])) {
2101 $checked = 'checked="checked"';
2102 }
2103
2104 return $this->render_simple_table_tpl($file, array(
2105 'name' => $name,
2106 'checked' => $checked,
2107 'class' => $class,
2108 'header_state' => isset($select_state['header_state']) ? $select_state['header_state'] : 'none',
2109 ));
2110 }
2111
2120 protected function render_table_row_select(array $record, $class) {
2121 $file = $this->_tabel_tpls['tpl_row_select'];
2122 $name = $this->_fid . '_select';
2123 $rid = $this->get_record_select_key($record);
2124 $checked = $this->check_is_multiselect($rid);
2125
2126 if ($checked) {
2127 $this->_post[$name] = 1;
2128 }
2129
2130 return $this->render_simple_table_tpl($file, array(
2131 'name' => $name,
2132 'value' => $rid,
2133 'rid' => $rid,
2134 'checked' => $checked,
2135 'class' => $class,
2136 'tooltip' => '',
2137 ));
2138 }
2139
2148 protected function render_table_header_data_columns(array $auto_flds, $fld_id) {
2149 $html = '';
2150 $count = 0;
2151
2152 foreach ($auto_flds as $key => $value) {
2153 $skip = 0;
2154
2155 if ($this->_create_row_select && $key == $fld_id) {
2156 $skip = 1;
2157 }
2158
2159 if (!$skip && $value > '') {
2160 $file = $this->_tabel_tpls['tpl_haeder_col'];
2161 $class = $this->get_class_haeder($key);
2162 $style = $this->get_style_haeder($key);
2163
2164 $tpl = $this->render_simple_table_tpl($file, array(
2165 'value' => $value,
2166 'name' => $key,
2167 'class' => $class,
2168 'style' => $style,
2169 ));
2170
2171 $html .= $tpl . "\n";
2172 $count++;
2173 }
2174 }
2175
2176 return array(
2177 'html' => $html,
2178 'count' => $count,
2179 );
2180 }
2181
2192 protected function render_table_row_data_columns(array $record, array $auto_flds, $fld_id, $defaultClass = 'auto-fld') {
2193 $html = '';
2194
2195 foreach ($auto_flds as $no => $key) {
2196 $xkey = '';
2197 $value = '-?-';
2198 $label = $auto_flds[$no];
2199 $skip = 0;
2200
2201 if (isset($record[$key])) {
2202 $xkey = $key;
2203 } elseif (isset($record[$no])) {
2204 $xkey = $no;
2205 }
2206
2207 if ($this->_create_row_select && $xkey == $fld_id) {
2208 $skip = 1;
2209 }
2210
2211 if (!$skip && $label > '') {
2212 if ($xkey) {
2213 $value = $record[$xkey];
2214 $value = $this->rpt_format($xkey, $value);
2215 }
2216
2217 $class = $defaultClass;
2218
2219 if ($defaultClass !== 'auto-fld') {
2220 $class = $this->get_class_body($xkey);
2221 }
2222
2223 $class = trim($class . ' dbx-report-cell');
2224 $value = $this->render_report_cell_value($xkey, $value);
2225
2226 $tpl = $this->render_simple_table_tpl($this->_tabel_tpls['tpl_row_col'], array(
2227 'value' => $value,
2228 'class' => $class,
2229 'tooltip' => '',
2230 ));
2231
2232 $html .= $tpl . "\n";
2233 }
2234 }
2235
2236 return $html;
2237 }
2238
2246 public function get_report_haeder($content = '') {
2247 if (!$content) {
2248 $content = $this->_haeder;
2249 }
2250
2251 $this->_current_page++;
2252 $col_count = 0;
2253 $auto_flds = $this->_auto_flds;
2254 $auto_mode = $this->_auto_mode;
2255 $select_state = $this->get_visible_multi_select_state();
2256
2257 if (!is_array($auto_flds)) {
2258 if (is_string($auto_flds) && $auto_flds !== '') {
2259 $auto_flds = explode(',', $auto_flds);
2260 } else {
2261 $auto_flds = array();
2262 }
2263 }
2264
2265 $pos = strpos($content, '[rpt:row]');
2266
2267 if ($pos !== false) {
2268 $row = '';
2269 $fld_id = $this->_fld_id;
2270
2271 if ($auto_mode == 'table' && is_array($auto_flds)) {
2272 $buttonBlock = $this->render_table_header_action_block();
2273 $columnBlock = $this->render_table_header_data_columns($auto_flds, $fld_id);
2274
2275 if ($this->_table_buttons != 'left') {
2276 if ($this->_create_row_select) {
2277 $row .= $this->render_table_header_select(
2278 $auto_flds,
2279 $fld_id,
2280 $this->get_class_haeder(isset($auto_flds[$fld_id]) ? $auto_flds[$fld_id] : 'xID'),
2281 $select_state
2282 ) . "\n";
2283 $col_count++;
2284 }
2285
2286 $row .= $columnBlock['html'];
2287 $col_count += $columnBlock['count'];
2288
2289 $row .= $buttonBlock['html'];
2290 $col_count += $buttonBlock['count'];
2291 } else {
2292 $row .= $buttonBlock['html'];
2293 $col_count += $buttonBlock['count'];
2294
2295 if ($this->_create_row_select) {
2296 $row .= $this->render_table_header_select(
2297 $auto_flds,
2298 $fld_id,
2299 'no-sort',
2300 $select_state
2301 ) . "\n";
2302 $col_count++;
2303 }
2304
2305 $row .= $columnBlock['html'];
2306 $col_count += $columnBlock['count'];
2307 }
2308
2309 $this->_table_col_count = $col_count;
2310 }
2311
2312 $content = str_replace('[rpt:row]', $row, $content);
2313 }
2314
2315 $content = $this->run_haeder($content);
2316
2317 return $content;
2318 }
2319
2325 public function get_report_body(): string {
2326 $content = '';
2327 $line = '';
2328 $loop = 0;
2329
2330 $auto_flds = $this->_auto_flds;
2331 $auto_mode = $this->_auto_mode;
2332
2333 if (!is_array($auto_flds)) {
2334 if (is_string($auto_flds) && $auto_flds !== '') {
2335 $auto_flds = explode(',', $auto_flds);
2336 } else {
2337 $auto_flds = array();
2338 }
2339 }
2340
2341 if (is_array($this->_rdata)) {
2342 foreach ($this->_rdata as $recnum => $record) {
2343 $loop++;
2344 $line = $this->_body;
2345
2346 $this->_record = $record;
2347 $record = ($this->_fid != 'pagination') ? $this->callback('next_record', $record) : $record;
2348 $this->_record = $record;
2349
2350 if (!is_array($record)) {
2351 continue;
2352 }
2353
2354 $line = $this->run_body($line);
2355 $record = $this->_record;
2356
2357 if (!is_array($record)) {
2358 continue;
2359 }
2360
2361 $fld_id = $this->_fld_id;
2362 $pos = strpos($line, '[rpt:row]');
2363
2364 if ($pos !== false && $this->_rdata_inline) {
2365 $inline = $this->_body_inline;
2366 return str_replace('[rpt:row]', $inline, $line);
2367 }
2368
2369 if ($pos !== false) {
2370 $row = '';
2371
2372 if ($auto_mode == 'table' && is_array($auto_flds)) {
2373 $buttonBlock = $this->render_table_row_action_block($record);
2374
2375 if ($this->_table_buttons != 'left') {
2376 if ($this->_create_row_select) {
2377 $row .= $this->render_table_row_select($record, 'no-sort') . "\n";
2378 }
2379
2380 $row .= $this->render_table_row_data_columns($record, $auto_flds, $fld_id, 'auto-fld');
2381 $row .= $buttonBlock;
2382 } else {
2383 $row .= $buttonBlock;
2384
2385 if ($this->_create_row_select) {
2386 $row .= $this->render_table_row_select($record, 'no-sort') . "\n";
2387 }
2388
2389 $row .= $this->render_table_row_data_columns($record, $auto_flds, $fld_id, 'body');
2390 }
2391 }
2392
2393 $line = str_replace('[rpt:row]', $row, $line);
2394 }
2395
2396 $tr_class = $this->get_class_tr($record);
2397 $tr_class .= ($loop % 2 != 0) ? ' odd' : ' even';
2398
2399 $line = str_replace('{tr-class}', $tr_class, $line);
2400
2401 if (is_array($record)) {
2402 foreach ($record as $field => $value) {
2403 $field_name = '{' . $field . '}';
2404
2405 if (strpos($line, $field_name) === false) {
2406 continue;
2407 }
2408
2409 $value = $this->rpt_format($field, $value);
2410
2411 if (!is_array($value) && !is_object($value)) {
2412 if ($value === null) {
2413 $value = '';
2414 }
2415
2416 $line = str_replace($field_name, (string) $value, $line);
2417 }
2418 }
2419 }
2420
2421 $col_count = $this->_table_col_count;
2422 $line = str_replace('{rpt:col_count}', $col_count, $line);
2423
2424 if (strpos($line, '{r}') !== false) {
2425 $r = dbx()->next_id(1);
2426 $line = str_replace('{r}', $r, $line);
2427 }
2428
2429 $content .= $line;
2430
2431 if ($this->_rdata_inline) {
2432 break;
2433 }
2434 }
2435 }
2436
2437 return $content;
2438 }
2439
2440 public function get_class_tr($record) {
2441 $class = '';
2442 $activ_id = $this->_activ_id;
2443
2444 if (!$activ_id) {
2445 $activ_id = $this->get_activ_id();
2446 }
2447
2448 if ($activ_id) {
2449 $key = $this->_fld_id;
2450
2451 if ($key && isset($record[$key])) {
2452 if ($activ_id == $record[$key]) {
2453 $class = 'table-active';
2454 }
2455 }
2456 }
2457
2458 return $class;
2459 }
2460
2461 public function get_report_footer() {
2462 $content = $this->_footer;
2463 $col_count = $this->_table_col_count;
2464
2465 $content = str_replace('{rpt:col_count}', $col_count, $content);
2466 $content = str_replace('{rpt:colspan}', max(1, $col_count - 1), $content);
2467 $content = $this->run_footer($content);
2468
2469 return $content;
2470 }
2471
2472 public function split_tpl($report) {
2473 $report_part = explode('<hr class="dbx_split">', $report);
2474 $report_header = '';
2475 $report_body = '';
2476 $report_footer = '';
2477 $next_haeder_page = '';
2478 $next_footer_page = '';
2479 $count = count($report_part);
2480
2481 if ($count > 0) {
2482 $report_body = $report_part[0];
2483 }
2484
2485 if ($count > 1) {
2486 $report_header = $report_part[0];
2487 $report_body = $report_part[1];
2488 }
2489
2490 if ($count > 2) {
2491 $report_header = $report_part[0];
2492 $report_body = $report_part[1];
2493 $report_footer = $report_part[2];
2494 $next_haeder_page = $report_part[0];
2495 $next_footer_page = $report_part[2];
2496 }
2497
2498 if ($count > 5) {
2499 $next_haeder_page = $report_part[3];
2500 $next_footer_page = $report_part[5];
2501 }
2502
2503 $this->_haeder = $report_header;
2504 $this->_body = $report_body;
2505 $this->_footer = $report_footer;
2506 $this->_footer_next_page = $next_footer_page;
2507 $this->_haeder_next_page = $next_haeder_page;
2508 }
2509
2522 if ((!$this->_create_row_select && !$this->_create_sel_flds) || !is_string($content) || stripos($content, 'dbxReport') === false) {
2523 return $content;
2524 }
2525
2526 return preg_replace_callback(
2527 '/<div\b(?=[^>]*\bclass\s*=\s*(["\'])[^"\']*\bdbxReport\b[^"\']*\1)([^>]*)>/i',
2528 function ($match) {
2529 $tag = $match[0];
2530
2531 if (preg_match('/\bdata-dbx\s*=\s*(["\'])(.*?)\1/i', $tag, $dataMatch)) {
2532 $value = trim($dataMatch[2]);
2533
2534 if (stripos($value, 'lib=report') !== false) {
2535 return $tag;
2536 }
2537
2538 $value = ($value === '') ? 'lib=report|form=0' : $value . '||lib=report|form=0';
2539 $newAtt = 'data-dbx=' . $dataMatch[1] . $value . $dataMatch[1];
2540
2541 return str_replace($dataMatch[0], $newAtt, $tag);
2542 }
2543
2544 return substr($tag, 0, -1) . ' data-dbx="lib=report|form=0">';
2545 },
2546 $content,
2547 1
2548 );
2549 }
2550
2559 public function get_report_pages() {
2560 $content = '';
2561 $modul = $this->_dbx_modul;
2562 $action = $this->_dbx_action;
2563 $rcount = $this->_rcount;
2564 $link = $this->_pagelink;
2565 $tpl = $this->_tpl_pagination;
2566 $rpos = $this->_rpos;
2567 $rrows = $this->_rrows;
2568
2569 if (!$link) {
2570 $link = '?dbx_modul=' . $modul . '&dbx_run1=' . $action;
2571 }
2572
2573 $link = $this->_action ?: $link;
2574 $content = $this->pagination($tpl, $link, $rpos, $rrows, $rcount);
2575
2576 return $content;
2577 }
2578
2579 private function lnk_page($p, $akt_page, $link, $rpos, $rrows, $rcount) {
2580 $active = '';
2581 $class = '';
2582 $current = '';
2583 $p_active = '';
2584 $s_active = '';
2585
2586 if ($p == $akt_page) {
2587 $p_active = ' aria-current="page"';
2588 $active = ' active';
2589 $current = ' aria-current="page" ';
2590 }
2591
2592 $rec = array();
2593 $rec['p'] = $p . $s_active;
2594 $rec['href_page'] = $link . '&dbx_rrows=' . $rrows . '&dbx_rpos=' . (($p - 1) * $rrows);
2595 $rec['p_active'] = $p_active;
2596 $rec['active'] = $active;
2597 $rec['current'] = $current;
2598 $rec['class'] = $class . ' dbxAjax';
2599
2600 return $rec;
2601 }
2602
2603 private function pagination($tpl, $link, $rpos, $rrows, $rcount) {
2604 if ($rrows == 0) {
2605 return '';
2606 }
2607
2608 $pages = intval($rcount / $rrows);
2609
2610 if ($rcount % $rrows) $pages++;
2611 if ($pages == 0) $pages = 1;
2612
2613
2614 $pmax = $this->_but_pagination;
2615 $akt_page = intval($rpos / $rrows) + 1;
2616
2617 if ($akt_page < 1) $akt_page = 1;
2618 if ($akt_page > $pages) $akt_page = $pages;
2619
2620 $half = intval($pmax / 2);
2621 $p_s = $akt_page - $half;
2622 $p_e = $akt_page + $half;
2623
2624 if ($p_s < 1) {
2625 $p_s = 1;
2626 $p_e = $pmax;
2627 }
2628
2629 if ($p_e > $pages) {
2630 $p_e = $pages;
2631 $p_s = $pages - $pmax + 1;
2632
2633 if ($p_s < 1) {
2634 $p_s = 1;
2635 }
2636 }
2637
2638 $last_pos = ($pages - 1) * $rrows;
2639 $prev = ($akt_page - 2) * $rrows;
2640 $next = ($akt_page) * $rrows;
2641
2642 if ($prev < 0) $prev = 0;
2643 if ($next > $last_pos) $next = $last_pos;
2644
2645 $href_first = $link . '&dbx_rpos=0&dbx_rrows=' . $rrows;
2646 $href_last = $link . '&dbx_rpos=' . $last_pos . '&dbx_rrows=' . $rrows ;
2647 $href_prev = $link . '&dbx_rpos=' . $prev . '&dbx_rrows=' . $rrows ;
2648 $href_next = $link . '&dbx_rpos=' . $next . '&dbx_rrows=' . $rrows ;
2649
2650 $this->_sys['dbx_rpos'] = $rpos;
2651 $this->_sys['dbx_rrows'] = $rrows;
2652
2653 $dv = array();
2654 $dv['dbx_rpos'] = $rpos;
2655 $dv['dbx_rrows'] = $rrows;
2656 $rdata = array();
2657
2658 for ($p = $p_s; $p <= $p_e; $p++) {
2659 $rdata[] = $this->lnk_page($p, $akt_page, $link, $rpos, $rrows, $rcount);
2660
2661 if ($p >= $pages) {
2662 break;
2663 }
2664 }
2665
2666 $oReport = dbx()->get_system_obj('dbxReport');
2667
2668 $oReport->init('pagination');
2669 $oReport->_data = $dv;
2670 $oReport->_dbx_modul = 'dbx';
2671 $oReport->_dbx_action = 'pagination';
2672 $oReport->_dbx_modul_id = 888;
2673 $oReport->_rdata = $rdata;
2674 $oReport->_rcount = $rcount;
2675 $oReport->_rrows = $rrows;
2676 $oReport->_rpos = $rpos;
2677 $oReport->_action = $link;
2678 $oReport->_tpl = $tpl;
2679 $oReport->_pages = 0;
2680 $oReport->_mode = 'table';
2681 $oReport->_rflds = array();
2682 $oReport->_body_inline = false;
2683 $oReport->_create_sel_flds = 0;
2684
2685 $content = $oReport->run();
2686
2687 $content = str_replace('{href_first}', $href_first, $content);
2688 $content = str_replace('{href_last}', $href_last, $content);
2689 $content = str_replace('{href_prev}', $href_prev, $content);
2690 $content = str_replace('{href_next}', $href_next, $content);
2691 $selectState = $this->get_visible_multi_select_state();
2692
2693 $countAll = ($this->_count_all >= 0) ? $this->_count_all : $rcount;
2694
2695 $content = $this->applyReportCountReplaces($content);
2696
2697 return $content;
2698 }
2699
2700 public function data_rows($data, $rpos, $rrows) {
2701 $rdata = array();
2702
2703 for ($i = $rpos; $i < ($rpos + $rrows); $i++) {
2704 if (isset($data[$i])) {
2705 $rdata[] = $data[$i];
2706 } else {
2707 break;
2708 }
2709 }
2710
2711 return $rdata;
2712 }
2713
2714 public function add_where($mode, $select, $where = '') {
2715 if ($select) {
2716 if ($where) {
2717 $where .= " $mode (";
2718 $where .= $select;
2719 $where .= ') ';
2720 } else {
2721 $where = $select;
2722 }
2723 }
2724
2725 return $where;
2726 }
2727
2728 public function no_page_reset() {
2729 $this->_page_reset = 0;
2730 }
2731
2739 protected function get_grid_action_url($url, $action) {
2740 $url = trim((string)$url);
2741 if ($url === '') {
2742 return '';
2743 }
2744
2745 $securedUrl = dbx()->action_url($url);
2746 if ($securedUrl === $url) {
2747 dbx()->debug(
2748 'dbxReport grid action blocked: convention not recognized'
2749 . ' action=(' . (string)$action . ') url=(' . $url . ')'
2750 );
2751 return '';
2752 }
2753
2754 return $securedUrl;
2755 }
2756
2757 protected function get_grid_replaces(): array {
2758 $gridId = $this->_grid_id;
2759
2760 if (!$gridId) {
2761 $gridId = $this->_fid . '_grid';
2762 }
2763
2764 $cols = $this->_grid_cols;
2765
2766 if (!$cols && $this->_dd) {
2767 $oDB = dbx()->get_system_obj('dbxDB');
2768 $cols = $oDB->get_dd_grid_cols($this->_dd);
2769 }
2770
2771 $rrows = (int) $this->_rrows;
2772 $rpos = (int) $this->_rpos;
2773 $page = ($rrows > 0) ? ((int) floor($rpos / $rrows) + 1) : 1;
2774
2775 return array(
2776 'read_url' => $this->_grid_read_url,
2777 'save_url' => $this->get_grid_action_url($this->_grid_save_url, 'save'),
2778 'delete_url' => $this->get_grid_action_url($this->_grid_delete_url, 'delete'),
2779 'insert_url' => $this->get_grid_action_url($this->_grid_insert_url, 'insert'),
2780 'sort_url' => $this->get_grid_action_url($this->_grid_sort_url, 'sort'),
2781 'sync_url' => $this->get_grid_action_url($this->_grid_sync_url, 'sync'),
2782 'print_url' => $this->_grid_print_url,
2783 'export_url' => $this->_grid_export_url,
2784 'grid_id' => $gridId,
2785 'grid_cols' => $cols,
2786 'grid_schema' => $this->_grid_schema,
2787 'grid_layout' => $this->_grid_layout,
2788 'grid_height' => $this->_rrows,
2789 'grid_synctime' => $this->_grid_synctime,
2790 'grid_page' => $page,
2791 'grid_page_size' => ($rrows > 0) ? $rrows : 25,
2792 );
2793 }
2794
2795 public function add_grid_stats(array $stats, $ariaLabel = '') {
2796 if (!$stats) {
2797 $this->add_rep('grid_stats', '');
2798 return;
2799 }
2800
2801 $html = '<div class="dbx-grid-stats"';
2802 if ((string)$ariaLabel !== '') {
2803 $html .= ' aria-label="' . htmlspecialchars((string)$ariaLabel, ENT_QUOTES) . '"';
2804 }
2805 $html .= '>';
2806
2807 foreach ($stats as $stat) {
2808 if (!is_array($stat)) {
2809 continue;
2810 }
2811
2812 $label = htmlspecialchars((string)($stat['label'] ?? ''), ENT_QUOTES);
2813 $value = htmlspecialchars((string)($stat['value'] ?? ''), ENT_QUOTES);
2814 $tone = (string)($stat['tone'] ?? '');
2815 $class = 'dbx-grid-stat';
2816
2817 if ($tone === 'ok') {
2818 $class .= ' dbx-grid-stat-ok';
2819 } elseif ($tone === 'lock') {
2820 $class .= ' dbx-grid-stat-lock';
2821 } elseif ($tone !== '') {
2822 $class .= ' dbx-grid-stat-' . preg_replace('/[^a-z0-9_-]/i', '', $tone);
2823 }
2824
2825 $html .= '<div class="' . $class . '"><span>' . $label . '</span><strong>' . $value . '</strong></div>';
2826 }
2827
2828 $html .= '</div>';
2829 $this->add_rep('grid_stats', $html);
2830 }
2831
2832 protected function buildGridBarObj() {
2833 if ($this->_mode !== 'tabulurator') {
2834 return;
2835 }
2836 }
2837
2838 protected function prepareReportFrameReplaces(int $i, array $options = array()): void {
2839 $withForm = (string)($this->_replaces['frame_use_form'] ?? '0') !== '0';
2840 if (array_key_exists('with_form', $options)) {
2841 $withForm = (bool)$options['with_form'];
2842 }
2843 $panelClass = trim('dbxReport ' . (string)($this->_replaces['report_shell_class'] ?? '') . ' ' . (string)($this->_replaces['shell_panel_class'] ?? ''));
2844 $frameId = trim((string)($this->_replaces['frame_id'] ?? ''));
2845 if ($frameId === '') {
2846 $frameId = 'dbx_target_' . $i;
2847 }
2848
2849 $this->add_rep('frame_id', $frameId);
2850 if (trim((string)($this->_replaces['frame_panel_class'] ?? '')) === '') {
2851 $this->add_rep('frame_panel_class', trim($panelClass));
2852 }
2853 $panelAttrs = (string)($this->_replaces['report_shell_attrs'] ?? '');
2854 if ($panelAttrs === '') {
2855 $panelAttrs = (string)($this->_replaces['shell_panel_attrs'] ?? '');
2856 }
2857 $this->add_rep('frame_panel_attrs', $panelAttrs);
2858 $this->add_rep('frame_subbar', '');
2859 $this->add_rep('frame_body_class', (string)($this->_replaces['shell_body_class'] ?? ''));
2860 $this->add_rep('frame_body_head', (string)($this->_replaces['frame_body_head'] ?? ''));
2861 $this->add_rep('frame_body_tail', (string)($this->_replaces['frame_body_tail'] ?? ''));
2862
2863 if ($withForm) {
2864 $reportFormClass = trim((string)($this->_replaces['report_form_class'] ?? ''));
2865 $reportFormAttrs = trim((string)($this->_replaces['report_form_attrs'] ?? ''));
2866 $this->add_rep('frame_form_open', '<form action="' . htmlspecialchars((string)$this->_action, ENT_QUOTES) . '" method="post" id="dbx_form_' . $i . '" class="dbxAjax' . ($reportFormClass !== '' ? ' ' . $reportFormClass : '') . '"' . ($reportFormAttrs !== '' ? ' ' . $reportFormAttrs : '') . '>');
2867 $this->add_rep('frame_form_close', '</form>');
2868 } else {
2869 $this->add_rep('frame_form_open', '');
2870 $this->add_rep('frame_form_close', '');
2871 }
2872 }
2873
2882 $rcount = (int) $this->_rcount;
2883 $countAll = ($this->_count_all >= 0) ? (int) $this->_count_all : $rcount;
2884
2885 $content = str_replace('{pagination:count_all}', (string) $countAll, (string) $content);
2886 $content = str_replace('{pagination:count_selected}', (string) $rcount, (string) $content);
2887 $content = str_replace('{pagination:count_checked}', (string) $this->get_count_selects(), (string) $content);
2888 $content = str_replace('{report_extra_stats}', (string)($this->_replaces['report_extra_stats'] ?? ''), (string) $content);
2889 $content = str_replace('{report_bar_actions}', (string)($this->_replaces['report_bar_actions'] ?? ''), (string) $content);
2890
2891 return $content;
2892 }
2893
2894 protected function cleanupReportBarSlots($content) {
2895 return preg_replace(
2896 '/<div class="dbx-report-bar-field"[^>]*>\s*\{obj:[a-z0-9_]+\}\s*<\/div>\s */i',
2897 '',
2898 (string) $content
2899 );
2900 }
2901
2909 protected function resolveReportMsgText($msg) {
2910 $msg = trim((string) $msg);
2911
2912 if ($msg === '') {
2913 return '';
2914 }
2915
2916 $editor = dbx()->get_system_var('dbx_editor', 0, 'int');
2917
2918 if (!$editor && preg_match('/^#form_msg_(info|success|error|warning)#$/', $msg)) {
2919 return '';
2920 }
2921
2922 return $msg;
2923 }
2924
2930 protected function buildReportFormMsgHtml() {
2931 $error = $this->resolveReportMsgText($this->_msg_error);
2932
2933 if ($error === '' && !empty($this->_msg_err)) {
2934 $error = $this->resolveReportMsgText($this->_msg_err);
2935 }
2936
2937 if ($error !== '') {
2938 return $this->get_form_msg('error', $error);
2939 }
2940
2941 $warning = $this->resolveReportMsgText($this->_msg_warning);
2942
2943 if ($warning !== '') {
2944 return $this->get_form_msg('warning', $warning);
2945 }
2946
2947 $success = $this->resolveReportMsgText($this->_msg_success);
2948
2949 if ($success !== '') {
2950 return $this->get_form_msg('success', $success);
2951 }
2952
2953 if ($this->submit() && $this->errors()) {
2954 return $this->get_form_msg('error', 'Pruefen Sie bitte Ihre Eingaben.');
2955 }
2956
2957 $info = $this->resolveReportMsgText($this->_msg_info);
2958
2959 if ($info !== '') {
2960 return $this->get_form_msg('info', $info);
2961 }
2962
2963 return '';
2964 }
2965
2976 public function add_action($obj, $tpl, $action = '', $data = '') {
2977 $dbx_do = $this->parse_report_action_code($action);
2978 $actionUrl = (string)$action;
2979
2980 if ($actionUrl !== '' && $actionUrl[0] === '&') {
2981 $actionUrl = $this->get_report_action_url() . $actionUrl;
2982 }
2983
2984 if ($actionUrl !== '') {
2985 $actionUrl = dbx()->action_url($actionUrl);
2986 }
2987
2988 parent::add_action($obj, $tpl, $actionUrl, $data);
2989
2990 if ($dbx_do === '') {
2991 return;
2992 }
2993
2994 $confirm = '';
2995
2996 if ($tpl === 'action_button_delete') {
2997 $confirm = (string) $this->_msg_confirm_delete;
2998 }
2999
3000 $this->_report_multi_actions[$dbx_do] = array(
3001 'obj' => (string) $obj,
3002 'label' => $this->get_report_action_label($tpl),
3003 'tpl' => (string) $tpl,
3004 'action' => (string) $actionUrl,
3005 'confirm' => $confirm,
3006 'quick' => in_array($dbx_do, array('multi_select', 'multi_deselect'), true),
3007 );
3008 }
3009
3015 protected function parse_report_action_code($action) {
3016 $action = (string) $action;
3017
3018 if ($action === '' || $action[0] !== '&') {
3019 return '';
3020 }
3021
3022 if (preg_match('/(?:^|&)dbx_do=([^&]+)/', $action, $match)) {
3023 return (string) $match[1];
3024 }
3025
3026 if (preg_match('/(?:^|&)dbx_run2=([^&]+)/', $action, $match)) {
3027 return (string) $match[1];
3028 }
3029
3030 return '';
3031 }
3032
3038 protected function get_report_action_label($tpl) {
3039 $labels = array(
3040 'action_button_delete' => array(
3041 'key' => 'action_delete_selected',
3042 'de' => 'Ausgewählte löschen',
3043 'en' => 'Delete selected',
3044 'es' => 'Eliminar seleccionados',
3045 ),
3046 'action_button_activate' => array(
3047 'key' => 'action_activate_selected',
3048 'de' => 'Ausgewählte aktivieren',
3049 'en' => 'Activate selected',
3050 'es' => 'Activar seleccionados',
3051 ),
3052 'action_button_deactivate' => array(
3053 'key' => 'action_deactivate_selected',
3054 'de' => 'Ausgewählte deaktivieren',
3055 'en' => 'Deactivate selected',
3056 'es' => 'Desactivar seleccionados',
3057 ),
3058 'action_button_select' => array(
3059 'key' => 'action_select_visible',
3060 'de' => 'Sichtbare auswählen',
3061 'en' => 'Select visible',
3062 'es' => 'Seleccionar visibles',
3063 ),
3064 'action_button_deselect' => array(
3065 'key' => 'action_deselect_visible',
3066 'de' => 'Sichtbare abwählen',
3067 'en' => 'Deselect visible',
3068 'es' => 'Deseleccionar visibles',
3069 ),
3070 );
3071
3072 if (!isset($labels[$tpl])) {
3073 return (string) $tpl;
3074 }
3075
3076 $language = in_array($this->_dbx_lng, array('en', 'es'), true)
3077 ? $this->_dbx_lng
3078 : 'de';
3079 $definition = $labels[$tpl];
3080
3081 return $this->get_fd_message(
3082 $definition['key'],
3083 $definition[$language]
3084 );
3085 }
3086
3096 public function delete_multi_selected_records($dd, $verify_access = 1, $trace = 1) {
3097 $db = dbx()->get_system_obj('dbxDB');
3098 $selects = array_keys($this->get_multi_selects());
3099 $fld_id = $this->_fld_id ? $this->_fld_id : 'id';
3100 $deleted = 0;
3101 $failed = 0;
3102
3103 if (!is_array($selects) || !count($selects)) {
3104 return array(
3105 'deleted' => 0,
3106 'failed' => 0,
3107 'total' => 0,
3108 );
3109 }
3110
3111 foreach ($selects as $id) {
3112 $key = $this->normalize_multi_select_key($id);
3113
3114 if ($key === '') {
3115 continue;
3116 }
3117
3118 if (preg_match('/^-?\d+$/', $key)) {
3119 $where = $fld_id . '=' . (int) $key;
3120 } else {
3121 $where = $fld_id . "='" . addslashes($key) . "'";
3122 }
3123
3124 $ok = $db->delete($dd, $where, $verify_access, $trace);
3125 $this->del_selected($key);
3126
3127 if ((int) $ok > 0) {
3128 $deleted++;
3129 } else {
3130 $failed++;
3131 }
3132 }
3133
3134 $this->_count_selects = -1;
3135
3136 return array(
3137 'deleted' => $deleted,
3138 'failed' => $failed,
3139 'total' => $deleted + $failed,
3140 );
3141 }
3142
3150 public function apply_multi_delete_result(array $result) {
3151 $deleted = (int) ($result['deleted'] ?? 0);
3152 $failed = (int) ($result['failed'] ?? 0);
3153 $language = in_array($this->_dbx_lng, array('en', 'es'), true)
3154 ? $this->_dbx_lng
3155 : 'de';
3156
3157 if ($deleted <= 0 && $failed <= 0) {
3158 return;
3159 }
3160
3161 if ($deleted > 0 && $failed === 0) {
3162 if ($deleted === 1) {
3163 $fallback = array(
3164 'de' => '1 Datensatz gelöscht.',
3165 'en' => '1 record was deleted.',
3166 'es' => 'Se eliminó 1 registro.',
3167 )[$language];
3168 $this->_msg_success = $this->get_fd_message(
3169 'multi_delete_one',
3170 $fallback
3171 );
3172 } else {
3173 $fallback = array(
3174 'de' => $deleted . ' Datensätze gelöscht.',
3175 'en' => $deleted . ' records were deleted.',
3176 'es' => 'Se eliminaron ' . $deleted . ' registros.',
3177 )[$language];
3178 $this->_msg_success = $this->format_fd_message(
3179 'multi_delete_many',
3180 array('count' => $deleted),
3181 $fallback
3182 );
3183 }
3184 return;
3185 }
3186
3187 if ($deleted > 0) {
3188 $fallback = array(
3189 'de' => $deleted . ' Datensätze gelöscht, ' . $failed . ' fehlgeschlagen.',
3190 'en' => $deleted . ' records were deleted; ' . $failed . ' failed.',
3191 'es' => 'Se eliminaron ' . $deleted . ' registros; ' . $failed . ' fallaron.',
3192 )[$language];
3193 $this->_msg_error = $this->format_fd_message(
3194 'multi_delete_partial',
3195 array('deleted' => $deleted, 'failed' => $failed),
3196 $fallback
3197 );
3198 return;
3199 }
3200
3201 $fallback = array(
3202 'de' => 'Löschen fehlgeschlagen.',
3203 'en' => 'Deletion failed.',
3204 'es' => 'La eliminación falló.',
3205 )[$language];
3206 $this->_msg_error = $this->get_fd_message(
3207 'multi_delete_failed',
3208 $fallback
3209 );
3210 }
3211
3217 protected function buildReportFooterObj() {
3218 if (!$this->_create_row_select || !$this->_report_multi_actions) {
3219 return;
3220 }
3221
3222 if (isset($this->_obj['report_footer'])) {
3223 return;
3224 }
3225
3226 $selectOptions = '';
3227 $actionLinks = '';
3228 $hasSelect = 0;
3229
3230 foreach ($this->_report_multi_actions as $dbx_do => $action) {
3231 if (!empty($action['quick'])) {
3232 continue;
3233 }
3234
3235 $hasSelect = 1;
3236 $label = $this->get_report_action_label(
3237 (string) ($action['tpl'] ?? '')
3238 );
3239 $actionSuffix = (string) ($action['action'] ?? '');
3240 $actionUrl = $actionSuffix;
3241
3242 if ($actionSuffix !== '' && $actionSuffix[0] === '&') {
3243 $actionUrl = $this->get_report_action_url() . $actionSuffix;
3244 }
3245
3246 $selectOptions .= $this->get_tpl('dbx|report-footer-action-option', array(
3247 'value' => (string) $dbx_do,
3248 'label' => $label,
3249 ));
3250
3251 $actionLink = trim($this->get_tpl((string) ($action['tpl'] ?? 'dbx|action_button'), array(
3252 'action' => $actionUrl,
3253 'label' => $label,
3254 'title' => $this->get_fd_message(
3255 'report_action_confirm_title',
3256 array(
3257 'de' => 'Aktion bestätigen',
3258 'en' => 'Confirm action',
3259 'es' => 'Confirmar acción',
3260 )[in_array($this->_dbx_lng, array('en', 'es'), true)
3261 ? $this->_dbx_lng
3262 : 'de']
3263 ),
3264 'confirm' => (string) ($action['confirm'] ?? ''),
3265 'class' => '',
3266 'tooltip' => '',
3267 )));
3268
3269 if ($actionLink !== '') {
3270 $actionLinks .= $this->get_tpl('dbx|report-footer-action-link', array(
3271 'value' => (string) $dbx_do,
3272 'action_link' => $actionLink,
3273 ));
3274 }
3275 }
3276
3277 if (!$hasSelect) {
3278 return;
3279 }
3280
3281 $i = (int) $this->_next_i;
3282 $actionMain = $this->get_tpl('dbx|report-footer-action-main', array(
3283 'action_id' => 'dbx_report_action_' . $i,
3284 'report_action_options' => $selectOptions,
3285 'report_action_links' => $actionLinks,
3286 ));
3287
3288 $html = trim($this->get_tpl('dbx|report-footer', array(
3289 'report_action_main' => $actionMain,
3290 )));
3291
3292 if ($html !== '') {
3293 $this->add_obj('report_footer', 'obj-value', $html);
3294 }
3295 }
3296
3304 protected function injectReportFooter($content) {
3305 if (!isset($this->_obj['report_footer'])) {
3306 return (string) $content;
3307 }
3308
3309 if (strpos($content, '{obj:report_footer}') !== false) {
3310 return (string) $content;
3311 }
3312
3313 if (stripos($content, '<tfoot') !== false) {
3314 return (string) $content;
3315 }
3316
3317 return (string) preg_replace(
3318 '/<\/tbody>\s*<\/table>/i',
3319 '</tbody>{obj:report_footer}</table>',
3320 (string) $content,
3321 1
3322 );
3323 }
3324
3325 public function apply_tabulurator_request() {
3326 $page = dbx()->get_request_var('page', 0, 'int');
3327 $size = dbx()->get_request_var('size', 0, 'int');
3328 $limit = dbx()->get_request_var('limit', 0, 'int');
3329 $offset = dbx()->get_request_var('offset', -1, 'int');
3330
3331 if ($size > 0) {
3332 $this->_rrows = $size;
3333 } elseif ($limit > 0) {
3334 $this->_rrows = $limit;
3335 }
3336
3337 if ($offset >= 0) {
3338 $this->_rpos = $offset;
3339 } elseif ($page > 0 && $this->_rrows > 0) {
3340 $this->_rpos = (($page - 1) * $this->_rrows);
3341 }
3342 }
3343
3344 public function get_report_rows_array(): array {
3345 $rows = array();
3346
3347 if (!is_array($this->_rdata)) {
3348 return $rows;
3349 }
3350
3351 foreach ($this->_rdata as $record) {
3352 $this->_record = $record;
3353 $dummy = '';
3354 $this->run_body($dummy);
3355 $record = $this->_record;
3356
3357 if (!is_array($record)) {
3358 $record = array();
3359 }
3360
3361 $row = array();
3362
3363 foreach ($record as $field => $value) {
3364 if (is_array($value)) {
3365 $row[$field] = $value;
3366 } else {
3367 $row[$field] = $this->rpt_format($field, $value);
3368 }
3369 }
3370
3371 $rows[] = $row;
3372 }
3373
3374 return $rows;
3375 }
3376
3377 public function fast_response_rows_json() {
3378 $rows = $this->get_report_rows_array();
3379 $count = (int) $this->_rcount;
3380 $rrows = (int) $this->_rrows;
3381 $rpos = (int) $this->_rpos;
3382 $pages = 0;
3383 $page = 1;
3384
3385 if ($rrows > 0) {
3386 $pages = (int) ceil($count / $rrows);
3387 $page = (int) floor($rpos / $rrows) + 1;
3388 }
3389
3390 header('Content-Type: application/json; charset=utf-8');
3391
3392 echo json_encode(array(
3393 'ok' => 1,
3394 'count' => $count,
3395 'rows' => array_values($rows),
3396 'rpos' => $rpos,
3397 'rrows' => $rrows,
3398 'page' => $page,
3399 'pages' => $pages,
3400 ), JSON_UNESCAPED_UNICODE);
3401
3402 exit;
3403 }
3404
3405 public function create_selection_fields($fd = 'fd::') {
3406 dbx()->debug('create_selection_fields');
3407 $source = $fd;
3408
3409 if ($source === 'fd::') {
3410 $source = $this->_fd;
3411 } elseif ($source) {
3412 $this->_fd = $source;
3413 }
3414
3415 if (!$source) {
3416 return;
3417 }
3418
3419 $before = array_keys($this->_flds);
3420 $this->add_flds($source);
3421 $added = array_diff(array_keys($this->_flds), $before);
3422
3423 foreach ($this->_report_state_flds as $key => $state) {
3424 if (!array_key_exists($key, $this->_data)) {
3425 $this->_data[$key] = $state['default'] ?? '';
3426 }
3427 }
3428
3429 foreach ($added as $key) {
3430 if (!array_key_exists($key, $this->_data)) {
3431 $this->_data[$key] = $this->get_dd($source, $key, 'default');
3432 }
3433 }
3434 }
3435
3436
3437
3438 public function init($fid, $tpl = '', $first_page_lines = -1, $next_page_lines = -1, $current_line = -1) {
3439 if ($fid == 'pagination') return;
3440 $this->_dbx_modul= dbx()->get_system_var('dbx_activ_modul', 'dbx', '*');
3441 $this->forward_init($fid, $tpl);
3442 $this->set_callback_id($fid);
3443 //$this->create_selection_fields();
3444
3445 $modul = $this->_dbx_modul ;
3446 $modul_key = $modul . '-rpt-' . $this->_fid;
3447
3448
3449 if ($first_page_lines <= 0) $first_page_lines = 999999;
3450 if ($next_page_lines <= 0) $next_page_lines = 999999;
3451
3452 if ($current_line <= 0) $current_line = 0;
3453
3454 $current_page_line = 0;
3455 $current_page = 0;
3456
3457 if ($current_line >= 0) {
3458 if ($current_line < $first_page_lines) {
3459 $current_page = 1;
3460 $current_page_line = $current_line;
3461 } else {
3462 $remaining_lines = $current_line - $first_page_lines;
3463 $current_page = 2 + intval($remaining_lines / $next_page_lines);
3464 $current_page_line = ($remaining_lines % $next_page_lines);
3465 }
3466
3467 $current_page--;
3468 }
3469
3470 $this->_current_page = $current_page;
3471 $this->_current_report_ln = $current_line;
3472 $this->_current_page_ln = $current_page_line;
3473 $this->_first_page_lines = $first_page_lines;
3474 $this->_next_page_lines = $next_page_lines;
3475
3476 $this->_fld_haeder = '';
3477 $this->_haeder_report = '';
3478 $this->_footer_report = '';
3479 $this->_haeder_page = '';
3480 $this->_footer_page = '';
3481 $this->_haeder_next_page = '';
3482 $this->_footer_next_page = '';
3483
3484 dbx()->set_remember_var('last_report_i', $this->_next_i, $modul_key);
3485
3486 $this->set_form_selects();
3487 $this->_multi_select_work = '';
3488 }
3489
3500 public function run() {
3501 $content = '';
3502 $norep = '';
3503 $i = $this->_next_i;
3504 $fid = $this->_fid;
3505 $tpl = $this->_tpl;
3506
3507 $pages = $this->_pages;
3508 $mode = $this->_mode;
3509 $flds = $this->_rflds;
3510
3511 if (!is_array($flds)) $flds = array();
3512
3513 $this->_dbx_modul= dbx()->get_system_var('dbx_activ_modul', 'dbx', '*');
3514 $this->_auto_flds = $flds;
3515 $this->_auto_mode = $mode;
3516 //$count = $this->_rcount;
3517
3518 if ($this->_dd) {
3519 $oDB = dbx()->get_system_obj('dbxDB');
3520 if (method_exists($oDB, 'get_dd_file')) {
3521 $this->add_editor_file('dd', $oDB->get_dd_file($this->_dd));
3522 }
3523 }
3524
3525 $this->buildModuleBarObj();
3526 $this->buildGridBarObj();
3527 $this->buildReportFooterObj();
3528 $this->prepareReportFrameReplaces((int)$i);
3529
3530 $replaces = $this->_replaces;
3531
3532 if ($mode == 'tabulurator') {
3533 $replaces = array_merge($replaces, $this->get_grid_replaces());
3534 }
3535
3536 foreach (array(
3537 'report_shell_class' => '',
3538 'report_shell_attrs' => '',
3539 'report_form_class' => '',
3540 'report_form_attrs' => '',
3541 'shell_panel_class' => '',
3542 'shell_panel_attrs' => '',
3543 'shell_body_class' => '',
3544 ) as $shellKey => $shellDefault) {
3545 if (!isset($replaces[$shellKey]) || (string) $replaces[$shellKey] === '') {
3546 $replaces[$shellKey] = $shellDefault;
3547 }
3548 }
3549
3550 if (strpos($tpl, '|') === false) {
3551 $tpl = $this->_dbx_modul . '|' . $tpl;
3552 }
3553
3554 $report_tpl = $this->get_tpl($tpl, $replaces, 'htm', $i);
3555 $report_tpl = $this->merge_tpl_data($report_tpl, $i);
3556 $report_tpl = $this->injectReportFooter($report_tpl);
3557 $report_tpl = $this->merge_fld_data($report_tpl, $i);
3558 $report_tpl = $this->merge_obj($report_tpl, $i);
3559 $report_tpl = $this->ensureFormHelpBar($report_tpl);
3560 $report_tpl = $this->merge_db_placeholders($report_tpl);
3561 $report_tpl = $this->cleanupReportBarSlots($report_tpl);
3562 $report_tpl = $this->applyReportCountReplaces($report_tpl);
3563
3564 if ($mode == 'tabulurator') {
3565 $content = $report_tpl;
3566
3567 if ($fid != 'pagination') {
3568 $this->store_sysdata();
3569 }
3570
3571 $content = str_replace('{i}', $i, $content);
3572
3573 $msg_tpl = $this->buildReportFormMsgHtml();
3574 $content = str_replace('{obj:form_msg}', $msg_tpl, $content);
3575
3576 if ($pages) {
3577 $ReportPages = $this->get_report_pages();
3578 $content = str_replace('[dbx:pagination]', $ReportPages, $content);
3579 } else {
3580 $content = str_replace('[dbx:pagination]', '', $content);
3581 }
3582 $content = str_replace('{rpt:pages}', (string) $this->_current_page, $content);
3583
3584 $norep_ids = '';
3585 $js = $this->_js;
3586
3587 if (is_array($js)) {
3588 foreach ($js as $javascript) {
3589 $javascript = str_replace('{i}', $i, $javascript);
3590 $norep_ids .= dbx()->norep("\n" . '<script type="text/javascript">' . $javascript . '</script>' . "\n", $i);
3591 }
3592 }
3593
3594 if ($norep_ids) {
3595 $norep = '<div class="norep">' . $norep_ids . '</div>';
3596 }
3597
3598 $content = str_replace('[dbx:js]', $norep, $content);
3600
3601 return $this->add_editor_markers($content);
3602 }
3603
3604 $this->split_tpl($report_tpl);
3605
3606 $haeder = $this->get_report_haeder();
3607 $body = $this->get_report_body();
3608 $footer = $this->get_report_footer();
3609
3610 $content = $haeder . $body . $footer;
3611
3612 if ($fid != 'pagination') {
3613 $this->store_sysdata();
3614 }
3615
3616 if ($fid != 'pagination') {
3617 if ($pages) {
3618 $ReportPages = $this->get_report_pages();
3619 $content = str_replace('[dbx:pagination]', $ReportPages, $content);
3620 }
3621
3622 $haeder_report = $this->_haeder_report;
3623 $haeder_page = $this->_haeder_page;
3624 $footer_page = $this->_footer_page;
3625 $footer_report = $this->_footer_report;
3626
3627 $content = str_replace('{i}', $i, $content);
3628
3629 $msg_tpl = $this->buildReportFormMsgHtml();
3630 $content = str_replace('{obj:form_msg}', $msg_tpl, $content);
3631
3632 $haeder_report = $this->run_report_haeder($haeder_report);
3633 $haeder_page = $this->run_page_haeder($haeder_page);
3634 $footer_page = $this->run_page_footer($footer_page);
3635 $footer_report = $this->run_report_footer($footer_report);
3636
3637 $content = str_replace('[rpt:haeder_report]', $haeder_report, $content);
3638 $content = str_replace('[rpt:haeder_page]', $haeder_page, $content);
3639 $content = str_replace('[rpt:footer_page]', $footer_page, $content);
3640 $content = str_replace('[rpt:footer_report]', $footer_report, $content);
3641 }
3642
3643 $norep_ids = '';
3644 $js = $this->_js;
3645
3646 if (is_array($js)) {
3647 $count = count($js);
3648
3649 if ($count) {
3650 foreach ($js as $javascript) {
3651 $javascript = str_replace('{i}', $i, $javascript);
3652 $norep_ids .= dbx()->norep("\n" . '<script type="text/javascript">' . $javascript . '</script>' . "\n", $i);
3653 }
3654 }
3655 }
3656
3657 $content = str_replace('{i}', $i, $content);
3658
3659 if ($norep_ids) {
3660 $norep = '<div class="norep">' . $norep_ids . '</div>';
3661 }
3662
3663 $content = str_replace('[dbx:js]', $norep, $content);
3664 $content = str_replace('[dbx:pagination]', '', $content);
3665 $content = str_replace('{rpt:pages}', $this->_current_page, $content);
3667
3668 return $this->add_editor_markers($content);
3669 }
3670}
3671
3672?>
$table['server']
Definition .dd.php:6
get_activ_id($key='')
Liefert die aktive Remember-ID des aktuellen DD-Kontexts.
$_dbx_action
Aktive DBX-Aktion.
$_fld_id
Primärschlüsselfeld.
$_action
Formular-Action.
$_dbx_modul
Aktives Modul.
php_date_usr($value)
Wandelt Datumswerte in deutsches Format um.
add_editor_markers(string $content)
Fuegt passende Editor-Marker um den gerenderten Formularinhalt.
store_sysdata()
Speichert Sysdata des Formulars.
merge_fld_data($content, $i=0)
Fügt Felder in den Template-Inhalt ein.
$_dbx_work
Optionaler Work-Kontext.
ensureFormHelpBar(string $content)
Ergaenzt bei aelteren Formular-Templates ohne eigene Leiste eine kompakte Standardleiste.
merge_tpl_data($tpl, $i=0)
Führt grundlegende Form-Replaces in Templates aus.
format_fd_message(string $key, array $values=array(), string $default='')
Liefert eine FD-Meldung und ersetzt benannte Platzhalter.
replaces($content, $replaces=null)
Wendet dbxForm-Replacements auf einen beliebigen Inhalt an.
get_tpl($tpl, $data='', $type='htm', $i=0)
Wrapper auf dbxTPL->get_tpl().
get_form_msg($mode, $msg='')
Gibt die Formular-Infobox zurück.
forward_init($fid, $tpl='')
Initialisiert den Form-Kontext.
$oDB
Zentraler DB-/DD-Service.
add_obj($obj, $tpl, $data='', $data2='')
Fügt ein {obj:*}-Objekt hinzu.
merge_obj($content, $i=0)
Ersetzt {obj:*}-Platzhalter.
add_editor_file(string $kind, string $file)
Registriert eine genutzte FD-/DD-/Class-Datei fuer Editor-Marker.
_forward_clear()
Setzt den internen Formularzustand zurück.
get_fd_message(string $key, string $default='')
Liefert eine Meldung aus der aktuell geladenen FD.
get_dd(string $dd, string $fld, string $var)
Liest einen Feldwert oder das ganze Feld aus einer DD-/FD-Quelle.
php_datetime_usr($value)
Wandelt Datums-/Zeitwerte in deutsches Format um.
errors()
Gibt die Anzahl der Fehler zurück.
add_rep($key, $val)
Fügt einen allgemeinen Replace-Wert hinzu.
add_flds($dd='fd::')
Fügt alle Felder der aktiven DD-/FD-Felddefinitionsquelle hinzu.
set_callback_id(string $id)
Setzt den Namenspraefix fuer konventionelle Callback-Methoden.
Definition dbxKernel.php:96
set_callback(string $event, string $callback)
Ordnet einem Event einen konkreten Methodennamen zu.
callback(string $event, mixed $value)
Fuehrt einen Callback aus und gibt dessen Rueckgabewert zurueck.
$_options_rrows
Seitenlängenoptionen.
$_multi_page_select
Multi-Select seitenübergreifend.
$_options_rdesc
ASC/DESC Optionen.
get_count_selects()
Liefert die Anzahl aktuell selektierter Zeilen.
$_haeder_next_page
Header für Folgeseiten.
get_visible_multi_select_ids()
Liefert die aktuell im Report sichtbaren Select-IDs.
run_footer($content)
$_rpt_format
Feldformatierungen.
$_pages
Pagination aktiv.
get_multi_selects()
Liest die aktuelle Mehrfachauswahl.
$_footer_page
Seiten-Footer.
buildReportFormMsgHtml()
Baut die sichtbare Report-Formularmeldung (leer wenn nicht gesetzt).
resolveReportMsgText($msg)
Editor-Platzhalter (form_msg_info#) im Live-Betrieb als leer behandeln.
send_multi_select_json_response(array $visibleIds=array(), $dbx_do='')
Sendet einen JSON-Response für Multi-Select-AJAX.
add_action($obj, $tpl, $action='', $data='')
Registriert Report-Aktionen und baut Footer-Select-Metadaten auf.
$_create_row_undo
Zeilen-Undo aktiv.
$_delete_tab_dd
DD der Tabelle, die über {db:delete_tab} geleert werden darf.
$_grid_cols
Grid-Spalten-Definition.
set_style_haeder($key, $style)
render_table_row_data_columns(array $record, array $auto_flds, $fld_id, $defaultClass='auto-fld')
Rendert die automatischen Body-Datenspalten.
applyReportCountReplaces($content)
Entfernt unbenutzte Report-Bar-Feldslots ({obj:...} ohne Felddefinition).
render_table_row_action_block(array $record)
Rendert den zentralen Row-Buttonblock.
enable_delete_tab($dd, $label=null)
Aktiviert den Template-Platzhalter {db:delete_tab}.
$_haeder_page
Seiten-Header.
$_grid_export_url
Export-URL.
$_grid_headerfilter
Headerfilter für Grid.
split_tpl($report)
$_footer_next_page
Footer für Folgeseiten.
$_current_report_ln
Aktuelle Report-Zeile insgesamt.
$_rflds
Report-Feldliste.
clear()
Löscht den kompletten Report-Zustand und setzt saubere Defaultwerte.
run_page_haeder($content)
merge_db_placeholders($content)
Ersetzt DB-spezifische Report-Platzhalter.
$_options_rselect
Auswahloptionen.
$_page_break
Seitenumbruch-Markup.
get_report_body()
Erzeugt den HTML-Body für klassische Reportmodi.
rpt_format($key, $value)
Formatiert einen Reportwert anhand der Felddefinition.
get_visible_multi_select_state(array $visibleIds=array())
Liefert den Multi-Select-Zustand relativ zu den aktuell sichtbaren IDs.
$_count_selects
Caching für Anzahl ausgewählter Datensätze.
del_multi_select_ids(array $ids)
Entfernt mehrere IDs aus der Auswahl.
$_report_multi_actions
Registrierte Report-Mehrfachaktionen fuer Footer-Select.
$_create_row_show
Zeilen-Show aktiv.
$_add_action
Zusatzparameter an Row-Aktionen.
ensure_report_select_feature($content)
Aktiviert die Report-JS-Lib automatisch fuer Reports mit Row-Checkboxen.
get_record_rid($record, $default=-1)
Liefert die sauber ermittelte Record-ID eines Datensatzes.
apply_multi_delete_result(array $result)
Setzt Erfolgs-/Fehlermeldung nach Mehrfach-Loeschung.
$_auto_flds
Automatische Feldliste.
check_is_multiselect($rid)
Prüft, ob eine Zeile aktuell im Multi-Select aktiv ist.
init($fid, $tpl='', $first_page_lines=-1, $next_page_lines=-1, $current_line=-1)
get_report_haeder($content='')
Erzeugt den Report-Header.
get_delete_tab_button()
Rendert den Button fuer {db:delete_tab}.
$_current_page_ln
Aktuelle Zeile auf aktueller Seite.
$_table_buttons
Buttons links oder rechts.
set_footer_callback(string $callback)
$_haeder_report
Report-Header außerhalb der eigentlichen Seiten.
forward_run_haeder($content)
get_class_tr($record)
$_ajax
AJAX-Linkklasse für klassische Report-Buttons.
$_grid_headersort
Headersort für Grid.
$_rwhere_placeholder
Platzhaltertext für Suchfeld.
$_class_body
Body-Klassen.
del_multi_selects($id)
Entfernt IDs aus dem Remember-basierten Multi-Select.
$_footer_report
Report-Footer außerhalb der eigentlichen Seiten.
$_record
Aktueller Datensatz im Body-Lauf.
run_haeder($content)
add_rwhere_select($rwhere)
Ergänzt eine WHERE-Bedingung um aktuell selektierte IDs.
forward_run_body($content)
forward_run_report_footer($content)
get_grid_action_url($url, $action)
Markiert und signiert einen schreibenden Grid-Endpunkt.
$_fld_haeder
Historischer Header-Name.
get_table_action_definitions()
Liefert die aktivierten Tabellen-Aktionsdefinitionen.
set_record_val(string $name, mixed $value)
set_page_footer_callback(string $callback)
get_table_row_action_data($type, array $record)
Baut das Standard-Datenarray für Row-Aktions-Templates.
$_grid_save_url
Save-URL für Grid.
set_tabel_tpl($tid, $tpl)
Überschreibt ein Tabellen-Template gezielt.
$_create_row_delete
Zeilen-Delete aktiv.
$_mode
Report-Modus: table|tpl|tabulurator.
$_create_row_import
Zeilen-Import aktiv.
$_grid_allow_insert
Insert im Grid erlaubt.
prepareReportFrameReplaces(int $i, array $options=array())
del_selected($rid=0)
Entfernt Datensätze nur aus der gemerkten Auswahl.
$_delete_tab_label_from_fd
Verwendet für die Delete-Tab-Aktion die Meldungsschlüssel der aktiven FD.
run_page_footer($content)
parse_report_action_code($action)
$_first_page_lines
Maximale Zeilen auf erster Seite.
$_current_page
Aktuelle logische Report-Seite.
$_grid_read_url
Read-URL für Grid.
$_create_row_export
Zeilen-Export aktiv.
$_report_state_flds
Interne Report-State-Werte ohne sichtbares Formularfeld.
render_table_header_select(array $auto_flds, $fld_id, $class, array $select_state)
Rendert die Header-Checkbox für die sichtbaren Rows.
set_header_callback(string $callback)
get_report_format($key)
Ermittelt die explizite oder automatische Reportformatierung.
get_report_action_url()
Liefert die Basis-Action-URL des aktuellen Reports.
$_create_row_download
Zeilen-Download aktiv.
$_grid_delete_url
Delete-URL für Grid.
$_but_pagination
Anzahl sichtbarer Pagination-Buttons.
$_grid_allow_delete
Delete im Grid erlaubt.
create_selection_fields($fd='fd::')
$_rdata_inline
Inline-Modus: Daten werden nur einmal in Body eingefügt.
$_create_sel_flds
Selektionsfelder erstellen.
run_body($content)
$_grid_schema
Schema-Name für Grid.
$_delete_tab_label
Button-Label für {db:delete_tab}.
rpt_merge_obj($content)
Fügt reportweite Platzhalter, Objekte und dbxForm-Replacements ein.
$_count_all
Gesamtanzahl ohne Report-Filter; -1 = nicht separat gesetzt.
render_report_cell_value($key, $value)
Bereitet einen Tabellenwert fuer normale Reportzellen auf.
add_grid_stats(array $stats, $ariaLabel='')
$_rrows
Datensätze pro Seite.
get_record_select_key($record)
Liefert den reportbezogenen Select-Key eines Datensatzes.
report_cell_allows_html($key)
Prueft, ob eine Reportzelle bewusst HTML ausgeben darf.
get_report_action_label($tpl)
forward_run_report_haeder($content)
$_grid_print_url
Print-URL für Grid/Shell.
get_record_val(string $name, mixed $default=null)
$_data_table
Daten-Tabellen-/Expander-Schalter.
$_grid_layout
Grid-Layout.
del_selected($dd, $rid=0)
Löscht ausgewählte Datensätze.
$_grid_synctime
Grid-Synctime.
$_footer
Interner Bereich: Footer.
$_msg_confirm_copy
Confirm-Text für Copy.
forward_run_page_footer($content)
set_report_header_callback(string $callback)
$_create_row_copy
Zeilen-Copy aktiv.
$_grid_sync_url
Sync-URL für Grid.
render_simple_table_tpl($file, array $data)
$_rdata
Report-Daten.
$_table_col_count
Anzahl sichtbarer Tabellen-Spalten.
get_report_pages()
Erzeugt die Pagination des Reports.
set_page_header_callback(string $callback)
run_report_haeder($content)
cleanupReportBarSlots($content)
$_tpl_pagination
Pagination-Template.
$_msg_confirm_delete_tab
Confirm-Text für Tabellenleerung.
$_next_page_lines
Maximale Zeilen auf Folgeseiten.
buildReportFooterObj()
Baut Footer mit Aktions-Select und Schnellaktionen.
set_class_haeder($key, $class='')
$_table_render_tpl_cache
vorbereitete einfache Tabellen-Templates
set_multi_select($rid)
Fügt eine ID oder alle aktuell geladenen Reportzeilen zur Mehrfachauswahl hinzu.
set_callback_owner($owner)
Setzt ein explizites Owner-Objekt fuer Callback-Aufrufe.
$_multi_select_work
Interner Multi-Select-Arbeitsmodus.
run()
Rendert den Report mit bereits gesetzten Properties.
render_table_header_action_block()
Rendert den zentralen Header-Buttonblock.
$_tabel_tpls
Tabellen-Templates.
$_class_haeder
Header-Klassen.
$_msg_confirm_delete
Confirm-Text für Delete.
$_grid_sort_url
Sort-URL für Grid.
$_scroll_table
Scrollbare Tabelle.
add_where($mode, $select, $where='')
forward_run_footer($content)
add_rwhere_search($sql, $suchWert, $feldListe)
Ergänzt eine Such-WHERE über eine Feldliste.
forward_run_page_haeder($content)
$_body
Interner Bereich: Body.
data_rows($data, $rpos, $rrows)
set_next_record_callback(string $callback)
set_form_selects()
Verarbeitet AJAX-/Select-Aktionen für Report-Mehrfachauswahl.
$_pagelink
Pagination-Link.
set_record(array $record)
get_auto_report_format($key)
Ermittelt automatische Reportformatierung aus DD/FD-Metadaten.
delete_multi_selected_records($dd, $verify_access=1, $trace=1)
Loescht gemerkte Mehrfachauswahl Datensatz fuer Datensatz (Trace pro Zeile).
set_multi_selects($selects)
Speichert die komplette Mehrfachauswahl per Remember.
set_body_callback(string $callback)
normalize_multi_select_key($rid)
Normalisiert einen Multi-Select-Key.
$_create_row_edit
Zeilen-Edit aktiv.
set_report_footer_callback(string $callback)
$_create_row_select
Zeilen-Select aktiv.
$_grid_insert_url
Insert-URL für Grid.
$_grid_allow_edit
Edit im Grid erlaubt.
parse_multi_select_ids($raw)
Parst eine ID-Liste in ein sauberes eindeutiges Array.
$_body_inline
Inline-Body.
injectReportFooter($content)
Fuegt Report-Footer vor Tabellenende ein, falls noch kein Slot vorhanden.
$_options_rsort
Sortieroptionen.
$_auto_mode
Automatischer Ausgabemodus.
submit()
Öffentliche Submit-Abfrage.
$_style_haeder
Header-Styles.
$_rcount
Gesamtanzahl Datensätze.
del_multi_select($rid)
Entfernt eine ID oder alle IDs aus der Mehrfachauswahl.
run_report_footer($content)
$_create_row_print
Zeilen-Print aktiv.
render_table_header_data_columns(array $auto_flds, $fld_id)
Rendert die automatischen Header-Datenspalten.
$_haeder
Interner Bereich: Header.
render_table_row_select(array $record, $class)
Rendert die Row-Checkbox.
set_multi_select_ids(array $ids)
Fügt mehrere IDs zur Auswahl hinzu.
if((string)($formActionPolicy['action'] ?? '') !=='dbxAction.save'||!dbx() ->check_action_token((string)($formActionPolicy['scope'] ?? ''),(string)($formActionRoute['params']['dbx_token'] ?? ''))) $report
$messageOnlyForm _fd
$form _sys['_try_sys']
if($web->content_permalink_redirect_target() !=='') $tpl
if(!defined( 'IMG_WEBP')) define( 'IMG_WEBP'
foreach( $valid as $email) foreach($invalid as $email) $fd
exit
Definition index.php:146
DBX schema administration.
if($cinematic===''||!str_contains($cinematic, 'data-dbx-cinema')) $page