ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilKprimChoiceWizardInputGUI.php
Go to the documentation of this file.
1 <?php
2 
19 require_once 'Modules/TestQuestionPool/classes/class.ilSingleChoiceWizardInputGUI.php';
20 require_once 'Modules/TestQuestionPool/classes/class.ilAssKprimChoiceAnswer.php';
21 require_once 'Services/MediaObjects/classes/class.ilObjMediaObject.php';
22 
30 {
31  public const CUSTOM_UPLOAD_ERR = 99;
32 
36  protected $tpl;
37 
41  protected $qstObject;
42 
43  private $files;
44 
46 
47  public function __construct($a_title = "", $a_postvar = "")
48  {
49  parent::__construct($a_title, $a_postvar);
50 
51  global $DIC;
52  $lng = $DIC['lng'];
53  $tpl = $DIC['tpl'];
54 
55  $this->lng = $lng;
56  $this->tpl = $tpl;
57 
58  $this->files = [];
59 
60  $this->ignoreMissingUploadsEnabled = false;
61  }
62 
63  public function setFiles($files): void
64  {
65  $this->files = $files;
66  }
67 
68  public function getFiles(): array
69  {
70  return $this->files;
71  }
72 
74  {
75  $this->ignoreMissingUploadsEnabled = $ignoreMissingUploadsEnabled;
76  }
77 
78  public function isIgnoreMissingUploadsEnabled(): bool
79  {
81  }
82 
83  public function setValue($value): void
84  {
85  $this->values = [];
86 
87  $is_rte = isset($_POST["answer_type"]) && $_POST["answer_type"] == "multiLine";
88  $a_value = $this->cleanupAnswerText($value, $is_rte);
89 
90  if (is_array($a_value) && is_array($a_value['answer'])) {
91  foreach ($a_value['answer'] as $index => $value) {
92  $answer = new ilAssKprimChoiceAnswer();
93 
94  $answer->setPosition($index);
95  $answer->setAnswertext($value);
96  if (isset($a_value['imagename'])) {
97  $answer->setImageFile($a_value['imagename'][$index] ?? '');
98  }
99 
100  if (isset($a_value['correctness']) && isset($a_value['correctness'][$index]) && strlen($a_value['correctness'][$index])) {
101  $answer->setCorrectness((bool) $a_value['correctness'][$index]);
102  }
103 
104  $answer->setThumbPrefix($this->qstObject->getThumbPrefix());
105  $answer->setImageFsDir($this->qstObject->getImagePath());
106  $answer->setImageWebDir($this->qstObject->getImagePathWeb());
107 
108  $this->values[] = $answer;
109  }
110  }
111 
112  #vd($this->values);
113  }
114 
115  public function checkInput(): bool
116  {
117  global $DIC;
118  $lng = $DIC['lng'];
119 
120  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
121  if (is_array($_POST[$this->getPostVar()])) {
122  $foundvalues = ilArrayUtil::stripSlashesRecursive(
123  $_POST[$this->getPostVar()],
124  false,
126  );
127  } else {
128  $foundvalues = $_POST[$this->getPostVar()];
129  }
130 
131  if (is_array($foundvalues)) {
132  // check answers
133  if (is_array($foundvalues['answer'])) {
134  foreach ($foundvalues['answer'] as $aidx => $answervalue) {
135  $hasImage = isset($foundvalues['imagename']) ? true : false;
136  if (((strlen($answervalue)) == 0) && !$hasImage) {
137  $this->setAlert($lng->txt("msg_input_is_required"));
138  return false;
139  }
140 
141  if (mb_strlen($answervalue) > $this->getMaxLength()) {
142  $this->setAlert($lng->txt("msg_input_char_limit_max"));
143  return false;
144  }
145  }
146  }
147 
148  // check correctness
149  if (!isset($foundvalues['correctness']) || count($foundvalues['correctness']) < count($foundvalues['answer'])) {
150  $this->setAlert($lng->txt("msg_input_is_required"));
151  return false;
152  }
153 
154  if (!$this->checkUploads($foundvalues)) {
155  return false;
156  }
157  } else {
158  $this->setAlert($lng->txt("msg_input_is_required"));
159  return false;
160  }
161 
162  return $this->checkSubItemsInput();
163  }
164 
168  public function insert(ilTemplate $a_tpl): void
169  {
170  $tpl = new ilTemplate("tpl.prop_kprimchoicewizardinput.html", true, true, "Modules/TestQuestionPool");
171 
172  foreach ($this->values as $value) {
177  if ($this->getSingleline()) {
178  if (!$this->hideImages) {
179  if (strlen($value->getImageFile())) {
180  $imagename = $value->getImageWebPath();
181 
182  if (($this->getSingleline()) && ($this->qstObject->getThumbSize())) {
183  if (@file_exists($value->getThumbFsPath())) {
184  $imagename = $value->getThumbWebPath();
185  }
186  }
187 
188  $tpl->setCurrentBlock('image');
189  $tpl->setVariable('SRC_IMAGE', $imagename);
190  $tpl->setVariable('IMAGE_NAME', $value->getImageFile());
191  $tpl->setVariable(
192  'ALT_IMAGE',
193  ilLegacyFormElementsUtil::prepareFormOutput($value->getAnswertext())
194  );
195  $tpl->setVariable("TXT_DELETE_EXISTING", $this->lng->txt("delete_existing_file"));
196  $tpl->setVariable("IMAGE_ROW_NUMBER", $value->getPosition());
197  $tpl->setVariable("IMAGE_POST_VAR", $this->getPostVar());
198  $tpl->parseCurrentBlock();
199  }
200  $tpl->setCurrentBlock('addimage');
201  $tpl->setVariable("IMAGE_BROWSE", $this->lng->txt('select_file'));
202  $tpl->setVariable("IMAGE_ID", $this->getPostVar() . "[image][{$value->getPosition()}]");
203  $tpl->setVariable("IMAGE_SUBMIT", $this->lng->txt("upload"));
204  $tpl->setVariable("IMAGE_ROW_NUMBER", $value->getPosition());
205  $tpl->setVariable("IMAGE_POST_VAR", $this->getPostVar());
206  $tpl->parseCurrentBlock();
207  }
208 
209  $tpl->setCurrentBlock("prop_text_propval");
210  $tpl->setVariable(
211  "PROPERTY_VALUE",
212  ilLegacyFormElementsUtil::prepareFormOutput(htmlspecialchars_decode((string) $value->getAnswertext()))
213  );
214  $tpl->parseCurrentBlock();
215 
216  $tpl->setCurrentBlock('singleline');
217  $tpl->setVariable("SIZE", $this->getSize());
218  $tpl->setVariable("SINGLELINE_ID", $this->getPostVar() . "[answer][{$value->getPosition()}]");
219  $tpl->setVariable("SINGLELINE_ROW_NUMBER", $value->getPosition());
220  $tpl->setVariable("SINGLELINE_POST_VAR", $this->getPostVar());
221  $tpl->setVariable("MAXLENGTH", $this->getMaxLength());
222  if ($this->getDisabled()) {
223  $tpl->setVariable("DISABLED_SINGLELINE", " disabled=\"disabled\"");
224  }
225  $tpl->parseCurrentBlock();
226  } elseif (!$this->getSingleline()) {
227  $tpl->setCurrentBlock('multiline');
228  $tpl->setVariable(
229  "PROPERTY_VALUE",
230  ilLegacyFormElementsUtil::prepareFormOutput($value->getAnswertext())
231  );
232  $tpl->setVariable("MULTILINE_ID", $this->getPostVar() . "[answer][{$value->getPosition()}]");
233  $tpl->setVariable("MULTILINE_ROW_NUMBER", $value->getPosition());
234  $tpl->setVariable("MULTILINE_POST_VAR", $this->getPostVar());
235  $tpl->setVariable("MAXLENGTH", $this->getMaxLength());
236  if ($this->getDisabled()) {
237  $tpl->setVariable("DISABLED_MULTILINE", " disabled=\"disabled\"");
238  }
239  $tpl->parseCurrentBlock();
240  }
241  if ($this->getAllowMove()) {
242  $tpl->setCurrentBlock("move");
243  $tpl->setVariable("CMD_UP", "cmd[up" . $this->getFieldId() . "][{$value->getPosition()}]");
244  $tpl->setVariable("CMD_DOWN", "cmd[down" . $this->getFieldId() . "][{$value->getPosition()}]");
245  $tpl->setVariable("UP_ID", "up_{$this->getPostVar()}[{$value->getPosition()}]");
246  $tpl->setVariable("DOWN_ID", "down_{$this->getPostVar()}[{$value->getPosition()}]");
247  $tpl->setVariable("UP_BUTTON", ilGlyphGUI::get(ilGlyphGUI::UP));
248  $tpl->setVariable("DOWN_BUTTON", ilGlyphGUI::get(ilGlyphGUI::DOWN));
249  $tpl->parseCurrentBlock();
250  }
251 
252  $tpl->setCurrentBlock("row");
253 
254  $tpl->setVariable("POST_VAR", $this->getPostVar());
255  $tpl->setVariable("ROW_NUMBER", $value->getPosition());
256  $tpl->setVariable("ID", $this->getPostVar() . "[answer][{$value->getPosition()}]");
257 
258  $tpl->setVariable(
259  "CORRECTNESS_TRUE_ID",
260  $this->getPostVar() . "[correctness][{$value->getPosition()}][true]"
261  );
262  $tpl->setVariable(
263  "CORRECTNESS_FALSE_ID",
264  $this->getPostVar() . "[correctness][{$value->getPosition()}][false]"
265  );
266  $tpl->setVariable("CORRECTNESS_TRUE_VALUE", 1);
267  $tpl->setVariable("CORRECTNESS_FALSE_VALUE", 0);
268 
269  if ($value->getCorrectness() !== null) {
270  if ($value->getCorrectness()) {
271  $tpl->setVariable('CORRECTNESS_TRUE_SELECTED', ' checked="checked"');
272  } else {
273  $tpl->setVariable('CORRECTNESS_FALSE_SELECTED', ' checked="checked"');
274  }
275  }
276 
277  if ($this->getDisabled()) {
278  $tpl->setVariable("DISABLED_CORRECTNESS", " disabled=\"disabled\"");
279  }
280 
281  $tpl->parseCurrentBlock();
282  }
283 
284  if ($this->getSingleline()) {
285  if (!$this->hideImages) {
286  if (is_array($this->getSuffixes())) {
287  $suff_str = $delim = "";
288  foreach ($this->getSuffixes() as $suffix) {
289  $suff_str .= $delim . "." . $suffix;
290  $delim = ", ";
291  }
292  $tpl->setCurrentBlock('allowed_image_suffixes');
293  $tpl->setVariable("TXT_ALLOWED_SUFFIXES", $this->lng->txt("file_allowed_suffixes") . " " . $suff_str);
294  $tpl->parseCurrentBlock();
295  }
296 
297  $tpl->setCurrentBlock("image_heading");
298  $tpl->setVariable("ANSWER_IMAGE", $this->lng->txt('answer_image'));
299  $tpl->setVariable("TXT_MAX_SIZE", ilFileUtils::getFileSizeInfo());
300  $tpl->parseCurrentBlock();
301  }
302  }
303 
304  foreach ($this->qstObject->getValidOptionLabels() as $optionLabel) {
305  if ($this->qstObject->isCustomOptionLabel($optionLabel)) {
306  continue;
307  }
308 
309  $tpl->setCurrentBlock('option_label_translations');
310  $tpl->setVariable('OPTION_LABEL', $optionLabel);
311  $tpl->setVariable('TRANSLATION_TRUE', $this->qstObject->getTrueOptionLabelTranslation($this->lng, $optionLabel));
312  $tpl->setVariable('TRANSLATION_FALSE', $this->qstObject->getFalseOptionLabelTranslation($this->lng, $optionLabel));
313  $tpl->parseCurrentBlock();
314  }
315 
316  $tpl->setVariable("ELEMENT_ID", $this->getPostVar());
317  $tpl->setVariable("DELETE_IMAGE_HEADER", $this->lng->txt('delete_image_header'));
318  $tpl->setVariable("DELETE_IMAGE_QUESTION", $this->lng->txt('delete_image_question'));
319  $tpl->setVariable("ANSWER_TEXT", $this->lng->txt('answer_text'));
320 
321  $tpl->setVariable("OPTIONS_TEXT", $this->lng->txt('options'));
322 
323  // winzards input column label values will be updated on document ready js
324  //$tpl->setVariable("TRUE_TEXT", $this->qstObject->getTrueOptionLabelTranslation($this->lng, $this->qstObject->getOptionLabel()));
325  //$tpl->setVariable("FALSE_TEXT", $this->qstObject->getFalseOptionLabelTranslation($this->lng, $this->qstObject->getOptionLabel()));
326 
327  $a_tpl->setCurrentBlock("prop_generic");
328  $a_tpl->setVariable("PROP_GENERIC", $tpl->get());
329  $a_tpl->parseCurrentBlock();
330 
331  include_once "./Services/YUI/classes/class.ilYuiUtil.php";
332  $this->tpl->addJavascript("./Services/Form/js/ServiceFormWizardInput.js");
333  $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/kprimchoicewizard.js");
334  $this->tpl->addJavascript('Modules/TestQuestionPool/js/ilAssKprimChoice.js');
335  }
336 
337  public function checkUploads($foundvalues): bool
338  {
339  if (is_array($_FILES) && count($_FILES) && $this->getSingleline()) {
340  if (!$this->hideImages) {
341  if (is_array($_FILES[$this->getPostVar()]['error']['image'])) {
342  foreach ($_FILES[$this->getPostVar()]['error']['image'] as $index => $error) {
343  // error handling
344  if ($error > 0) {
345  switch ($error) {
346  case UPLOAD_ERR_FORM_SIZE:
347  case UPLOAD_ERR_INI_SIZE:
348  $this->setAlert($this->lng->txt("form_msg_file_size_exceeds"));
349  return false;
350  break;
351 
352  case UPLOAD_ERR_PARTIAL:
353  $this->setAlert($this->lng->txt("form_msg_file_partially_uploaded"));
354  return false;
355  break;
356 
357  case UPLOAD_ERR_NO_FILE:
358  if ($this->getRequired() && !$this->isIgnoreMissingUploadsEnabled()) {
359  $has_image = isset($foundvalues['imagename'][$index]) ? true : false;
360  if (!$has_image && (!strlen($foundvalues['answer'][$index]))) {
361  $this->setAlert($this->lng->txt("form_msg_file_no_upload"));
362  return false;
363  }
364  }
365  break;
366 
367  case UPLOAD_ERR_NO_TMP_DIR:
368  $this->setAlert($this->lng->txt("form_msg_file_missing_tmp_dir"));
369  return false;
370  break;
371 
372  case UPLOAD_ERR_CANT_WRITE:
373  $this->setAlert($this->lng->txt("form_msg_file_cannot_write_to_disk"));
374  return false;
375  break;
376 
377  case UPLOAD_ERR_EXTENSION:
378  $this->setAlert($this->lng->txt("form_msg_file_upload_stopped_ext"));
379  return false;
380  break;
381  }
382  }
383  }
384  } else {
385  if ($this->getRequired()) {
386  $this->setAlert($this->lng->txt("form_msg_file_no_upload"));
387  return false;
388  }
389  }
390 
391  if (is_array($_FILES[$this->getPostVar()]['tmp_name']['image'])) {
392  foreach ($_FILES[$this->getPostVar()]['tmp_name']['image'] as $index => $tmpname) {
393  $filename = $_FILES[$this->getPostVar()]['name']['image'][$index];
394  $filename_arr = pathinfo($filename);
395  if (isset($filename_arr["extension"])) {
396  $suffix = $filename_arr["extension"];
397  $mimetype = $_FILES[$this->getPostVar()]['type']['image'][$index];
398  $size_bytes = $_FILES[$this->getPostVar()]['size']['image'][$index];
399  // check suffixes
400  if (strlen($tmpname) && is_array($this->getSuffixes())) {
401  if (!in_array(strtolower($suffix), $this->getSuffixes())) {
402  $this->setAlert($this->lng->txt("form_msg_file_wrong_file_type"));
403  return false;
404  }
405  }
406  }
407  }
408  }
409 
410  if (is_array($_FILES[$this->getPostVar()]['tmp_name']['image'])) {
411  foreach ($_FILES[$this->getPostVar()]['tmp_name']['image'] as $index => $tmpname) {
412  if ($_FILES[$this->getPostVar()]['error']['image'][$index] > 0) {
413  continue;
414  }
415 
416  $mimetype = ilObjMediaObject::getMimeType($tmpname);
417 
418  if (!preg_match("/^image/", $mimetype)) {
419  $_FILES[$this->getPostVar()]['error']['image'][$index] = self::CUSTOM_UPLOAD_ERR;
420  $this->setAlert($this->lng->txt("form_msg_file_wrong_mime_type"));
421  return false;
422  }
423  }
424  }
425 
426 
427  if (is_array($_FILES[$this->getPostVar()]['tmp_name']['image'])) {
428  foreach ($_FILES[$this->getPostVar()]['tmp_name']['image'] as $index => $tmpname) {
429  $filename = $_FILES[$this->getPostVar()]['name']['image'][$index];
430  $filename_arr = pathinfo($filename);
431  if (isset($filename_arr["extension"])) {
432  $suffix = $filename_arr["extension"];
433  $mimetype = $_FILES[$this->getPostVar()]['type']['image'][$index];
434  $size_bytes = $_FILES[$this->getPostVar()]['size']['image'][$index];
435  // virus handling
436  if (strlen($tmpname)) {
437  $vir = ilVirusScanner::virusHandling($tmpname, $filename);
438  if ($vir[0] == false) {
439  $_FILES[$this->getPostVar()]['error']['image'][$index] = self::CUSTOM_UPLOAD_ERR;
440  $this->setAlert($this->lng->txt("form_msg_file_virus_found") . "<br />" . $vir[1]);
441  return false;
442  }
443  }
444  }
445  }
446  }
447  }
448  }
449 
450  return true;
451  }
452 
453  public function collectValidFiles(): void
454  {
455  foreach ($_FILES[$this->getPostVar()]['error']['image'] as $index => $err) {
456  if ($err > 0) {
457  continue;
458  }
459 
460  $this->files[$index] = array(
461  'position' => $index,
462  'tmp_name' => $_FILES[$this->getPostVar()]['tmp_name']['image'][$index],
463  'name' => $_FILES[$this->getPostVar()]['name']['image'][$index],
464  'type' => $_FILES[$this->getPostVar()]['type']['image'][$index],
465  'size' => $_FILES[$this->getPostVar()]['size']['image'][$index]
466  );
467  }
468  }
469 
474  private function cleanupAnswerText(array $answer_text, bool $is_rte): array
475  {
476  if (!is_array($answer_text)) {
477  return [];
478  }
479 
480  if ($is_rte) {
482  $answer_text,
483  false,
485  );
486  }
487 
489  $answer_text,
490  true,
492  );
493  }
494 }
parseCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
static stripSlashesRecursive($a_data, bool $a_strip_html=true, string $a_allow="")
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 get(string $a_glyph, string $a_text="")
static virusHandling(string $a_file, string $a_orig_name='', bool $a_clean=true)
static prepareFormOutput($a_str, bool $a_strip=false)
$index
Definition: metadata.php:145
global $DIC
Definition: feed.php:28
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:514
static getMimeType(string $a_file, bool $a_external=false)
get mime type for file
cleanupAnswerText(array $answer_text, bool $is_rte)
sk - 12.05.2023: This is one more of those that we need, but don&#39;t want.
static _getUsedHTMLTagsAsString(string $a_module="")
Returns a string of all allowed HTML tags for text editing.
static getFileSizeInfo()
$filename
Definition: buildRTE.php:78
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
const ALLOWED_PLAIN_TEXT_TAGS
sk - 12.05.2023: This const is also used in ilKprimChoiceWizardInputGUI.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(Container $dic, ilPlugin $plugin)
setIgnoreMissingUploadsEnabled($ignoreMissingUploadsEnabled)