1<?php 2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4require_once 'Services/Form/classes/class.ilIdentifiedMultiValuesInputGUI.php'; 5require_once 'Services/UIComponent/Glyph/classes/class.ilGlyphGUI.php'; 6 7/** 8 * @author Björn Heyser <bheyser@databay.de> 9 * @version $Id$ 10 * 11 * @package Modules/Test(QuestionPool) 12 */ 13abstract class ilMultipleImagesInputGUI extends ilIdentifiedMultiValuesInputGUI 14{ 15 const RENDERING_TEMPLATE = 'tpl.prop_multi_image_inp.html'; 16 17 const ITERATOR_SUBFIELD_NAME = 'iteratorfield'; 18 const STORED_IMAGE_SUBFIELD_NAME = 'storedimage'; 19 const IMAGE_UPLOAD_SUBFIELD_NAME = 'imageupload'; 20 21 const FILE_DATA_INDEX_DODGING_FILE = 'dodging_file'; 22 /** 23 * @var bool 24 */ 25 protected $editElementOccuranceEnabled = false; 26 27 /** 28 * @var bool 29 */ 30 protected $editElementOrderEnabled = false; 31 32 /** 33 * @var array 34 */ 35 protected $suffixes = array(); 36 37 protected $imageRemovalCommand = 'removeImage'; 38 39 protected $imageUploadCommand = 'uploadImage'; 40 41 /** 42 * Constructor 43 * 44 * @param string $a_title Title 45 * @param string $a_postvar Post Variable 46 */ 47 public function __construct($a_title = "", $a_postvar = "") 48 { 49 global $DIC; 50 51 $this->lng = $DIC->language(); 52 parent::__construct($a_title, $a_postvar); 53 54 $this->setSuffixes(array("jpg", "jpeg", "png", "gif")); 55 $this->setSize('25'); 56 $this->validationRegexp = ""; 57 58 require_once 'Services/Form/classes/class.ilMultipleImagesAdditionalIndexLevelRemover.php'; 59 $manipulator = new ilMultipleImagesAdditionalIndexLevelRemover(); 60 $manipulator->setPostVar($this->getPostVar()); 61 $this->addFormValuesManipulator($manipulator); 62 63 require_once 'Services/Form/classes/class.ilMultipleImagesFileSubmissionDataCompletion.php'; 64 $manipulator = new ilMultipleImagesFileSubmissionDataCompletion(); 65 $manipulator->setPostVar($this->getPostVar()); 66 $this->addFormValuesManipulator($manipulator); 67 68 require_once 'Services/Form/classes/class.ilIdentifiedMultiFilesJsPositionIndexRemover.php'; 69 $manipulator = new ilIdentifiedMultiFilesJsPositionIndexRemover(); 70 $manipulator->setPostVar($this->getPostVar()); 71 $this->addFormValuesManipulator($manipulator); 72 73 require_once 'Services/Form/classes/class.ilMultiFilesSubmitRecursiveSlashesStripper.php'; 74 $manipulator = new ilMultiFilesSubmitRecursiveSlashesStripper(); 75 $manipulator->setPostVar($this->getPostVar()); 76 $this->addFormValuesManipulator($manipulator); 77 } 78 79 /** 80 * Set Accepted Suffixes. 81 * 82 * @param array $a_suffixes Accepted Suffixes 83 */ 84 public function setSuffixes($a_suffixes) 85 { 86 $this->suffixes = $a_suffixes; 87 } 88 89 /** 90 * Get Accepted Suffixes. 91 * 92 * @return array Accepted Suffixes 93 */ 94 public function getSuffixes() 95 { 96 return $this->suffixes; 97 } 98 99 /** 100 * @return string 101 */ 102 public function getImageRemovalCommand() 103 { 104 return $this->imageRemovalCommand; 105 } 106 107 /** 108 * @param string $imageRemovalCommand 109 */ 110 public function setImageRemovalCommand($imageRemovalCommand) 111 { 112 $this->imageRemovalCommand = $imageRemovalCommand; 113 } 114 115 /** 116 * @return string 117 */ 118 public function getImageUploadCommand() 119 { 120 return $this->imageUploadCommand; 121 } 122 123 /** 124 * @param string $imageUploadCommand 125 */ 126 public function setImageUploadCommand($imageUploadCommand) 127 { 128 $this->imageUploadCommand = $imageUploadCommand; 129 } 130 131 /** 132 * @return boolean $editElementOccuranceEnabled 133 */ 134 public function isEditElementOccuranceEnabled() 135 { 136 return $this->editElementOccuranceEnabled; 137 } 138 139 /** 140 * @param boolean $editElementOccuranceEnabled 141 */ 142 public function setEditElementOccuranceEnabled($editElementOccuranceEnabled) 143 { 144 $this->editElementOccuranceEnabled = $editElementOccuranceEnabled; 145 } 146 147 /** 148 * @return boolean 149 */ 150 public function isEditElementOrderEnabled() 151 { 152 return $this->editElementOrderEnabled; 153 } 154 155 /** 156 * @param boolean $editElementOrderEnabled 157 */ 158 public function setEditElementOrderEnabled($editElementOrderEnabled) 159 { 160 $this->editElementOrderEnabled = $editElementOrderEnabled; 161 } 162 163 /** 164 * @param mixed $value 165 * @return bool 166 */ 167 abstract protected function isValidFilenameInput($filenameInput); 168 169 /** 170 * Check input, strip slashes etc. set alert, if input is not ok. 171 * 172 * @return boolean $validationSuccess 173 */ 174 public function onCheckInput() 175 { 176 $lng = $GLOBALS['DIC'] ? $GLOBALS['DIC']['lng'] : $GLOBALS['lng']; 177 $F = $_FILES[$this->getPostVar()]; 178 if ($F && isset($_REQUEST[$this->getPostVar()][self::FILE_DATA_INDEX_DODGING_FILE])) { 179 $F = array_merge(array(self::FILE_DATA_INDEX_DODGING_FILE => $_REQUEST[$this->getPostVar()][self::FILE_DATA_INDEX_DODGING_FILE]), $F); 180 } 181 182 if ($this->getRequired() && !is_array($F['error'])) { 183 $this->setAlert($lng->txt("form_msg_file_no_upload")); 184 return false; 185 } else { 186 foreach ($F['error'] as $index => $error) { 187 // error handling 188 if ($error > 0) { 189 switch ($error) { 190 case UPLOAD_ERR_INI_SIZE: 191 $this->setAlert($lng->txt("form_msg_file_size_exceeds")); 192 return false; 193 break; 194 195 case UPLOAD_ERR_FORM_SIZE: 196 $this->setAlert($lng->txt("form_msg_file_size_exceeds")); 197 return false; 198 break; 199 200 case UPLOAD_ERR_PARTIAL: 201 $this->setAlert($lng->txt("form_msg_file_partially_uploaded")); 202 return false; 203 break; 204 205 case UPLOAD_ERR_NO_FILE: 206 if (!$this->getRequired()) { 207 break; 208 } elseif (strlen($F[self::FILE_DATA_INDEX_DODGING_FILE][$index])) { 209 break; 210 } 211 $this->setAlert($lng->txt("form_msg_file_no_upload")); 212 return false; 213 break; 214 215 case UPLOAD_ERR_NO_TMP_DIR: 216 $this->setAlert($lng->txt("form_msg_file_missing_tmp_dir")); 217 return false; 218 break; 219 220 case UPLOAD_ERR_CANT_WRITE: 221 $this->setAlert($lng->txt("form_msg_file_cannot_write_to_disk")); 222 return false; 223 break; 224 225 case UPLOAD_ERR_EXTENSION: 226 $this->setAlert($lng->txt("form_msg_file_upload_stopped_ext")); 227 return false; 228 break; 229 } 230 } 231 } 232 } 233 234 if (is_array($F['tmp_name'])) { 235 foreach ($F['tmp_name'] as $index => $tmpname) { 236 $filename = $F['name'][$index]; 237 $filename_arr = pathinfo($filename); 238 $suffix = $filename_arr["extension"]; 239 $mimetype = $F['type'][$index]; 240 $size_bytes = $F['size'][$index]; 241 // check suffixes 242 if (strlen($tmpname) && is_array($this->getSuffixes())) { 243 if (!in_array(strtolower($suffix), $this->getSuffixes())) { 244 $this->setAlert($lng->txt("form_msg_file_wrong_file_type")); 245 return false; 246 } 247 } 248 } 249 } 250 251 foreach ($F['tmp_name'] as $index => $tmpname) { 252 $filename = $F['name'][$index]; 253 $filename_arr = pathinfo($filename); 254 $suffix = $filename_arr["extension"]; 255 $mimetype = $F['type'][$index]; 256 $size_bytes = $F['size'][$index]; 257 // virus handling 258 if (strlen($tmpname)) { 259 $vir = ilUtil::virusHandling($tmpname, $filename); 260 if ($vir[0] == false) { 261 $this->setAlert($lng->txt("form_msg_file_virus_found") . "<br />" . $vir[1]); 262 return false; 263 } 264 } 265 } 266 267 return $this->checkSubItemsInput(); 268 } 269 270 /** 271 * @param string $mode 272 * @return string 273 */ 274 public function render($a_mode = "") 275 { 276 $lng = $this->lng; 277 278 $tpl = $this->getTemplate(); 279 $i = 0; 280 foreach ($this->getIdentifiedMultiValues() as $identifier => $value) { 281 if ($this->valueHasContentImageSource($value)) { 282 $tpl->setCurrentBlock('image'); 283 284 $tpl->setVariable('STORED_IMAGE_SRC', $this->fetchContentImageSourceFromValue($value)); 285 $tpl->setVariable('STORED_IMAGE_ALT', ilUtil::prepareFormOutput($this->fetchContentImageTitleFromValue($value))); 286 $tpl->setVariable('STORED_IMAGE_FILENAME', $this->fetchContentImageTitleFromValue($value)); 287 $tpl->setVariable("STORED_IMAGE_POST_VAR", $this->getMultiValuePostVarSubFieldPosIndexed($identifier, self::STORED_IMAGE_SUBFIELD_NAME, $i)); 288 289 $tpl->setVariable("TXT_DELETE_EXISTING", $lng->txt("delete_existing_file")); 290 $tpl->setVariable("IMAGE_CMD_REMOVE", $this->buildMultiValueSubmitVar($identifier, $i, $this->getImageRemovalCommand())); 291 292 $tpl->parseCurrentBlock(); 293 } 294 295 $tpl->setCurrentBlock('addimage'); 296 297 $tpl->setVariable("IMAGE_BROWSE", $lng->txt('select_file')); 298 $tpl->setVariable("IMAGE_ID", $this->getMultiValuePosIndexedSubFieldId($identifier, self::IMAGE_UPLOAD_SUBFIELD_NAME, $i)); 299 $tpl->setVariable("TXT_IMAGE_SUBMIT", $lng->txt("upload")); 300 $tpl->setVariable("IMAGE_CMD_UPLOAD", $this->buildMultiValueSubmitVar($identifier, $i, $this->getImageUploadCommand())); 301 $tpl->setVariable("UPLOAD_IMAGE_POST_VAR", $this->getMultiValuePostVarSubFieldPosIndexed($identifier, self::IMAGE_UPLOAD_SUBFIELD_NAME, $i)); 302 $tpl->setVariable("COUNT_POST_VAR", $this->getMultiValuePostVarSubFieldPosIndexed($identifier, self::ITERATOR_SUBFIELD_NAME, $i)); 303 304 $tpl->parseCurrentBlock(); 305 306 if ($this->isEditElementOrderEnabled()) { 307 $tpl->setCurrentBlock("move"); 308 $tpl->setVariable("ID_UP", $this->getMultiValuePosIndexedSubFieldId($identifier, 'up', $i)); 309 $tpl->setVariable("ID_DOWN", $this->getMultiValuePosIndexedSubFieldId($identifier, 'down', $i)); 310 $tpl->setVariable("CMD_UP", $this->buildMultiValueSubmitVar($identifier, $i, 'up')); 311 $tpl->setVariable("CMD_DOWN", $this->buildMultiValueSubmitVar($identifier, $i, 'down')); 312 $tpl->setVariable("UP_BUTTON", ilGlyphGUI::get(ilGlyphGUI::UP)); 313 $tpl->setVariable("DOWN_BUTTON", ilGlyphGUI::get(ilGlyphGUI::DOWN)); 314 $tpl->parseCurrentBlock(); 315 } 316 317 if ($this->isEditElementOccuranceEnabled()) { 318 $tpl->setCurrentBlock("row"); 319 $tpl->setVariable("ID_ADD", $this->getMultiValuePosIndexedSubFieldId($identifier, 'add', $i)); 320 $tpl->setVariable("ID_REMOVE", $this->getMultiValuePosIndexedSubFieldId($identifier, 'remove', $i)); 321 $tpl->setVariable("CMD_ADD", $this->buildMultiValueSubmitVar($identifier, $i, 'add')); 322 $tpl->setVariable("CMD_REMOVE", $this->buildMultiValueSubmitVar($identifier, $i, 'remove')); 323 $tpl->setVariable("ADD_BUTTON", ilGlyphGUI::get(ilGlyphGUI::ADD)); 324 $tpl->setVariable("REMOVE_BUTTON", ilGlyphGUI::get(ilGlyphGUI::REMOVE)); 325 $tpl->parseCurrentBlock(); 326 } 327 328 $i++; 329 } 330 331 if (is_array($this->getSuffixes())) { 332 $suff_str = $delim = ""; 333 foreach ($this->getSuffixes() as $suffix) { 334 $suff_str .= $delim . "." . $suffix; 335 $delim = ", "; 336 } 337 $tpl->setCurrentBlock('allowed_image_suffixes'); 338 $tpl->setVariable("TXT_ALLOWED_SUFFIXES", $lng->txt("file_allowed_suffixes") . " " . $suff_str); 339 $tpl->parseCurrentBlock(); 340 } 341 /* 342 $tpl->setCurrentBlock("image_heading"); 343 $tpl->setVariable("ANSWER_IMAGE", $lng->txt('answer_image')); 344 $tpl->parseCurrentBlock(); 345 */ 346 347 $tpl->setVariable("TXT_MAX_SIZE", ilUtil::getFileSizeInfo()); 348 $tpl->setVariable("ELEMENT_ID", $this->getPostVar()); 349 $tpl->setVariable("TEXT_YES", $lng->txt('yes')); 350 $tpl->setVariable("TEXT_NO", $lng->txt('no')); 351 $tpl->setVariable("DELETE_IMAGE_HEADER", $lng->txt('delete_image_header')); 352 $tpl->setVariable("DELETE_IMAGE_QUESTION", $lng->txt('delete_image_question')); 353 $tpl->setVariable("ANSWER_TEXT", $lng->txt('answer_text')); 354 $tpl->setVariable("COMMANDS_TEXT", $lng->txt('actions')); 355 356 if (!$this->getDisabled()) { 357 $tpl->setCurrentBlock('js_engine_initialisation'); 358 $tpl->setVariable('UPLOAD_CMD', $this->getImageUploadCommand()); 359 $tpl->setVariable('REMOVE_CMD', $this->getImageRemovalCommand()); 360 $tpl->setVariable('ITERATOR', self::ITERATOR_SUBFIELD_NAME); 361 $tpl->setVariable('STORED_IMAGE_POSTVAR', self::STORED_IMAGE_SUBFIELD_NAME); 362 $tpl->setVariable('UPLOAD_IMAGE_POSTVAR', self::IMAGE_UPLOAD_SUBFIELD_NAME); 363 $tpl->parseCurrentBlock(); 364 365 $globalTpl = $GLOBALS['DIC'] ? $GLOBALS['DIC']['tpl'] : $GLOBALS['tpl']; 366 $globalTpl->addJavascript("./Services/Form/js/ServiceFormWizardInput.js"); 367 $globalTpl->addJavascript("./Services/Form/js/ServiceFormIdentifiedWizardInputExtend.js"); 368 //$globalTpl->addJavascript("./Services/Form/js/ServiceFormIdentifiedImageWizardInputConcrete.js"); 369 } 370 371 return $tpl->get(); 372 } 373 374 /** 375 * @param $value 376 * @return bool 377 */ 378 protected function valueHasContentImageSource($value) 379 { 380 return isset($value['src']) && strlen($value['src']); 381 } 382 383 /** 384 * @param $value 385 * @return string 386 */ 387 protected function fetchContentImageSourceFromValue($value) 388 { 389 if ($this->valueHasContentImageSource($value)) { 390 return $value['src']; 391 } 392 393 return null; 394 } 395 396 /** 397 * @param $value 398 * @return bool 399 */ 400 protected function valueHasContentImageTitle($value) 401 { 402 return isset($value['title']) && strlen($value['title']); 403 } 404 405 /** 406 * @param string $value 407 */ 408 protected function fetchContentImageTitleFromValue($value) 409 { 410 if ($this->valueHasContentImageTitle($value)) { 411 return $value['title']; 412 } 413 414 return $this->fetchContentImageSourceFromValue($value); 415 } 416 417 /** 418 * @return ilTemplate 419 */ 420 protected function getTemplate() 421 { 422 return new ilTemplate(self::RENDERING_TEMPLATE, true, true, "Services/Form"); 423 } 424} 425