ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilTable2GUI.php
Go to the documentation of this file.
1 <?php
2 
25 class ilTable2GUI extends ilTableGUI
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 = "";
43  protected ?\ILIAS\Table\TableGUIRequest $table_request = null;
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);
169  $this->determineSelectedColumns();
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  {
194  return $this->open_form_tag;
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  {
204  return $this->close_form_tag;
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) {
357  $this->determineOffsetAndOrder();
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  {
395  return $this->noentriestext;
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 = ""
522  ): ?ilTableFilterItem {
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  }
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  {
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  {
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  {
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  {
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  {
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"]) {
1307  $data = ilArrayUtil::sortArray(
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  {
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  {
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  {
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 }
setNoEntriesText(string $a_text)
setOffset(int $a_offset)
set dataset offset
array $restore_filter_values
setData(array $a_data)
numericOrdering(string $a_field)
Should this field be sorted numeric?
This class represents a duration (typical hh:mm:ss) property in a property form.
static array static setUseRelativeDates(bool $a_status)
set use relative dates
addColumn(string $a_col)
ILIAS DI UIServices $ui
prepareOutput()
Anything that must be done before HTML is generated.
string $row_selector_label
setTopCommands(bool $a_val)
bool $enable_command_for_all
fillMetaCSV(ilCSVWriter $a_csv)
Add meta information to csv export.
setExportFormats(array $formats)
Set available export formats.
addCommandButtonInstance(ilButtonBase $a_button)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const ANONYMOUS_USER_ID
Definition: constants.php:27
getStyle(string $a_element)
bool $disable_filter_hiding
This class represents a selection list property in a property form.
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
setFormAction(string $a_form_action, bool $a_multipart=false)
addFilterItem(ilTableFilterItem $a_input_item, bool $a_optional=false)
setOrderLink(string $key, string $order_dir)
string $defaultorderdirection
string $requested_nav_par2
fillRowCSV(ilCSVWriter $a_csv, array $a_set)
CSV Version of Fill Row.
getSelectableColumns()
Get selectable columns.
setEnableTitle(bool $a_enabletitle)
renderFilter()
Render Filter section.
ILIAS Table TableGUIRequest $table_request
loadProperty(string $type)
addCommandButton(string $a_cmd, string $a_text, string $a_onclick='', string $a_id="", string $a_class="")
setResetCommand(string $a_val, string $a_caption="")
setSelectAllCheckbox(string $a_select_all_checkbox, bool $a_select_all_on_top=false)
$valid
getColumnCoord(int $a_col)
Get column "name" from number.
setCloseFormTag(bool $a_val)
setDescription(string $a_val)
setDisableFilterHiding(bool $a_val=true)
string $requested_nav_par1
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.
setPrintMode(bool $a_value=false)
isAdvMDFilter(ilAdvancedMDRecordGUI $a_gui, ilTableFilterItem $a_element)
Check if filter element is based on adv md.
loadLanguageModule(string $a_module)
Load language module.
$url
Definition: shib_logout.php:68
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$c
Definition: deliver.php:25
setFormName(string $a_name="")
static img(string $a_src, ?string $a_alt=null, $a_width="", $a_height="", $a_border=0, $a_id="", $a_class="")
Build img tag.
ilLanguage $lng
const FILTER_NUMBER_RANGE
array $selectable_columns
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setId(string $a_val)
getFilterValue(ilTableFilterItem $a_item)
Get current filter value.
getFilterItemByPostVar(string $a_post_var)
This class represents a date/time property in a property form.
exportData(int $format, bool $send=false)
Export and optionally send current table data.
ilGlobalTemplateInterface $main_tpl
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
setIsDataTable(bool $a_val)
addMultiItemSelectionButton(string $a_sel_var, array $a_options, string $a_cmd, string $a_text, string $a_default_selection='')
isFilterSelected(string $a_col)
Is given filter selected?
resetOffset(bool $a_in_determination=false)
getHTML()
Get HTML.
setExternalSorting(bool $a_val)
bool $default_filter_visibility
isColumnSelected(string $col)
setCell(int $a_row, int $col, $value, ?string $datatype=null, bool $disable_strip_tags_for_strings=false)
Set cell value.
setShowRowsSelector(bool $a_value)
Toggle rows-per-page selector.
addFilterItemByMetaType(string $id, int $type=self::FILTER_TEXT, bool $a_optional=false, string $caption="")
Add filter by standard type.
setBold(string $a_coords)
Set cell(s) to bold.
getNextClass($a_gui_class=null)
fillRow(array $a_set)
Standard Version of Fill Row.
const FILTER_DATETIME_RANGE
addHiddenInput(string $a_name, string $a_value)
isFilterVisible()
Check if filter is visible: manually shown (session, db) or default value set.
setOrderDirection(string $a_order_direction)
setDefaultOrderField(string $a_defaultorderfield)
This class represents a number property in a property form.
const FILTER_DURATION_RANGE
setRowTemplate(string $a_template, string $a_template_dir="")
Set row template.
setContext(string $id)
setFilterCommand(string $a_val, string $a_caption="")
global $DIC
Definition: shib_login.php:26
static getAllCommandLimit()
fillMetaExcel(ilExcel $a_excel, int &$a_row)
Add meta information to excel export.
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
setDefaultOrderDirection(string $a_defaultorderdirection)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
fillRowExcel(ilExcel $a_excel, int &$a_row, array $a_set)
Excel Version of Fill Row.
setEnableAllCommand(bool $a_value)
string $row_template_dir
setTopAnchor(string $a_val)
addHeaderCommand(string $a_href, string $a_text, string $a_target="", string $a_img="")
getInstalledLanguages()
Get installed languages.
$txt
Definition: error.php:31
setCloseCommand(string $a_link)
exit
fillHeaderCSV(ilCSVWriter $a_csv)
CSV Version of Fill Header.
setOrderField(string $a_order_field)
getLinkbar(string $a_num)
setTitle(string $a_title, string $a_icon="", string $a_icon_alt="")
$filename
Definition: buildRTE.php:78
setFilterValue(ilTableFilterItem $a_item, $a_value)
fillHeaderExcel(ilExcel $a_excel, int &$a_row)
Excel Version of Fill Header.
This class represents a number property in a property form.
const IL_CAL_DATE
setRowSelectorLabel(string $row_selector_label)
setEnableNumInfo(bool $a_val)
setPreventDoubleSubmission(bool $a_val)
setFooter(string $a_style, string $a_previous="", string $a_next="")
__construct(Container $dic, ilPlugin $plugin)
setLimit(int $a_limit=0, int $a_default_limit=0)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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)
getCurrentState()
get current settings for order, limit, columns and filter
getFilterElements(bool $a_only_non_empty=true)
Get SQL conditions for current filter value(s)
string $requested_nav_par
__construct(?object $a_parent_obj, string $a_parent_cmd="", string $a_template_context="")
setParameter(object $a_gui_obj, string $a_parameter, $a_value)
setDisplayAsBlock(bool $a_val)
setHeaderHTML(string $html)
string $defaultorderfield
getFilterItems(bool $a_optionals=false)
setOpenFormTag(bool $a_val)
setDefaultFilterVisiblity(bool $a_status)
addMultiCommand(string $a_cmd, string $a_text)
header()
expected output: > ILIAS shows the rendered Component.
Definition: header.php:29
setCustomPreviousNext(string $a_prev_link, string $a_next_link)
static initConnection(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI Connection module.
determineOffsetAndOrder(bool $a_omit_offset=false)
getSelectAllCheckbox()
get the name of the checkbox that should be toggled with a select all button
storeProperty(string $type, string $value)
setEnableHeader(bool $a_enableheader)
setMaxCount(int $a_max_count)
set max.
bool $prevent_double_submission
setFilterCols(int $a_val)
setExternalSegmentation(bool $a_val)
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)
setPrefix(string $a_prefix)