ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilPropertyFormGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21use ILIAS\HTTP;
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;
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 {
306 return $this->disable_standard_message;
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;
490 $tpl = $DIC["tpl"];
491 $ilSetting = $this->settings;
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"];
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)) {
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}
static ofString(string $string)
Creates a new stream with an initial value.
Definition: Streams.php:41
Class ilCtrl provides processing control methods.
getNextClass($a_gui_class=null)
@inheritDoc
static getASCIIFilename(string $a_filename)
static rename(string $a_source, string $a_target)
static getDataDir()
get data directory (outside webspace)
static createDirectory(string $a_dir, int $a_mod=0755)
create 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
This class represents a form user interface.
setPreventDoubleSubmission(bool $a_val)
This class represents a property in a property form.
getItemByPostVar(string $a_post_var)
Get item by post var.
This class represents a section header in a property form.
This class represents a hidden form property in a property form.
language handling
loadLanguageModule(string $a_module)
Load language module.
User class.
This class represents a property form user interface.
setValuesByArray(array $a_values, bool $a_restrict_to_value_keys=false)
hasFileUpload(string $a_field, ?string $a_index=null, ?string $a_sub_index=null)
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.
setDisableStandardMessage(bool $a_val)
setTableWidth(string $a_width)
getFileUpload(string $a_field, ?string $a_index=null, ?string $a_sub_index=null)
Get file upload data.
ilGlobalTemplateInterface $global_tpl
insertItem( $item, bool $a_sub_item=false)
addCommandButton(string $a_cmd, string $a_text, string $a_id="")
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-...
removeItemByPostVar(string $a_post_var, bool $a_remove_unused_headers=false)
setTitleIcon(string $a_titleicon)
Refinery Factory $refinery
getItemByPostVar(string $a_post_var)
getInputItemsRecursive()
returns a flat array of all input items including the possibly existing subitems recursively
setHideLabels(bool $a_value=true)
ILIAS Setting Class.
This class represents a property that may include a sub form.
special template class to simplify handling of ITX/PEAR
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
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 initDom(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI Dom.
static initEvent(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI Event.
$http
Definition: deliver.php:30
$txt
Definition: error.php:31
Interface for multi values support.
$res
Definition: ltiservices.php:69
$post
Definition: ltitoken.php:46
static http()
Fetches the global http state from ILIAS.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
global $lng
Definition: privfeed.php:31
global $ilSetting
Definition: privfeed.php:31
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26