ILIAS  trunk Revision v12.0_alpha-1227-g7ff6d300864
class.ilMultipleImagesInputGUI.php
Go to the documentation of this file.
1<?php
2
20use ILIAS\UI\Component\Button\Factory as ButtonFactory;
23
28{
29 public const RENDERING_TEMPLATE = 'tpl.prop_multi_image_inp.html';
30
31 public const ITERATOR_SUBFIELD_NAME = 'iteratorfield';
32 public const STORED_IMAGE_SUBFIELD_NAME = 'storedimage';
33 public const IMAGE_UPLOAD_SUBFIELD_NAME = 'imageupload';
34
35 public const FILE_DATA_INDEX_DODGING_FILE = 'dodging_file';
36
41
45 protected $editElementOrderEnabled = false;
46
47 protected stdClass $dodging_files;
48
52 protected $suffixes = [];
53
54 protected $imageRemovalCommand = 'removeImage';
55
56 protected $imageUploadCommand = 'uploadImage';
57
58 protected ilLanguage $lng;
60 protected GlyphFactory $glyph_factory;
61 protected ButtonFactory $button_factory;
64
71 public function __construct($a_title = "", $a_postvar = "")
72 {
73 parent::__construct($a_title, $a_postvar);
74
75 global $DIC;
76 $this->lng = $DIC->language();
77 $this->tpl = $DIC->ui()->mainTemplate();
78 $this->glyph_factory = $DIC->ui()->factory()->symbol()->glyph();
79 $this->button_factory = $DIC->ui()->factory()->button();
80 $this->renderer = $DIC->ui()->renderer();
81 $this->upload_limit = $DIC['ui.upload_limit_resolver'];
82
83 $this->setSuffixes(["jpg", "jpeg", "png", "gif"]);
84 $this->setSize(25);
85 $this->validationRegexp = "";
86
88 $manipulator->setPostVar($this->getPostVar());
89 $this->addFormValuesManipulator($manipulator);
90
91 $this->dodging_files = new stdClass();
92
93 $manipulator = new ilMultipleImagesFileSubmissionDataCompletion($this->dodging_files);
94 $this->addFormValuesManipulator($manipulator);
95
97 $manipulator->setPostVar($this->getPostVar());
98 $this->addFormValuesManipulator($manipulator);
99
101 $manipulator->setPostVar($this->getPostVar());
102 $this->addFormValuesManipulator($manipulator);
103 }
104
110 public function setSuffixes($a_suffixes): void
111 {
112 $this->suffixes = $a_suffixes;
113 }
114
120 public function getSuffixes(): array
121 {
122 return $this->suffixes;
123 }
124
128 public function getImageRemovalCommand(): string
129 {
131 }
132
137 {
138 $this->imageRemovalCommand = $imageRemovalCommand;
139 }
140
144 public function getImageUploadCommand(): string
145 {
147 }
148
153 {
154 $this->imageUploadCommand = $imageUploadCommand;
155 }
156
160 public function isEditElementOccuranceEnabled(): bool
161 {
163 }
164
169 {
170 $this->editElementOccuranceEnabled = $editElementOccuranceEnabled;
171 }
172
176 public function isEditElementOrderEnabled(): bool
177 {
179 }
180
185 {
186 $this->editElementOrderEnabled = $editElementOrderEnabled;
187 }
188
193 abstract protected function isValidFilenameInput($filenameInput): bool;
194
200 public function onCheckInput(): bool
201 {
202 $F = $_FILES[$this->getPostVar()];
203
204 $submittedElements = $this->getInput();
205
206 if ($F && ((array) $this->dodging_files) !== []) {
207 $F = array_merge([self::FILE_DATA_INDEX_DODGING_FILE => (array) $this->dodging_files], $F);
208 }
209
210 if ($this->getRequired() && !is_array($F['error'])) {
211 $this->setAlert($this->lng->txt("form_msg_file_no_upload"));
212 return false;
213 } else {
214 foreach ($F['error'] as $index => $error) {
215 // error handling
216 if ($error > 0) {
217 switch ($error) {
218 case UPLOAD_ERR_FORM_SIZE:
219 case UPLOAD_ERR_INI_SIZE:
220 $this->setAlert($this->lng->txt("form_msg_file_size_exceeds"));
221 return false;
222 break;
223
224 case UPLOAD_ERR_PARTIAL:
225 $this->setAlert($this->lng->txt("form_msg_file_partially_uploaded"));
226 return false;
227 break;
228
229 case UPLOAD_ERR_NO_FILE:
230 if (!$this->getRequired()) {
231 break;
232 } elseif (isset($F[self::FILE_DATA_INDEX_DODGING_FILE][$index]) && $F[self::FILE_DATA_INDEX_DODGING_FILE][$index] !== '') {
233 break;
234 }
235 $this->setAlert($this->lng->txt("form_msg_file_no_upload"));
236 return false;
237 break;
238
239 case UPLOAD_ERR_NO_TMP_DIR:
240 $this->setAlert($this->lng->txt("form_msg_file_missing_tmp_dir"));
241 return false;
242 break;
243
244 case UPLOAD_ERR_CANT_WRITE:
245 $this->setAlert($this->lng->txt("form_msg_file_cannot_write_to_disk"));
246 return false;
247 break;
248
249 case UPLOAD_ERR_EXTENSION:
250 $this->setAlert($this->lng->txt("form_msg_file_upload_stopped_ext"));
251 return false;
252 break;
253 }
254 }
255 }
256 }
257
258 if (is_array($F['tmp_name'])) {
259 foreach ($F['tmp_name'] as $index => $tmpname) {
260 $filename = $F['name'][$index];
261 if (is_array($filename)) {
262 $filename = array_shift($filename);
263 $tmpname = array_shift($tmpname);
264 }
265 $filename_arr = pathinfo($filename);
266 $suffix = $filename_arr["extension"] ?? '';
267 $mimetype = $F['type'][$index];
268 $size_bytes = $F['size'][$index];
269 // check suffixes
270 if (strlen($tmpname) && is_array($this->getSuffixes())) {
271 if (!in_array(strtolower($suffix), $this->getSuffixes())) {
272 $this->setAlert($this->lng->txt("form_msg_file_wrong_file_type"));
273 return false;
274 }
275 }
276 }
277 }
278
279 foreach ($F['tmp_name'] as $index => $tmpname) {
280 $filename = $F['name'][$index];
281 if (is_array($filename)) {
282 $filename = array_shift($filename);
283 $tmpname = array_shift($tmpname);
284 }
285 $filename_arr = pathinfo($filename);
286 $suffix = $filename_arr["extension"] ?? '';
287 $mimetype = $F['type'][$index];
288 $size_bytes = $F['size'][$index];
289 // virus handling
290 if (strlen($tmpname)) {
292 if ($vir[0] == false) {
293 $this->setAlert($this->lng->txt("form_msg_file_virus_found") . "<br />" . $vir[1]);
294 return false;
295 }
296 }
297 }
298
299 return $this->checkSubItemsInput();
300 }
301
306 public function render(string $a_mode = ""): string
307 {
309
310 $tpl = $this->getTemplate();
311 $i = 0;
312
314 foreach ($identified_multi_values as $identifier => $value) {
316 $tpl->setCurrentBlock('image');
317
318 $tpl->setVariable('STORED_IMAGE_SRC', $this->fetchContentImageSourceFromValue($value));
319 $tpl->setVariable(
320 'STORED_IMAGE_ALT',
322 );
323 $tpl->setVariable('STORED_IMAGE_FILENAME', $this->fetchContentImageTitleFromValue($value));
324 $tpl->setVariable('STORED_IMAGE_POST_VAR', $this->getMultiValuePostVarSubFieldPosIndexed($identifier, self::STORED_IMAGE_SUBFIELD_NAME, $i));
325
326 $tpl->setVariable('TXT_DELETE_EXISTING', $lng->txt('delete_existing_file'));
327 $tpl->setVariable('IMAGE_CMD_REMOVE', $this->buildMultiValueSubmitVar($identifier, $i, $this->getImageRemovalCommand()));
328
329 $tpl->parseCurrentBlock();
330 }
331
332 $tpl->setCurrentBlock('addimage');
333
334 $tpl->setVariable('IMAGE_BROWSE', $lng->txt('select_file'));
335 $tpl->setVariable('IMAGE_ID', $this->getMultiValuePosIndexedSubFieldId($identifier, self::IMAGE_UPLOAD_SUBFIELD_NAME, $i));
336 $tpl->setVariable('MAX_SIZE_WARNING', $this->lng->txt('form_msg_file_size_exceeds'));
337 $tpl->setVariable('MAX_SIZE', $this->upload_limit->getPhpUploadLimitInBytes());
338 $tpl->setVariable('TXT_IMAGE_SUBMIT', $lng->txt('upload'));
339 $tpl->setVariable('IMAGE_CMD_UPLOAD', $this->buildMultiValueSubmitVar($identifier, $i, $this->getImageUploadCommand()));
340 $tpl->setVariable('UPLOAD_IMAGE_POST_VAR', $this->getMultiValuePostVarSubFieldPosIndexed($identifier, self::IMAGE_UPLOAD_SUBFIELD_NAME, $i));
341 $tpl->setVariable('COUNT_POST_VAR', $this->getMultiValuePostVarSubFieldPosIndexed($identifier, self::ITERATOR_SUBFIELD_NAME, $i));
342
344
345 if ($this->isEditElementOrderEnabled()) {
346 $tpl->setCurrentBlock('move');
347 $tpl->setVariable('UP_BUTTON', $this->renderer->render(
348 $this->button_factory->shy('', '')->withSymbol($this->glyph_factory->up())
349 ));
350 $tpl->setVariable('DOWN_BUTTON', $this->renderer->render(
351 $this->button_factory->shy('', '')->withSymbol($this->glyph_factory->down())
352 ));
354 }
355
356 if ($this->isEditElementOccuranceEnabled()) {
357 $tpl->setCurrentBlock('row');
358 $tpl->setVariable('ID_ADD', $this->getMultiValuePosIndexedSubFieldId($identifier, 'add', $i));
359 $tpl->setVariable('ID_REMOVE', $this->getMultiValuePosIndexedSubFieldId($identifier, 'remove', $i));
360 $tpl->setVariable('ADD_BUTTON', $this->renderer->render(
361 $this->button_factory->shy('', '')->withSymbol($this->glyph_factory->add())
362 ));
363 $tpl->setVariable('REMOVE_BUTTON', $this->renderer->render(
364 $this->button_factory->shy('', '')->withSymbol($this->glyph_factory->remove())
365 ));
367 }
368
369 $i++;
370 }
371
372 if (is_array($this->getSuffixes())) {
373 $suff_str = $delim = '';
374 foreach ($this->getSuffixes() as $suffix) {
375 $suff_str .= $delim . '.' . $suffix;
376 $delim = ', ';
377 }
378 $tpl->setCurrentBlock('allowed_image_suffixes');
379 $tpl->setVariable('TXT_ALLOWED_SUFFIXES', $lng->txt('file_allowed_suffixes') . ' ' . $suff_str);
381 }
382
384 $tpl->setVariable('ELEMENT_ID', $this->getPostVar());
385 $tpl->setVariable('TEXT_YES', $lng->txt('yes'));
386 $tpl->setVariable('TEXT_NO', $lng->txt('no'));
387 $tpl->setVariable('DELETE_IMAGE_HEADER', $lng->txt('delete_image_header'));
388 $tpl->setVariable('DELETE_IMAGE_QUESTION', $lng->txt('delete_image_question'));
389 $tpl->setVariable('ANSWER_TEXT', $lng->txt('answer_text'));
390 $tpl->setVariable('COMMANDS_TEXT', $lng->txt('actions'));
391
392 if (!$this->getDisabled()) {
393 $iterator_subfield_name = self::ITERATOR_SUBFIELD_NAME;
394 $image_upload_subfield_name = self::IMAGE_UPLOAD_SUBFIELD_NAME;
395
396 $init_code = <<<JS
397$.extend({}, AnswerWizardInput, IdentifiedWizardInput).init(
398 {
399 'fieldContainerSelector': '.ilWzdContainerImage',
400 'reindexingRequiredElementsSelectors': [
401 'input:hidden[name*="[{$iterator_subfield_name}]"]',
402 'input:file[id*="__{$image_upload_subfield_name}__"]',
403 'input:submit[name*="[{$this->getImageUploadCommand()}]"]',
404 'input:submit[name*="[{$this->getImageRemovalCommand()}]"]',
405 'button'
406 ],
407 'handleRowCleanUpCallback': function(rowElem) {
408 $(rowElem).find('div.imagepresentation').remove();
409 $(rowElem).find('input[type=text]').val('');
410 }
411 }
412);
413JS;
414
415 $this->tpl->addJavascript("assets/js/answerwizardinput.js");
416 $this->tpl->addJavascript("assets/js/identifiedwizardinput.js");
417 $this->tpl->addOnLoadCode($init_code);
418 }
419
420 return $tpl->get();
421 }
422
427 protected function valueHasContentImageSource($value): bool
428 {
429 return is_array($value)
430 && array_key_exists('src', $value)
431 && $value['src'] !== '';
432 }
433
438 protected function fetchContentImageSourceFromValue($value): ?string
439 {
441 return $value['src'];
442 }
443
444 return null;
445 }
446
451 protected function valueHasContentImageTitle($value): bool
452 {
453 return isset($value['title']) && strlen($value['title']);
454 }
455
456 protected function fetchContentImageTitleFromValue($value): ?string
457 {
458 if ($this->valueHasContentImageTitle($value)) {
459 return $value['title'];
460 }
461
463 }
464
468 protected function getTemplate(): ilTemplate
469 {
470 return new ilTemplate(self::RENDERING_TEMPLATE, true, true, "components/ILIAS/TestQuestionPool");
471 }
472}
renderer()
$filename
Definition: buildRTE.php:78
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
static getFileSizeInfo()
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addFormValuesManipulator(ilFormValuesManipulator $manipulator)
getMultiValuePostVarSubFieldPosIndexed($identifier, $sub_field_index, $position_index)
getMultiValuePosIndexedSubFieldId($identifier, $sub_field_index, $position_index)
buildMultiValueSubmitVar($identifier, $position_index, $submit_cmd)
language handling
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...
static prepareFormOutput($a_str, bool $a_strip=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct($a_title="", $a_postvar="")
Constructor.
onCheckInput()
Check input, strip slashes etc.
setEditElementOccuranceEnabled($editElementOccuranceEnabled)
isValidFilenameInput($filenameInput)
setEditElementOrderEnabled($editElementOrderEnabled)
setSuffixes($a_suffixes)
Set Accepted Suffixes.
special template class to simplify handling of ITX/PEAR
static virusHandling(string $a_file, string $a_orig_name='', bool $a_clean=true)
setVariable(string $variable, $value='')
Sets the given variable to the given value.
parseCurrentBlock(string $block_name=self::DEFAULT_BLOCK)
Parses the given block.
setCurrentBlock(string $part=self::DEFAULT_BLOCK)
Sets the template to the given block.
get(string $part=self::DEFAULT_BLOCK)
Renders the given block and returns the html string.
This is how a factory for glyphs looks like.
Definition: Factory.php:27
An entity that renders components to a string output.
Definition: Renderer.php:31
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $DIC
Definition: shib_login.php:26