ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilOrgUnitGenericMultiInputGUI.php
Go to the documentation of this file.
1 <?php
2 
20 declare(strict_types=1);
21 
25 
32 {
33  public const HOOK_IS_LINE_REMOVABLE = "hook_is_line_removable";
34  public const HOOK_IS_INPUT_DISABLED = "hook_is_disabled";
35  public const HOOK_BEFORE_INPUT_RENDER = "hook_before_render";
36 
37  public const MULTI_FIELD_ID = "id";
38  public const MULTI_FIELD_OVER = "over";
39  public const MULTI_FIELD_SCOPE = "scope";
40 
41  protected array $cust_attr = [];
42  protected $value;
43  protected array $inputs = [];
44  protected array $input_options = [];
45  protected array $hooks = [];
46  protected array $line_values = [];
47  protected string $template_dir = '';
48  protected array $post_var_cache = [];
49  protected bool $show_label = false;
50  protected bool $show_label_once = false;
51  protected array $hidden_inputs = [];
52  protected bool $position_movable = false;
53  protected int $counter = 0;
54  protected bool $show_info = false;
55  protected bool $render_one_for_empty_value = true;
56 
60 
61  public function __construct(string $a_title = "", string $a_postvar = "")
62  {
63  parent::__construct($a_title, $a_postvar);
64  $this->setType("line_select");
65  $this->setMulti(true);
66  $this->initCSSandJS();
67 
68  global $DIC;
69  $this->ui_factory = $DIC['ui.factory'];
70  $this->ui_renderer = $DIC['ui.renderer'];
71  $this->renderer_loader = $DIC["ui.component_renderer_loader"];
72 
73  }
74 
75  public function getHook(string $key)
76  {
77  if (isset($this->hooks[$key])) {
78  return $this->hooks[$key];
79  }
80 
81  return false;
82  }
83 
84  public function addHook(string $key, array $options)
85  {
86  $this->hooks[$key] = $options;
87  }
88 
89  public function removeHook(string $key): bool
90  {
91  if (isset($this->hooks[$key])) {
92  unset($this->hooks[$key]);
93 
94  return true;
95  }
96 
97  return false;
98  }
99 
100  public function addInput(\ilFormPropertyGUI $input, array $options = []): void
101  {
102  $this->inputs[$input->getPostVar()] = $input;
103  $this->input_options[$input->getPostVar()] = $options;
104  $this->counter++;
105  }
106 
107  public function getTemplateDir(): string
108  {
109  return $this->template_dir;
110  }
111 
112  public function setTemplateDir(string $template_dir)
113  {
114  $this->template_dir = $template_dir;
115  }
116 
117  public function isShowLabel(): bool
118  {
119  return $this->show_label;
120  }
121 
122  public function setShowLabel(bool $show_label)
123  {
124  $this->show_label = $show_label;
125  }
126 
131  public function getInputs(): array
132  {
133  return $this->inputs;
134  }
135 
136  public function setMulti(bool $a_multi, bool $a_sortable = false, bool $a_addremove = true): void
137  {
138  $this->multi = $a_multi;
139  }
140 
141  public function setValue(array $value)
142  {
143  $this->value = $value;
144 
145  foreach ($this->inputs as $key => $item) {
146  if ($item instanceof \ilDateTimeInputGUI) {
147  $item->setDate(new \ilDate($value[$key]['date'], IL_CAL_DATE));
148  } else {
149  if (array_key_exists($key, $value)) {
150  $item->setValue((string) $value[$key]);
151  }
152  }
153  }
154  }
155 
156  public function getValue(): array
157  {
158  $out = [];
159  foreach ($this->inputs as $key => $item) {
160  $out[$key] = $item->getValue();
161  }
162 
163  return $out;
164  }
165 
166  public function setValueByArray(array $a_values): void
167  {
168  $data = $a_values[$this->getPostVar()] ?? [];
169  if ($this->getMulti()) {
170  $this->line_values = $data;
171  } else {
172  $this->setValue($data);
173  }
174  }
175 
180  public function checkInput(): bool
181  {
182  $internal_fields = array_keys($this->inputs);
183  $key = $this->getPostVar();
184  $post = $this->raw($key);
185 
186  if (is_array($post)) {
187  foreach ($post as $authority) {
188  if (!(
189  array_key_exists(self::MULTI_FIELD_ID, $authority) &&
190  array_key_exists(self::MULTI_FIELD_OVER, $authority) &&
191  array_key_exists(self::MULTI_FIELD_SCOPE, $authority) &&
192  trim($authority[self::MULTI_FIELD_OVER]) !== '' &&
193  trim($authority[self::MULTI_FIELD_SCOPE]) !== ''
194  )) {
195  $this->setAlert($this->lng->txt("msg_input_is_required"));
196  return false;
197  }
198  }
199  }
200 
201  return true;
202  }
203 
204  public function addCustomAttribute(string $key, string $value, bool $override = false): void
205  {
206  if (isset($this->cust_attr[$key]) && !$override) {
207  $this->cust_attr[$key] .= ' ' . $value;
208  } else {
209  $this->cust_attr[$key] = $value;
210  }
211  }
212 
213  public function getCustomAttributes(): array
214  {
215  return (array) $this->cust_attr;
216  }
217 
218  private function createInputPostVar(string $iterator_id, \ilFormPropertyGUI $input): string
219  {
220  if ($this->getMulti()) {
221  return $this->getPostVar() . '[' . $iterator_id . '][' . $input->getPostVar() . ']';
222  } else {
223  return $this->getPostVar() . '[' . $input->getPostVar() . ']';
224  }
225  }
226 
227 
228  public function render(int|string $iterator_id = 0, bool $clean_render = false): string
229  {
230  $first_label = true;
231  $tpl = new ilTemplate("tpl.prop_generic_multi_line.html", true, true, 'components/ILIAS/OrgUnit');
232 
233  $class = 'multi_input_line';
234  $this->addCustomAttribute('class', $class, true);
235  foreach ($this->getCustomAttributes() as $key => $value) {
236  $tpl->setCurrentBlock('cust_attr');
237  $tpl->setVariable('CUSTOM_ATTR_KEY', $key);
238  $tpl->setVariable('CUSTOM_ATTR_VALUE', $value);
239  $tpl->parseCurrentBlock();
240  }
241  $inputs = $this->inputs;
242  foreach ($inputs as $key => $input) {
243  $input = clone $input;
244  $is_hidden = false;
245  $is_ta = false;
246  if (!method_exists($input, 'render')) {
247  switch (true) {
248  case ($input instanceof \ilHiddenInputGUI):
249  $is_hidden = true;
250  break;
251  case ($input instanceof \ilTextAreaInputGUI):
252  $is_ta = true;
253  break;
254  default:
255  throw new \ilException("Method " . get_class($input)
256  . "::render() does not exists! You cannot use this input-type in ilMultiLineInputGUI");
257  }
258  }
259 
260  $is_disabled_hook = $this->getHook(self::HOOK_IS_INPUT_DISABLED);
261  if ($is_disabled_hook !== false && !$clean_render) {
262  $input->setDisabled($is_disabled_hook($this->getValue()));
263  }
264  if ($this->getDisabled()) {
265  $input->setDisabled(true);
266  }
267  if ($iterator_id == 0 && !isset($this->post_var_cache[$key])) {
268  $this->post_var_cache[$key] = $input->getPostVar();
269  } else {
270  // Reset post var
271  $input->setPostVar($this->post_var_cache[$key]);
272  }
273  $post_var = $this->createInputPostVar((string) $iterator_id, $input);
274  $input->setPostVar($post_var);
275  $before_render_hook = $this->getHook(self::HOOK_BEFORE_INPUT_RENDER);
276  if ($before_render_hook !== false && !$clean_render) {
277  $input = $before_render_hook($this->getValue(), $key, $input);
278  }
279  switch (true) {
280  case $is_hidden:
281  $tpl->setCurrentBlock('hidden');
282  $tpl->setVariable('NAME', $post_var);
283  $tpl->setVariable('VALUE', ilLegacyFormElementsUtil::prepareFormOutput($input->getValue()));
284  break;
285  case $is_ta:
286  if ($this->isShowLabel() || ($this->isShowLabelOnce() && $first_label)) {
287  $tpl->setCurrentBlock('input_label');
288  $tpl->setVariable('LABEL', $input->getTitle());
289  $tpl->setVariable('CONTENT', $input->getHTML());
290  $tpl->parseCurrentBlock();
291  $first_label = false;
292  } else {
293  $tpl->setCurrentBlock('input');
294  $tpl->setVariable('CONTENT', $input->getHTML());
295  }
296  break;
297  default:
298  if ($this->isShowLabel() || ($this->isShowLabelOnce() && $first_label)) {
299  $tpl->setCurrentBlock('input_label');
300  $tpl->setVariable('LABEL', $input->getTitle());
301  $tpl->setVariable('CONTENT', $input->render());
302  $first_label = false;
303  } else {
304  $tpl->setCurrentBlock('input');
305  $tpl->setVariable('CONTENT', $input->render());
306  }
307  break;
308  }
309  if ($this->isShowInfo()) {
310  if ($this->isShowLabel()) {
311  $tpl->setCurrentBlock('input_info_label');
312  $tpl->setVariable('INFO_LABEL', $input->getInfo());
313  $tpl->parseCurrentBlock();
314  } else {
315  $tpl->setCurrentBlock('input_info');
316  $tpl->setVariable('INFO', $input->getInfo());
317  $tpl->parseCurrentBlock();
318  }
319  }
320  $tpl->parseCurrentBlock();
321  }
322  if ($this->getMulti() && !$this->getDisabled()) {
323  $is_removeable_hook = $this->getHook(self::HOOK_IS_LINE_REMOVABLE);
324  if ($is_removeable_hook !== false && !$clean_render) {
325  $show_remove = $is_removeable_hook($this->getValue());
326  }
327  $tpl->setCurrentBlock('multi_icons');
328  $tpl->setVariable('IMAGE_PLUS', $this->getGlyph('add'));
329  $tpl->setVariable('IMAGE_MINUS', $this->getGlyph('remove'));
330  $tpl->parseCurrentBlock();
331 
332  if ($this->isPositionMovable()) {
333  $tpl->setCurrentBlock('multi_icons_move');
334  $tpl->setVariable('IMAGE_UP', $this->getGlyph('up'));
335  $tpl->setVariable('IMAGE_DOWN', $this->getGlyph('down'));
336  $tpl->parseCurrentBlock();
337  }
338  }
339 
340  return $tpl->get();
341  }
342 
343  public function initCSSandJS()
344  {
345  $this->global_tpl->addJavascript('assets/js/generic_multi_line_input.js');
346  }
347 
352  public function insert(\ilTemplate $a_tpl): void
353  {
354  $output = "";
355 
356  $output .= $this->render(0, true);
357  if ($this->getMulti() && is_array($this->line_values) && count($this->line_values) > 0) {
358  $tpl = new ilTemplate("tpl.prop_generic_multi_line.html", true, true, 'components/ILIAS/OrgUnit');
359  $tpl->setVariable('ADDITIONAL_ATTRS', "id='multi_line_add_button' style='display:none'");
360  $tpl->setCurrentBlock('multi_icons');
361  $tpl->setVariable('IMAGE_PLUS', $this->getGlyph('add'));
362  $tpl->setVariable('IMAGE_MINUS', $this->getGlyph('remove'));
363  $tpl->parseCurrentBlock();
364  $output .= $tpl->get();
365 
366  foreach ($this->line_values as $run => $data) {
367  $object = $this;
368  $object->setValue($data);
369  $output .= $object->render($run);
370  }
371  } else {
372  if ($this->render_one_for_empty_value) {
373  $output .= $this->render(0, true);
374  } else {
375  $tpl = new ilTemplate("tpl.prop_generic_multi_line.html", true, true, 'components/ILIAS/OrgUnit');
376  $tpl->setVariable('ADDITIONAL_ATTRS', "id='multi_line_add_button'");
377  $tpl->setCurrentBlock('multi_icons');
378  $tpl->setVariable('IMAGE_PLUS', $this->getGlyph('add'));
379  $tpl->setVariable('IMAGE_MINUS', $this->getGlyph('remove'));
380 
381  $tpl->parseCurrentBlock();
382  $output .= $tpl->get();
383  }
384  }
385  if ($this->getMulti()) {
386  $output = "<div style=\"display:none;\" id='{$this->getFieldId()}' class='multi_line_input'>{$output}</div>";
387  $config = json_encode($this->input_options);
388  $options = json_encode([
389  'limit' => 999999,
390  'sortable' => false,
391  'locale' => $this->lng->getLangKey()
392  ]);
393  global $tpl;
394  $tpl->addOnLoadCode("
395  il.DataCollection.genericMultiLineInit('{$this->getFieldId()}',$config,$options);
396  document.body.querySelector('#{$this->getFieldId()}').removeAttribute('style');
397  ");
398  }
399 
400  $a_tpl->setCurrentBlock("prop_generic");
401  $a_tpl->setVariable("PROP_GENERIC", $output);
402  $a_tpl->parseCurrentBlock();
403  }
404 
408  public function getTableFilterHTML(): string
409  {
410  return $this->render();
411  }
412 
416  public function getToolbarHTML(): string
417  {
418  return $this->render("toolbar");
419  }
420 
421  public function isPositionMovable(): bool
422  {
424  }
425 
426  public function setPositionMovable(bool $position_movable): void
427  {
428  $this->position_movable = $position_movable;
429  }
430 
431  public function isShowLabelOnce(): bool
432  {
433  return $this->show_label_once;
434  }
435 
436  public function setShowLabelOnce(bool $show_label_once): void
437  {
438  $this->setShowLabel(false);
439  $this->show_label_once = $show_label_once;
440  }
441 
442  public function isShowInfo(): bool
443  {
444  return $this->show_info;
445  }
446 
447  public function setShowInfo(bool $show_info): void
448  {
449  $this->show_info = $show_info;
450  }
451 
452  public function isRenderOneForEmptyValue(): bool
453  {
455  }
456 
457  public function setRenderOneForEmptyValue(bool $render_one_for_empty_value): void
458  {
459  $this->render_one_for_empty_value = $render_one_for_empty_value;
460  }
461 
462  private function getGlyph(string $which): string
463  {
464  $symbol = $this->ui_factory->symbol()->glyph()->$which();
469  $renderer = $this->renderer_loader->getRendererFor(
470  $symbol,
471  [$this->ui_factory->button()->bulky($symbol, '', '')]
472  );
473  return $renderer->render($symbol, $this->ui_renderer);
474  }
475 }
parseCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
addInput(\ilFormPropertyGUI $input, array $options=[])
checkInput()
Check input, strip slashes etc.
insert(\ilTemplate $a_tpl)
Insert property html.
$renderer
setMulti(bool $a_multi, bool $a_sortable=false, bool $a_addremove=true)
render(int|string $iterator_id=0, bool $clean_render=false)
addCustomAttribute(string $key, string $value, bool $override=false)
static prepareFormOutput($a_str, bool $a_strip=false)
setRenderOneForEmptyValue(bool $render_one_for_empty_value)
This class represents a date/time property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:546
__construct(string $a_title="", string $a_postvar="")
$out
Definition: buildRTE.php:24
global $DIC
Definition: shib_login.php:25
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
const IL_CAL_DATE
createInputPostVar(string $iterator_id, \ilFormPropertyGUI $input)
__construct(Container $dic, ilPlugin $plugin)
This class represents a text area property in a property form.
$post
Definition: ltitoken.php:46