ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilPropertyFormGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 use ILIAS\HTTP;
22 use ILIAS\Refinery;
23 
32 {
33  private array $kept_uploads = [];
34  protected bool $required_text = false;
35  protected ilLanguage $lng;
36  protected ilCtrl $ctrl;
37  protected ilTemplate $tpl;
38  protected ?ilObjUser $user = null;
39  protected ?ilSetting $settings = null;
40  private array $buttons = array();
41  private array $items = array();
42  protected string $mode = "std";
43  protected bool $check_input_called = false;
44  protected bool $disable_standard_message = false;
45  protected string $top_anchor = "il_form_top";
46  protected string $title = '';
47  protected string $titleicon = "";
48  protected string $description = "";
49  protected string $tbl_width = "";
50  protected bool $show_top_buttons = true;
51  protected bool $hide_labels = false;
52  protected bool $force_top_buttons = false;
53  protected HTTP\Services $http;
54  protected ?Refinery\Factory $refinery = null;
55 
57  protected $onload_code = [];
58 
59  public function __construct()
60  {
61  global $DIC;
62 
63  $this->lng = $DIC->language();
64  $this->ctrl = $DIC->ctrl();
65 
66  $this->user = null;
67  if (isset($DIC["ilUser"])) {
68  $this->user = $DIC["ilUser"];
69  }
70 
71  $this->settings = null;
72  if (isset($DIC["ilSetting"])) {
73  $this->settings = $DIC["ilSetting"];
74  }
75 
76  $lng = $DIC->language();
77 
78  $lng->loadLanguageModule("form");
79 
80  // avoid double submission
81  $this->setPreventDoubleSubmission(true);
82 
83  // do it as early as possible
84  if (isset($DIC["http"])) {
85  $this->http = $DIC->http();
86  }
87  if (isset($DIC["refinery"])) {
88  $this->refinery = $DIC->refinery();
89  }
90  $this->rebuildUploadedFiles();
91  if (isset($DIC["tpl"])) { // some unit tests will fail otherwise
92  $this->global_tpl = $DIC['tpl'];
93  }
94  }
95 
100  public function executeCommand()
101  {
102  $ilCtrl = $this->ctrl;
103 
104  $next_class = $ilCtrl->getNextClass($this);
105 
106  switch ($next_class) {
107  case 'ilformpropertydispatchgui':
108  $ilCtrl->saveParameter($this, 'postvar');
109  $form_prop_dispatch = new ilFormPropertyDispatchGUI();
110  $item = $this->getItemByPostVar($this->getRequestedPostVar());
111  $form_prop_dispatch->setItem($item);
112  return $ilCtrl->forwardCommand($form_prop_dispatch);
113  }
114  return false;
115  }
116 
117  protected function getRequestedPostVar(): ?string
118  {
119  $t = $this->refinery->kindlyTo()->string();
120  $w = $this->http->wrapper();
121  if ($w->post()->has("postvar")) {
122  return $w->post()->retrieve("postvar", $t);
123  }
124  if ($w->query()->has("postvar")) {
125  return $w->query()->retrieve("postvar", $t);
126  }
127  return null;
128  }
129 
130  final public function setTableWidth(string $a_width): void
131  {
132  $this->tbl_width = $a_width;
133  }
134 
135  final public function getTableWidth(): string
136  {
137  return $this->tbl_width;
138  }
139 
140  // Set Mode ('std', 'subform').
141  public function setMode(string $a_mode): void
142  {
143  $this->mode = $a_mode;
144  }
145 
146  public function getMode(): string
147  {
148  return $this->mode;
149  }
150 
151  public function setTitle(string $a_title): void
152  {
153  $this->title = $a_title;
154  }
155 
156  public function getTitle(): string
157  {
158  return $this->title;
159  }
160 
161  public function setTitleIcon(string $a_titleicon): void
162  {
163  $this->titleicon = $a_titleicon;
164  }
165 
166  public function getTitleIcon(): string
167  {
168  return $this->titleicon;
169  }
170 
171  public function setDescription(string $a_val): void
172  {
173  $this->description = $a_val;
174  }
175 
176  public function getDescription(): string
177  {
178  return $this->description;
179  }
180 
181  public function setTopAnchor(string $a_val): void
182  {
183  $this->top_anchor = $a_val;
184  }
185 
186  public function getTopAnchor(): string
187  {
188  return $this->top_anchor;
189  }
190 
191  public function setShowTopButtons(bool $a_val): void
192  {
193  $this->show_top_buttons = $a_val;
194  }
195 
196  public function getShowTopButtons(): bool
197  {
199  }
200 
201  public function setForceTopButtons(bool $a_val): void
202  {
203  $this->force_top_buttons = $a_val;
204  }
205 
206  public function getForceTopButtons(): bool
207  {
209  }
210 
214  public function addItem($a_item): void
215  {
216  $a_item->setParentForm($this);
217  $this->items[] = $a_item;
218  }
219 
220  public function removeItemByPostVar(
221  string $a_post_var,
222  bool $a_remove_unused_headers = false
223  ): void {
224  foreach ($this->items as $key => $item) {
225  if (method_exists($item, "getPostVar") && $item->getPostVar() == $a_post_var) {
226  unset($this->items[$key]);
227  }
228  }
229 
230  // remove section headers if they do not contain any items anymore
231  if ($a_remove_unused_headers) {
232  $unset_keys = array();
233  $last_item = null;
234  $last_key = null;
235  foreach ($this->items as $key => $item) {
236  if ($item instanceof ilFormSectionHeaderGUI && $last_item instanceof ilFormSectionHeaderGUI) {
237  $unset_keys[] = $last_key;
238  }
239  $last_item = $item;
240  $last_key = $key;
241  }
242  if ($last_item instanceof ilFormSectionHeaderGUI) {
243  $unset_keys[] = $last_key;
244  }
245  foreach ($unset_keys as $key) {
246  unset($this->items[$key]);
247  }
248  }
249  }
250 
251  public function getItemByPostVar(string $a_post_var): ?ilFormPropertyGUI
252  {
253  foreach ($this->items as $item) {
254  if ($item->getType() != "section_header") {
255  //if ($item->getPostVar() == $a_post_var)
256  $ret = $item->getItemByPostVar($a_post_var);
257  if (is_object($ret)) {
258  return $ret;
259  }
260  }
261  }
262 
263  return null;
264  }
265 
266  public function setItems(array $a_items): void
267  {
268  $this->items = $a_items;
269  }
270 
271  public function getItems(): array
272  {
273  return $this->items;
274  }
275 
280  public function getInputItemsRecursive(): array
281  {
282  $inputItems = array();
283 
284  foreach ($this->items as $item) {
285  if ($item->getType() == 'section_header') {
286  continue;
287  }
288 
289  $inputItems[] = $item;
290 
291  if ($item instanceof ilSubEnabledFormPropertyGUI) {
292  $inputItems = array_merge($inputItems, $item->getSubInputItemsRecursive());
293  }
294  }
295 
296  return $inputItems;
297  }
298 
299  public function setDisableStandardMessage(bool $a_val): void
300  {
301  $this->disable_standard_message = $a_val;
302  }
303 
304  public function getDisableStandardMessage(): bool
305  {
307  }
308 
309  // Get a value indicating whether the labels should be hidden or not.
310  public function getHideLabels(): bool
311  {
312  return $this->hide_labels;
313  }
314 
315  public function setHideLabels(bool $a_value = true): void
316  {
317  $this->hide_labels = $a_value;
318  }
319 
320  public function setValuesByArray(
321  array $a_values,
322  bool $a_restrict_to_value_keys = false
323  ): void {
324  foreach ($this->items as $item) {
325  if (!($a_restrict_to_value_keys) ||
326  in_array($item->getPostVar(), array_keys($a_values))) {
327  $item->setValueByArray($a_values);
328  }
329  }
330  }
331 
332  public function setValuesByPost()
333  {
334  global $DIC;
335 
336  if (!isset($DIC["http"])) {
337  return null;
338  }
339 
340  foreach ($this->items as $item) {
341  $item->setValueByArray($DIC->http()->request()->getParsedBody());
342  }
343  }
344 
345  public function checkInput(): bool
346  {
347  global $DIC;
348 
349  if ($this->check_input_called) {
350  die("Error: ilPropertyFormGUI->checkInput() called twice.");
351  }
352 
353  $ok = true;
354  foreach ($this->items as $item) {
355  $item_ok = $item->checkInput();
356  if (!$item_ok) {
357  $ok = false;
358  }
359  }
360 
361  // check if POST is missing completely (if post_max_size exceeded)
362  $post = $this->http->request()->getParsedBody();
363  if (count($this->items) > 0 && count($post) === 0) {
364  $ok = false;
365  }
366 
367  $this->check_input_called = true;
368 
369  // try to keep uploads for another try
370  $filehash = $this->getFileHash();
371  if (!$ok && !is_null($filehash) && $filehash && count($_FILES)) {
372  $hash = $filehash;
373 
374  foreach ($_FILES as $field => $data) {
375  // only try to keep files that are ok
376  // see 25484: Wrong error handling when uploading icon instead of tile
377  $item = $this->getItemByPostVar($field);
378  if (is_null($item) || !$item->checkInput()) {
379  continue;
380  }
381  // we support up to 2 nesting levels (see test/assessment)
382  if (is_array($data["tmp_name"])) {
383  foreach ($data["tmp_name"] as $idx => $upload) {
384  if (is_array($upload)) {
385  foreach ($upload as $idx2 => $file) {
386  if ($file && is_uploaded_file($file)) {
387  $file_name = $data["name"][$idx][$idx2];
388  $file_type = $data["type"][$idx][$idx2];
389  $this->keepFileUpload($hash, $field, $file, $file_name, $file_type, (string) $idx, (string) $idx2);
390  }
391  }
392  } elseif ($upload && is_uploaded_file($upload)) {
393  $file_name = $data["name"][$idx];
394  $file_type = $data["type"][$idx];
395  $this->keepFileUpload($hash, $field, $upload, $file_name, $file_type, (string) $idx);
396  }
397  }
398  } else {
399  $this->keepFileUpload($hash, $field, $data["tmp_name"], $data["name"], $data["type"]);
400  }
401  }
402  }
403  $http = $DIC->http();
404  $txt = $DIC->language()->txt("form_input_not_valid");
405  switch ($http->request()->getHeaderLine('Accept')) {
406  // When JS asks for a valid JSON-Response, we send the success and message as JSON
407  case 'application/json':
408  $stream = \ILIAS\Filesystem\Stream\Streams::ofString(json_encode([
409  'success' => $ok,
410  'message' => $txt,
411  ]));
412  $http->saveResponse($http->response()->withBody($stream));
413 
414  return $ok;
415 
416  // Otherwise, we send it using ilUtil, and it will be rendered in the Template
417  default:
418 
419  if (!$ok && !$this->getDisableStandardMessage()) {
420  $this->global_tpl->setOnScreenMessage('failure', $txt);
421  }
422 
423  return $ok;
424  }
425  }
426 
427  protected function getFileHash(): ?string
428  {
429  if (is_null($this->refinery)) {
430  return null;
431  }
432  // try to keep uploads for another try
433  $t = $this->refinery->kindlyTo()->string();
434  $w = $this->http->wrapper();
435  $filehash = null;
436  if ($w->post()->has("ilfilehash")) {
437  $filehash = $w->post()->retrieve("ilfilehash", $t);
438  }
439  return $filehash;
440  }
441 
449  public function getInput(
450  string $a_post_var,
451  bool $ensureValidation = true
452  ) {
453  // this check ensures, that checkInput has been called (incl. stripSlashes())
454  if (!$this->check_input_called && $ensureValidation) {
455  throw new LogicException('Error: ilPropertyFormGUI->getInput() called without calling checkInput() first.');
456  }
457 
458  $item = $this->getItemByPostVar($a_post_var);
459  if (is_object($item) && method_exists($item, "getInput")) {
460  return $item->getInput();
461  }
462 
463  $post = $this->http->request()->getParsedBody();
464  return $post[$a_post_var] ?? '';
465  }
466 
467  public function addCommandButton(
468  string $a_cmd,
469  string $a_text,
470  string $a_id = ""
471  ): void {
472  $this->buttons[] = array("cmd" => $a_cmd, "text" => $a_text, "id" => $a_id);
473  }
474 
475 
476  public function getCommandButtons(): array
477  {
478  return $this->buttons;
479  }
480 
481  public function clearCommandButtons(): void
482  {
483  $this->buttons = array();
484  }
485 
486  public function getContent(): string
487  {
488  global $DIC;
489  $lng = $this->lng;
490  $tpl = $DIC["tpl"];
492 
495 
496  $tpl->addJavaScript("assets/js/Basic.js");
497  $tpl->addJavaScript("assets/js/Form.js");
498 
499  $this->tpl = new ilTemplate("tpl.property_form.html", true, true, "components/ILIAS/Form");
500 
501  // check if form has not title and first item is a section header
502  // -> use section header for title and remove section header
503  // -> command buttons are presented on top
504  $fi = $this->items[0] ?? null;
505  if ($this->getMode() == "std" &&
506  $this->getTitle() == "" &&
507  is_object($fi) && $fi->getType() == "section_header"
508  ) {
509  $this->setTitle($fi->getTitle());
510  unset($this->items[0]);
511  }
512 
513 
514  // title icon
515  if ($this->getTitleIcon() != "" && is_file($this->getTitleIcon())) {
516  $this->tpl->setCurrentBlock("title_icon");
517  $this->tpl->setVariable("IMG_ICON", $this->getTitleIcon());
518  $this->tpl->parseCurrentBlock();
519  }
520 
521  // title
522  if ($this->getTitle() != "") {
523  // commands on top
524  if (count($this->buttons) > 0 && $this->getShowTopButtons() && (count($this->items) > 2 || $this->force_top_buttons)) {
525  // command buttons
526  foreach ($this->buttons as $button) {
527  $this->tpl->setCurrentBlock("cmd2");
528  $this->tpl->setVariable("CMD", $button["cmd"]);
529  $this->tpl->setVariable("CMD_TXT", $button["text"]);
530  if ($button["id"] != "") {
531  $this->tpl->setVariable("CMD2_ID", " id='" . $button["id"] . "_top'");
532  }
533  $this->tpl->parseCurrentBlock();
534  }
535  $this->tpl->setCurrentBlock("commands2");
536  $this->tpl->parseCurrentBlock();
537  }
538 
539  // required top
540  $this->tpl->setCurrentBlock("header");
541  if ($this->checkForRequiredField()) {
542  $this->tpl->setCurrentBlock("required_text_top");
543  $this->tpl->setVariable("TXT_REQUIRED_TOP", $lng->txt("required_field"));
544  $this->tpl->parseCurrentBlock();
545  }
546 
547  $this->tpl->setVariable("TXT_TITLE", $this->getTitle());
548  //$this->tpl->setVariable("LABEL", $this->getTopAnchor());
549  $this->tpl->setVariable("TXT_DESCRIPTION", $this->getDescription());
550  $this->tpl->parseCurrentBlock();
551  } elseif (!$this->required_text && $this->getMode() == "std") {
552  $this->tpl->setCurrentBlock("header");
553  // required top
554  $this->tpl->setCurrentBlock("required_text_top");
555  $this->tpl->setVariable("TXT_REQUIRED_TOP", $lng->txt("required_field"));
556  $this->tpl->parseCurrentBlock();
557  }
558  $this->tpl->touchBlock("item");
559 
560  // properties
561  $this->required_text = false;
562  foreach ($this->items as $item) {
563  if ($item->getType() != "hidden") {
564  $this->insertItem($item);
565  }
566  }
567 
568  // required
569  if ($this->required_text && $this->getMode() == "std") {
570  $this->tpl->setCurrentBlock("required_text");
571  $this->tpl->setVariable("TXT_REQUIRED", $lng->txt("required_field"));
572  $this->tpl->parseCurrentBlock();
573  }
574 
575  // command buttons
576  foreach ($this->buttons as $button) {
577  $this->tpl->setCurrentBlock("cmd");
578  $this->tpl->setVariable("CMD", $button["cmd"]);
579  $this->tpl->setVariable("CMD_TXT", $button["text"]);
580 
581  if ($button["id"] != "") {
582  $this->tpl->setVariable("CMD_ID", " id='" . $button["id"] . "'");
583  }
584 
585  $this->tpl->parseCurrentBlock();
586  }
587 
588  // #18808
589  if ($this->getMode() != "subform") {
590  // try to keep uploads even if checking input fails
591  if ($this->getMultipart()) {
592  $hash = $this->getFileHash() ?? null;
593  if (!$hash) {
594  $hash = md5(uniqid((string) mt_rand(), true));
595  }
596  $fhash = new ilHiddenInputGUI("ilfilehash");
597  $fhash->setValue($hash);
598  $this->addItem($fhash);
599  }
600  }
601 
602  // hidden properties
603  $hidden_fields = false;
604  foreach ($this->items as $item) {
605  if ($item->getType() == "hidden") {
606  $item->insert($this->tpl);
607  $hidden_fields = true;
608  }
609  }
610 
611  if ($this->required_text || count($this->buttons) > 0 || $hidden_fields) {
612  $this->tpl->setCurrentBlock("commands");
613  $this->tpl->parseCurrentBlock();
614  }
615 
616 
617  if ($this->getMode() == "subform") {
618  $this->tpl->touchBlock("sub_table");
619  } else {
620  $this->tpl->touchBlock("std_table");
621  $this->tpl->setVariable('STD_TABLE_WIDTH', $this->getTableWidth());
622  }
623 
624  return $this->tpl->get();
625  }
626 
627  protected function hideRequired(string $a_type): bool
628  {
629  // #15818
630  return $a_type == "non_editable_value";
631  }
632 
636  public function insertItem(
637  $item,
638  bool $a_sub_item = false
639  ): void {
640  global $DIC;
641  $tpl = $DIC["tpl"];
642  $lng = $this->lng;
643 
644 
645  //$cfg = array();
646 
647  //if(method_exists($item, "getMulti") && $item->getMulti())
648  if ($item instanceof ilMultiValuesItem && $item->getMulti()) {
649  $tpl->addJavascript("assets/js/ServiceFormMulti.js");
650 
651  $this->tpl->setCurrentBlock("multi_in");
652  $this->tpl->setVariable("ID", $item->getFieldId());
653  $this->tpl->parseCurrentBlock();
654 
655  $this->tpl->touchBlock("multi_out");
656 
657 
658  // add hidden item to enable preset multi items
659  // not used yet, should replace hidden field stuff
660  $multi_values = $item->getMultiValues();
661  if (is_array($multi_values) && sizeof($multi_values) > 1) {
662  $multi_value = new ilHiddenInputGUI("ilMultiValues~" . $item->getPostVar());
663  $multi_value->setValue(base64_encode(json_encode($multi_values)));
664  $this->addItem($multi_value);
665  }
666  //$cfg["multi_values"] = $multi_values;
667  }
668 
669  $item->insert($this->tpl);
670 
671  if ($item->getType() == "file" || $item->getType() == "image_file") {
672  $this->setMultipart(true);
673  }
674 
675  if ($item->getType() != "section_header") {
676  //$cfg["id"] = $item->getFieldId();
677 
678  // info text
679  if ($item->getInfo() != "") {
680  $this->tpl->setCurrentBlock("description");
681  $this->tpl->setVariable(
682  "PROPERTY_DESCRIPTION",
683  $item->getInfo()
684  );
685  $this->tpl->setVariable(
686  "DESCRIPTION_FOR_ID",
687  $item->getFieldId()
688  );
689  $this->tpl->parseCurrentBlock();
690  }
691 
692  if ($this->getMode() == "subform") {
693  // required
694  if (!$this->hideRequired($item->getType())) {
695  if ($item->getRequired()) {
696  $this->tpl->touchBlock("sub_required");
697  $this->required_text = true;
698  }
699  }
700 
701  // hidden title (for accessibility, e.g. file upload)
702  if ($item->getHiddenTitle() != "") {
703  $this->tpl->setCurrentBlock("sub_hid_title");
704  $this->tpl->setVariable(
705  "SPHID_TITLE",
706  $item->getHiddenTitle()
707  );
708  $this->tpl->parseCurrentBlock();
709  }
710 
711  $this->tpl->setCurrentBlock("sub_prop_start");
712  $this->tpl->setVariable("PROPERTY_TITLE", $item->getTitle());
713  $this->tpl->setVariable("PROPERTY_CLASS", "il_" . $item->getType());
714  if ($item->getType() != "non_editable_value" && $item->getFormLabelFor() != "") {
715  $this->tpl->setVariable("FOR_ID", ' for="' . $item->getFormLabelFor() . '" ');
716  }
717  $this->tpl->setVariable("LAB_ID", $item->getFieldId());
718  } else {
719  // required
720  if (!$this->hideRequired($item->getType())) {
721  if ($item->getRequired()) {
722  $this->tpl->touchBlock("required");
723  $this->required_text = true;
724  }
725  }
726 
727  // hidden title (for accessibility, e.g. file upload)
728  if ($item->getHiddenTitle() != "") {
729  $this->tpl->setCurrentBlock("std_hid_title");
730  $this->tpl->setVariable(
731  "PHID_TITLE",
732  $item->getHiddenTitle()
733  );
734  $this->tpl->parseCurrentBlock();
735  }
736 
737  $this->tpl->setCurrentBlock("std_prop_start");
738  $this->tpl->setVariable("PROPERTY_TITLE", $item->getTitle());
739  if ($item->getType() != "non_editable_value" && $item->getFormLabelFor() != "") {
740  $this->tpl->setVariable("FOR_ID", ' for="' . $item->getFormLabelFor() . '" ');
741  }
742  $this->tpl->setVariable("LAB_ID", $item->getFieldId());
743  if ($this->getHideLabels()) {
744  $this->tpl->setVariable("HIDE_LABELS_STYLE", " ilFormOptionHidden");
745  }
746  }
747  $this->tpl->parseCurrentBlock();
748 
749  // alert
750  if ($item->getType() != "non_editable_value" && $item->getAlert() != "") {
751  $this->tpl->setCurrentBlock("alert");
752  $this->tpl->setVariable(
753  "IMG_ALERT",
754  ilUtil::getImagePath("standard/icon_alert.svg")
755  );
756  $this->tpl->setVariable(
757  "ALT_ALERT",
758  $lng->txt("alert")
759  );
760  $this->tpl->setVariable(
761  "TXT_ALERT",
762  $item->getAlert()
763  );
764  $this->tpl->setVariable(
765  "ALERT_FOR_ID",
766  $item->getFieldId()
767  );
768  $this->tpl->parseCurrentBlock();
769  }
770 
771  // subitems
772  $sf = null;
773  if ($item->getType() != "non_editable_value" or 1) {
774  $sf = $item->getSubForm();
775  if ($item->hideSubForm() && is_object($sf)) {
776  if ($this->global_tpl) {
777  $dsfid = $item->getFieldId();
778  $this->global_tpl->addOnloadCode(
779  "il.Form.hideSubForm('subform_$dsfid');"
780  );
781  }
782  $this->addAsyncOnloadCode("il.Form.hideSubForm('subform_$dsfid');");
783  }
784  }
785 
786  $sf_content = "";
787  if (is_object($sf)) {
788  $sf_content = $sf->getContent();
789  if ($sf->getMultipart()) {
790  $this->setMultipart(true);
791  }
792  $this->tpl->setCurrentBlock("sub_form");
793  $this->tpl->setVariable("PROP_SUB_FORM", $sf_content);
794  $this->tpl->setVariable("SFID", $item->getFieldId());
795  $this->tpl->parseCurrentBlock();
796  }
797 
798  $this->tpl->setCurrentBlock("prop");
799  /* not used yet
800  $this->tpl->setVariable("ID", $item->getFieldId());
801  $this->tpl->setVariable("CFG", json_encode($cfg, JSON_THROW_ON_ERROR));*/
802  $this->tpl->parseCurrentBlock();
803  }
804 
805 
806  $this->tpl->touchBlock("item");
807  }
808 
809  public function addAsyncOnloadCode(string $code): void
810  {
811  $this->onload_code[] = $code;
812  }
813 
814  public function getHTML(): string
815  {
816  $html = parent::getHTML();
817 
818  // #13531 - get content that has to reside outside of the parent form tag, e.g. panels/layers
819  foreach ($this->items as $item) {
820  // #13536 - ilFormSectionHeaderGUI does NOT extend ilFormPropertyGUI ?!
821  if (method_exists($item, "getContentOutsideFormTag")) {
822  $outside = $item->getContentOutsideFormTag();
823  if ($outside) {
824  $html .= $outside;
825  }
826  }
827  }
828  if ($this->ctrl->isAsynch()) {
829  $html = $this->appendOnloadCode($html);
830  }
831  return $html;
832  }
833 
834  public function getHTMLAsync(): string
835  {
836  $html = $this->getHTML();
837  if (!$this->ctrl->isAsynch()) {
838  $html = $this->appendOnloadCode($html);
839  }
840  return $html;
841  }
842 
843  protected function appendOnloadCode(string $html): string
844  {
845  if (count($this->onload_code) > 0) {
846  $html .= "<script>";
847  foreach ($this->onload_code as $code) {
848  $html .= $code . "\n";
849  }
850  $html .= "</script>";
851  }
852  return $html;
853  }
854 
855  //
856  // UPLOAD HANDLING
857  //
858 
871  protected function keepFileUpload(
872  string $a_hash,
873  string $a_field,
874  string $a_tmp_name,
875  string $a_name,
876  string $a_type,
877  ?string $a_index = null,
878  ?string $a_sub_index = null
879  ): void {
880  if (in_array($a_tmp_name, $this->kept_uploads)) {
881  return; // already kept
882  }
883 
884  if (trim($a_tmp_name) == "") {
885  return;
886  }
887 
888  $a_name = ilFileUtils::getASCIIFilename($a_name);
889 
890  $tmp_file_name = implode("~~", array(session_id(),
891  $a_hash,
892  $a_field,
893  $a_index,
894  $a_sub_index,
895  str_replace("/", "~~", $a_type),
896  str_replace("~~", "_", $a_name)));
897 
898  // make sure temp directory exists
899  $temp_path = ilFileUtils::getDataDir() . "/temp";
900  if (!is_dir($temp_path)) {
901  ilFileUtils::createDirectory($temp_path);
902  }
903 
904  ilFileUtils::moveUploadedFile($a_tmp_name, $tmp_file_name, $temp_path . "/" . $tmp_file_name);
905 
907  $file_input = $this->getItemByPostVar($a_field);
908  $file_input->setPending($a_name);
909  $this->kept_uploads[] = $a_tmp_name;
910  }
911 
920  public function getFileUpload(
921  string $a_field,
922  ?string $a_index = null,
923  ?string $a_sub_index = null
924  ): array {
925  $res = array();
926  if ($a_index) {
927  if ($_FILES[$a_field]["tmp_name"][$a_index][$a_sub_index] ?? false) {
928  $res = array(
929  "tmp_name" => $_FILES[$a_field]["tmp_name"][$a_index][$a_sub_index],
930  "name" => $_FILES[$a_field]["name"][$a_index][$a_sub_index],
931  "type" => $_FILES[$a_field]["type"][$a_index][$a_sub_index],
932  "error" => $_FILES[$a_field]["error"][$a_index][$a_sub_index],
933  "size" => $_FILES[$a_field]["size"][$a_index][$a_sub_index],
934  "is_upload" => $_FILES[$a_field]["is_upload"][$a_index][$a_sub_index] ?? true
935  );
936  }
937  } elseif ($a_sub_index) {
938  if ($_FILES[$a_field]["tmp_name"][$a_index] ?? false) {
939  $res = array(
940  "tmp_name" => $_FILES[$a_field]["tmp_name"][$a_index],
941  "name" => $_FILES[$a_field]["name"][$a_index],
942  "type" => $_FILES[$a_field]["type"][$a_index],
943  "error" => $_FILES[$a_field]["error"][$a_index],
944  "size" => $_FILES[$a_field]["size"][$a_index],
945  "is_upload" => $_FILES[$a_field]["is_upload"][$a_index] ?? true
946  );
947  }
948  } else {
949  if ($_FILES[$a_field]["tmp_name"] ?? false) {
950  $res = array(
951  "tmp_name" => $_FILES[$a_field]["tmp_name"],
952  "name" => $_FILES[$a_field]["name"],
953  "type" => $_FILES[$a_field]["type"],
954  "error" => $_FILES[$a_field]["error"],
955  "size" => $_FILES[$a_field]["size"],
956  "is_upload" => $_FILES[$a_field]["is_upload"] ?? true
957  );
958  }
959  }
960  return $res;
961  }
962 
963  public function hasFileUpload(
964  string $a_field,
965  ?string $a_index = null,
966  ?string $a_sub_index = null
967  ): bool {
968  $data = $this->getFileUpload($a_field, $a_index, $a_sub_index);
969  return (bool) ($data["tmp_name"] ?? false);
970  }
971 
983  public function moveFileUpload(
984  string $a_target_directory,
985  string $a_field,
986  ?string $a_target_name = null,
987  ?string $a_index = null,
988  ?string $a_sub_index = null
989  ): string {
990  if (!is_dir($a_target_directory)) {
991  return "";
992  }
993 
994  $data = $this->getFileUpload($a_field, $a_index, $a_sub_index);
995  if ($data["tmp_name"] && file_exists($data["tmp_name"])) {
996  if ($a_target_name) {
997  $data["name"] = $a_target_name;
998  }
999 
1000  $target_file = $a_target_directory . "/" . $data["name"];
1001  $target_file = str_replace("//", "/", $target_file);
1002 
1003  if ($data["is_upload"]) {
1004  if (!ilFileUtils::moveUploadedFile($data["tmp_name"], $data["name"], $target_file)) {
1005  return "";
1006  }
1007  } else {
1008  if (!ilFileUtils::rename($data["tmp_name"], $target_file)) {
1009  return "";
1010  }
1011  }
1012 
1013  return $target_file;
1014  }
1015  return "";
1016  }
1017 
1018  protected function rebuildUploadedFiles(): void
1019  {
1020  $file_hash = (string) $this->getFileHash();
1021  if ($file_hash != "") {
1022  $temp_path = ilFileUtils::getDataDir() . "/temp";
1023  if (is_dir($temp_path)) {
1024  $temp_files = glob($temp_path . "/" . session_id() . "~~" . $file_hash . "~~*");
1025  if (is_array($temp_files)) {
1026  foreach ($temp_files as $full_file) {
1027  $file = explode("~~", basename($full_file));
1028  $field = $file[2];
1029  $idx = $file[3];
1030  $idx2 = $file[4];
1031  $type = $file[5] . "/" . $file[6];
1032  $name = $file[7];
1033 
1034  if ($idx2 != "") {
1035  if (!isset($_FILES[$field]["tmp_name"][$idx][$idx2])) {
1036  $_FILES[$field]["tmp_name"][$idx][$idx2] = $full_file;
1037  $_FILES[$field]["name"][$idx][$idx2] = $name;
1038  $_FILES[$field]["type"][$idx][$idx2] = $type;
1039  $_FILES[$field]["error"][$idx][$idx2] = 0;
1040  $_FILES[$field]["size"][$idx][$idx2] = filesize($full_file);
1041  $_FILES[$field]["is_upload"][$idx][$idx2] = false;
1042  }
1043  } elseif ($idx != "") {
1044  if (!isset($_FILES[$field]["tmp_name"][$idx])) {
1045  $_FILES[$field]["tmp_name"][$idx] = $full_file;
1046  $_FILES[$field]["name"][$idx] = $name;
1047  $_FILES[$field]["type"][$idx] = $type;
1048  $_FILES[$field]["error"][$idx] = 0;
1049  $_FILES[$field]["size"][$idx] = filesize($full_file);
1050  $_FILES[$field]["is_upload"][$idx] = false;
1051  }
1052  } else {
1053  if (!isset($_FILES[$field]["tmp_name"])) {
1054  $_FILES[$field]["tmp_name"] = $full_file;
1055  $_FILES[$field]["name"] = $name;
1056  $_FILES[$field]["type"] = $type;
1057  $_FILES[$field]["error"] = 0;
1058  $_FILES[$field]["size"] = filesize($full_file);
1059  $_FILES[$field]["is_upload"] = false;
1060  }
1061  }
1062  }
1063  }
1064  }
1065  }
1066  }
1067 
1068  protected function checkForRequiredField(): bool
1069  {
1070  foreach ($this->items as $item) {
1071  if ($item instanceof ilFormSectionHeaderGUI) {
1072  return false;
1073  } elseif ($item->getType() != "hidden") {
1074  if ($this->getMode() == "subform") {
1075  if (!$this->hideRequired($item->getType())) {
1076  if ($item->getRequired()) {
1077  return true;
1078  }
1079  }
1080  } elseif (!$this->hideRequired($item->getType())) {
1081  if ($item->getRequired()) {
1082  return true;
1083  }
1084  }
1085  }
1086  }
1087 
1088  return false;
1089  }
1090 }
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setMultipart(bool $a_multipart)
$res
Definition: ltiservices.php:66
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...
getItemByPostVar(string $a_post_var)
removeItemByPostVar(string $a_post_var, bool $a_remove_unused_headers=false)
This class represents a form user interface.
setValue(string $a_value)
moveFileUpload(string $a_target_directory, string $a_field, ?string $a_target_name=null, ?string $a_index=null, ?string $a_sub_index=null)
Move upload to target directory.
loadLanguageModule(string $a_module)
Load language module.
getInput(string $a_post_var, bool $ensureValidation=true)
Returns the input of an item, if item provides getInput method and as fallback the value of the HTTP-...
static getASCIIFilename(string $a_filename)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static initDom(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI Dom.
This class represents a hidden form property in a property form.
getNextClass($a_gui_class=null)
static http()
Fetches the global http state from ILIAS.
ilGlobalTemplateInterface $global_tpl
setHideLabels(bool $a_value=true)
setPreventDoubleSubmission(bool $a_val)
global $DIC
Definition: shib_login.php:26
static createDirectory(string $a_dir, int $a_mod=0755)
create directory
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
static getDataDir()
get data directory (outside webspace)
setValuesByArray(array $a_values, bool $a_restrict_to_value_keys=false)
$txt
Definition: error.php:31
setTitleIcon(string $a_titleicon)
setTableWidth(string $a_width)
addCommandButton(string $a_cmd, string $a_text, string $a_id="")
Interface for multi values support.
static ofString(string $string)
Creates a new stream with an initial value.
Definition: Streams.php:41
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
insertItem( $item, bool $a_sub_item=false)
getFileUpload(string $a_field, ?string $a_index=null, ?string $a_sub_index=null)
Get file upload data.
getInputItemsRecursive()
returns a flat array of all input items including the possibly existing subitems recursively ...
global $ilSetting
Definition: privfeed.php:31
This class represents a property that may include a sub form.
static rename(string $a_source, string $a_target)
static initEvent(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI Event.
hasFileUpload(string $a_field, ?string $a_index=null, ?string $a_sub_index=null)
setDisableStandardMessage(bool $a_val)
$post
Definition: ltitoken.php:46
Refinery Factory $refinery