ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
Table.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
23 use ilYuiUtil;
24 use iljQueryUtil;
25 use Closure;
30 use ilTable2GUI;
36 
37 class Table extends ilTable2GUI implements TableSelection
38 {
40  private readonly array $columns;
42  private array $sel = [];
43 
44  public function __construct(?object $gui, string $command, TableInterface $table)
45  {
46  global $DIC;
47  $apply = fn($proc) => fn(array $args) => $proc(...$args);
48  $translate = fn(string $txt, ...$args) => [$txt, ...$args];
49 
50  $id = substr(md5($table->name()), 0, 30);
51  $this->setId($id);
52  $this->columns = array_map($apply($translate), $table->columns());
53  $this->setFormName($id);
54  $config = new SmoothTableConfig($this);
55  $table->config($config);
56  parent::__construct($gui, $command);
57  $config->flush();
58  $this->setFormAction($this->ctrl->getFormAction($this->getParentObject(), $command));
59  $this->setRowTemplate('legacy-table-row.html', 'Services/LegalDocuments');
60  array_map($apply($this->addColumn(...)), $this->visibleColumns());
61  $this->setShowRowsSelector(false);
62  $this->setExternalSorting(true);
63  $this->setExternalSegmentation(true);
64  iljQueryUtil::initjQuery($DIC->ui()->mainTemplate());
65  ilYuiUtil::initPanel(false, $DIC->ui()->mainTemplate());
66  ilYuiUtil::initOverlay($DIC->ui()->mainTemplate());
67  $DIC->ui()->mainTemplate()->addJavaScript('./Services/Form/js/Form.js');
68  $this->determineOffsetAndOrder();
69  $this->setData($table->rows($this));
70  }
71 
72  public function setMaxCount(int $a_max_count): void
73  {
74  $this->setShowRowsSelector(true);
75  parent::setMaxCount($a_max_count);
76  }
77 
78  public function setSelectableColumns(...$names): void
79  {
80  $this->sel = array_merge($this->sel, $names);
81  }
82 
83  public function selection(): array
84  {
85  return array_flip($this->sel);
86  }
87 
88  public function getSelectableColumns(): array
89  {
90  return array_map(fn($x) => ['txt' => $x[0]], array_intersect_key(
91  $this->columns,
92  $this->selection()
93  ));
94  }
95 
96  public function filter(): array
97  {
98  return array_column(array_map(
99  fn($input) => [
100  $input->getPostVar(),
101  $input->getValue()
102  ],
103  $this->filterInputs()
104  ), 1, 0);
105  }
106 
107  public function render(): string
108  {
109  return parent::render() . $this->renderModals();
110  }
111 
112  protected function isColumnVisible(int $index): bool
113  {
114  return true;
115  }
116 
117  private function visibleColumns(): array
118  {
119  $restore_key_order = fn($array) => array_intersect_key($this->columns, $array);
120  $base = array_diff_key($this->columns, $this->selection());
121 
122  return $restore_key_order(array_merge($base, array_intersect_key($this->columns, $this->getSelectedColumns())));
123  }
124 
128  private function resetParameters(array $parameters): void
129  {
130  $this->applyParamters(array_map(static fn(): string => '', $parameters));
131  }
132 
136  private function applyParamters(array $parameters): void
137  {
138  foreach ($parameters as $key => $value) {
139  $this->ctrl->setParameter($this->getParentObject(), $key, $value);
140  }
141  }
142 
143  protected function fillRow(array $a_set): void
144  {
145  $this->requireKeys(array_keys($this->columns), $a_set);
146  $set = array_intersect_key($a_set, $this->visibleColumns());
147  $this->tpl->setVariable('VALUE', join('', array_map($this->tableCellOfField(...), $set)));
148  }
149 
150  protected function tableCellOfField($x): string
151  {
152  return sprintf('<td>%s</td>', $this->asString($x));
153  }
154 
158  private function asString($x): string
159  {
160  $is_component = fn($x): bool => $x instanceof Component;
161 
162  if ($is_component($x) || (is_array($x) && array_filter($x, fn($x) => !$is_component($x)) === [])) {
163  global $DIC;
164  return $DIC->ui()->renderer()->render($this->removeModals($x));
165  } elseif ($x instanceof Closure) {
166  return $x();
167  } elseif (is_string($x)) {
168  return htmlentities($x);
169  }
170 
171  throw new InvalidArgumentException('Value must be either: Component|list<Component>|Closure|string. Given: ' . var_export($x, true));
172  }
173 
174  protected function txt(string $key): string
175  {
176  return $key === '' ? '' : $this->lng->txt($key);
177  }
178 
183  private function requireKeys(array $required, array $given): void
184  {
185  $given = array_keys($given);
186  $missing = $this->intersect($required, $this->diff($required, $given));
187  if ([] !== $missing) {
188  throw new InvalidArgumentException('Missing keys: ' . join(', ', $missing));
189  }
190  }
191 
192  private function diff(array $a, array $b): array
193  {
194  return array_filter($a, fn($x) => !$this->has($x, $b));
195  }
196 
197  private function intersect(array $a, array $b): array
198  {
199  return array_filter($a, fn($x) => $this->has($x, $b));
200  }
201 
202  private function has($x, array $array): bool
203  {
204  return in_array($x, $array, true);
205  }
206 
207  private function filterInputs(): array
208  {
209  return [
210  ...$this->getFilterItems(),
211  ...$this->getFilterItems(true),
212  ];
213  }
214 
215  public function setupFilter(string $reset_command): void
216  {
217  global $DIC;
218  $this->initFilter();
219  $this->setFilterCommand($this->getParentCmd());
220  $this->setResetCommand($reset_command);
221  $this->determineSelectedFilters();
222  if ($DIC->ctrl()->getCmd() === $reset_command) {
223  $this->resetFilter();
224  } elseif (strtoupper($DIC->http()->request()->getMethod()) === 'POST') {
225  $this->writeFilterToSession();
226  } else {
227  $read = static fn(ilFormPropertyGUI $x) => $x->readFromSession();
228  array_map($read, $this->getFilterItems());
229  array_map($read, array_filter($this->getFilterItems(true), fn($x) => $this->isFilterSelected($x->getPostVar())));
230  }
231  }
232 
233  private function renderModals(): string
234  {
235  global $DIC;
236 
237  return $DIC->ui()->renderer()->render($this->flatMap(
238  fn($x) => $this->flatMap(fn($x) => array_filter($this->asArray($x), $this->isModal(...)), $x),
239  $this->getData()
240  ));
241  }
242 
243  private function removeModals($x): array
244  {
245  return array_filter($this->asArray($x), fn($x) => !$this->isModal($x));
246  }
247 
248  private function flatMap(callable $proc, array $a): array
249  {
250  return array_merge(...array_values(array_map($proc, $a)));
251  }
252 
253  private function asArray($x): array
254  {
255  return is_array($x) ? $x : [$x];
256  }
257 
258  private function isModal($x): bool
259  {
260  return $x instanceof Modal;
261  }
262 }
This describes commonalities between the different modals.
Definition: Modal.php:34
setData(array $a_data)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
intersect(array $a, array $b)
Definition: Table.php:197
This class takes care of the order in which the methods must be called.
setFormAction(string $a_form_action, bool $a_multipart=false)
setResetCommand(string $a_val, string $a_caption="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
diff(array $a, array $b)
Definition: Table.php:192
requireKeys(array $required, array $given)
Definition: Table.php:183
flatMap(callable $proc, array $a)
Definition: Table.php:248
setFormName(string $a_name="")
setSelectableColumns(... $names)
Definition: Table.php:78
applyParamters(array $parameters)
Definition: Table.php:136
setId(string $a_val)
resetParameters(array $parameters)
Definition: Table.php:128
global $DIC
Definition: feed.php:28
__construct(?object $gui, string $command, TableInterface $table)
Definition: Table.php:44
isFilterSelected(string $a_col)
Is given filter selected?
setupFilter(string $reset_command)
Definition: Table.php:215
setExternalSorting(bool $a_val)
setShowRowsSelector(bool $a_value)
Toggle rows-per-page selector.
__construct(VocabulariesInterface $vocabularies)
setRowTemplate(string $a_template, string $a_template_dir="")
Set row template.
setFilterCommand(string $a_val, string $a_caption="")
string $key
Consumer key/client ID value.
Definition: System.php:193
$txt
Definition: error.php:14
static initjQuery(ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery JS-File to the global or a passed template
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
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)
getFilterItems(bool $a_optionals=false)
setMaxCount(int $a_max_count)
Definition: Table.php:72
determineOffsetAndOrder(bool $a_omit_offset=false)
static initPanel(bool $a_resize=false, ?ilGlobalTemplateInterface $a_main_tpl=null)
Init yui panel used in Modules/Test, Services/TermsOfService (Jan 2022)
static initOverlay(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI Overlay module used in Modules/Test, Services/TermsOfService, Services/Tracking, Services/UIComponent.
setExternalSegmentation(bool $a_val)