ILIAS  trunk Revision v11.0_alpha-1753-gb21ca8c4367
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.FormAdapterGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
26 
31 {
32  use StdObjProperties;
33 
34  protected const DEFAULT_SECTION = "@internal_default_section";
35  protected bool $in_modal = false;
36  protected string $submit_caption = "";
37  protected \ilLanguage $lng;
38  protected const ASYNC_NONE = 0;
39  protected const ASYNC_MODAL = 1;
40  protected const ASYNC_ON = 2;
41  protected \ILIAS\Data\Factory $data;
42  protected \ilObjUser $user;
43  protected string $last_key = "";
44  protected \ILIAS\Refinery\Factory $refinery;
45 
46  protected string $title = "";
47  protected array $values = [];
48  protected array $disable = [];
49 
53  protected $raw_data = null;
54  protected \ILIAS\HTTP\Services $http;
55  protected \ilCtrlInterface $ctrl;
56  protected \ILIAS\DI\UIServices $ui;
57  protected array $fields = [];
58  protected array $field_path = [];
59  protected array $sections = [self::DEFAULT_SECTION => ["title" => "", "description" => "", "fields" => []]];
60  protected string $current_section = self::DEFAULT_SECTION;
61  protected array $section_of_field = [];
62  protected $class_path;
63  protected string $cmd = self::DEFAULT_SECTION;
64  protected ?Form\Standard $form = null;
65  protected array $upload_handler = [];
66  protected int $async_mode = self::ASYNC_NONE;
67  protected \ilGlobalTemplateInterface $main_tpl;
68  protected ?array $current_switch = null;
69  protected ?array $current_optional = null;
70  protected ?array $current_group = null;
71  protected static bool $initialised = false;
72 
76  public function __construct(
78  string $cmd,
79  string $submit_caption = ""
80  ) {
81  global $DIC;
82  $this->class_path = $class_path;
83  $this->cmd = $cmd;
84  $this->ui = $DIC->ui();
85  $this->ctrl = $DIC->ctrl();
86  $this->http = $DIC->http();
87  $this->lng = $DIC->language();
88  $this->refinery = $DIC->refinery();
89  $this->main_tpl = $DIC->ui()->mainTemplate();
90  $this->user = $DIC->user();
91  $this->data = new \ILIAS\Data\Factory();
92  $this->submit_caption = $submit_caption;
93  self::initJavascript();
94  $this->initStdObjProperties($DIC);
95  $this->lng->loadLanguageModule("rep");
96  }
97 
98  public static function getOnLoadCode(): string
99  {
100  return "il.repository.ui.init();\n" .
101  "il.repository.core.init('" . ILIAS_HTTP_PATH . "')";
102  }
103 
104  public static function initJavascript(): void
105  {
106  global $DIC;
107 
108  if (!isset($DIC["ui.factory"])) {
109  return;
110  }
111 
112  $f = $DIC->ui()->factory();
113  $r = $DIC->ui()->renderer();
114  if (!self::$initialised) {
115  $main_tpl = $DIC->ui()->mainTemplate();
116  $main_tpl->addJavaScript("assets/js/repository.js");
117  $main_tpl->addOnLoadCode(self::getOnLoadCode());
118 
119  // render dummy components to load the necessary .js needed for async processing
120  $d = [];
121  $d[] = $f->input()->field()->text("");
122  $r->render($d);
123  self::$initialised = true;
124  }
125  }
126 
127  public function asyncModal(): self
128  {
129  $this->async_mode = self::ASYNC_MODAL;
130  $this->in_modal = true;
131  return $this;
132  }
133 
134  public function async(): self
135  {
136  $this->async_mode = self::ASYNC_ON;
137  return $this;
138  }
139 
140  public function syncModal(): self
141  {
142  $this->in_modal = true;
143  return $this;
144  }
145 
146  public function isSentAsync(): bool
147  {
148  return ($this->async_mode !== self::ASYNC_NONE);
149  }
150 
151  public function getTitle(): string
152  {
153  return $this->title;
154  }
155 
156  public function section(
157  string $key,
158  string $title,
159  string $description = ""
160  ): self {
161  if ($this->title == "") {
162  $this->title = $title;
163  }
164 
165  $this->sections[$key] = [
166  "title" => $title,
167  "description" => $description,
168  "fields" => []
169  ];
170  $this->current_section = $key;
171  return $this;
172  }
173 
174  public function text(
175  string $key,
176  string $title,
177  string $description = "",
178  ?string $value = null
179  ): self {
180  $this->values[$key] = $value;
181  $field = $this->ui->factory()->input()->field()->text($title, $description);
182  if (!is_null($value)) {
183  $field = $field->withValue($value);
184  }
185  $this->addField($key, $field);
186  return $this;
187  }
188 
189  public function checkbox(
190  string $key,
191  string $title,
192  string $description = "",
193  ?bool $value = null
194  ): self {
195  $this->values[$key] = $value;
196  $field = $this->ui->factory()->input()->field()->checkbox($title, $description);
197  if (!is_null($value)) {
198  $field = $field->withValue($value);
199  }
200  $this->addField($key, $field);
201  return $this;
202  }
203 
204  public function hidden(
205  string $key,
206  string $value
207  ): self {
208  $this->values[$key] = $value;
209  $field = $this->ui->factory()->input()->field()->hidden();
210  $field = $field->withValue($value);
211  $this->addField($key, $field);
212  return $this;
213  }
214 
215  public function required($required = true): self
216  {
217  if ($required && ($field = $this->getLastField())) {
218  if ($field instanceof \ILIAS\UI\Component\Input\Field\Text) {
219  $field = $field->withRequired(true, new NotEmpty(
220  new Factory(),
221  $this->lng
222  ));
223  } else {
224  $field = $field->withRequired(true);
225  }
226  $this->replaceLastField($field);
227  }
228  return $this;
229  }
230 
231  public function disabled($disabled = true): self
232  {
233  if ($disabled && ($field = $this->getLastField())) {
234  $field = $field->withDisabled(true);
235  $this->disable[$this->last_key] = true;
236  $this->replaceLastField($field);
237  }
238  return $this;
239  }
240 
241  public function textarea(
242  string $key,
243  string $title,
244  string $description = "",
245  ?string $value = null
246  ): self {
247  $this->values[$key] = $value;
248  $field = $this->ui->factory()->input()->field()->textarea($title, $description);
249  if (!is_null($value)) {
250  $field = $field->withValue($value);
251  }
252  $this->addField($key, $field);
253  return $this;
254  }
255 
256  public function number(
257  string $key,
258  string $title,
259  string $description = "",
260  ?int $value = null,
261  ?int $min_value = null,
262  ?int $max_value = null
263  ): self {
264  $this->values[$key] = $value;
265  $trans = [];
266  if (!is_null($min_value)) {
267  $trans[] = $this->refinery->int()->isGreaterThanOrEqual($min_value);
268  }
269  if (!is_null($max_value)) {
270  $trans[] = $this->refinery->int()->isLessThanOrEqual($max_value);
271  }
272  $field = $this->ui->factory()->input()->field()->numeric($title, $description);
273  if (count($trans) > 0) {
274  $field = $field->withAdditionalTransformation($this->refinery->logical()->parallel($trans));
275  }
276  if (!is_null($value)) {
277  $field = $field->withValue($value);
278  }
279  $this->addField($key, $field);
280  return $this;
281  }
282 
283  public function date(
284  string $key,
285  string $title,
286  string $description = "",
287  ?\ilDate $value = null
288  ): self {
289  $this->values[$key] = $value;
290  $field = $this->ui->factory()->input()->field()->dateTime($title, $description);
291 
292  $format = $this->user->getDateFormat();
293  $dt_format = (string) $format;
294 
295  $field = $field->withFormat($format);
296  if (!is_null($value)) {
297  $field = $field->withValue(
298  (new \DateTime($value->get(IL_CAL_DATE)))->format($dt_format)
299  );
300  }
301  $this->addField($key, $field);
302  return $this;
303  }
304 
305  public function dateTime(
306  string $key,
307  string $title,
308  string $description = "",
309  ?\ilDateTime $value = null
310  ): self {
311  $this->values[$key] = $value;
312  $field = $this->ui->factory()->input()->field()->dateTime($title, $description)->withUseTime(true);
313 
314  if ((int) $this->user->getTimeFormat() === \ilCalendarSettings::TIME_FORMAT_12) {
315  $dt_format = $this->data->dateFormat()->withTime12($this->user->getDateFormat());
316  } else {
317  $dt_format = $this->data->dateFormat()->withTime24($this->user->getDateFormat());
318  }
319  $field = $field->withFormat($dt_format);
320  if (!is_null($value) && !is_null($value->get(IL_CAL_DATETIME))) {
321  $field = $field->withValue(
322  (new \DateTime($value->get(IL_CAL_DATETIME)))->format(
323  ((string) $dt_format)
324  )
325  );
326  }
327  $this->addField($key, $field);
328  return $this;
329  }
330 
331  public function dateTimeDuration(
332  string $key,
333  string $title,
334  string $description = "",
335  ?\ilDateTime $from = null,
336  ?\ilDateTime $to = null,
337  string $label_from = "",
338  string $label_to = ""
339  ): self {
340  $this->values[$key] = [$from, $to];
341  if ($label_from === "") {
342  $label_from = $this->lng->txt("rep_activation_limited_start");
343  }
344  if ($label_to === "") {
345  $label_to = $this->lng->txt("rep_activation_limited_end");
346  }
347  $field = $this->ui->factory()->input()->field()->duration($title, $description)->withUseTime(true)->withLabels($label_from, $label_to);
348 
349  if ((int) $this->user->getTimeFormat() === \ilCalendarSettings::TIME_FORMAT_12) {
350  $dt_format = $this->data->dateFormat()->withTime12($this->user->getDateFormat());
351  } else {
352  $dt_format = $this->data->dateFormat()->withTime24($this->user->getDateFormat());
353  }
354  $field = $field->withFormat($dt_format);
355  $val_from = $val_to = null;
356  if (!is_null($from) && !is_null($from->get(IL_CAL_DATETIME))) {
357  $val_from = (new \DateTime(
358  $from->get(IL_CAL_DATETIME)
359  ))->format((string) $dt_format);
360  }
361  if (!is_null($to) && !is_null($to->get(IL_CAL_DATETIME))) {
362  $val_to = (new \DateTime(
363  $to->get(IL_CAL_DATETIME)
364  ))->format((string) $dt_format);
365  }
366  $field = $field->withValue([$val_from, $val_to]);
367  $this->addField($key, $field);
368  return $this;
369  }
370 
374  protected function getDateTimeData(?\DateTimeImmutable $value, $use_time = false)
375  {
376  if (is_null($value)) {
377  return null;
378  }
379  if ($use_time) {
380  return new \ilDateTime($value->format("Y-m-d H:i:s"), IL_CAL_DATETIME);
381  }
382  return new \ilDate($value->format("Y-m-d"), IL_CAL_DATE);
383  }
384 
385  public function select(
386  string $key,
387  string $title,
388  array $options,
389  string $description = "",
390  ?string $value = null
391  ): self {
392  $this->values[$key] = $value;
393  $field = $this->ui->factory()->input()->field()->select($title, $options, $description);
394  if (!is_null($value)) {
395  $field = $field->withValue($value);
396  }
397  $this->addField(
398  $key,
399  $field
400  );
401  return $this;
402  }
403 
404  public function radio(
405  string $key,
406  string $title,
407  string $description = "",
408  ?string $value = null
409  ): self {
410  $this->values[$key] = $value;
411  $field = $this->ui->factory()->input()->field()->radio($title, $description);
412  if (!is_null($value)) {
413  $field = $field->withOption($value, ""); // dummy to prevent exception, will be overwritten by radioOption
414  $field = $field->withValue($value);
415  }
416  $this->addField(
417  $key,
418  $field
419  );
420  return $this;
421  }
422 
423  public function radioOption(string $value, string $title, string $description = ""): self
424  {
425  if ($field = $this->getLastField()) {
426  $field = $field->withOption($value, $title, $description);
427  $this->replaceLastField($field);
428  }
429  return $this;
430  }
431 
432  public function switch(
433  string $key,
434  string $title,
435  string $description = "",
436  ?string $value = null
437  ): self {
438  $this->values[$key] = $value;
439  $this->current_switch = [
440  "key" => $key,
441  "title" => $title,
442  "description" => $description,
443  "value" => $value,
444  "groups" => []
445  ];
446  return $this;
447  }
448 
449  public function optional(
450  string $key,
451  string $title,
452  string $description = "",
453  ?bool $value = null
454  ): self {
455  $this->values[$key] = $value;
456  $this->current_optional = [
457  "key" => $key,
458  "title" => $title,
459  "description" => $description,
460  "value" => $value,
461  "group" => []
462  ];
463  return $this;
464  }
465 
466  public function group(string $key, string $title, string $description = "", $disabled = false): self
467  {
468  $this->endCurrentGroup();
469  $this->current_group = [
470  "key" => $key,
471  "title" => $title,
472  "description" => $description,
473  "disabled" => $disabled,
474  "fields" => []
475  ];
476  return $this;
477  }
478 
479  protected function endCurrentGroup(): void
480  {
481  if (!is_null($this->current_group)) {
482  if (!is_null($this->current_switch)) {
483  $fields = [];
484  foreach ($this->current_group["fields"] as $key) {
485  $fields[$key] = $this->fields[$key];
486  }
487  $this->current_switch["groups"][$this->current_group["key"]] =
488  $this->ui->factory()->input()->field()->group(
489  $fields,
490  $this->current_group["title"]
491  )->withByline($this->current_group["description"]);
492  if ($this->current_group["disabled"]) {
493  $this->current_switch["groups"][$this->current_group["key"]] =
494  $this->current_switch["groups"][$this->current_group["key"]]
495  ->withDisabled(true);
496  }
497  }
498  }
499  $this->current_group = null;
500  }
501 
502  public function end(): self
503  {
504  $this->endCurrentGroup();
505  if (!is_null($this->current_switch)) {
506  $field = $this->ui->factory()->input()->field()->switchableGroup(
507  $this->current_switch["groups"],
508  $this->current_switch["title"],
509  $this->current_switch["description"]
510  );
511  if (!is_null($this->current_switch["value"])) {
512  $cvalue = $this->current_switch["value"];
513  if (isset($this->current_switch["groups"][$cvalue])) {
514  $field = $field->withValue($cvalue);
515  }
516  }
517  $key = $this->current_switch["key"];
518  $this->current_switch = null;
519  $this->addField($key, $field);
520  }
521  if (!is_null($this->current_optional)) {
522  $field = $this->ui->factory()->input()->field()->optionalGroup(
523  $this->current_optional["fields"],
524  $this->current_optional["title"],
525  $this->current_optional["description"]
526  );
527  if ($this->current_optional["value"]) {
528  $value = [];
529  foreach ($this->current_optional["fields"] as $key => $input) {
530  $value[$key] = $input->getValue();
531  }
532  $field = $field->withValue($value);
533  } else {
534  $field = $field->withValue(null);
535  }
536  $key = $this->current_optional["key"];
537  $this->current_optional = null;
538  $this->addField($key, $field);
539  }
540  return $this;
541  }
542 
543  public function file(
544  string $key,
545  string $title,
546  \Closure $result_handler,
547  string $id_parameter,
548  string $description = "",
549  ?int $max_files = null,
550  array $mime_types = [],
551  array $ctrl_path = [],
552  string $logger_id = ""
553  ): self {
554  $this->upload_handler[$key] = new \ilRepoStandardUploadHandlerGUI(
555  $result_handler,
556  $id_parameter,
557  $logger_id,
558  $ctrl_path
559  );
560 
561  foreach (["application/x-compressed", "application/x-zip-compressed"] as $zipmime) {
562  if (in_array("application/zip", $mime_types) &&
563  !in_array($zipmime, $mime_types)) {
564  $mime_types[] = $zipmime;
565  }
566  }
567 
568  if (count($mime_types) > 0) {
569  $description .= $this->lng->txt("rep_allowed_types") . ": " .
570  implode(", ", $mime_types);
571  }
572 
573  $field = $this->ui->factory()->input()->field()->file(
574  $this->upload_handler[$key],
575  $title,
576  $description
577  )
578  ->withMaxFileSize((int) \ilFileUtils::getPhpUploadSizeLimitInBytes());
579  if (!is_null($max_files)) {
580  $field = $field->withMaxFiles($max_files);
581  }
582  if (count($mime_types) > 0) {
583  $field = $field->withAcceptedMimeTypes($mime_types);
584  }
585 
586  $this->addField(
587  $key,
588  $field
589  );
590  return $this;
591  }
592 
594  {
595  if (!isset($this->upload_handler[$key])) {
596  throw new \ilException("Unknown file upload field: " . $key);
597  }
598  return $this->upload_handler[$key];
599  }
600 
601 
602  protected function addField(string $key, FormInput $field, $supress_0_key = false): void
603  {
604  if ($key === "") {
605  throw new \ilException("Missing Input Key: " . $key);
606  }
607  if (isset($this->field[$key])) {
608  throw new \ilException("Duplicate Input Key: " . $key);
609  }
610  $field_path = [];
611  if ($this->current_section !== self::DEFAULT_SECTION) {
612  $field_path[] = $this->current_section;
613  }
614  if (!is_null($this->current_group)) {
615  $this->current_group["fields"][] = $key;
616  if (!is_null($this->current_switch)) {
617  $field_path[] = $this->current_switch["key"];
618  $field_path[] = 1; // the value of subitems in SwitchableGroup are in the 1 key of the raw data
619  $field_path[] = $key;
620  }
621  } elseif (!is_null($this->current_optional)) {
622  $field_path[] = $this->current_optional["key"];
623  $this->current_optional["fields"][$key] = $field;
624  $field_path[] = $key;
625  } else {
626  $this->sections[$this->current_section]["fields"][] = $key;
627  $field_path[] = $key;
628  if ($field instanceof \ILIAS\UI\Component\Input\Field\SwitchableGroup) {
629  $field_path[] = 0; // the value of the SwitchableGroup is in the 0 key of the raw data
630  }
631  if ($field instanceof \ILIAS\UI\Component\Input\Field\OptionalGroup) {
632  //$field_path[] = 0; // the value of the SwitchableGroup is in the 0 key of the raw data
633  }
634  if ($field instanceof \ILIAS\UI\Component\Input\Field\File) {
635  if (!$supress_0_key) { // needed for tiles, that come with a custom transformation omitting the 0
636  $field_path[] = 0; // the value of File Inputs is in the 0 key of the raw data
637  }
638  }
639  }
640  $this->fields[$key] = $field;
641  $this->field_path[$key] = $field_path;
642  $this->last_key = $key;
643  $this->form = null;
644  }
645 
646  protected function getFieldForKey(string $key): FormInput
647  {
648  if (!isset($this->fields[$key])) {
649  throw new \ilException("Unknown Key: " . $key);
650  }
651  return $this->fields[$key];
652  }
653 
654  protected function getLastField(): ?FormInput
655  {
656  return $this->fields[$this->last_key] ?? null;
657  }
658 
659  protected function replaceLastField(FormInput $field): void
660  {
661  if ($this->last_key !== "") {
662  $this->fields[$this->last_key] = $field;
663  }
664  }
665 
666  protected function getForm(): Form\Standard
667  {
668  $ctrl = $this->ctrl;
669 
670  if (is_null($this->form)) {
671  $async = ($this->async_mode !== self::ASYNC_NONE);
672  $action = "";
673  if (!is_null($this->class_path)) {
674  $action = $ctrl->getLinkTargetByClass($this->class_path, $this->cmd, "", $async);
675  }
676  $inputs = [];
677  foreach ($this->sections as $sec_key => $section) {
678  if ($sec_key === self::DEFAULT_SECTION) {
679  foreach ($this->sections[$sec_key]["fields"] as $f_key) {
680  $inputs[$f_key] = $this->getFieldForKey($f_key);
681  }
682  } elseif (count($this->sections[$sec_key]["fields"]) > 0) {
683  $sec_inputs = [];
684  foreach ($this->sections[$sec_key]["fields"] as $f_key) {
685  $sec_inputs[$f_key] = $this->getFieldForKey($f_key);
686  }
687  $inputs[$sec_key] = $this->ui->factory()->input()->field()->section(
688  $sec_inputs,
689  $section["title"],
690  $section["description"]
691  );
692  }
693  }
694  $this->form = $this->ui->factory()->input()->container()->form()->standard(
695  $action,
696  $inputs
697  );
698  if ($this->submit_caption !== "") {
699  $this->form = $this->form->withSubmitLabel($this->submit_caption);
700  }
701  }
702  return $this->form;
703  }
704 
705  public function getSubmitLabel(): string
706  {
707  return $this->getForm()->getSubmitLabel() ?? $this->lng->txt("save");
708  }
709 
710  protected function _getData(): void
711  {
712  if (is_null($this->raw_data)) {
713  $request = $this->http->request();
714  $this->form = $this->getForm()->withRequest($request);
715  $this->raw_data = $this->form->getData();
716  }
717  }
718 
719  public function isValid(): bool
720  {
721  $this->_getData();
722  return !(is_null($this->raw_data));
723  }
724 
728  public function getData(string $key)
729  {
730  $this->_getData();
731 
732  if (!isset($this->fields[$key])) {
733  return null;
734  }
735 
736  if (isset($this->disable[$key])) {
737  return $this->values[$key];
738  }
739 
740  $value = $this->raw_data;
741  foreach ($this->field_path[$key] as $path_key) {
742  if (!isset($value[$path_key])) {
743  return null;
744  }
745  $value = $value[$path_key];
746  }
747 
748  $field = $this->getFieldForKey($key);
749 
750  if ($field instanceof \ILIAS\UI\Component\Input\Field\DateTime) {
752  $value = $this->getDateTimeData($value, $field->getUseTime());
753  }
754 
755  if ($field instanceof \ILIAS\UI\Component\Input\Field\Duration) {
757  $value = [
758  $this->getDateTimeData($value["start"], $field->getUseTime()),
759  $this->getDateTimeData($value["end"], $field->getUseTime()),
760  ];
761  }
762 
763  if ($field instanceof \ILIAS\UI\Component\Input\Field\OptionalGroup) {
764  $value = is_array($value);
765  }
766 
767  return $value;
768  }
769 
770  public function render(): string
771  {
772  if ($this->async_mode === self::ASYNC_NONE && !$this->ctrl->isAsynch()) {
773  $html = $this->ui->renderer()->render($this->getForm());
774  } else {
775  $html = $this->ui->renderer()->renderAsync($this->getForm()) . "<script>" . $this->getOnLoadCode() . "</script>";
776  }
777  if ($this->in_modal) {
778  if ($this->async_mode === self::ASYNC_MODAL) {
779  $html = str_replace("<form ", "<form data-rep-modal-form='async' ", $html);
780  } else {
781  $html = str_replace("<form ", "<form data-rep-modal-form='sync' ", $html);
782  }
783  }
784  return $html;
785  }
786 }
optional(string $key, string $title, string $description="", ?bool $value=null)
const IL_CAL_DATETIME
radio(string $key, string $title, string $description="", ?string $value=null)
text(string $key, string $title, string $description="", ?string $value=null)
checkbox(string $key, string $title, string $description="", ?bool $value=null)
getLinkTargetByClass( $a_class, ?string $a_cmd=null, ?string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
Returns a link target for the given information.
Interface Observer Contains several chained tasks and infos about them.
select(string $key, string $title, array $options, string $description="", ?string $value=null)
dateTimeDuration(string $key, string $title, string $description="", ?\ilDateTime $from=null, ?\ilDateTime $to=null, string $label_from="", string $label_to="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: Factory.php:21
__construct( $class_path, string $cmd, string $submit_caption="")
Builds a Color from either hex- or rgb values.
Definition: Factory.php:30
This implements commonalities between all forms.
Definition: Form.php:33
section(string $key, string $title, string $description="")
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
file(string $key, string $title, \Closure $result_handler, string $id_parameter, string $description="", ?int $max_files=null, array $mime_types=[], array $ctrl_path=[], string $logger_id="")
initStdObjProperties(Container $DIC)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
number(string $key, string $title, string $description="", ?int $value=null, ?int $min_value=null, ?int $max_value=null)
global $DIC
Definition: shib_login.php:22
addField(string $key, FormInput $field, $supress_0_key=false)
dateTime(string $key, string $title, string $description="", ?\ilDateTime $value=null)
form( $class_path, string $cmd, string $submit_caption="")
const IL_CAL_DATE
radioOption(string $value, string $title, string $description="")
static getPhpUploadSizeLimitInBytes()
This describes commonalities between all inputs.
Definition: Input.php:46
date(string $key, string $title, string $description="", ?\ilDate $value=null)
group(string $key, string $title, string $description="", $disabled=false)
textarea(string $key, string $title, string $description="", ?string $value=null)
$r