ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilTable2GUI.php
Go to the documentation of this file.
1<?php
2
26{
27 public const FILTER_TEXT = 1;
28 public const FILTER_SELECT = 2;
29 public const FILTER_DATE = 3;
30 public const FILTER_LANGUAGE = 4;
31 public const FILTER_NUMBER_RANGE = 5;
32 public const FILTER_DATE_RANGE = 6;
33 public const FILTER_DURATION_RANGE = 7;
34 public const FILTER_DATETIME_RANGE = 8;
35 public const FILTER_CHECKBOX = 9;
36 public const EXPORT_EXCEL = 1;
37 public const EXPORT_CSV = 2;
38 public const ACTION_ALL_LIMIT = 1000;
39 private \ILIAS\DI\UIServices $ui;
40 protected string $requested_nav_par2 = "";
41 protected string $requested_nav_par = "";
42 protected string $requested_nav_par1 = "";
44 protected array $selected_columns = [];
45
46 protected ilCtrl $ctrl;
47 protected ?object $parent_obj = null;
48 protected string $parent_cmd = "";
49 protected string $close_command = "";
50 private string $unique_id = "";
51 private string $headerHTML = "";
52 protected string $top_anchor = "il_table_top";
53 protected array $filters = array();
54 protected array $optional_filters = array();
55 protected string $filter_cmd = 'applyFilter';
56 protected string $reset_cmd = 'resetFilter';
57 protected int $filter_cols = 5;
58 protected bool $ext_sort = false;
59 protected bool $ext_seg = false;
60 protected string $context = "";
61
62 protected array $mi_sel_buttons = [];
63 protected bool $disable_filter_hiding = false;
64 protected bool $top_commands = true;
65 protected array $selectable_columns = array();
66 protected array $selected_column = array();
67 protected bool $show_rows_selector = true; // JF, 2014-10-27
68 protected bool $rows_selector_off = false;
69
70 protected bool $nav_determined = false;
71 protected bool $limit_determined = false;
72 protected bool $filters_determined = false;
73 protected bool $columns_determined = false;
74 protected bool $open_form_tag = true;
75 protected bool $close_form_tag = true;
76 protected array $export_formats = [];
77 protected int $export_mode = 0;
78 protected bool $print_mode = false;
79 protected bool $enable_command_for_all = false;
80 protected bool $restore_filter = false;
81 protected array $restore_filter_values = [];
82 protected bool $default_filter_visibility = false;
83 protected array $sortable_fields = array();
84 protected bool $prevent_double_submission = true;
85 protected string $row_selector_label = "";
86 protected bool $select_all_on_top = false;
87 protected array $sel_buttons = [];
88 protected string $nav_value = '';
89 protected string $noentriestext = '';
90 protected string $css_row = '';
91 protected bool $display_as_block = false;
92 protected string $description = '';
93 protected string $id = "";
94 protected bool $custom_prev_next = false;
95 protected string $reset_cmd_txt = "";
96 protected string $defaultorderfield = "";
97 protected string $defaultorderdirection = "";
98 protected array $column = [];
99 protected bool $datatable = false;
100 protected bool $num_info = false;
101 protected bool $form_multipart = false;
102 protected array $row_data = [];
103 protected string $order_field = "";
104 protected array $selected_filter = [];
105 protected string $form_action = "";
106 protected string $formname = "";
107 protected string $sort_order = "";
108 protected array $buttons = [];
109 protected array $multi = [];
110 protected array $hidden_inputs = [];
111 protected array $header_commands = [];
112 protected string $row_template = "";
113 protected string $row_template_dir = "";
114 protected string $filter_cmd_txt = "";
115 protected string $custom_prev = "";
116 protected string $custom_next = "";
117 protected ?array $raw_post_data = null;
118 protected \ilGlobalTemplateInterface $main_tpl;
119
123 public function __construct(
124 ?object $a_parent_obj,
125 string $a_parent_cmd = "",
126 string $a_template_context = ""
127 ) {
128 global $DIC;
129 $this->main_tpl = $DIC->ui()->mainTemplate();
130 $this->ui = $DIC->ui();
131
132 $this->lng = $DIC->language();
133 $this->ctrl = $DIC->ctrl();
134 $lng = $DIC->language();
135
136 if (isset($DIC["http"])) {
137 $this->table_request = new \ILIAS\Table\TableGUIRequest(
138 $DIC->http(),
139 $DIC->refinery()
140 );
141 }
142 $this->getRequestedValues();
143 parent::__construct([], false);
144 $this->unique_id = md5(uniqid('', true));
145 $this->parent_obj = $a_parent_obj;
146 $this->parent_cmd = $a_parent_cmd;
147 $this->buttons = array();
148 $this->header_commands = array();
149 $this->multi = array();
150 $this->hidden_inputs = array();
151 $this->formname = "table_" . $this->unique_id;
152 $this->tpl = new ilTemplate("tpl.table2.html", true, true, "components/ILIAS/Table");
153
154 $lng->loadLanguageModule('tbl');
155
156 if (!$a_template_context) {
157 $a_template_context = $this->getId();
158 }
159 $this->setContext($a_template_context);
160
161 // activate export mode
162 if (isset($this->table_request)) {
163 $this->export_mode = $this->table_request->getExportMode($this->prefix);
164 }
165
166 $this->determineLimit();
167 $this->setIsDataTable(true);
168 $this->setEnableNumInfo(true);
170
171 $this->raw_post_data = [];
172 if (isset($DIC["http"])) {
173 $this->raw_post_data = $DIC->http()->request()->getParsedBody();
174 }
175 }
176
177 protected function getRequestedValues(): void
178 {
179 if (is_null($this->table_request)) {
180 return;
181 }
182 $this->requested_nav_par = $this->table_request->getNavPar($this->getNavParameter());
183 $this->requested_nav_par1 = $this->table_request->getNavPar($this->getNavParameter(), 1);
184 $this->requested_nav_par2 = $this->table_request->getNavPar($this->getNavParameter(), 2);
185 }
186
187 public function setOpenFormTag(bool $a_val): void
188 {
189 $this->open_form_tag = $a_val;
190 }
191
192 public function getOpenFormTag(): bool
193 {
195 }
196
197 public function setCloseFormTag(bool $a_val): void
198 {
199 $this->close_form_tag = $a_val;
200 }
201
202 public function getCloseFormTag(): bool
203 {
205 }
206
207 public function determineLimit(): void
208 {
209 global $DIC;
210
211 $ilUser = null;
212 if (isset($DIC["ilUser"])) {
213 $ilUser = $DIC["ilUser"];
214 }
215
216 if ($this->limit_determined) {
217 return;
218 }
219
220 $limit = 0;
221 if (isset($this->table_request) && !is_null($this->table_request->getRows($this->prefix))) {
222 $this->storeProperty("rows", $this->table_request->getRows($this->prefix));
223 $limit = $this->table_request->getRows($this->prefix) ?? 0;
224 $this->resetOffset();
225 }
226
227 if ($limit == 0) {
228 $rows = (int) $this->loadProperty("rows");
229 if ($rows > 0) {
230 $limit = $rows;
231 } else {
232 $limit = 40;
233 }
234 }
235
236 $this->setLimit($limit);
237 $this->limit_determined = true;
238 }
239
244 public function getSelectableColumns(): array
245 {
246 return [];
247 }
248
249 public function determineSelectedColumns(): void
250 {
251 if ($this->columns_determined) {
252 return;
253 }
254
255 $old_sel = $this->loadProperty("selfields");
256 $sel_fields = [];
257 $stored = false;
258 if ($old_sel != "") {
259 $sel_fields = unserialize((string) $old_sel);
260 $stored = true;
261 }
262 if (!is_array($sel_fields)) {
263 $stored = false;
264 $sel_fields = array();
265 }
266
267 $this->selected_columns = array();
268 $set = false;
269
270 $fsh = false;
271 $fs = [];
272 if (isset($this->table_request)) {
273 $fs = $this->table_request->getFS($this->getId());
274 $fsh = $this->table_request->getFSH($this->getId());
275 }
276
277 foreach ($this->getSelectableColumns() as $k => $c) {
278 $this->selected_column[$k] = false;
279
280 $new_column = (!isset($sel_fields[$k]));
281
282 if ($fsh) {
283 $set = true;
284 if (in_array($k, $fs)) {
285 $this->selected_column[$k] = true;
286 }
287 } elseif ($stored && !$new_column) { // take stored values
288 $this->selected_column[$k] = $sel_fields[$k];
289 } else { // take default values
290 if ($new_column) {
291 $set = true;
292 }
293 if (isset($c["default"]) && $c["default"]) {
294 $this->selected_column[$k] = true;
295 }
296 }
297
298 // Optional filters
299 $ff = [];
300 if (isset($this->table_request)) {
301 $ff = $this->table_request->getFF($this->getId());
302 }
303 if (count($ff) > 0) {
304 $set = true;
305 if (in_array($k, $ff)) {
306 $this->selected_column[$k] = true;
307 }
308 }
309 }
310
311 if ($old_sel != serialize($this->selected_column) && $set) {
312 $this->storeProperty("selfields", serialize($this->selected_column));
313 }
314
315 $this->columns_determined = true;
316 }
317
318 public function isColumnSelected(string $col): bool
319 {
320 return $this->selected_column[$col] ?? false;
321 }
322
323 public function getSelectedColumns(): array
324 {
325 $scol = array();
326 foreach ($this->selected_column as $k => $v) {
327 if ($v) {
328 $scol[$k] = $k;
329 }
330 }
331 return $scol;
332 }
333
334 public function executeCommand(): bool
335 {
336 $ilCtrl = $this->ctrl;
337
338 $next_class = $ilCtrl->getNextClass($this);
339
340 switch ($next_class) {
341 case 'ilformpropertydispatchgui':
342 $form_prop_dispatch = new ilFormPropertyDispatchGUI();
343 $this->initFilter();
345 $item = $this->getFilterItemByPostVar(
346 $this->table_request->getPostVar()
347 );
348 $form_prop_dispatch->setItem($item);
349 return (bool) $ilCtrl->forwardCommand($form_prop_dispatch);
350 }
351 return false;
352 }
353
354 public function resetOffset(bool $a_in_determination = false): void
355 {
356 if (!$this->nav_determined && !$a_in_determination) {
358 }
359 $this->nav_value = $this->getOrderField() . ":" . $this->getOrderDirection() . ":0";
360 $this->requested_nav_par = $this->requested_nav_par1 = $this->nav_value;
361 $this->setOffset(0);
362 }
363
364 public function initFilter(): void
365 {
366 }
367
368 public function getParentObject(): ?object
369 {
370 return $this->parent_obj;
371 }
372
373 public function getParentCmd(): string
374 {
375 return $this->parent_cmd;
376 }
377
378 public function setTopAnchor(string $a_val): void
379 {
380 $this->top_anchor = $a_val;
381 }
382
383 public function getTopAnchor(): string
384 {
385 return $this->top_anchor;
386 }
387
388 public function setNoEntriesText(string $a_text): void
389 {
390 $this->noentriestext = $a_text;
391 }
392
393 public function getNoEntriesText(): string
394 {
396 }
397
398 public function setIsDataTable(bool $a_val): void
399 {
400 $this->datatable = $a_val;
401 }
402
403 public function getIsDataTable(): bool
404 {
405 return $this->datatable;
406 }
407
408 public function setEnableTitle(bool $a_enabletitle): void
409 {
410 $this->enabled["title"] = $a_enabletitle;
411 }
412
413 public function getEnableTitle(): bool
414 {
415 return $this->enabled["title"];
416 }
417
418 public function setEnableHeader(bool $a_enableheader): void
419 {
420 $this->enabled["header"] = $a_enableheader;
421 }
422
423 public function getEnableHeader(): bool
424 {
425 return $this->enabled["header"];
426 }
427
428 public function setEnableNumInfo(bool $a_val): void
429 {
430 $this->num_info = $a_val;
431 }
432
433 public function getEnableNumInfo(): bool
434 {
435 return $this->num_info;
436 }
437
438 final public function setTitle(
439 string $a_title,
440 string $a_icon = "",
441 string $a_icon_alt = ""
442 ): void {
443 parent::setTitle($a_title, $a_icon, $a_icon_alt);
444 }
445
446 public function setDescription(string $a_val): void
447 {
448 $this->description = $a_val;
449 }
450
451 public function getDescription(): string
452 {
453 return $this->description;
454 }
455
456 public function setOrderField(string $a_order_field): void
457 {
458 $this->order_field = $a_order_field;
459 }
460
461 public function getOrderField(): string
462 {
463 return $this->order_field;
464 }
465
466 final public function setData(array $a_data): void
467 {
468 $this->row_data = $a_data;
469 }
470
471 final public function getData(): array
472 {
473 return $this->row_data;
474 }
475
476 final public function dataExists(): bool
477 {
478 return count($this->row_data) > 0;
479 }
480
481 final public function setPrefix(string $a_prefix): void
482 {
483 $this->prefix = $a_prefix;
484 $this->getRequestedValues();
485 }
486
487 final public function getPrefix(): string
488 {
489 return $this->prefix;
490 }
491
492 final public function addFilterItem(
493 ilTableFilterItem $a_input_item,
494 bool $a_optional = false
495 ): void {
496 $a_input_item->setParentTable($this);
497 if (!$a_optional) {
498 $this->filters[] = $a_input_item;
499 } else {
500 $this->optional_filters[] = $a_input_item;
501 }
502
503 // restore filter values (from stored view)
504 if ($this->restore_filter) {
505 if (array_key_exists($a_input_item->getFieldId(), $this->restore_filter_values ?? [])) {
506 $this->setFilterValue($a_input_item, $this->restore_filter_values[$a_input_item->getFieldId()]);
507 } else {
508 $this->setFilterValue($a_input_item, null); // #14949
509 }
510 }
511 }
512
517 public function addFilterItemByMetaType(
518 string $id,
519 int $type = self::FILTER_TEXT,
520 bool $a_optional = false,
521 string $caption = ""
523 global $DIC;
524
525 $lng = $DIC->language(); // constructor may not be called here, if initFilter is being called in subclasses before parent::__construct
526
527 if (!$caption) {
528 $caption = $lng->txt($id);
529 }
530
531 switch ($type) {
532 case self::FILTER_CHECKBOX:
533 $item = new ilCheckboxInputGUI($caption, $id);
534 break;
535
536 case self::FILTER_SELECT:
537 $item = new ilSelectInputGUI($caption, $id);
538 break;
539
540 case self::FILTER_DATE:
541 $item = new ilDateTimeInputGUI($caption, $id);
542 break;
543
544 case self::FILTER_TEXT:
545 $item = new ilTextInputGUI($caption, $id);
546 $item->setMaxLength(64);
547 $item->setSize(20);
548 // $item->setSubmitFormOnEnter(true);
549 break;
550
551 case self::FILTER_LANGUAGE:
552 $lng->loadLanguageModule("meta");
553 $item = new ilSelectInputGUI($caption, $id);
554 $options = array("" => $lng->txt("trac_all"));
555 foreach ($lng->getInstalledLanguages() as $lang_key) {
556 $options[$lang_key] = $lng->txt("meta_l_" . $lang_key);
557 }
558 $item->setOptions($options);
559 break;
560
561 case self::FILTER_NUMBER_RANGE:
562 $item = new ilCombinationInputGUI($caption, $id);
563 $combi_item = new ilNumberInputGUI("", $id . "_from");
564 $combi_item->setSize(5);
565 $item->addCombinationItem("from", $combi_item, $lng->txt("from"));
566 $combi_item = new ilNumberInputGUI("", $id . "_to");
567 $combi_item->setSize(5);
568 $item->addCombinationItem("to", $combi_item, $lng->txt("to"));
569 $item->setComparisonMode(ilCombinationInputGUI::COMPARISON_ASCENDING);
570 //$item->setMaxLength(7);
571 //$item->setSize(20);
572 break;
573
574 case self::FILTER_DATE_RANGE:
575 $item = new ilCombinationInputGUI($caption, $id);
576 $combi_item = new ilDateTimeInputGUI("", $id . "_from");
577 $item->addCombinationItem("from", $combi_item, $lng->txt("from"));
578 $combi_item = new ilDateTimeInputGUI("", $id . "_to");
579 $item->addCombinationItem("to", $combi_item, $lng->txt("to"));
580 $item->setComparisonMode(ilCombinationInputGUI::COMPARISON_ASCENDING);
581 break;
582
583 case self::FILTER_DATETIME_RANGE:
584 $item = new ilCombinationInputGUI($caption, $id);
585 $combi_item = new ilDateTimeInputGUI("", $id . "_from");
586 $combi_item->setShowTime(true);
587 $item->addCombinationItem("from", $combi_item, $lng->txt("from"));
588 $combi_item = new ilDateTimeInputGUI("", $id . "_to");
589 $combi_item->setShowTime(true);
590 $item->addCombinationItem("to", $combi_item, $lng->txt("to"));
591 $item->setComparisonMode(ilCombinationInputGUI::COMPARISON_ASCENDING);
592 break;
593
594 case self::FILTER_DURATION_RANGE:
595 $lng->loadLanguageModule("form");
596 $item = new ilCombinationInputGUI($caption, $id);
597 $combi_item = new ilDurationInputGUI("", $id . "_from");
598 $combi_item->setShowMonths(false);
599 $combi_item->setShowDays(true);
600 $combi_item->setShowSeconds(true);
601 $item->addCombinationItem("from", $combi_item, $lng->txt("from"));
602 $combi_item = new ilDurationInputGUI("", $id . "_to");
603 $combi_item->setShowMonths(false);
604 $combi_item->setShowDays(true);
605 $combi_item->setShowSeconds(true);
606 $item->addCombinationItem("to", $combi_item, $lng->txt("to"));
607 $item->setComparisonMode(ilCombinationInputGUI::COMPARISON_ASCENDING);
608 break;
609
610 default:
611 return null;
612 }
613
614 $this->addFilterItem($item, $a_optional);
615 $item->readFromSession();
616 return $item;
617 }
618
619 final public function getFilterItems(bool $a_optionals = false): array
620 {
621 if (!$a_optionals) {
622 return $this->filters;
623 }
624 return $this->optional_filters;
625 }
626
627 final public function getFilterItemByPostVar(string $a_post_var): ?ilTableFilterItem
628 {
629 foreach ($this->getFilterItems() as $item) {
630 if ($item->getPostVar() == $a_post_var) {
631 return $item;
632 }
633 }
634 foreach ($this->getFilterItems(true) as $item) {
635 if ($item->getPostVar() == $a_post_var) {
636 return $item;
637 }
638 }
639 return null;
640 }
641
642 public function setFilterCols(int $a_val): void
643 {
644 $this->filter_cols = $a_val;
645 }
646
647 public function getFilterCols(): int
648 {
649 return $this->filter_cols;
650 }
651
652 public function setDisableFilterHiding(bool $a_val = true): void
653 {
654 $this->disable_filter_hiding = $a_val;
655 }
656
657 public function getDisableFilterHiding(): bool
658 {
659 return $this->disable_filter_hiding;
660 }
661
665 public function isFilterSelected(string $a_col): bool
666 {
667 return (bool) $this->selected_filter[$a_col];
668 }
669
670 public function getSelectedFilters(): array
671 {
672 $sfil = array();
673 foreach ($this->selected_filter as $k => $v) {
674 if ($v) {
675 $sfil[$k] = $k;
676 }
677 }
678 return $sfil;
679 }
680
681 public function determineSelectedFilters(): void
682 {
683 if ($this->filters_determined) {
684 return;
685 }
686
687 $old_sel = $this->loadProperty("selfilters");
688 $stored = false;
689 $sel_filters = null;
690 if ($old_sel != "") {
691 $sel_filters =
692 unserialize((string) $old_sel);
693 $stored = true;
694 }
695 if (!is_array($sel_filters)) {
696 $stored = false;
697 $sel_filters = array();
698 }
699
700 $this->selected_filter = array();
701 $set = false;
702 foreach ($this->getFilterItems(true) as $item) {
703 $k = $item->getPostVar();
704
705 $this->selected_filter[$k] = false;
706
707 if ($this->table_request->getFSF($this->getId())) {
708 $set = true;
709 if (in_array($k, $this->table_request->getFF($this->getId()))) {
710 $this->selected_filter[$k] = true;
711 } else {
712 $item->setValue(null);
713 $item->writeToSession();
714 }
715 } elseif ($stored) { // take stored values
716 $this->selected_filter[$k] = $sel_filters[$k] ?? "";
717 }
718 }
719
720 if ($old_sel != serialize($this->selected_filter) && $set) {
721 $this->storeProperty("selfilters", serialize($this->selected_filter));
722 }
723
724 $this->filters_determined = true;
725 }
726
727 public function setCustomPreviousNext(
728 string $a_prev_link,
729 string $a_next_link
730 ): void {
731 $this->custom_prev_next = true;
732 $this->custom_prev = $a_prev_link;
733 $this->custom_next = $a_next_link;
734 }
735
736 final public function setFormAction(
737 string $a_form_action,
738 bool $a_multipart = false
739 ): void {
740 $this->form_action = $a_form_action;
741 $this->form_multipart = $a_multipart;
742 }
743
744 final public function getFormAction(): string
745 {
746 return $this->form_action;
747 }
748
749 public function setFormName(string $a_name = ""): void
750 {
751 $this->formname = $a_name;
752 }
753
754 public function getFormName(): string
755 {
756 return $this->formname;
757 }
758
759 public function setId(string $a_val): void
760 {
761 $this->id = $a_val;
762 if ($this->getPrefix() == "") {
763 $this->setPrefix($a_val);
764 }
765 if (strlen($this->id) > 30) {
766 throw new ilException("Table ID to long (max. 30 char): " . $this->id);
767 }
768 }
769
770 public function getId(): string
771 {
772 return $this->id;
773 }
774
775 public function setDisplayAsBlock(bool $a_val): void
776 {
777 $this->display_as_block = $a_val;
778 }
779
780 public function getDisplayAsBlock(): bool
781 {
782 return $this->display_as_block;
783 }
784
785 public function setSelectAllCheckbox(
786 string $a_select_all_checkbox,
787 bool $a_select_all_on_top = false
788 ): void {
789 $this->select_all_checkbox = $a_select_all_checkbox;
790 $this->select_all_on_top = $a_select_all_on_top;
791 }
792
793 public function setExternalSorting(bool $a_val): void
794 {
795 $this->ext_sort = $a_val;
796 }
797
798 public function getExternalSorting(): bool
799 {
800 return $this->ext_sort;
801 }
802
803 public function setFilterCommand(
804 string $a_val,
805 string $a_caption = ""
806 ): void {
807 $this->filter_cmd = $a_val;
808 $this->filter_cmd_txt = $a_caption;
809 }
810
811 public function getFilterCommand(): string
812 {
813 return $this->filter_cmd;
814 }
815
816 public function setResetCommand(
817 string $a_val,
818 string $a_caption = ""
819 ): void {
820 $this->reset_cmd = $a_val;
821 $this->reset_cmd_txt = $a_caption;
822 }
823
824 public function getResetCommand(): string
825 {
826 return $this->reset_cmd;
827 }
828
829 public function setExternalSegmentation(bool $a_val): void
830 {
831 $this->ext_seg = $a_val;
832 }
833
834 public function getExternalSegmentation(): bool
835 {
836 return $this->ext_seg;
837 }
838
844 final public function setRowTemplate(string $a_template, string $a_template_dir = ""): void
845 {
846 $this->row_template = $a_template;
847 $this->row_template_dir = $a_template_dir;
848 }
849
850 public function setDefaultOrderField(string $a_defaultorderfield): void
851 {
852 $this->defaultorderfield = $a_defaultorderfield;
853 }
854
855 public function getDefaultOrderField(): string
856 {
857 return $this->defaultorderfield;
858 }
859
860
861 public function setDefaultOrderDirection(string $a_defaultorderdirection): void
862 {
863 $this->defaultorderdirection = $a_defaultorderdirection;
864 }
865
866 public function getDefaultOrderDirection(): string
867 {
868 return $this->defaultorderdirection;
869 }
870
871 public function setDefaultFilterVisiblity(bool $a_status): void
872 {
873 $this->default_filter_visibility = $a_status;
874 }
875
876 public function getDefaultFilterVisibility(): bool
877 {
878 return $this->default_filter_visibility;
879 }
880
881 public function clearCommandButtons(): void
882 {
883 $this->buttons = array();
884 }
885
886 public function addCommandButton(
887 string $a_cmd,
888 string $a_text,
889 string $a_onclick = '',
890 string $a_id = "",
891 string $a_class = ""
892 ): void {
893 $this->buttons[] = array("cmd" => $a_cmd, "text" => $a_text, 'onclick' => $a_onclick,
894 "id" => $a_id, "class" => $a_class);
895 }
896
897 public function addCommandButtonInstance(ilButtonBase $a_button): void
898 {
899 $this->buttons[] = $a_button;
900 }
901
911 string $a_sel_var,
912 array $a_options,
913 string $a_cmd,
914 string $a_text,
915 string $a_default_selection = ''
916 ): void {
917 $this->mi_sel_buttons[] = array("sel_var" => $a_sel_var, "options" => $a_options, "selected" => $a_default_selection, "cmd" => $a_cmd, "text" => $a_text);
918 $this->addHiddenInput("cmd_sv[" . $a_cmd . "]", $a_sel_var);
919 }
920
921 public function setCloseCommand(string $a_link): void
922 {
923 $this->close_command = $a_link;
924 }
925
926 public function addMultiCommand(string $a_cmd, string $a_text): void
927 {
928 $this->multi[] = array("cmd" => $a_cmd, "text" => $a_text);
929 }
930
931 public function addHiddenInput(string $a_name, string $a_value): void
932 {
933 $this->hidden_inputs[] = array("name" => $a_name, "value" => $a_value);
934 }
935
936 public function addHeaderCommand(
937 string $a_href,
938 string $a_text,
939 string $a_target = "",
940 string $a_img = ""
941 ): void {
942 $this->header_commands[] = array("href" => $a_href, "text" => $a_text,
943 "target" => $a_target, "img" => $a_img);
944 }
945
946 public function setTopCommands(bool $a_val): void
947 {
948 $this->top_commands = $a_val;
949 }
950
951 public function getTopCommands(): bool
952 {
953 return $this->top_commands;
954 }
955
956 final public function addColumn(
957 string $a_text,
958 string $a_sort_field = "",
959 string $a_width = "",
960 bool $a_is_checkbox_action_column = false,
961 string $a_class = "",
962 string $a_tooltip = "",
963 bool $a_tooltip_with_html = false
964 ): void {
965 $this->column[] = array(
966 "text" => $a_text,
967 "sort_field" => $a_sort_field,
968 "width" => $a_width,
969 "is_checkbox_action_column" => $a_is_checkbox_action_column,
970 "class" => $a_class,
971 "tooltip" => $a_tooltip,
972 "tooltip_html" => $a_tooltip_with_html
973 );
974 if ($a_sort_field != "") {
975 $this->sortable_fields[] = $a_sort_field;
976 }
977 $this->column_count = count($this->column);
978 }
979
980
981 final public function getNavParameter(): string
982 {
983 return $this->prefix . "_table_nav";
984 }
985
986 public function setOrderLink(string $key, string $order_dir): void
987 {
988 global $DIC;
989
990 $ilUser = $DIC->user();
991
992 $ilCtrl = $this->ctrl;
993
994 $hash = "";
995
996 $old = $this->requested_nav_par ?? '';
997
998 // set order link
999 $ilCtrl->setParameter(
1000 $this->parent_obj,
1001 $this->getNavParameter(),
1002 urlencode($key) . ":" . $order_dir . ":" . $this->offset
1003 );
1004 $this->tpl->setVariable(
1005 "TBL_ORDER_LINK",
1006 $ilCtrl->getLinkTarget($this->parent_obj, $this->parent_cmd) . $hash
1007 );
1008
1009 // set old value of nav variable
1010 $ilCtrl->setParameter(
1011 $this->parent_obj,
1012 $this->getNavParameter(),
1013 $old
1014 );
1015 }
1016
1017 public function fillHeader(): void
1018 {
1019 $lng = $this->lng;
1020
1021 $allcolumnswithwidth = true;
1022 foreach ($this->column as $idx => $column) {
1023 if (!strlen($column["width"])) {
1024 $allcolumnswithwidth = false;
1025 } elseif ($column["width"] == "1") {
1026 // IE does not like 1 but seems to work with 1%
1027 $this->column[$idx]["width"] = "1%";
1028 }
1029 }
1030 if ($allcolumnswithwidth) {
1031 foreach ($this->column as $column) {
1032 $this->tpl->setCurrentBlock("tbl_colgroup_column");
1033 $width = (is_numeric($column["width"]))
1034 ? $column["width"] . "px"
1035 : $column["width"];
1036 $this->tpl->setVariable("COLGROUP_COLUMN_WIDTH", " style=\"width:" . $width . "\"");
1037 $this->tpl->parseCurrentBlock();
1038 }
1039 }
1040 $ccnt = 0;
1041 foreach ($this->column as $column) {
1042 $ccnt++;
1043
1044 if ($column['is_checkbox_action_column'] && $this->select_all_on_top) {
1045 $this->tpl->setCurrentBlock('tbl_header_top_select_all');
1046 $this->tpl->setVariable("HEAD_SELECT_ALL_TXT_SELECT_ALL", $lng->txt("select_all"));
1047 $this->tpl->setVariable("HEAD_SELECT_ALL_CHECKBOX_NAME", $this->getSelectAllCheckbox());
1048 $this->tpl->setVariable("HEAD_SELECT_ALL_FORM_NAME", $this->getFormName());
1049 $this->tpl->setVariable("HEAD_CHECKBOXNAME", "chb_select_all_" . $this->unique_id . '_top');
1050 $this->tpl->parseCurrentBlock();
1051 continue;
1052 }
1053
1054 if ($column['is_checkbox_action_column'] && !$this->select_all_on_top) {
1055 $this->tpl->setCurrentBlock('tbl_header_top_select_column');
1056 if ($column["width"] != "") {
1057 $width = (is_numeric($column["width"]))
1058 ? $column["width"] . "px"
1059 : $column["width"];
1060 $this->tpl->setVariable("TBL_COLUMN_WIDTH", " style=\"width:" . $width . "\"");
1061 }
1062 $this->tpl->parseCurrentBlock();
1063 continue;
1064 }
1065
1066 if (
1067 !$this->enabled["sort"] ||
1068 (($column["sort_field"] == "") &&
1069 !($column["is_checkbox_action_column"] && $this->select_all_on_top))
1070 ) {
1071 $this->tpl->setCurrentBlock("tbl_header_no_link");
1072 if ($column["width"] != "") {
1073 $width = (is_numeric($column["width"]))
1074 ? $column["width"] . "px"
1075 : $column["width"];
1076 $this->tpl->setVariable("TBL_COLUMN_WIDTH_NO_LINK", " style=\"width:" . $width . "\"");
1077 }
1078 if ($column["class"] != "") {
1079 $this->tpl->setVariable("TBL_COLUMN_CLASS_NO_LINK", " class=\"" . $column["class"] . "\"");
1080 }
1081 if (!$column["is_checkbox_action_column"]) {
1082 $this->tpl->setVariable(
1083 "TBL_HEADER_CELL_NO_LINK",
1084 $column["text"]
1085 );
1086 } else {
1087 $this->tpl->setVariable(
1088 "TBL_HEADER_CELL_NO_LINK",
1089 ilUtil::img(ilUtil::getImagePath("media/spacer.png"), $lng->txt("action"))
1090 );
1091 }
1092 $this->tpl->setVariable("HEAD_CELL_NL_ID", "thc_" . $this->getId() . "_" . $ccnt);
1093 if ($column["class"] != "") {
1094 $this->tpl->setVariable("TBL_HEADER_CLASS", " " . $column["class"]);
1095 }
1096 $this->tpl->parseCurrentBlock();
1097 $this->tpl->touchBlock("tbl_header_th");
1098 continue;
1099 }
1100 if (($column["sort_field"] == $this->order_field) && ($this->order_direction != "")) {
1101 $this->tpl->setCurrentBlock("tbl_order_image");
1102 if ($this->order_direction === "asc") {
1103 $this->tpl->setVariable("ORDER_CLASS", "glyphicon glyphicon-arrow-up");
1104 $this->tpl->setVariable("ORDER_TXT", $this->lng->txt("sorting_asc"));
1105 } else {
1106 $this->tpl->setVariable("ORDER_CLASS", "glyphicon glyphicon-arrow-down");
1107 $this->tpl->setVariable("ORDER_TXT", $this->lng->txt("sorting_desc"));
1108 }
1109 $this->tpl->setVariable("IMG_ORDER_ALT", $this->lng->txt("change_sort_direction"));
1110 $this->tpl->parseCurrentBlock();
1111 }
1112
1113 $this->tpl->setCurrentBlock("tbl_header_cell");
1114 $this->tpl->setVariable("TBL_HEADER_CELL", $column["text"]);
1115 $this->tpl->setVariable("HEAD_CELL_ID", "thc_" . $this->getId() . "_" . $ccnt);
1116
1117 // only set width if a value is given for that column
1118 if ($column["width"] != "") {
1119 $width = (is_numeric($column["width"]))
1120 ? $column["width"] . "px"
1121 : $column["width"];
1122 $this->tpl->setVariable("TBL_COLUMN_WIDTH", " style=\"width:" . $width . "\"");
1123 }
1124 if ($column["class"] != "") {
1125 $this->tpl->setVariable("TBL_COLUMN_CLASS", " class=\"" . $column["class"] . "\"");
1126 }
1127
1128 $lng_sort_column = $this->lng->txt("sort_by_this_column");
1129 $this->tpl->setVariable("TBL_ORDER_ALT", $lng_sort_column);
1130
1131 $order_dir = "asc";
1132
1133 if ($column["sort_field"] == $this->order_field) {
1134 $order_dir = $this->sort_order;
1135
1136 if ($order_dir === "asc") {
1137 $lng_change_sort = $this->lng->txt("sort_ascending_long");
1138 } else {
1139 $lng_change_sort = $this->lng->txt("sort_descending_long");
1140 }
1141 $this->tpl->setVariable("TBL_ORDER_ALT", $lng_change_sort);
1142 }
1143
1144 if ($column["class"] != "") {
1145 $this->tpl->setVariable("TBL_HEADER_CLASS", " " . $column["class"]);
1146 }
1147 $this->setOrderLink($column["sort_field"], $order_dir);
1148 $this->tpl->parseCurrentBlock();
1149 $this->tpl->touchBlock("tbl_header_th");
1150 }
1151
1152 $this->tpl->setCurrentBlock("tbl_header");
1153 $this->tpl->parseCurrentBlock();
1154 }
1155
1159 protected function prepareOutput(): void
1160 {
1161 }
1162
1163 public function determineOffsetAndOrder(bool $a_omit_offset = false): void
1164 {
1165 global $DIC;
1166
1167 $ilUser = null;
1168 if (isset($DIC["ilUser"])) {
1169 $ilUser = $DIC["ilUser"];
1170 }
1171
1172 if ($this->nav_determined) {
1173 return;
1174 }
1175
1176 if ($this->requested_nav_par1 != "") {
1177 if ($this->requested_nav_par1 != ($this->requested_nav_par ?? "")) {
1178 $this->nav_value = $this->requested_nav_par1;
1179 } elseif (
1180 $this->requested_nav_par2 != "" &&
1181 $this->requested_nav_par2 != $this->requested_nav_par
1182 ) {
1183 $this->nav_value = $this->requested_nav_par2;
1184 }
1185 } elseif ($this->requested_nav_par != "") {
1186 $this->nav_value = $this->requested_nav_par;
1187 }
1188
1189 if ($this->nav_value == "" && $this->getId() != "" && $ilUser->getId() != ANONYMOUS_USER_ID) {
1190 $order = $this->loadProperty("order");
1191 if (in_array($order, $this->sortable_fields)) {
1192 $direction = $this->loadProperty("direction");
1193 } else {
1194 $direction = $this->getDefaultOrderDirection();
1195 }
1196 // get order and direction from db
1197 $this->nav_value =
1198 $order . ":" .
1199 $direction . ":" .
1200 $this->loadProperty("offset");
1201 }
1202 $nav = explode(":", $this->nav_value);
1203
1204 // $nav[0] is order by
1205 $req_order_field = $nav[0] ?? "";
1206 $req_order_dir = $nav[1] ?? "";
1207 $req_offset = (int) ($nav[2] ?? 0);
1208 $this->setOrderField(($req_order_field != "") ? $req_order_field : $this->getDefaultOrderField());
1209 $this->setOrderDirection(($req_order_dir != "") ? $req_order_dir : $this->getDefaultOrderDirection());
1210
1211 if (!$a_omit_offset) {
1212 // #8904: offset must be discarded when no limit is given
1213 if (!$this->getExternalSegmentation() && $this->limit_determined && $this->limit == 9999) {
1214 $this->resetOffset(true);
1215 } elseif (!$this->getExternalSegmentation() && $req_offset >= $this->max_count) {
1216 $this->resetOffset(true);
1217 } else {
1218 $this->setOffset($req_offset);
1219 }
1220 }
1221
1222 if (!$a_omit_offset) {
1223 $this->nav_determined = true;
1224 }
1225 }
1226
1227 public function storeNavParameter(): void
1228 {
1229 if ($this->getOrderField() != "") {
1230 $this->storeProperty("order", $this->getOrderField());
1231 }
1232 if ($this->getOrderDirection() != "") {
1233 $this->storeProperty("direction", $this->getOrderDirection());
1234 }
1235 if ($this->getOffset() >= 0) {
1236 $this->storeProperty("offset", (string) $this->getOffset());
1237 }
1238 }
1239
1240
1244 public function getHTML(): string
1245 {
1246 global $DIC;
1247
1248 $ilUser = null;
1249 if (isset($DIC["ilUser"])) {
1250 $ilUser = $DIC["ilUser"];
1251 }
1252
1253 $lng = $this->lng;
1254 $ilCtrl = $this->ctrl;
1255
1256
1257 if ($this->getExportMode() > 0) {
1258 $this->exportData($this->getExportMode(), true);
1259 }
1260
1261 $this->prepareOutput();
1262
1263 if (is_object($ilCtrl) && is_object($this->getParentObject()) && $this->getId() == "") {
1264 $ilCtrl->saveParameter($this->getParentObject(), $this->getNavParameter());
1265 }
1266
1267 if (!$this->getPrintMode()) {
1268 // set form action
1269 if ($this->form_action != "" && $this->getOpenFormTag()) {
1270 $hash = "";
1271
1272 if ($this->form_multipart) {
1273 $this->tpl->touchBlock("form_multipart_bl");
1274 }
1275
1276 if ($this->getPreventDoubleSubmission()) {
1277 $this->tpl->touchBlock("pdfs");
1278 }
1279
1280 $this->tpl->setCurrentBlock("tbl_form_header");
1281 $this->tpl->setVariable("FORMACTION", $this->getFormAction() . $hash);
1282 $this->tpl->setVariable("FORMNAME", $this->getFormName());
1283 $this->tpl->parseCurrentBlock();
1284 }
1285
1286 if ($this->form_action != "" && $this->getCloseFormTag()) {
1287 $this->tpl->touchBlock("tbl_form_footer");
1288 }
1289 }
1290
1291 if (!$this->enabled['content']) {
1292 return $this->render();
1293 }
1294
1295 if (!$this->getExternalSegmentation()) {
1296 $this->setMaxCount(count($this->row_data));
1297 }
1298
1299 $this->determineOffsetAndOrder();
1300
1301 $this->setFooter("tblfooter", $this->lng->txt("previous"), $this->lng->txt("next"));
1302
1303 $data = $this->getData();
1304 if ($this->dataExists()) {
1305 // sort
1306 if (!$this->getExternalSorting() && $this->enabled["sort"]) {
1308 $data,
1309 $this->getOrderField(),
1310 $this->getOrderDirection(),
1311 $this->numericOrdering($this->getOrderField())
1312 );
1313 }
1314
1315 // slice
1316 if (!$this->getExternalSegmentation()) {
1317 $data = array_slice($data, $this->getOffset(), $this->getLimit());
1318 }
1319 }
1320
1321 // fill rows
1322 if ($this->dataExists()) {
1323 if ($this->getPrintMode()) {
1325 }
1326
1327 $this->tpl->addBlockFile(
1328 "TBL_CONTENT",
1329 "tbl_content",
1330 $this->row_template,
1331 $this->row_template_dir
1332 );
1333
1334 foreach ($data as $set) {
1335 $this->tpl->setCurrentBlock("tbl_content");
1336 $this->css_row = ($this->css_row !== "tblrow1")
1337 ? "tblrow1"
1338 : "tblrow2";
1339 $this->tpl->setVariable("CSS_ROW", $this->css_row);
1340
1341 $this->fillRow($set);
1342 $this->tpl->setCurrentBlock("tbl_content");
1343 $this->tpl->parseCurrentBlock();
1344 }
1345 } else {
1346 // add standard no items text (please tell me, if it messes something up, alex, 29.8.2008)
1347 $no_items_text = (trim($this->getNoEntriesText()) != '')
1348 ? $this->getNoEntriesText()
1349 : $lng->txt("no_items");
1350
1351 $this->css_row = ($this->css_row !== "tblrow1")
1352 ? "tblrow1"
1353 : "tblrow2";
1354
1355 $this->tpl->setCurrentBlock("tbl_no_entries");
1356 $this->tpl->setVariable('TBL_NO_ENTRY_CSS_ROW', $this->css_row);
1357 $this->tpl->setVariable('TBL_NO_ENTRY_COLUMN_COUNT', $this->column_count);
1358 $this->tpl->setVariable('TBL_NO_ENTRY_TEXT', trim($no_items_text));
1359 $this->tpl->parseCurrentBlock();
1360 }
1361
1362
1363 if (!$this->getPrintMode()) {
1364 $this->fillFooter();
1365
1366 $this->fillHiddenRow();
1367
1368 $this->fillActionRow();
1369
1370 $this->storeNavParameter();
1371 }
1372
1373 return $this->render();
1374 }
1375
1379 public function numericOrdering(string $a_field): bool
1380 {
1381 return false;
1382 }
1383
1384 public function render(): string
1385 {
1386 $lng = $this->lng;
1387
1388 $this->tpl->setVariable("CSS_TABLE", $this->getStyle("table"));
1389 if ($this->getId() != "") {
1390 $this->tpl->setVariable("ID", 'id="' . $this->getId() . '"');
1391 }
1392
1393 // description
1394 if ($this->getDescription() != "") {
1395 $this->tpl->setCurrentBlock("tbl_header_description");
1396 $this->tpl->setVariable("TBL_DESCRIPTION", $this->getDescription());
1397 $this->tpl->parseCurrentBlock();
1398 }
1399
1400 if (!$this->getPrintMode()) {
1401 $this->renderFilter();
1402 }
1403
1404 if ($this->getDisplayAsBlock()) {
1405 $this->tpl->touchBlock("outer_start_1");
1406 $this->tpl->touchBlock("outer_end_1");
1407 } else {
1408 $this->tpl->touchBlock("outer_start_2");
1409 $this->tpl->touchBlock("outer_end_2");
1410 }
1411
1412 // table title and icon
1413 if ($this->enabled["title"] && ($this->title != ""
1414 || $this->icon != "" || count($this->header_commands) > 0 ||
1415 $this->headerHTML != "" || $this->close_command != "")) {
1416 if ($this->enabled["icon"]) {
1417 $this->tpl->setCurrentBlock("tbl_header_title_icon");
1418 $this->tpl->setVariable("TBL_TITLE_IMG", ilUtil::getImagePath($this->icon));
1419 $this->tpl->setVariable("TBL_TITLE_IMG_ALT", $this->icon_alt);
1420 $this->tpl->parseCurrentBlock();
1421 }
1422
1423 if (!$this->getPrintMode()) {
1424 foreach ($this->header_commands as $command) {
1425 if ($command["img"] != "") {
1426 $this->tpl->setCurrentBlock("tbl_header_img_link");
1427 if ($command["target"] != "") {
1428 $this->tpl->setVariable(
1429 "TARGET_IMG_LINK",
1430 'target="' . $command["target"] . '"'
1431 );
1432 }
1433 $this->tpl->setVariable("ALT_IMG_LINK", $command["text"]);
1434 $this->tpl->setVariable("HREF_IMG_LINK", $command["href"]);
1435 $this->tpl->setVariable(
1436 "SRC_IMG_LINK",
1437 $command["img"]
1438 );
1439 } else {
1440 $this->tpl->setCurrentBlock("head_cmd");
1441 $this->tpl->setVariable("TXT_HEAD_CMD", $command["text"]);
1442 $this->tpl->setVariable("HREF_HEAD_CMD", $command["href"]);
1443 }
1444 $this->tpl->parseCurrentBlock();
1445 }
1446 }
1447
1448 if (isset($this->headerHTML)) {
1449 $this->tpl->setCurrentBlock("tbl_header_html");
1450 $this->tpl->setVariable("HEADER_HTML", $this->headerHTML);
1451 $this->tpl->parseCurrentBlock();
1452 }
1453
1454 // close command
1455 if ($this->close_command != "") {
1456 $this->tpl->setCurrentBlock("tbl_header_img_link");
1457 $this->tpl->setVariable("ALT_IMG_LINK", $lng->txt("close"));
1458 $this->tpl->setVariable("HREF_IMG_LINK", $this->close_command);
1459 $this->tpl->parseCurrentBlock();
1460 }
1461
1462 $this->tpl->setCurrentBlock("tbl_header_title");
1463 $this->tpl->setVariable("TBL_TITLE", $this->title);
1464 if ($this->getDisplayAsBlock()) {
1465 $this->tpl->setVariable("BLK_CLASS", "Block");
1466 }
1467 $this->tpl->parseCurrentBlock();
1468 }
1469
1470 // table header
1471 if ($this->enabled["header"]) {
1472 $this->fillHeader();
1473 }
1474
1475 $this->tpl->touchBlock("tbl_table_end");
1476
1477 return $this->tpl->get();
1478 }
1479
1483 private function renderFilter(): void
1484 {
1485 global $DIC;
1486
1487 $lng = $this->lng;
1488 $main_tpl = $DIC["tpl"];
1489
1490 $filter = $this->getFilterItems();
1491 $opt_filter = $this->getFilterItems(true);
1492
1493 $main_tpl->addJavascript("assets/js/ServiceTable.js");
1494
1495 if (count($filter) == 0 && count($opt_filter) == 0) {
1496 return;
1497 }
1498
1500
1501 $ccnt = 0;
1502
1503 // render standard filter
1504 if (count($filter) > 0) {
1505 foreach ($filter as $item) {
1506 if ($ccnt >= $this->getFilterCols()) {
1507 $this->tpl->setCurrentBlock("filter_row");
1508 $this->tpl->parseCurrentBlock();
1509 $ccnt = 0;
1510 }
1511 $this->tpl->setCurrentBlock("filter_item");
1512 $this->tpl->setVariable(
1513 "OPTION_NAME",
1514 $item->getTitle()
1515 );
1516 $this->tpl->setVariable(
1517 "F_INPUT_ID",
1518 $item->getTableFilterLabelFor()
1519 );
1520 $this->tpl->setVariable(
1521 "INPUT_HTML",
1522 $item->getTableFilterHTML()
1523 );
1524 $this->tpl->parseCurrentBlock();
1525 $ccnt++;
1526 }
1527 }
1528
1529 // render optional filter
1530 if (count($opt_filter) > 0) {
1531 $this->determineSelectedFilters();
1532
1533 foreach ($opt_filter as $item) {
1534 if ($this->isFilterSelected($item->getPostVar())) {
1535 if ($ccnt >= $this->getFilterCols()) {
1536 $this->tpl->setCurrentBlock("filter_row");
1537 $this->tpl->parseCurrentBlock();
1538 $ccnt = 0;
1539 }
1540 $this->tpl->setCurrentBlock("filter_item");
1541 $this->tpl->setVariable(
1542 "OPTION_NAME",
1543 $item->getTitle()
1544 );
1545 $this->tpl->setVariable(
1546 "F_INPUT_ID",
1547 $item->getFieldId()
1548 );
1549 $this->tpl->setVariable(
1550 "INPUT_HTML",
1551 $item->getTableFilterHTML()
1552 );
1553 $this->tpl->parseCurrentBlock();
1554 $ccnt++;
1555 }
1556 }
1557
1558 // filter selection
1559 $items = array();
1560 foreach ($opt_filter as $item) {
1561 $k = $item->getPostVar();
1562 $items[$k] = array("txt" => $item->getTitle(),
1563 "selected" => $this->isFilterSelected($k));
1564 }
1565
1566 $cb_over = new ilCheckboxListOverlayGUI("tbl_filters_" . $this->getId());
1567 $cb_over->setLinkTitle($lng->txt("optional_filters"));
1568 $cb_over->setItems($items);
1569
1570 $cb_over->setFormCmd($this->getParentCmd());
1571 $cb_over->setFieldVar("tblff" . $this->getId());
1572 $cb_over->setHiddenVar("tblfsf" . $this->getId());
1573
1574 $cb_over->setSelectionHeaderClass("ilTableMenuItem");
1575 $this->tpl->setCurrentBlock("filter_select");
1576
1577 // apply should be the first submit because of enter/return, inserting hidden submit
1578 $this->tpl->setVariable("HIDDEN_CMD_APPLY", $this->filter_cmd);
1579
1580 $this->tpl->setVariable("FILTER_SELECTOR", $cb_over->getHTML(false));
1581 $this->tpl->parseCurrentBlock();
1582 }
1583
1584 // if any filter
1585 if ($ccnt > 0 || count($opt_filter) > 0) {
1586 $this->tpl->setVariable("TXT_FILTER", $lng->txt("filter"));
1587
1588 if ($ccnt > 0) {
1589 if ($ccnt < $this->getFilterCols()) {
1590 for ($i = $ccnt; $i <= $this->getFilterCols(); $i++) {
1591 $this->tpl->touchBlock("filter_empty_cell");
1592 }
1593 }
1594 $this->tpl->setCurrentBlock("filter_row");
1595 $this->tpl->parseCurrentBlock();
1596
1597 $this->tpl->setCurrentBlock("filter_buttons");
1598 $this->tpl->setVariable("CMD_APPLY", $this->filter_cmd);
1599 $this->tpl->setVariable("TXT_APPLY", $this->filter_cmd_txt
1600 ?: $lng->txt("apply_filter"));
1601 $this->tpl->setVariable("CMD_RESET", $this->reset_cmd);
1602 $this->tpl->setVariable("TXT_RESET", $this->reset_cmd_txt
1603 ?: $lng->txt("reset_filter"));
1604 } elseif (count($opt_filter) > 0) {
1605 $this->tpl->setCurrentBlock("optional_filter_hint");
1606 $this->tpl->setVariable('TXT_OPT_HINT', $lng->txt('optional_filter_hint'));
1607 $this->tpl->parseCurrentBlock();
1608 }
1609
1610 $this->tpl->setCurrentBlock("filter_section");
1611 $this->tpl->setVariable("FIL_ID", $this->getId());
1612 $this->tpl->parseCurrentBlock();
1613
1614 // (keep) filter hidden?
1615 if (!$this->isFilterVisible() && !$this->getDisableFilterHiding()) {
1616 $id = $this->getId();
1617 $this->main_tpl->addOnLoadCode("
1618 ilTableHideFilter['atfil_$id'] = true;
1619 ilTableHideFilter['tfil_$id'] = true;
1620 ilTableHideFilter['dtfil_$id'] = true;
1621 ");
1622 }
1623 /*
1624 * BT 35757: filter has to be initialized after it has a chance to get hidden,
1625 * moving this here from ServiceTable.js to avoid timing weirdness with onLoadCode.
1626 */
1627 $this->main_tpl->addOnLoadCode("ilInitTableFilters()");
1628 }
1629 }
1630
1634 protected function isFilterVisible(): bool
1635 {
1636 $prop = $this->loadProperty('filter');
1637 if ($prop === '0' || $prop === '1') {
1638 return (bool) $prop;
1639 }
1640 return $this->getDefaultFilterVisibility();
1641 }
1642
1646 protected function isAdvMDFilter(
1647 ilAdvancedMDRecordGUI $a_gui,
1648 ilTableFilterItem $a_element
1649 ): bool {
1650 foreach ($a_gui->getFilterElements(false) as $item) {
1651 if ($item === $a_element) {
1652 return true;
1653 }
1654 }
1655 return false;
1656 }
1657
1658 public function writeFilterToSession(): void
1659 {
1660 $advmd_record_gui = null;
1661 if (method_exists($this, "getAdvMDRecordGUI")) {
1662 $advmd_record_gui = $this->getAdvMDRecordGUI();
1663 }
1664
1665 foreach ($this->getFilterItems() as $item) {
1666 if ($advmd_record_gui &&
1667 $this->isAdvMDFilter($advmd_record_gui, $item)) {
1668 continue;
1669 }
1670
1671 if ($item->checkInput()) {
1672 $item->setValueByArray($this->raw_post_data);
1673 $item->writeToSession();
1674 }
1675 }
1676 foreach ($this->getFilterItems(true) as $item) {
1677 if ($advmd_record_gui &&
1678 $this->isAdvMDFilter($advmd_record_gui, $item)) {
1679 continue;
1680 }
1681
1682 if ($item->checkInput()) {
1683 $item->setValueByArray($this->raw_post_data);
1684 $item->writeToSession();
1685 }
1686 }
1687
1688 if ($advmd_record_gui) {
1689 $advmd_record_gui->importFilter();
1690 }
1691 }
1692
1693 public function resetFilter(): void
1694 {
1695 $filter = $this->getFilterItems();
1696 $opt_filter = $this->getFilterItems(true);
1697
1698 foreach ($filter as $item) {
1699 if ($item->checkInput()) {
1700 // see #26490
1701 $item->setValueByArray([]);
1702 $item->clearFromSession();
1703 }
1704 }
1705 foreach ($opt_filter as $item) {
1706 if ($item->checkInput()) {
1707 // see #26490
1708 $item->setValueByArray([]);
1709 $item->clearFromSession();
1710 }
1711 }
1712 }
1713
1719 protected function fillRow(array $a_set): void
1720 {
1721 foreach ($a_set as $key => $value) {
1722 $this->tpl->setVariable("VAL_" . strtoupper($key), $value);
1723 }
1724 }
1725
1726 public function fillFooter(): void
1727 {
1728 global $DIC;
1729
1730 $ilUser = null;
1731 if (isset($DIC["ilUser"])) {
1732 $ilUser = $DIC["ilUser"];
1733 }
1734
1735 $ui_factory = $this->ui->factory();
1736 $ui_renderer = $this->ui->renderer();
1737
1738 $lng = $this->lng;
1739 $ilCtrl = $this->ctrl;
1740
1741 $footer = false;
1742 $numinfo = '';
1743 $linkbar = '';
1744 $column_selector = '';
1745
1746 // select all checkbox
1747 if ((strlen($this->getFormName())) && (strlen($this->getSelectAllCheckbox())) && $this->dataExists()) {
1748 $this->tpl->setCurrentBlock("select_all_checkbox");
1749 $this->tpl->setVariable("SELECT_ALL_TXT_SELECT_ALL", $lng->txt("select_all"));
1750 $this->tpl->setVariable("SELECT_ALL_CHECKBOX_NAME", $this->getSelectAllCheckbox());
1751 $this->tpl->setVariable("SELECT_ALL_FORM_NAME", $this->getFormName());
1752 $this->tpl->setVariable("CHECKBOXNAME", "chb_select_all_" . $this->unique_id);
1753 $this->tpl->parseCurrentBlock();
1754 }
1755
1756 // table footer numinfo
1757 if ($this->enabled["numinfo"] && $this->enabled["footer"]) {
1758 $start = $this->offset + 1; // compute num info
1759 if (!$this->dataExists()) {
1760 $start = 0;
1761 }
1762 $end = $this->offset + $this->limit;
1763
1764 if ($end > $this->max_count or $this->limit == 0) {
1765 $end = $this->max_count;
1766 }
1767
1768 if ($this->max_count > 0) {
1769 if ($this->lang_support) {
1770 $numinfo = "(" . $start . " - " . $end . " " . strtolower($this->lng->txt("of")) . " " . $this->max_count . ")";
1771 } else {
1772 $numinfo = "(" . $start . " - " . $end . " of " . $this->max_count . ")";
1773 }
1774 }
1775 if ($this->max_count > 0) {
1776 if ($this->getEnableNumInfo()) {
1777 $this->tpl->setCurrentBlock("tbl_footer_numinfo");
1778 $this->tpl->setVariable("NUMINFO", $numinfo);
1779 $this->tpl->parseCurrentBlock();
1780 }
1781 }
1782 $footer = true;
1783 }
1784
1785 // table footer linkbar
1786 if ($this->enabled["linkbar"] && $this->enabled["footer"] && $this->limit != 0
1787 && $this->max_count > 0) {
1788 $linkbar = $this->getLinkbar("1");
1789 $this->tpl->setCurrentBlock("tbl_footer_linkbar");
1790 $this->tpl->setVariable("LINKBAR", $linkbar);
1791 $this->tpl->parseCurrentBlock();
1792 $linkbar = true;
1793 $footer = true;
1794 }
1795
1796 // column selector
1797 if (is_array($this->getSelectableColumns()) && count($this->getSelectableColumns()) > 0) {
1798 $items = array();
1799 foreach ($this->getSelectableColumns() as $k => $c) {
1800 $items[$k] = array("txt" => $c["txt"],
1801 "selected" => $this->isColumnSelected($k));
1802 }
1803 $cb_over = new ilCheckboxListOverlayGUI("tbl_" . $this->getId());
1804 $cb_over->setLinkTitle($lng->txt("columns"));
1805 $cb_over->setItems($items);
1806 //$cb_over->setUrl("./ilias.php?baseClass=ilTablePropertiesStorage&table_id=".
1807 // $this->getId()."&cmd=saveSelectedFields&user_id=".$ilUser->getId());
1808 $cb_over->setFormCmd($this->getParentCmd());
1809 $cb_over->setFieldVar("tblfs" . $this->getId());
1810 $cb_over->setHiddenVar("tblfsh" . $this->getId());
1811 $cb_over->setSelectionHeaderClass("ilTableMenuItem");
1812 $column_selector = $cb_over->getHTML();
1813 $footer = true;
1814 }
1815
1816 if ($footer) {
1817 $this->tpl->setCurrentBlock("tbl_footer");
1818 $this->tpl->setVariable("COLUMN_COUNT", $this->getColumnCount());
1819 if ($this->getDisplayAsBlock()) {
1820 $this->tpl->setVariable("BLK_CLASS", "Block");
1821 }
1822 $this->tpl->parseCurrentBlock();
1823
1824 // top navigation, if number info or linkbar given
1825 if ($numinfo != "" || $linkbar != "" || $column_selector != "" ||
1826 count($this->filters) > 0 || count($this->optional_filters) > 0) {
1827 if (is_object($ilUser) && (count($this->filters) || count($this->optional_filters))) {
1828 $this->tpl->setCurrentBlock("filter_activation");
1829 $this->tpl->setVariable("TXT_ACTIVATE_FILTER", $lng->txt("show_filter"));
1830 $this->tpl->setVariable("FILA_ID", $this->getId());
1831 if ($this->getId() != "") {
1832 $this->tpl->setVariable("SAVE_URLA", "./ilias.php?baseClass=ilTablePropertiesStorageGUI&table_id=" .
1833 $this->getId() . "&cmd=showFilter&user_id=" . $ilUser->getId());
1834 }
1835 $this->tpl->parseCurrentBlock();
1836
1837
1838 if (!$this->getDisableFilterHiding()) {
1839 $this->tpl->setCurrentBlock("filter_deactivation");
1840 $this->tpl->setVariable("TXT_HIDE", $lng->txt("hide_filter"));
1841 if ($this->getId() != "") {
1842 $this->tpl->setVariable("SAVE_URL", "./ilias.php?baseClass=ilTablePropertiesStorageGUI&table_id=" .
1843 $this->getId() . "&cmd=hideFilter&user_id=" . $ilUser->getId());
1844 $this->tpl->setVariable("FILD_ID", $this->getId());
1845 }
1846 $this->tpl->parseCurrentBlock();
1847 }
1848 }
1849
1850 if ($numinfo != "" && $this->getEnableNumInfo()) {
1851 $this->tpl->setCurrentBlock("top_numinfo");
1852 $this->tpl->setVariable("NUMINFO", $numinfo);
1853 $this->tpl->parseCurrentBlock();
1854 }
1855 if ($linkbar != "" && !$this->getDisplayAsBlock()) {
1856 $linkbar = $this->getLinkbar("2");
1857 $this->tpl->setCurrentBlock("top_linkbar");
1858 $this->tpl->setVariable("LINKBAR", $linkbar);
1859 $this->tpl->parseCurrentBlock();
1860 }
1861
1862 // column selector
1863 $this->tpl->setVariable("COLUMN_SELECTOR", $column_selector);
1864
1865 // row selector
1866 if ($this->getShowRowsSelector() &&
1867 is_object($ilUser) &&
1868 $this->getId() &&
1869 !$this->rows_selector_off) { // JF, 2014-10-27
1870 $actions = [];
1871
1872 $options = array(5 => 5, 10 => 10, 15 => 15, 20 => 20,
1873 30 => 30, 40 => 40, 50 => 50,
1874 100 => 100, 200 => 200, 400 => 400, 800 => 800);
1875 foreach ($options as $k => $v) {
1876 $ilCtrl->setParameter($this->parent_obj, $this->prefix . "_trows", $k);
1877 $actions[] = $ui_factory->link()->standard(
1878 $v,
1879 $ilCtrl->getLinkTarget($this->parent_obj, $this->parent_cmd)
1880 );
1881 $ilCtrl->setParameter($this->parent_obj, $this->prefix . "_trows", "");
1882 }
1883 $dd = $ui_factory->dropdown()->standard($actions)->withLabel(
1884 $this->getRowSelectorLabel() ?: $lng->txt("rows")
1885 );
1886 $this->tpl->setVariable("ROW_SELECTOR", $ui_renderer->render($dd));
1887 }
1888
1889 // export
1890 if (count($this->export_formats) > 0 && $this->dataExists()) {
1891 $actions = [];
1892 foreach ($this->export_formats as $format => $caption_lng_id) {
1893 $ilCtrl->setParameter($this->parent_obj, $this->prefix . "_xpt", $format);
1894 $url = $ilCtrl->getLinkTarget($this->parent_obj, $this->parent_cmd);
1895 $ilCtrl->setParameter($this->parent_obj, $this->prefix . "_xpt", "");
1896 $actions[] = $ui_factory->link()->standard(
1897 $lng->txt($caption_lng_id),
1898 $url
1899 );
1900 }
1901 $dd = $ui_factory->dropdown()->standard($actions)->withLabel($lng->txt("export"));
1902 $this->tpl->setVariable("EXPORT_SELECTOR", "&nbsp;" . $ui_renderer->render($dd));
1903 }
1904
1905 $this->tpl->setCurrentBlock("top_navigation");
1906 $this->tpl->setVariable("COLUMN_COUNT", $this->getColumnCount());
1907 if ($this->getDisplayAsBlock()) {
1908 $this->tpl->setVariable("BLK_CLASS", "Block");
1909 }
1910 $this->tpl->parseCurrentBlock();
1911 }
1912 }
1913 }
1914
1915 public function getLinkbar(string $a_num): ?string
1916 {
1917 global $DIC;
1918
1919 $ilUser = $DIC->user();
1920
1921 $ilCtrl = $this->ctrl;
1922 $lng = $this->lng;
1923
1924 $hash = "";
1925
1926 $link = $ilCtrl->getLinkTargetByClass(get_class($this->parent_obj), $this->parent_cmd) .
1927 "&" . $this->getNavParameter() . "=" .
1928 $this->getOrderField() . ":" . $this->getOrderDirection() . ":";
1929
1930 $LinkBar = "";
1931 $layout_prev = $lng->txt("previous");
1932 $layout_next = $lng->txt("next");
1933
1934 // if more entries then entries per page -> show link bar
1935 if ($this->max_count > $this->getLimit() || $this->custom_prev_next) {
1936 $sep = "<span>&nbsp;&nbsp;|&nbsp;&nbsp;</span>";
1937
1938 // calculate number of pages
1939 $pages = intval($this->max_count / $this->getLimit());
1940
1941 // add a page if a rest remains
1942 if (($this->max_count % $this->getLimit())) {
1943 $pages++;
1944 }
1945
1946 // links to other pages
1947 $offset_arr = array();
1948 for ($i = 1 ;$i <= $pages ; $i++) {
1949 $newoffset = $this->getLimit() * ($i - 1);
1950
1951 $nav_value = $this->getOrderField() . ":" . $this->getOrderDirection() . ":" . $newoffset;
1952 $offset_arr[$nav_value] = $i;
1953 }
1954
1955 $sep = "<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>";
1956
1957 // previous link
1958 if ($this->custom_prev_next && $this->custom_prev != "") {
1959 $LinkBar .= "<a href=\"" . $this->custom_prev . $hash . "\">" . $layout_prev . "</a>";
1960 } elseif ($this->getOffset() >= 1 && !$this->custom_prev_next) {
1961 $prevoffset = $this->getOffset() - $this->getLimit();
1962 $LinkBar .= "<a href=\"" . $link . $prevoffset . $hash . "\">" . $layout_prev . "</a>";
1963 } else {
1964 $LinkBar .= '<span class="ilTableFootLight">' . $layout_prev . "</span>";
1965 }
1966
1967 // current value
1968 if ($a_num == "1") {
1969 $LinkBar .= '<input type="hidden" name="' . $this->getNavParameter() .
1970 '" value="' . $this->getOrderField() . ":" . $this->getOrderDirection() . ":" . $this->getOffset() . '" />';
1971 }
1972
1973 $sep = "<span>&nbsp;&nbsp;|&nbsp;&nbsp;</span>";
1974
1975 // show next link (if not last page)
1976 $LinkBar .= $sep;
1977 if ($this->custom_prev_next && $this->custom_next != "") {
1978 $LinkBar .= "<a href=\"" . $this->custom_next . $hash . "\">" . $layout_next . "</a>";
1979 } elseif (!(($this->getOffset() / $this->getLimit()) == ($pages - 1)) && ($pages != 1) &&
1980 !$this->custom_prev_next) {
1981 $newoffset = $this->getOffset() + $this->getLimit();
1982 $LinkBar .= "<a href=\"" . $link . $newoffset . $hash . "\">" . $layout_next . "</a>";
1983 } else {
1984 $LinkBar .= '<span class="ilTableFootLight">' . $layout_next . "</span>";
1985 }
1986
1987 $sep = "<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>";
1988
1989 if (count($offset_arr) && !$this->getDisplayAsBlock() && !$this->custom_prev_next) {
1990 $LinkBar .= $sep;
1991
1992 $LinkBar .=
1993 '<label for="tab_page_sel_' . $a_num . '">' . $lng->txt("page") . '</label> ' .
1995 $this->nav_value,
1996 $this->getNavParameter() . $a_num,
1997 $offset_arr,
1998 false,
1999 true,
2000 0,
2001 "small",
2002 array("id" => "tab_page_sel_" . $a_num,
2003 "onchange" => "ilTablePageSelection(this, 'cmd[" . $this->parent_cmd . "]')")
2004 );
2005 }
2006
2007 return $LinkBar;
2008 } else {
2009 return null;
2010 }
2011 }
2012
2013 public function fillHiddenRow(): void
2014 {
2015 $hidden_row = false;
2016 if (count($this->hidden_inputs)) {
2017 foreach ($this->hidden_inputs as $hidden_input) {
2018 $this->tpl->setCurrentBlock("tbl_hidden_field");
2019 $this->tpl->setVariable("FIELD_NAME", $hidden_input["name"]);
2020 $this->tpl->setVariable("FIELD_VALUE", $hidden_input["value"]);
2021 $this->tpl->parseCurrentBlock();
2022 }
2023
2024 $this->tpl->setCurrentBlock("tbl_hidden_row");
2025 $this->tpl->parseCurrentBlock();
2026 }
2027 }
2028
2029 public function fillActionRow(): void
2030 {
2031 $lng = $this->lng;
2032
2033 // action row
2034 $action_row = false;
2035 $arrow = false;
2036 $txt = "";
2037 $cmd = "";
2038
2039 // add selection buttons
2040 if (count($this->sel_buttons) > 0) {
2041 foreach ($this->sel_buttons as $button) {
2042 $this->tpl->setCurrentBlock("sel_button");
2043 $this->tpl->setVariable(
2044 "SBUTTON_SELECT",
2046 $button["selected"],
2047 $button["sel_var"],
2048 $button["options"],
2049 false,
2050 true
2051 )
2052 );
2053 $this->tpl->setVariable("SBTN_NAME", $button["cmd"]);
2054 $this->tpl->setVariable("SBTN_VALUE", $button["text"]);
2055 $this->tpl->parseCurrentBlock();
2056
2057 if ($this->getTopCommands()) {
2058 $this->tpl->setCurrentBlock("sel_top_button");
2059 $this->tpl->setVariable(
2060 "SBUTTON_SELECT",
2062 $button["selected"],
2063 $button["sel_var"],
2064 $button["options"],
2065 false,
2066 true
2067 )
2068 );
2069 $this->tpl->setVariable("SBTN_NAME", $button["cmd"]);
2070 $this->tpl->setVariable("SBTN_VALUE", $button["text"]);
2071 $this->tpl->parseCurrentBlock();
2072 }
2073 }
2074 $buttons = true;
2075 $action_row = true;
2076 }
2077 $this->sel_buttons[] = array("options" => [], "cmd" => '', "text" => '');
2078
2079 // add buttons
2080 if (count($this->buttons) > 0) {
2081 foreach ($this->buttons as $button) {
2082 if (!is_array($button)) {
2083 if ($button instanceof ilButtonBase) {
2084 $this->tpl->setVariable('BUTTON_OBJ', $button->render());
2085
2086 // this will remove id - should be unique
2087 $button = clone $button;
2088
2089 $this->tpl->setVariable('BUTTON_TOP_OBJ', $button->render());
2090 }
2091 continue;
2092 }
2093
2094 if (strlen($button['onclick'])) {
2095 $this->tpl->setCurrentBlock('cmdonclick');
2096 $this->tpl->setVariable('CMD_ONCLICK', $button['onclick']);
2097 $this->tpl->parseCurrentBlock();
2098 }
2099 $this->tpl->setCurrentBlock("plain_button");
2100 if ($button["id"] != "") {
2101 $this->tpl->setVariable("PBID", ' id="' . $button["id"] . '" ');
2102 }
2103 if ($button["class"] != "") {
2104 $this->tpl->setVariable("PBBT_CLASS", ' ' . $button["class"]);
2105 }
2106 $this->tpl->setVariable("PBTN_NAME", $button["cmd"]);
2107 $this->tpl->setVariable("PBTN_VALUE", $button["text"]);
2108 $this->tpl->parseCurrentBlock();
2109
2110 if ($this->getTopCommands()) {
2111 if (strlen($button['onclick'])) {
2112 $this->tpl->setCurrentBlock('top_cmdonclick');
2113 $this->tpl->setVariable('CMD_ONCLICK', $button['onclick']);
2114 $this->tpl->parseCurrentBlock();
2115 }
2116 $this->tpl->setCurrentBlock("plain_top_button");
2117 $this->tpl->setVariable("PBTN_NAME", $button["cmd"]);
2118 $this->tpl->setVariable("PBTN_VALUE", $button["text"]);
2119 if ($button["class"] != "") {
2120 $this->tpl->setVariable("PBBT_CLASS", ' ' . $button["class"]);
2121 }
2122 $this->tpl->parseCurrentBlock();
2123 }
2124 }
2125
2126 $buttons = true;
2127 $action_row = true;
2128 }
2129
2130 // multi selection
2131 if (count($this->mi_sel_buttons)) {
2132 foreach ($this->mi_sel_buttons as $button) {
2133 $this->tpl->setCurrentBlock("mi_sel_button");
2134 $this->tpl->setVariable(
2135 "MI_BUTTON_SELECT",
2137 $button["selected"],
2138 $button["sel_var"],
2139 $button["options"],
2140 false,
2141 true
2142 )
2143 );
2144 $this->tpl->setVariable("MI_BTN_NAME", $button["cmd"]);
2145 $this->tpl->setVariable("MI_BTN_VALUE", $button["text"]);
2146 $this->tpl->parseCurrentBlock();
2147
2148 if ($this->getTopCommands()) {
2149 $this->tpl->setCurrentBlock("mi_top_sel_button");
2150 $this->tpl->setVariable(
2151 "MI_BUTTON_SELECT",
2153 $button["selected"],
2154 $button["sel_var"] . "_2",
2155 $button["options"],
2156 false,
2157 true
2158 )
2159 );
2160 $this->tpl->setVariable("MI_BTN_NAME", $button["cmd"]);
2161 $this->tpl->setVariable("MI_BTN_VALUE", $button["text"]);
2162 $this->tpl->parseCurrentBlock();
2163 }
2164 }
2165 $arrow = true;
2166 $action_row = true;
2167 }
2168
2169
2170 if (count($this->multi) > 1 && $this->dataExists()) {
2171 if ($this->enable_command_for_all && $this->max_count <= self::getAllCommandLimit()) {
2172 $this->tpl->setCurrentBlock("tbl_cmd_select_all");
2173 $this->tpl->setVariable("TXT_SELECT_CMD_ALL", $lng->txt("all_objects"));
2174 $this->tpl->parseCurrentBlock();
2175 }
2176
2177 $this->tpl->setCurrentBlock("tbl_cmd_select");
2178 $sel = array();
2179 foreach ($this->multi as $mc) {
2180 $sel[$mc["cmd"]] = $mc["text"];
2181 }
2182 $this->tpl->setVariable(
2183 "SELECT_CMDS",
2184 ilLegacyFormElementsUtil::formSelect("", "selected_cmd", $sel, false, true)
2185 );
2186 $this->tpl->setVariable("TXT_EXECUTE", $lng->txt("execute"));
2187 $this->tpl->parseCurrentBlock();
2188 $arrow = true;
2189 $action_row = true;
2190
2191 if ($this->getTopCommands()) {
2192 if ($this->enable_command_for_all && $this->max_count <= self::getAllCommandLimit()) {
2193 $this->tpl->setCurrentBlock("tbl_top_cmd_select_all");
2194 $this->tpl->setVariable("TXT_SELECT_CMD_ALL", $lng->txt("all_objects"));
2195 $this->tpl->parseCurrentBlock();
2196 }
2197
2198 $this->tpl->setCurrentBlock("tbl_top_cmd_select");
2199 $sel = array();
2200 foreach ($this->multi as $mc) {
2201 $sel[$mc["cmd"]] = $mc["text"];
2202 }
2203 $this->tpl->setVariable(
2204 "SELECT_CMDS",
2205 ilLegacyFormElementsUtil::formSelect("", "selected_cmd2", $sel, false, true)
2206 );
2207 $this->tpl->setVariable("TXT_EXECUTE", $lng->txt("execute"));
2208 $this->tpl->parseCurrentBlock();
2209 }
2210 } elseif (count($this->multi) == 1 && $this->dataExists()) {
2211 $this->tpl->setCurrentBlock("tbl_single_cmd");
2212 foreach ($this->multi as $mc) {
2213 $cmd = $mc['cmd'];
2214 $txt = $mc['text'];
2215 }
2216 $this->tpl->setVariable("TXT_SINGLE_CMD", $txt);
2217 $this->tpl->setVariable("SINGLE_CMD", $cmd);
2218 $this->tpl->parseCurrentBlock();
2219 $arrow = true;
2220 $action_row = true;
2221
2222 if ($this->getTopCommands()) {
2223 $this->tpl->setCurrentBlock("tbl_top_single_cmd");
2224 foreach ($this->multi as $mc) {
2225 $cmd = $mc['cmd'];
2226 $txt = $mc['text'];
2227 }
2228 $this->tpl->setVariable("TXT_SINGLE_CMD", $txt);
2229 $this->tpl->setVariable("SINGLE_CMD", $cmd);
2230 $this->tpl->parseCurrentBlock();
2231 }
2232 }
2233
2234 if ($arrow) {
2235 $this->tpl->setCurrentBlock("tbl_action_img_arrow");
2236 $this->tpl->setVariable("IMG_ARROW", ilUtil::getImagePath("nav/arrow_downright.svg"));
2237 $this->tpl->setVariable("ALT_ARROW", $lng->txt("action"));
2238 $this->tpl->parseCurrentBlock();
2239
2240 if ($this->getTopCommands()) {
2241 $this->tpl->setCurrentBlock("tbl_top_action_img_arrow");
2242 $this->tpl->setVariable("IMG_ARROW", ilUtil::getImagePath("nav/arrow_upright.svg"));
2243 $this->tpl->setVariable("ALT_ARROW", $lng->txt("action"));
2244 $this->tpl->parseCurrentBlock();
2245 }
2246 }
2247
2248 if ($action_row) {
2249 $this->tpl->setCurrentBlock("tbl_action_row");
2250 $this->tpl->parseCurrentBlock();
2251 if ($this->getTopCommands()) {
2252 $this->tpl->setCurrentBlock("tbl_top_action_row");
2253 $this->tpl->parseCurrentBlock();
2254 }
2255 }
2256 }
2257
2258 public function setHeaderHTML(string $html): void
2259 {
2260 $this->headerHTML = $html;
2261 }
2262
2263 public function storeProperty(string $type, string $value): void
2264 {
2265 global $DIC;
2266
2267 $ilUser = null;
2268 if (isset($DIC["ilUser"])) {
2269 $ilUser = $DIC["ilUser"];
2270 }
2271
2272 if (is_object($ilUser) && $this->getId() != "") {
2273 $tab_prop = new ilTablePropertiesStorageGUI();
2274
2275 $tab_prop->storeProperty($this->getId(), $ilUser->getId(), $type, $value);
2276 }
2277 }
2278
2279 public function loadProperty(string $type): ?string
2280 {
2281 global $DIC;
2282
2283 $ilUser = null;
2284 if (isset($DIC["ilUser"])) {
2285 $ilUser = $DIC["ilUser"];
2286 }
2287
2288 if (is_object($ilUser) && $this->getId() != "") {
2289 $tab_prop = new ilTablePropertiesStorageGUI();
2290
2291 return $tab_prop->getProperty($this->getId(), $ilUser->getId(), $type);
2292 }
2293 return null;
2294 }
2295
2299 public function getCurrentState(): array
2300 {
2301 $this->determineOffsetAndOrder();
2302 $this->determineLimit();
2303 $this->determineSelectedColumns();
2304 $this->determineSelectedFilters();
2305
2306 // "filter" show/hide is not saved
2307
2308 $result = array();
2309 $result["order"] = $this->getOrderField();
2310 $result["direction"] = $this->getOrderDirection();
2311 $result["offset"] = $this->getOffset();
2312 $result["rows"] = $this->getLimit();
2313 $result["selfilters"] = $this->getSelectedFilters();
2314
2315 // #9514 - $this->getSelectedColumns() will omit deselected, leading to
2316 // confusion on restoring template
2317 $result["selfields"] = $this->selected_column;
2318
2319 // gather filter values
2320 if ($this->filters) {
2321 foreach ($this->filters as $item) {
2322 $result["filter_values"][$item->getFieldId()] = $this->getFilterValue($item);
2323 }
2324 }
2325 if ($this->optional_filters && $result["selfilters"]) {
2326 foreach ($this->optional_filters as $item) {
2327 if (in_array($item->getFieldId(), $result["selfilters"])) {
2328 $result["filter_values"][$item->getFieldId()] = $this->getFilterValue($item);
2329 }
2330 }
2331 }
2332
2333 return $result;
2334 }
2335
2340 protected function getFilterValue(ilTableFilterItem $a_item)
2341 {
2342 if (method_exists($a_item, "getChecked")) {
2343 return (string) $a_item->getChecked();
2344 } elseif (method_exists($a_item, "getValue")) {
2345 return $a_item->getValue() ?: "";
2346 } elseif (method_exists($a_item, "getDate")) {
2347 return $a_item->getDate()?->get(IL_CAL_DATE) ?? "";
2348 }
2349 return "";
2350 }
2351
2356 protected function setFilterValue(ilTableFilterItem $a_item, $a_value): void
2357 {
2358 if (method_exists($a_item, "setChecked")) {
2359 $a_item->setChecked((bool) $a_value);
2360 } elseif (method_exists($a_item, "setValue")) {
2361 $a_item->setValue($a_value);
2362 } elseif (method_exists($a_item, "setDate")) {
2363 $a_item->setDate(new ilDate($a_value, IL_CAL_DATE));
2364 }
2365 $a_item->writeToSession();
2366 }
2367
2368 public function setContext(string $id): void
2369 {
2370 if (trim($id)) {
2371 $this->context = $id;
2372 }
2373 }
2374
2375 public function getContext(): string
2376 {
2377 return $this->context;
2378 }
2379
2383 public function setShowRowsSelector(bool $a_value): void
2384 {
2385 $this->show_rows_selector = $a_value;
2386 }
2387
2388 public function getShowRowsSelector(): bool
2389 {
2390 return $this->show_rows_selector;
2391 }
2392
2393 public function getLimit(): int
2394 {
2395 if ($this->getExportMode() || $this->getPrintMode()) {
2396 return 9999;
2397 }
2398 return parent::getLimit();
2399 }
2400
2401 public function getOffset(): int
2402 {
2403 if ($this->getExportMode() || $this->getPrintMode()) {
2404 return 0;
2405 }
2406 return parent::getOffset();
2407 }
2408
2412 public function setExportFormats(array $formats): void
2413 {
2414 $this->export_formats = array();
2415
2416 // #11339
2417 $valid = array(self::EXPORT_EXCEL => "tbl_export_excel",
2418 self::EXPORT_CSV => "tbl_export_csv");
2419
2420 foreach ($formats as $format) {
2421 if (array_key_exists($format, $valid)) {
2422 $this->export_formats[$format] = $valid[$format];
2423 }
2424 }
2425 }
2426
2427 public function setPrintMode(bool $a_value = false): void
2428 {
2429 $this->print_mode = $a_value;
2430 }
2431
2432 public function getPrintMode(): bool
2433 {
2434 return $this->print_mode;
2435 }
2436
2437 public function getExportMode(): int
2438 {
2439 return $this->export_mode;
2440 }
2441
2445 public function exportData(int $format, bool $send = false): void
2446 {
2447 if ($this->dataExists()) {
2448 // #9640: sort
2449 if (!$this->getExternalSorting() && $this->enabled["sort"]) {
2450 $this->determineOffsetAndOrder(true);
2451
2452 $this->row_data = ilArrayUtil::sortArray(
2453 $this->row_data,
2454 $this->getOrderField(),
2455 $this->getOrderDirection(),
2456 $this->numericOrdering($this->getOrderField())
2457 );
2458 }
2459
2460 $filename = "export";
2461 switch ($format) {
2462 case self::EXPORT_EXCEL:
2463 $excel = new ilExcel();
2464 $excel->addSheet($this->title
2465 ?: $this->lng->txt("export"));
2466 $row = 1;
2467
2468 ob_start();
2469 $this->fillMetaExcel($excel, $row); // row must be increment in fillMetaExcel()! (optional method)
2470
2471 // #14813
2472 $pre = $row;
2473 $this->fillHeaderExcel($excel, $row); // row should NOT be incremented in fillHeaderExcel()! (required method)
2474 if ($pre == $row) {
2475 $row++;
2476 }
2477
2478 foreach ($this->row_data as $set) {
2479 $this->fillRowExcel($excel, $row, $set);
2480 $row++; // #14760
2481 }
2482 ob_end_clean();
2483
2484 if ($send) {
2485 $excel->sendToClient($filename);
2486 } else {
2487 $excel->writeToFile($filename);
2488 }
2489 break;
2490
2491 case self::EXPORT_CSV:
2492 $csv = new ilCSVWriter();
2493 $csv->setSeparator(";");
2494
2495 ob_start();
2496 $this->fillMetaCSV($csv);
2497 $this->fillHeaderCSV($csv);
2498 foreach ($this->row_data as $set) {
2499 $this->fillRowCSV($csv, $set);
2500 }
2501 ob_end_clean();
2502
2503 if ($send) {
2504 $filename .= ".csv";
2505 header("Content-type: text/comma-separated-values");
2506 header("Content-Disposition: attachment; filename=\"" . $filename . "\"");
2507 header("Expires: 0");
2508 header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
2509 header("Pragma: public");
2510 echo $csv->getCSVString();
2511 } else {
2512 file_put_contents($filename, $csv->getCSVString());
2513 }
2514 break;
2515 }
2516
2517 if ($send) {
2518 exit();
2519 }
2520 }
2521 }
2522
2529 protected function fillMetaExcel(ilExcel $a_excel, int &$a_row): void
2530 {
2531 }
2532
2539 protected function fillHeaderExcel(ilExcel $a_excel, int &$a_row): void
2540 {
2541 $col = 0;
2542 foreach ($this->column as $column) {
2543 $title = strip_tags($column["text"]);
2544 if ($title) {
2545 $a_excel->setCell($a_row, $col++, $title);
2546 }
2547 }
2548 $a_excel->setBold("A" . $a_row . ":" . $a_excel->getColumnCoord($col - 1) . $a_row);
2549 }
2550
2558 protected function fillRowExcel(ilExcel $a_excel, int &$a_row, array $a_set): void
2559 {
2560 $col = 0;
2561 foreach ($a_set as $value) {
2562 if (is_array($value)) {
2563 $value = implode(', ', $value);
2564 }
2565 $a_excel->setCell($a_row, $col++, $value);
2566 }
2567 }
2568
2574 protected function fillMetaCSV(ilCSVWriter $a_csv): void
2575 {
2576 }
2577
2583 protected function fillHeaderCSV(ilCSVWriter $a_csv): void
2584 {
2585 foreach ($this->column as $column) {
2586 $title = strip_tags($column["text"]);
2587 if ($title) {
2588 $a_csv->addColumn($title);
2589 }
2590 }
2591 $a_csv->addRow();
2592 }
2593
2600 protected function fillRowCSV(ilCSVWriter $a_csv, array $a_set): void
2601 {
2602 foreach ($a_set as $key => $value) {
2603 if (is_array($value)) {
2604 $value = implode(', ', $value);
2605 }
2606 $a_csv->addColumn(strip_tags($value));
2607 }
2608 $a_csv->addRow();
2609 }
2610
2611 public function setEnableAllCommand(bool $a_value): void
2612 {
2613 $this->enable_command_for_all = $a_value;
2614 }
2615
2616 public static function getAllCommandLimit(): int
2617 {
2618 global $DIC;
2619
2620 $ilClientIniFile = $DIC["ilClientIniFile"];
2621
2622 $limit = $ilClientIniFile->readVariable("system", "TABLE_ACTION_ALL_LIMIT");
2623 if (!$limit) {
2624 $limit = self::ACTION_ALL_LIMIT;
2625 }
2626
2627 return $limit;
2628 }
2629
2630 public function setRowSelectorLabel(string $row_selector_label): void
2631 {
2632 $this->row_selector_label = $row_selector_label;
2633 }
2634
2635 public function getRowSelectorLabel(): string
2636 {
2637 return $this->row_selector_label;
2638 }
2639
2640 public function setPreventDoubleSubmission(bool $a_val): void
2641 {
2642 $this->prevent_double_submission = $a_val;
2643 }
2644
2645 public function getPreventDoubleSubmission(): bool
2646 {
2647 return $this->prevent_double_submission;
2648 }
2649
2650 public function setLimit(int $a_limit = 0, int $a_default_limit = 0): void
2651 {
2652 parent::setLimit($a_limit, $a_default_limit);
2653
2654 // #17077 - if limit is set "manually" to 9999, force rows selector off
2655 if ($a_limit == 9999 &&
2656 $this->limit_determined) {
2657 $this->rows_selector_off = true;
2658 }
2659 }
2660}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$filename
Definition: buildRTE.php:78
const IL_CAL_DATE
return true
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addColumn(string $a_col)
This class represents a checkbox property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a number property in a property form.
Class ilCtrl provides processing control methods.
getNextClass($a_gui_class=null)
@inheritDoc
static setUseRelativeDates(bool $a_status)
set use relative dates
This class represents a date/time property in a property form.
Class for single dates.
This class represents a duration (typical hh:mm:ss) property in a property form.
setBold(string $a_coords)
Set cell(s) to bold.
setCell(int $a_row, int $col, $value, ?string $datatype=null, bool $disable_strip_tags_for_strings=false)
Set cell value.
getColumnCoord(int $a_col)
Get column "name" from number.
Base class for ILIAS Exception handling.
loadLanguageModule(string $a_module)
Load language module.
static formSelect( $selected, string $varname, array $options, bool $multiple=false, bool $direct_text=false, int $size=0, string $style_class="", array $attribs=[], bool $disabled=false)
Builds a select form field with options and shows the selected option first.
This class represents a number property in a property form.
This class represents a selection list property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
string $defaultorderdirection
setTopAnchor(string $a_val)
isFilterSelected(string $a_col)
Is given filter selected?
isColumnSelected(string $col)
array $restore_filter_values
__construct(?object $a_parent_obj, string $a_parent_cmd="", string $a_template_context="")
setOrderLink(string $key, string $order_dir)
bool $enable_command_for_all
setShowRowsSelector(bool $a_value)
Toggle rows-per-page selector.
setFilterCommand(string $a_val, string $a_caption="")
getFormName()
get the name of the parent form
prepareOutput()
Anything that must be done before HTML is generated.
setOrderField(string $a_order_field)
setPreventDoubleSubmission(bool $a_val)
getFilterItemByPostVar(string $a_post_var)
getHTML()
Get HTML.
loadProperty(string $type)
bool $disable_filter_hiding
setContext(string $id)
setEnableAllCommand(bool $a_value)
setLimit(int $a_limit=0, int $a_default_limit=0)
set max.
bool $prevent_double_submission
string $requested_nav_par1
fillRowCSV(ilCSVWriter $a_csv, array $a_set)
CSV Version of Fill Row.
setIsDataTable(bool $a_val)
setRowSelectorLabel(string $row_selector_label)
determineOffsetAndOrder(bool $a_omit_offset=false)
setCustomPreviousNext(string $a_prev_link, string $a_next_link)
setOpenFormTag(bool $a_val)
setTitle(string $a_title, string $a_icon="", string $a_icon_alt="")
string $row_selector_label
setEnableNumInfo(bool $a_val)
setExportFormats(array $formats)
Set available export formats.
setExternalSegmentation(bool $a_val)
addCommandButton(string $a_cmd, string $a_text, string $a_onclick='', string $a_id="", string $a_class="")
addFilterItem(ilTableFilterItem $a_input_item, bool $a_optional=false)
setEnableTitle(bool $a_enabletitle)
setFormName(string $a_name="")
getLinkbar(string $a_num)
setDescription(string $a_val)
addHiddenInput(string $a_name, string $a_value)
addMultiCommand(string $a_cmd, string $a_text)
addFilterItemByMetaType(string $id, int $type=self::FILTER_TEXT, bool $a_optional=false, string $caption="")
Add filter by standard type.
setPrefix(string $a_prefix)
set prefix for sort and offset fields (if you have two or more tables on a page that you want to sort...
setFormAction(string $a_form_action, bool $a_multipart=false)
resetOffset(bool $a_in_determination=false)
setHeaderHTML(string $html)
string $defaultorderfield
addColumn(string $a_text, string $a_sort_field="", string $a_width="", bool $a_is_checkbox_action_column=false, string $a_class="", string $a_tooltip="", bool $a_tooltip_with_html=false)
ILIAS Table TableGUIRequest $table_request
fillHeaderCSV(ilCSVWriter $a_csv)
CSV Version of Fill Header.
setEnableHeader(bool $a_enableheader)
renderFilter()
Render Filter section.
fillRowExcel(ilExcel $a_excel, int &$a_row, array $a_set)
Excel Version of Fill Row.
isFilterVisible()
Check if filter is visible: manually shown (session, db) or default value set.
addCommandButtonInstance(ilButtonBase $a_button)
setDefaultOrderField(string $a_defaultorderfield)
string $row_template_dir
ilGlobalTemplateInterface $main_tpl
setPrintMode(bool $a_value=false)
setDisplayAsBlock(bool $a_val)
fillRow(array $a_set)
Standard Version of Fill Row.
getCurrentState()
get current settings for order, limit, columns and filter
getSelectableColumns()
Get selectable columns.
addHeaderCommand(string $a_href, string $a_text, string $a_target="", string $a_img="")
static getAllCommandLimit()
setSelectAllCheckbox(string $a_select_all_checkbox, bool $a_select_all_on_top=false)
string $requested_nav_par
setDisableFilterHiding(bool $a_val=true)
numericOrdering(string $a_field)
Should this field be sorted numeric?
setNoEntriesText(string $a_text)
fillMetaExcel(ilExcel $a_excel, int &$a_row)
Add meta information to excel export.
setTopCommands(bool $a_val)
getFilterItems(bool $a_optionals=false)
setFilterValue(ilTableFilterItem $a_item, $a_value)
setExternalSorting(bool $a_val)
isAdvMDFilter(ilAdvancedMDRecordGUI $a_gui, ilTableFilterItem $a_element)
Check if filter element is based on adv md.
array $selectable_columns
const FILTER_DURATION_RANGE
string $requested_nav_par2
addMultiItemSelectionButton(string $a_sel_var, array $a_options, string $a_cmd, string $a_text, string $a_default_selection='')
setCloseCommand(string $a_link)
getFilterValue(ilTableFilterItem $a_item)
Get current filter value.
setRowTemplate(string $a_template, string $a_template_dir="")
Set row template.
setId(string $a_val)
bool $default_filter_visibility
setDefaultOrderDirection(string $a_defaultorderdirection)
setFilterCols(int $a_val)
setResetCommand(string $a_val, string $a_caption="")
storeProperty(string $type, string $value)
ILIAS DI UIServices $ui
setDefaultFilterVisiblity(bool $a_status)
setData(array $a_data)
Set table data.
const FILTER_NUMBER_RANGE
exportData(int $format, bool $send=false)
Export and optionally send current table data.
fillMetaCSV(ilCSVWriter $a_csv)
Add meta information to csv export.
fillHeaderExcel(ilExcel $a_excel, int &$a_row)
Excel Version of Fill Header.
setCloseFormTag(bool $a_val)
const FILTER_DATETIME_RANGE
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilLanguage $lng
setOffset(int $a_offset)
set dataset offset
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
special template class to simplify handling of ITX/PEAR
This class represents a text property in a property form.
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static img(string $a_src, ?string $a_alt=null, $a_width="", $a_height="", $a_border=0, $a_id="", $a_class="")
Build img tag.
static initConnection(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI Connection module.
const ANONYMOUS_USER_ID
Definition: constants.php:27
$c
Definition: deliver.php:25
$valid
exit
$txt
Definition: error.php:31
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $lng
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26
$url
Definition: shib_logout.php:68
$context
Definition: webdav.php:31