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