1<?php 2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4include_once("./Services/Form/classes/class.ilFormGUI.php"); 5 6// please do not add any more includes here if things are not really 7// highly re-used 8include_once("./Services/Form/classes/class.ilFormPropertyGUI.php"); 9include_once("./Services/Form/classes/class.ilSubEnabledFormPropertyGUI.php"); 10include_once("./Services/Form/classes/class.ilCheckboxInputGUI.php"); 11include_once("./Services/Form/classes/class.ilCustomInputGUI.php"); 12include_once("./Services/Form/classes/class.ilDateTimeInputGUI.php"); 13include_once("./Services/Form/classes/class.ilFileInputGUI.php"); 14include_once("./Services/Form/classes/class.ilImageFileInputGUI.php"); 15include_once('./Services/Form/classes/class.ilFlashFileInputGUI.php'); 16include_once("./Services/Form/classes/class.ilLocationInputGUI.php"); 17include_once("./Services/Form/classes/class.ilRadioGroupInputGUI.php"); 18include_once("./Services/Form/classes/class.ilCheckboxGroupInputGUI.php"); 19include_once("./Services/Form/classes/class.ilFormSectionHeaderGUI.php"); 20include_once("./Services/Form/classes/class.ilSelectInputGUI.php"); 21include_once("./Services/Form/classes/class.ilTextAreaInputGUI.php"); 22include_once("./Services/Form/classes/class.ilTextInputGUI.php"); 23include_once("./Services/Form/classes/class.ilDurationInputGUI.php"); 24include_once("./Services/Form/classes/class.ilFeedUrlInputGUI.php"); 25include_once("./Services/Form/classes/class.ilNonEditableValueGUI.php"); 26include_once("./Services/Form/classes/class.ilRegExpInputGUI.php"); 27include_once('./Services/Form/classes/class.ilColorPickerInputGUI.php'); 28include_once('./Services/Form/classes/class.ilPasswordInputGUI.php'); 29include_once('./Services/Form/classes/class.ilUserLoginInputGUI.php'); 30include_once('./Services/Form/classes/class.ilEMailInputGUI.php'); 31include_once('./Services/Form/classes/class.ilHiddenInputGUI.php'); 32include_once('./Services/Form/classes/class.ilNumberInputGUI.php'); 33include_once('./Services/Form/classes/class.ilCSSRectInputGUI.php'); 34include_once('./Services/Form/classes/class.ilTextWizardInputGUI.php'); 35include_once './Services/Form/classes/class.ilFileWizardInputGUI.php'; 36include_once './Services/Form/classes/class.ilFormulaInputGUI.php'; 37include_once './Services/Form/classes/class.ilBirthdayInputGUI.php'; 38 39/** 40* This class represents a property form user interface 41* 42* @author Alex Killing <alex.killing@gmx.de> 43* @version $Id$ 44* @ilCtrl_Calls ilPropertyFormGUI: ilFormPropertyDispatchGUI 45* @ingroup ServicesForm 46*/ 47class ilPropertyFormGUI extends ilFormGUI 48{ 49 /** 50 * @var ilLanguage 51 */ 52 protected $lng; 53 54 /** 55 * @var ilCtrl 56 */ 57 protected $ctrl; 58 59 /** 60 * @var ilTemplate 61 */ 62 protected $tpl; 63 64 /** 65 * @var ilObjUser 66 */ 67 protected $user; 68 69 /** 70 * @var ilSetting 71 */ 72 protected $settings; 73 74 private $buttons = array(); 75 private $items = array(); 76 protected $mode = "std"; 77 protected $check_input_called = false; 78 protected $disable_standard_message = false; 79 protected $top_anchor = "il_form_top"; 80 protected $titleicon = false; 81 protected $description = ""; 82 protected $tbl_width = false; 83 protected $show_top_buttons = true; 84 protected $hide_labels = false; 85 86 protected $force_top_buttons = false; 87 88 /** 89 * Constructor 90 * 91 * @param 92 */ 93 public function __construct() 94 { 95 global $DIC; 96 97 $this->lng = $DIC->language(); 98 $this->ctrl = $DIC->ctrl(); 99 100 $this->user = null; 101 if (isset($DIC["ilUser"])) { 102 $this->user = $DIC["ilUser"]; 103 } 104 105 $this->settings = null; 106 if (isset($DIC["ilSetting"])) { 107 $this->settings = $DIC["ilSetting"]; 108 } 109 110 $lng = $DIC->language(); 111 112 $lng->loadLanguageModule("form"); 113 114 // avoid double submission 115 $this->setPreventDoubleSubmission(true); 116 117 // do it as early as possible 118 $this->rebuildUploadedFiles(); 119 } 120 121 /** 122 * Execute command. 123 */ 124 public function executeCommand() 125 { 126 $ilCtrl = $this->ctrl; 127 128 $next_class = $ilCtrl->getNextClass($this); 129 $cmd = $ilCtrl->getCmd(); 130 131 switch ($next_class) { 132 case 'ilformpropertydispatchgui': 133 $ilCtrl->saveParameter($this, 'postvar'); 134 include_once './Services/Form/classes/class.ilFormPropertyDispatchGUI.php'; 135 $form_prop_dispatch = new ilFormPropertyDispatchGUI(); 136 $item = $this->getItemByPostVar($_REQUEST["postvar"]); 137 $form_prop_dispatch->setItem($item); 138 return $ilCtrl->forwardCommand($form_prop_dispatch); 139 break; 140 141 } 142 return false; 143 } 144 145 /** 146 * Set table width 147 * 148 * @access public 149 * @param string table width 150 * 151 */ 152 final public function setTableWidth($a_width) 153 { 154 $this->tbl_width = $a_width; 155 } 156 157 /** 158 * get table width 159 * 160 * @access public 161 * 162 */ 163 final public function getTableWidth() 164 { 165 return $this->tbl_width; 166 } 167 168 /** 169 * Set Mode ('std', 'subform'). 170 * 171 * @param string $a_mode Mode ('std', 'subform') 172 */ 173 public function setMode($a_mode) 174 { 175 $this->mode = $a_mode; 176 } 177 178 /** 179 * Get Mode ('std', 'subform'). 180 * 181 * @return string Mode ('std', 'subform') 182 */ 183 public function getMode() 184 { 185 return $this->mode; 186 } 187 188 /** 189 * Set Title. 190 * 191 * @param string $a_title Title 192 */ 193 public function setTitle($a_title) 194 { 195 $this->title = $a_title; 196 } 197 198 /** 199 * Get Title. 200 * 201 * @return string Title 202 */ 203 public function getTitle() 204 { 205 return $this->title; 206 } 207 208 /** 209 * Set TitleIcon. 210 * 211 * @param string $a_titleicon TitleIcon 212 */ 213 public function setTitleIcon($a_titleicon) 214 { 215 $this->titleicon = $a_titleicon; 216 } 217 218 /** 219 * Get TitleIcon. 220 * 221 * @return string TitleIcon 222 */ 223 public function getTitleIcon() 224 { 225 return $this->titleicon; 226 } 227 228 /** 229 * Set description 230 * 231 * @param string description 232 */ 233 public function setDescription($a_val) 234 { 235 $this->description = $a_val; 236 } 237 238 /** 239 * Get description 240 * 241 * @return string description 242 */ 243 public function getDescription() 244 { 245 return $this->description; 246 } 247 248 /** 249 * Set top anchor 250 * 251 * @param string top anchor 252 * @deprecated 253 */ 254 public function setTopAnchor($a_val) 255 { 256 $this->top_anchor = $a_val; 257 } 258 259 /** 260 * Get top anchor 261 * 262 * @return string top anchor 263 */ 264 public function getTopAnchor() 265 { 266 return $this->top_anchor; 267 } 268 269 /** 270 * Get show top buttons 271 */ 272 public function setShowTopButtons($a_val) 273 { 274 $this->show_top_buttons = $a_val; 275 } 276 277 /** 278 * Set show top buttons 279 */ 280 public function getShowTopButtons() 281 { 282 return $this->show_top_buttons; 283 } 284 285 /** 286 * Set force top buttons 287 * 288 * @param bool $a_val force top buttons 289 */ 290 public function setForceTopButtons($a_val) 291 { 292 $this->force_top_buttons = $a_val; 293 } 294 295 /** 296 * Get force top buttons 297 * 298 * @return bool force top buttons 299 */ 300 public function getForceTopButtons() 301 { 302 return $this->force_top_buttons; 303 } 304 305 306 /** 307 * Add Item (Property, SectionHeader). 308 * 309 * @param object $a_property Item object 310 */ 311 public function addItem($a_item) 312 { 313 $a_item->setParentForm($this); 314 return $this->items[] = $a_item; 315 } 316 317 /** 318 * Remove Item. 319 * 320 * @param string $a_postvar Post Var 321 */ 322 public function removeItemByPostVar($a_post_var, $a_remove_unused_headers = false) 323 { 324 foreach ($this->items as $key => $item) { 325 if (method_exists($item, "getPostVar") && $item->getPostVar() == $a_post_var) { 326 unset($this->items[$key]); 327 } 328 } 329 330 // remove section headers if they do not contain any items anymore 331 if ($a_remove_unused_headers) { 332 $unset_keys = array(); 333 $last_item = null; 334 $last_key = null; 335 foreach ($this->items as $key => $item) { 336 if ($item instanceof ilFormSectionHeaderGUI && $last_item instanceof ilFormSectionHeaderGUI) { 337 $unset_keys[] = $last_key; 338 } 339 $last_item = $item; 340 $last_key = $key; 341 } 342 if ($last_item instanceof ilFormSectionHeaderGUI) { 343 $unset_keys[] = $last_key; 344 } 345 foreach ($unset_keys as $key) { 346 unset($this->items[$key]); 347 } 348 } 349 } 350 351 /** 352 * Get Item by POST variable. 353 * 354 * @param string $a_postvar Post Var 355 */ 356 public function getItemByPostVar($a_post_var) 357 { 358 foreach ($this->items as $key => $item) { 359 if ($item->getType() != "section_header") { 360 //if ($item->getPostVar() == $a_post_var) 361 $ret = $item->getItemByPostVar($a_post_var); 362 if (is_object($ret)) { 363 return $ret; 364 } 365 } 366 } 367 368 return false; 369 } 370 371 /** 372 * Set Items 373 * 374 * @param array $a_items array of item objects 375 */ 376 public function setItems($a_items) 377 { 378 $this->items = $a_items; 379 } 380 381 /** 382 * Get Items 383 * 384 * @return array array of item objects 385 */ 386 public function getItems() 387 { 388 return $this->items; 389 } 390 391 /** 392 * returns a flat array of all input items including 393 * the possibly existing subitems recursively 394 * 395 * @return array 396 */ 397 public function getInputItemsRecursive() 398 { 399 $inputItems = array(); 400 401 foreach ($this->items as $item) { 402 if ($item->getType() == 'section_header') { 403 continue; 404 } 405 406 $inputItems[] = $item; 407 408 if ($item instanceof ilSubEnabledFormPropertyGUI) { 409 $inputItems = array_merge($inputItems, $item->getSubInputItemsRecursive()); 410 } 411 } 412 413 return $inputItems; 414 } 415 416 /** 417 * Set disable standard message 418 * 419 * @param boolean disable standard message 420 */ 421 public function setDisableStandardMessage($a_val) 422 { 423 $this->disable_standard_message = $a_val; 424 } 425 426 /** 427 * Get disable standard message 428 * 429 * @return boolean disable standard message 430 */ 431 public function getDisableStandardMessage() 432 { 433 return $this->disable_standard_message; 434 } 435 436 /** 437 * Get a value indicating whether the labels should be hidden or not. 438 * 439 * @return boolean true, to hide the labels; otherwise, false. 440 */ 441 public function getHideLabels() 442 { 443 return $this->hide_labels; 444 } 445 446 /** 447 * Set a value indicating whether the labels should be hidden or not. 448 * 449 * @param boolean $a_value Indicates whether the labels should be hidden. 450 */ 451 public function setHideLabels($a_value = true) 452 { 453 $this->hide_labels = $a_value; 454 } 455 456 /** 457 * Set form values from an array 458 * 459 * @param array $a_values Value array (key is post variable name, value is value) 460 */ 461 public function setValuesByArray($a_values, $a_restrict_to_value_keys = false) 462 { 463 foreach ($this->items as $item) { 464 if (!($a_restrict_to_value_keys) || 465 in_array($item->getPostVar(), array_keys($a_values))) { 466 $item->setValueByArray($a_values); 467 } 468 } 469 } 470 471 /** 472 * Set form values from POST values 473 * 474 */ 475 public function setValuesByPost() 476 { 477 foreach ($this->items as $item) { 478 $item->setValueByArray($_POST); 479 } 480 } 481 482 /** 483 * Check Post Input. This method also strips slashes and html from 484 * input and sets the alert texts for the items, if the input was not ok. 485 * 486 * @return boolean ok true/false 487 */ 488 public function checkInput() 489 { 490 global $DIC; 491 492 if ($this->check_input_called) { 493 die("Error: ilPropertyFormGUI->checkInput() called twice."); 494 } 495 496 $ok = true; 497 foreach ($this->items as $item) { 498 $item_ok = $item->checkInput(); 499 if (!$item_ok) { 500 $ok = false; 501 } 502 } 503 504 // check if POST is missint completely (if post_max_size exceeded) 505 if (count($this->items) > 0 && !is_array($_POST)) { 506 $ok = false; 507 } 508 509 $this->check_input_called = true; 510 511 512 513 // try to keep uploads for another try 514 if (!$ok && $_POST["ilfilehash"] && sizeof($_FILES)) { 515 $hash = $_POST["ilfilehash"]; 516 517 foreach ($_FILES as $field => $data) { 518 // only try to keep files that are ok 519 // see 25484: Wrong error handling when uploading icon instead of tile 520 $item = $this->getItemByPostVar($field); 521 if (is_bool($item) || !$item->checkInput()) { 522 continue; 523 } 524 // we support up to 2 nesting levels (see test/assesment) 525 if (is_array($data["tmp_name"])) { 526 foreach ($data["tmp_name"] as $idx => $upload) { 527 if (is_array($upload)) { 528 foreach ($upload as $idx2 => $file) { 529 if ($file && is_uploaded_file($file)) { 530 $file_name = $data["name"][$idx][$idx2]; 531 $file_type = $data["type"][$idx][$idx2]; 532 $this->keepFileUpload($hash, $field, $file, $file_name, $file_type, $idx, $idx2); 533 } 534 } 535 } elseif ($upload && is_uploaded_file($upload)) { 536 $file_name = $data["name"][$idx]; 537 $file_type = $data["type"][$idx]; 538 $this->keepFileUpload($hash, $field, $upload, $file_name, $file_type, $idx); 539 } 540 } 541 } else { 542 $this->keepFileUpload($hash, $field, $data["tmp_name"], $data["name"], $data["type"]); 543 } 544 } 545 } 546 $http = $DIC->http(); 547 $txt = $DIC->language()->txt("form_input_not_valid"); 548 switch ($http->request()->getHeaderLine('Accept')) { 549 // When JS asks for a valid JSON-Response, we send the success and message as JSON 550 case 'application/json': 551 $stream = \ILIAS\Filesystem\Stream\Streams::ofString(json_encode([ 552 'success' => $ok, 553 'message' => $txt, 554 ])); 555 $http->saveResponse($http->response()->withBody($stream)); 556 557 return $ok; 558 559 // Otherwise we send it using ilUtil and it will be rendered in the Template 560 default: 561 562 if (!$ok && !$this->getDisableStandardMessage()) { 563 ilUtil::sendFailure($txt); 564 } 565 566 return $ok; 567 } 568 } 569 570 /** 571 * 572 * Returns the value of a HTTP-POST variable, identified by the passed id 573 * 574 * @param string The key used for value determination 575 * @param boolean A flag whether the form input has to be validated before calling this method 576 * @return string The value of a HTTP-POST variable, identified by the passed id 577 * @access public 578 * 579 */ 580 public function getInput($a_post_var, $ensureValidation = true) 581 { 582 // this check ensures, that checkInput has been called (incl. stripSlashes()) 583 if (!$this->check_input_called && $ensureValidation) { 584 die("Error: ilPropertyFormGUI->getInput() called without calling checkInput() first."); 585 } 586 587 return $_POST[$a_post_var]; 588 } 589 590 /** 591 * Add a custom property. 592 * 593 * @param string Title 594 * @param string HTML. 595 * @param string Info text. 596 * @param string Alert text. 597 * @param boolean Required field. (Default false) 598 */ 599 public function addCustomProperty( 600 $a_title, 601 $a_html, 602 $a_info = "", 603 $a_alert = "", 604 $a_required = false 605 ) { 606 $this->properties[] = array("type" => "custom", 607 "title" => $a_title, 608 "html" => $a_html, 609 "info" => $a_info); 610 } 611 612 /** 613 * Add Command button 614 * 615 * @param string Command 616 * @param string Text 617 */ 618 public function addCommandButton($a_cmd, $a_text, $a_id = "") 619 { 620 $this->buttons[] = array("cmd" => $a_cmd, "text" => $a_text, "id" => $a_id); 621 } 622 623 624 /** 625 * Return all Command buttons 626 * 627 * @return array 628 */ 629 public function getCommandButtons() 630 { 631 return $this->buttons; 632 } 633 634 /** 635 * Remove all command buttons 636 */ 637 public function clearCommandButtons() 638 { 639 $this->buttons = array(); 640 } 641 642 /** 643 * Get Content. 644 */ 645 public function getContent() 646 { 647 global $DIC; 648 $lng = $this->lng; 649 $tpl = $DIC["tpl"]; 650 $ilSetting = $this->settings; 651 652 include_once("./Services/YUI/classes/class.ilYuiUtil.php"); 653 ilYuiUtil::initEvent(); 654 ilYuiUtil::initDom(); 655 ilYuiUtil::initAnimation(); 656 657 $tpl->addJavaScript("./Services/JavaScript/js/Basic.js"); 658 $tpl->addJavaScript("Services/Form/js/Form.js"); 659 660 $this->tpl = new ilTemplate("tpl.property_form.html", true, true, "Services/Form"); 661 662 // check if form has not title and first item is a section header 663 // -> use section header for title and remove section header 664 // -> command buttons are presented on top 665 $fi = $this->items[0]; 666 if ($this->getMode() == "std" && 667 $this->getTitle() == "" && 668 is_object($fi) && $fi->getType() == "section_header" 669 ) { 670 $this->setTitle($fi->getTitle()); 671 unset($this->items[0]); 672 } 673 674 675 // title icon 676 if ($this->getTitleIcon() != "" && @is_file($this->getTitleIcon())) { 677 $this->tpl->setCurrentBlock("title_icon"); 678 $this->tpl->setVariable("IMG_ICON", $this->getTitleIcon()); 679 $this->tpl->parseCurrentBlock(); 680 } 681 682 // title 683 if ($this->getTitle() != "") { 684 // commands on top 685 if (count($this->buttons) > 0 && $this->getShowTopButtons() && (count($this->items) > 2 || $this->force_top_buttons)) { 686 // command buttons 687 foreach ($this->buttons as $button) { 688 $this->tpl->setCurrentBlock("cmd2"); 689 $this->tpl->setVariable("CMD", $button["cmd"]); 690 $this->tpl->setVariable("CMD_TXT", $button["text"]); 691 if ($button["id"] != "") { 692 $this->tpl->setVariable("CMD2_ID", " id='" . $button["id"] . "_top'"); 693 } 694 $this->tpl->parseCurrentBlock(); 695 } 696 $this->tpl->setCurrentBlock("commands2"); 697 $this->tpl->parseCurrentBlock(); 698 } 699 700 if (is_object($ilSetting)) { 701 if ($ilSetting->get('char_selector_availability') > 0) { 702 require_once 'Services/UIComponent/CharSelector/classes/class.ilCharSelectorGUI.php'; 703 if (ilCharSelectorGUI::_isAllowed()) { 704 $char_selector = ilCharSelectorGUI::_getCurrentGUI(); 705 if ($char_selector->getConfig()->getAvailability() == ilCharSelectorConfig::ENABLED) { 706 $char_selector->addToPage(); 707 $this->tpl->TouchBlock('char_selector'); 708 } 709 } 710 } 711 } 712 713 $this->tpl->setCurrentBlock("header"); 714 $this->tpl->setVariable("TXT_TITLE", $this->getTitle()); 715 //$this->tpl->setVariable("LABEL", $this->getTopAnchor()); 716 $this->tpl->setVariable("TXT_DESCRIPTION", $this->getDescription()); 717 $this->tpl->parseCurrentBlock(); 718 } 719 $this->tpl->touchBlock("item"); 720 721 // properties 722 $this->required_text = false; 723 foreach ($this->items as $item) { 724 if ($item->getType() != "hidden") { 725 $this->insertItem($item); 726 } 727 } 728 729 // required 730 if ($this->required_text && $this->getMode() == "std") { 731 $this->tpl->setCurrentBlock("required_text"); 732 $this->tpl->setVariable("TXT_REQUIRED", $lng->txt("required_field")); 733 $this->tpl->parseCurrentBlock(); 734 } 735 736 // command buttons 737 foreach ($this->buttons as $button) { 738 $this->tpl->setCurrentBlock("cmd"); 739 $this->tpl->setVariable("CMD", $button["cmd"]); 740 $this->tpl->setVariable("CMD_TXT", $button["text"]); 741 742 if ($button["id"] != "") { 743 $this->tpl->setVariable("CMD_ID", " id='" . $button["id"] . "'"); 744 } 745 746 $this->tpl->parseCurrentBlock(); 747 } 748 749 // #18808 750 if ($this->getMode() != "subform") { 751 // try to keep uploads even if checking input fails 752 if ($this->getMultipart()) { 753 $hash = $_POST["ilfilehash"]; 754 if (!$hash) { 755 $hash = md5(uniqid(mt_rand(), true)); 756 } 757 $fhash = new ilHiddenInputGUI("ilfilehash"); 758 $fhash->setValue($hash); 759 $this->addItem($fhash); 760 } 761 } 762 763 // hidden properties 764 $hidden_fields = false; 765 foreach ($this->items as $item) { 766 if ($item->getType() == "hidden") { 767 $item->insert($this->tpl); 768 $hidden_fields = true; 769 } 770 } 771 772 if ($this->required_text || count($this->buttons) > 0 || $hidden_fields) { 773 $this->tpl->setCurrentBlock("commands"); 774 $this->tpl->parseCurrentBlock(); 775 } 776 777 778 if ($this->getMode() == "subform") { 779 $this->tpl->touchBlock("sub_table"); 780 } else { 781 $this->tpl->touchBlock("std_table"); 782 $this->tpl->setVariable('STD_TABLE_WIDTH', $this->getTableWidth()); 783 } 784 785 return $this->tpl->get(); 786 } 787 788 protected function hideRequired($a_type) 789 { 790 // #15818 791 return in_array($a_type, array("non_editable_value")); 792 } 793 794 public function insertItem($item, $a_sub_item = false) 795 { 796 global $DIC; 797 $tpl = $DIC["tpl"]; 798 ; 799 $lng = $this->lng; 800 801 802 $cfg = array(); 803 804 //if(method_exists($item, "getMulti") && $item->getMulti()) 805 if ($item instanceof ilMultiValuesItem && $item->getMulti()) { 806 $tpl->addJavascript("./Services/Form/js/ServiceFormMulti.js"); 807 808 $this->tpl->setCurrentBlock("multi_in"); 809 $this->tpl->setVariable("ID", $item->getFieldId()); 810 $this->tpl->parseCurrentBlock(); 811 812 $this->tpl->touchBlock("multi_out"); 813 814 815 // add hidden item to enable preset multi items 816 // not used yet, should replace hidden field stuff 817 $multi_values = $item->getMultiValues(); 818 if (is_array($multi_values) && sizeof($multi_values) > 1) { 819 $multi_value = new ilHiddenInputGUI("ilMultiValues~" . $item->getPostVar()); 820 $multi_value->setValue(implode("~", $multi_values)); 821 $this->addItem($multi_value); 822 } 823 $cfg["multi_values"] = $multi_values; 824 } 825 826 $item->insert($this->tpl); 827 828 if ($item->getType() == "file" || $item->getType() == "image_file") { 829 $this->setMultipart(true); 830 } 831 832 if ($item->getType() != "section_header") { 833 $cfg["id"] = $item->getFieldId(); 834 835 // info text 836 if ($item->getInfo() != "") { 837 $this->tpl->setCurrentBlock("description"); 838 $this->tpl->setVariable( 839 "PROPERTY_DESCRIPTION", 840 $item->getInfo() 841 ); 842 $this->tpl->parseCurrentBlock(); 843 } 844 845 if ($this->getMode() == "subform") { 846 // required 847 if (!$this->hideRequired($item->getType())) { 848 if ($item->getRequired()) { 849 $this->tpl->touchBlock("sub_required"); 850 $this->required_text = true; 851 } 852 } 853 854 // hidden title (for accessibility, e.g. file upload) 855 if ($item->getHiddenTitle() != "") { 856 $this->tpl->setCurrentBlock("sub_hid_title"); 857 $this->tpl->setVariable( 858 "SPHID_TITLE", 859 $item->getHiddenTitle() 860 ); 861 $this->tpl->parseCurrentBlock(); 862 } 863 864 $this->tpl->setCurrentBlock("sub_prop_start"); 865 $this->tpl->setVariable("PROPERTY_TITLE", $item->getTitle()); 866 $this->tpl->setVariable("PROPERTY_CLASS", "il_" . $item->getType()); 867 if ($item->getType() != "non_editable_value" && $item->getFormLabelFor() != "") { 868 $this->tpl->setVariable("FOR_ID", ' for="'.$item->getFormLabelFor().'" '); 869 } 870 $this->tpl->setVariable("LAB_ID", $item->getFieldId()); 871 $this->tpl->parseCurrentBlock(); 872 } else { 873 // required 874 if (!$this->hideRequired($item->getType())) { 875 if ($item->getRequired()) { 876 $this->tpl->touchBlock("required"); 877 $this->required_text = true; 878 } 879 } 880 881 // hidden title (for accessibility, e.g. file upload) 882 if ($item->getHiddenTitle() != "") { 883 $this->tpl->setCurrentBlock("std_hid_title"); 884 $this->tpl->setVariable( 885 "PHID_TITLE", 886 $item->getHiddenTitle() 887 ); 888 $this->tpl->parseCurrentBlock(); 889 } 890 891 $this->tpl->setCurrentBlock("std_prop_start"); 892 $this->tpl->setVariable("PROPERTY_TITLE", $item->getTitle()); 893 if ($item->getType() != "non_editable_value" && $item->getFormLabelFor() != "") { 894 $this->tpl->setVariable("FOR_ID", ' for="'.$item->getFormLabelFor().'" '); 895 } 896 $this->tpl->setVariable("LAB_ID", $item->getFieldId()); 897 if ($this->getHideLabels()) { 898 $this->tpl->setVariable("HIDE_LABELS_STYLE", " ilFormOptionHidden"); 899 } 900 $this->tpl->parseCurrentBlock(); 901 } 902 903 // alert 904 if ($item->getType() != "non_editable_value" && $item->getAlert() != "") { 905 $this->tpl->setCurrentBlock("alert"); 906 $this->tpl->setVariable( 907 "IMG_ALERT", 908 ilUtil::getImagePath("icon_alert.svg") 909 ); 910 $this->tpl->setVariable( 911 "ALT_ALERT", 912 $lng->txt("alert") 913 ); 914 $this->tpl->setVariable( 915 "TXT_ALERT", 916 $item->getAlert() 917 ); 918 $this->tpl->parseCurrentBlock(); 919 } 920 921 // subitems 922 $sf = null; 923 if ($item->getType() != "non_editable_value" or 1) { 924 $sf = $item->getSubForm(); 925 if ($item->hideSubForm() && is_object($sf)) { 926 $this->tpl->setCurrentBlock("sub_form_hide"); 927 $this->tpl->setVariable("DSFID", $item->getFieldId()); 928 $this->tpl->parseCurrentBlock(); 929 } 930 } 931 932 933 $sf_content = ""; 934 if (is_object($sf)) { 935 $sf_content = $sf->getContent(); 936 if ($sf->getMultipart()) { 937 $this->setMultipart(true); 938 } 939 $this->tpl->setCurrentBlock("sub_form"); 940 $this->tpl->setVariable("PROP_SUB_FORM", $sf_content); 941 $this->tpl->setVariable("SFID", $item->getFieldId()); 942 $this->tpl->parseCurrentBlock(); 943 } 944 945 $this->tpl->setCurrentBlock("prop"); 946 /* not used yet 947 $this->tpl->setVariable("ID", $item->getFieldId()); 948 $this->tpl->setVariable("CFG", ilJsonUtil::encode($cfg));*/ 949 $this->tpl->parseCurrentBlock(); 950 } 951 952 953 $this->tpl->touchBlock("item"); 954 } 955 956 public function getHTML() 957 { 958 $html = parent::getHTML(); 959 960 // #13531 - get content that has to reside outside of the parent form tag, e.g. panels/layers 961 foreach ($this->items as $item) { 962 // #13536 - ilFormSectionHeaderGUI does NOT extend ilFormPropertyGUI ?! 963 if (method_exists($item, "getContentOutsideFormTag")) { 964 $outside = $item->getContentOutsideFormTag(); 965 if ($outside) { 966 $html .= $outside; 967 } 968 } 969 } 970 971 return $html; 972 } 973 974 975 // 976 // UPLOAD HANDLING 977 // 978 979 /** 980 * Import upload into temp directory 981 * 982 * @param string $a_hash unique form hash 983 * @param string $a_field form field 984 * @param string $a_tmp_name temp file name 985 * @param string $a_name original file name 986 * @param string $a_type file mime type 987 * @param mixed $a_index form field index (if array) 988 * @param mixed $a_sub_index form field subindex (if array) 989 * @return bool 990 */ 991 protected function keepFileUpload($a_hash, $a_field, $a_tmp_name, $a_name, $a_type, $a_index = null, $a_sub_index = null) 992 { 993 if (trim($a_tmp_name) == "") { 994 return; 995 } 996 997 $a_name = ilUtil::getAsciiFileName($a_name); 998 999 $tmp_file_name = implode("~~", array(session_id(), 1000 $a_hash, 1001 $a_field, 1002 $a_index, 1003 $a_sub_index, 1004 str_replace("/", "~~", $a_type), 1005 str_replace("~~", "_", $a_name))); 1006 1007 // make sure temp directory exists 1008 $temp_path = ilUtil::getDataDir() . "/temp"; 1009 if (!is_dir($temp_path)) { 1010 ilUtil::createDirectory($temp_path); 1011 } 1012 1013 ilUtil::moveUploadedFile($a_tmp_name, $tmp_file_name, $temp_path . "/" . $tmp_file_name); 1014 1015 /** @var ilFileInputGUI $file_input */ 1016 $file_input = $this->getItemByPostVar($a_field); 1017 $file_input->setPending($a_name); 1018 } 1019 1020 /** 1021 * Get file upload data 1022 * 1023 * @param string $a_field form field 1024 * @param mixed $a_index form field index (if array) 1025 * @param mixed $a_sub_index form field subindex (if array) 1026 * @return array (tmp_name, name, type, error, size, is_upload) 1027 */ 1028 public function getFileUpload($a_field, $a_index = null, $a_sub_index = null) 1029 { 1030 $res = array(); 1031 if ($a_index) { 1032 if ($_FILES[$a_field]["tmp_name"][$a_index][$a_sub_index]) { 1033 $res = array( 1034 "tmp_name" => $_FILES[$a_field]["tmp_name"][$a_index][$a_sub_index], 1035 "name" => $_FILES[$a_field]["name"][$a_index][$a_sub_index], 1036 "type" => $_FILES[$a_field]["type"][$a_index][$a_sub_index], 1037 "error" => $_FILES[$a_field]["error"][$a_index][$a_sub_index], 1038 "size" => $_FILES[$a_field]["size"][$a_index][$a_sub_index], 1039 "is_upload" => true 1040 ); 1041 } 1042 } elseif ($a_sub_index) { 1043 if ($_FILES[$a_field]["tmp_name"][$a_index]) { 1044 $res = array( 1045 "tmp_name" => $_FILES[$a_field]["tmp_name"][$a_index], 1046 "name" => $_FILES[$a_field]["name"][$a_index], 1047 "type" => $_FILES[$a_field]["type"][$a_index], 1048 "error" => $_FILES[$a_field]["error"][$a_index], 1049 "size" => $_FILES[$a_field]["size"][$a_index], 1050 "is_upload" => true 1051 ); 1052 } 1053 } else { 1054 if ($_FILES[$a_field]["tmp_name"]) { 1055 $res = array( 1056 "tmp_name" => $_FILES[$a_field]["tmp_name"], 1057 "name" => $_FILES[$a_field]["name"], 1058 "type" => $_FILES[$a_field]["type"], 1059 "error" => $_FILES[$a_field]["error"], 1060 "size" => $_FILES[$a_field]["size"], 1061 "is_upload" => true 1062 ); 1063 } 1064 } 1065 return $res; 1066 } 1067 1068 /** 1069 * Was any file uploaded? 1070 * 1071 * @param string $a_field form field 1072 * @param mixed $a_index form field index (if array) 1073 * @param mixed $a_sub_index form field subindex (if array) 1074 * @return bool 1075 */ 1076 public function hasFileUpload($a_field, $a_index = null, $a_sub_index = null) 1077 { 1078 $data = $this->getFileUpload($a_field, $a_index, $a_sub_index); 1079 return (bool) $data["tmp_name"]; 1080 } 1081 1082 /** 1083 * Move upload to target directory 1084 * 1085 * @param string $a_target_directory target directory (without filename!) 1086 * @param string $a_field form field 1087 * @param string $a_target_name target file name (if different from uploaded file) 1088 * @param mixed $a_index form field index (if array) 1089 * @param mixed $a_sub_index form field subindex (if array) 1090 * @return string target file name incl. path 1091 */ 1092 public function moveFileUpload($a_target_directory, $a_field, $a_target_name = null, $a_index = null, $a_sub_index = null) 1093 { 1094 if (!is_dir($a_target_directory)) { 1095 return; 1096 } 1097 1098 $data = $this->getFileUpload($a_field, $a_index, $a_sub_index); 1099 if ($data["tmp_name"] && file_exists($data["tmp_name"])) { 1100 if ($a_target_name) { 1101 $data["name"] = $a_target_name; 1102 } 1103 1104 $target_file = $a_target_directory . "/" . $data["name"]; 1105 $target_file = str_replace("//", "/", $target_file); 1106 1107 if ($data["is_upload"]) { 1108 if (!ilUtil::moveUploadedFile($data["tmp_name"], $data["name"], $target_file)) { 1109 return; 1110 } 1111 } else { 1112 if (!rename($data["tmp_name"], $target_file)) { 1113 return; 1114 } 1115 } 1116 1117 return $target_file; 1118 } 1119 } 1120 1121 /** 1122 * try to rebuild files 1123 */ 1124 protected function rebuildUploadedFiles() 1125 { 1126 if (isset($_POST["ilfilehash"]) && $_POST["ilfilehash"]) { 1127 $temp_path = ilUtil::getDataDir() . "/temp"; 1128 if (is_dir($temp_path)) { 1129 $reload = array(); 1130 1131 $temp_files = glob($temp_path . "/" . session_id() . "~~" . $_POST["ilfilehash"] . "~~*"); 1132 if (is_array($temp_files)) { 1133 foreach ($temp_files as $full_file) { 1134 $file = explode("~~", basename($full_file)); 1135 $field = $file[2]; 1136 $idx = $file[3]; 1137 $idx2 = $file[4]; 1138 $type = $file[5] . "/" . $file[6]; 1139 $name = $file[7]; 1140 1141 if ($idx2 != "") { 1142 if (!$_FILES[$field]["tmp_name"][$idx][$idx2]) { 1143 $_FILES[$field]["tmp_name"][$idx][$idx2] = $full_file; 1144 $_FILES[$field]["name"][$idx][$idx2] = $name; 1145 $_FILES[$field]["type"][$idx][$idx2] = $type; 1146 $_FILES[$field]["error"][$idx][$idx2] = 0; 1147 $_FILES[$field]["size"][$idx][$idx2] = filesize($full_file); 1148 } 1149 } elseif ($idx != "") { 1150 if (!$_FILES[$field]["tmp_name"][$idx]) { 1151 $_FILES[$field]["tmp_name"][$idx] = $full_file; 1152 $_FILES[$field]["name"][$idx] = $name; 1153 $_FILES[$field]["type"][$idx] = $type; 1154 $_FILES[$field]["error"][$idx] = 0; 1155 $_FILES[$field]["size"][$idx] = filesize($full_file); 1156 } 1157 } else { 1158 if (!$_FILES[$field]["tmp_name"]) { 1159 $_FILES[$field]["tmp_name"] = $full_file; 1160 $_FILES[$field]["name"] = $name; 1161 $_FILES[$field]["type"] = $type; 1162 $_FILES[$field]["error"] = 0; 1163 $_FILES[$field]["size"] = filesize($full_file); 1164 } 1165 } 1166 } 1167 } 1168 } 1169 } 1170 } 1171} 1172