ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.assFileUploadGUI.php
Go to the documentation of this file.
1 <?php
2 
19 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
20 
36 {
37  public const REUSE_FILES_TBL_POSTVAR = 'reusefiles';
38  public const DELETE_FILES_TBL_POSTVAR = 'deletefiles';
39  private const HANDLE_FILE_UPLOAD = 'handleFileUpload';
40 
49  public function __construct($id = -1)
50  {
52  include_once "./Modules/TestQuestionPool/classes/class.assFileUpload.php";
53  $this->object = new assFileUpload();
54  $this->setErrorMessage($this->lng->txt("msg_form_save_error"));
55  if ($id >= 0) {
56  $this->object->loadFromDb($id);
57  }
58  }
59 
63  protected function writePostData(bool $always = false): int
64  {
65  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
66  if (!$hasErrors) {
67  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
70  $this->saveTaxonomyAssignments();
71  return 0;
72  }
73  return 1;
74  }
75 
76  public function writeQuestionSpecificPostData(ilPropertyFormGUI $form): void
77  {
78  $this->object->setPoints((float) str_replace(',', '.', $_POST["points"]));
79  $this->object->setMaxSize(($_POST['maxsize'] ?? null) ? (int) $_POST['maxsize'] : null);
80  $this->object->setAllowedExtensions($_POST["allowedextensions"]);
81  $this->object->setCompletionBySubmission(isset($_POST['completion_by_submission']) && $_POST['completion_by_submission'] == 1);
82  }
83 
89  public function editQuestion($checkonly = false): bool
90  {
91  $save = $this->isSaveCommand();
92  $this->getQuestionTemplate();
93 
94  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
95  $form = new ilPropertyFormGUI();
96  $this->editForm = $form;
97 
98  $form->setFormAction($this->ctrl->getFormAction($this));
99  $form->setTitle($this->outQuestionType());
100  $form->setMultipart(false);
101  $form->setTableWidth("100%");
102  $form->setId("assfileupload");
103 
104  $this->addBasicQuestionFormProperties($form);
105  $this->populateQuestionSpecificFormPart($form);
106 
107  $this->populateTaxonomyFormSection($form);
108  $this->addQuestionFormCommandButtons($form);
109 
110  $errors = false;
111 
112  if ($save) {
113  $form->setValuesByPost();
114  $errors = !$form->checkInput();
115  $form->setValuesByPost(); // again, because checkInput now performs the whole stripSlashes handling and
116  // we need this if we don't want to have duplication of backslashes
117  if ($errors) {
118  $checkonly = false;
119  }
120  }
121 
122  if (!$checkonly) {
123  $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
124  }
125  return $errors;
126  }
127 
129  {
130  $maxsize = new ilNumberInputGUI($this->lng->txt("maxsize"), "maxsize");
131  $maxsize->allowDecimals(false);
132  $maxsize->setValue($this->object->getMaxSize() > 0 ? (string) $this->object->getMaxSize() : null);
133  $maxsize->setInfo($this->lng->txt("maxsize_info"));
134  $maxsize->setSize(10);
135  $maxsize->setMinValue(0);
136  $maxsize->setMaxValue((float) $this->determineMaxFilesize());
137  $maxsize->setRequired(false);
138  $form->addItem($maxsize);
139 
140  $allowedextensions = new ilTextInputGUI($this->lng->txt("allowedextensions"), "allowedextensions");
141  $allowedextensions->setInfo($this->lng->txt("allowedextensions_info"));
142  $allowedextensions->setValue($this->object->getAllowedExtensions());
143  $allowedextensions->setRequired(false);
144  $form->addItem($allowedextensions);
145 
146  $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
147  $points->allowDecimals(true);
148  $points->setValue(
149  is_numeric($this->object->getPoints()) && $this->object->getPoints(
150  ) >= 0 ? $this->object->getPoints() : ''
151  );
152  $points->setRequired(true);
153  $points->setSize(3);
154  $points->setMinValue(0.0);
155  $points->setMinvalueShouldBeGreater(true);
156  $form->addItem($points);
157 
158  $subcompl = new ilCheckboxInputGUI($this->lng->txt(
159  'ass_completion_by_submission'
160  ), 'completion_by_submission');
161  $subcompl->setInfo($this->lng->txt('ass_completion_by_submission_info'));
162  $subcompl->setValue('1');
163  $subcompl->setChecked($this->object->isCompletionBySubmissionEnabled());
164  $form->addItem($subcompl);
165  return $form;
166  }
167 
168  public function determineMaxFilesize(): int
169  {
170  //mbecker: Quick fix for mantis bug 8595: Change size file
171  $upload_max_filesize = get_cfg_var("upload_max_filesize");
172  // get the value for the maximal post data from the php.ini (if available)
173  $post_max_size = get_cfg_var("post_max_size");
174 
175  //convert from short-string representation to "real" bytes
176  $multiplier_a = array( "K" => 1024, "M" => 1024 * 1024, "G" => 1024 * 1024 * 1024 );
177  $umf_parts = preg_split(
178  "/(\d+)([K|G|M])/",
179  $upload_max_filesize,
180  -1,
181  PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
182  );
183  $pms_parts = preg_split(
184  "/(\d+)([K|G|M])/",
185  $post_max_size,
186  -1,
187  PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
188  );
189 
190  if (count($umf_parts) === 2) {
191  $upload_max_filesize = $umf_parts[0] * $multiplier_a[$umf_parts[1]];
192  }
193 
194  if (count($pms_parts) === 2) {
195  $post_max_size = $pms_parts[0] * $multiplier_a[$pms_parts[1]];
196  }
197 
198  // use the smaller one as limit
199  $max_filesize = min($upload_max_filesize, $post_max_size);
200 
201  if (!$max_filesize) {
202  $max_filesize = max($upload_max_filesize, $post_max_size);
203  return $max_filesize;
204  }
205 
206  return $max_filesize;
207  }
208 
221  public function getSolutionOutput(
222  $active_id,
223  $pass = null,
224  $graphicalOutput = false,
225  $result_output = false,
226  $show_question_only = true,
227  $show_feedback = false,
228  $show_correct_solution = false,
229  $show_manual_scoring = false,
230  $show_question_text = true
231  ): string {
232  // get the solution of the user for the active pass or from the last pass if allowed
233  $template = new ilTemplate("tpl.il_as_qpl_fileupload_output_solution.html", true, true, "Modules/TestQuestionPool");
234 
235  $solutionvalue = "";
236  if (($active_id > 0) && (!$show_correct_solution)) {
237  $solutions = $this->object->getSolutionValues($active_id, $pass);
238 
239  $files = ($show_manual_scoring) ? $this->object->getUploadedFilesForWeb($active_id, $pass) : $this->object->getUploadedFiles($active_id, $pass);
240  include_once "./Modules/TestQuestionPool/classes/tables/class.assFileUploadFileTableGUI.php";
241  $table_gui = new assFileUploadFileTableGUI($this, 'gotoquestion');
242  $table_gui->setTitle(
243  $this->lng->txt('already_delivered_files'),
244  'icon_file.svg',
245  $this->lng->txt('already_delivered_files')
246  );
247  $table_gui->setData($files);
248  // hey: prevPassSolutions - table refactored
249  #$table_gui->initCommand(
250  #$this->buildFileTableDeleteButtonInstance(), assFileUploadGUI::DELETE_FILES_TBL_POSTVAR
251  #);
252  // hey.
253  $table_gui->setRowTemplate("tpl.il_as_qpl_fileupload_file_view_row.html", "Modules/TestQuestionPool");
254  $table_gui->setSelectAllCheckbox("");
255  // hey: prevPassSolutions - table refactored
256  #$table_gui->clearCommandButtons();
257  #$table_gui->disable('select_all');
258  // hey.
259  $table_gui->disable('numinfo');
260  $template->setCurrentBlock("files");
261  $template->setVariable('FILES', $table_gui->getHTML());
262  $template->parseCurrentBlock();
263  }
264 
265  if (strlen($this->object->getAllowedExtensions())) {
266  $template->setCurrentBlock("allowed_extensions");
267  $template->setVariable("TXT_ALLOWED_EXTENSIONS", $this->object->prepareTextareaOutput($this->lng->txt("allowedextensions") . ": " . $this->object->getAllowedExtensions()));
268  $template->parseCurrentBlock();
269  }
270  $template->setVariable("CMD_UPLOAD", self::HANDLE_FILE_UPLOAD);
271  $template->setVariable("TEXT_UPLOAD", $this->object->prepareTextareaOutput($this->lng->txt('upload')));
272  $template->setVariable("TXT_UPLOAD_FILE", $this->object->prepareTextareaOutput($this->lng->txt('file_add')));
273  $template->setVariable("TXT_MAX_SIZE", $this->object->prepareTextareaOutput($this->lng->txt('file_notice') . " " . $this->object->getMaxFilesizeAsString()));
274 
275  if (($active_id > 0) && (!$show_correct_solution)) {
276  $reached_points = $this->object->getReachedPoints($active_id, $pass);
277  if ($graphicalOutput) {
278  $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_NOT_OK);
279  if ($reached_points == $this->object->getMaximumPoints()) {
280  $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_OK);
281  } elseif ($reached_points > 0) {
282  $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_MOSTLY_OK);
283  }
284  $template->setCurrentBlock("icon_ok");
285  $template->setVariable("ICON_OK", $correctness_icon);
286  $template->parseCurrentBlock();
287  }
288  } else {
289  $reached_points = $this->object->getPoints();
290  }
291 
292  if ($result_output) {
293  $resulttext = ($reached_points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
294  $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $reached_points));
295  }
296  if ($show_question_text == true) {
297  $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
298  }
299  $questionoutput = $template->get();
300  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
301  $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getGenericFeedbackOutput((int) $active_id, $pass) : "";
302  if (strlen($feedback)) {
303  $cssClass = (
304  $this->hasCorrectSolution($active_id, $pass) ?
306  );
307 
308  $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
309  $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
310  }
311  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
312  $solutionoutput = $solutiontemplate->get();
313  if (!$show_question_only) {
314  // get page object output
315  $solutionoutput = $this->getILIASPage($solutionoutput);
316  }
317  return $solutionoutput;
318  }
319 
320  public function getPreview($show_question_only = false, $showInlineFeedback = false): string
321  {
322  $template = new ilTemplate("tpl.il_as_qpl_fileupload_output.html", true, true, "Modules/TestQuestionPool");
323 
324  if (is_object($this->getPreviewSession())) {
325  $files = $this->object->getPreviewFileUploads($this->getPreviewSession());
326  include_once "./Modules/TestQuestionPool/classes/tables/class.assFileUploadFileTableGUI.php";
327  $table_gui = new assFileUploadFileTableGUI(null, $this->getQuestionActionCmd(), 'ilAssQuestionPreview');
328  $table_gui->setTitle(
329  $this->lng->txt('already_delivered_files'),
330  'icon_file.svg',
331  $this->lng->txt('already_delivered_files')
332  );
333  $table_gui->setData($files);
334  // hey: prevPassSolutions - support file reuse with table
335  $table_gui->initCommand(
338  );
339  // hey.
340  $template->setCurrentBlock("files");
341  $template->setVariable('FILES', $table_gui->getHTML());
342  $template->parseCurrentBlock();
343  }
344 
345  if ($this->object->getAllowedExtensions() !== '') {
346  $template->setCurrentBlock("allowed_extensions");
347  $template->setVariable("TXT_ALLOWED_EXTENSIONS", $this->object->prepareTextareaOutput($this->lng->txt("allowedextensions") . ": " . $this->object->getAllowedExtensions()));
348  $template->parseCurrentBlock();
349  }
350  $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
351  $template->setVariable("CMD_UPLOAD", $this->getQuestionActionCmd());
352  $template->setVariable("TEXT_UPLOAD", $this->object->prepareTextareaOutput($this->lng->txt('upload')));
353  $template->setVariable("TXT_UPLOAD_FILE", $this->object->prepareTextareaOutput($this->lng->txt('file_add')));
354  $template->setVariable("TXT_MAX_SIZE", $this->object->prepareTextareaOutput($this->lng->txt('file_notice') . " " . $this->object->getMaxFilesizeAsString()));
355 
356  $questionoutput = $template->get();
357  if (!$show_question_only) {
358  // get page object output
359  $questionoutput = $this->getILIASPage($questionoutput);
360  }
361  return $questionoutput;
362  }
363 
364  // hey: prevPassSolutions - pass will be always available from now on
365  public function getTestOutput($active_id, $pass, $is_postponed = false, $use_post_solutions = false, $show_feedback = false): string
366  // hey.
367  {
368  // generate the question output
369  $template = new ilTemplate("tpl.il_as_qpl_fileupload_output.html", true, true, "Modules/TestQuestionPool");
370 
371  if ($active_id) {
372  $files = $this->object->getTestOutputSolutions($active_id, $pass);
373  // hey.
374  include_once "./Modules/TestQuestionPool/classes/tables/class.assFileUploadFileTableGUI.php";
375  $table_gui = new assFileUploadFileTableGUI(null, $this->getQuestionActionCmd());
376  $table_gui->setTitle(
377  $this->lng->txt('already_delivered_files'),
378  'icon_file.svg',
379  $this->lng->txt('already_delivered_files')
380  );
381  $table_gui->setData($files);
382  // hey: prevPassSolutions - support file reuse with table
383  $table_gui->initCommand(
386  );
387  // hey.
388  $template->setCurrentBlock("files");
389  $template->setVariable('FILES', $table_gui->getHTML());
390  $template->parseCurrentBlock();
391  }
392 
393  if ($this->object->getAllowedExtensions() !== '') {
394  $template->setCurrentBlock("allowed_extensions");
395  $template->setVariable("TXT_ALLOWED_EXTENSIONS", $this->object->prepareTextareaOutput($this->lng->txt("allowedextensions") . ": " . $this->object->getAllowedExtensions()));
396  $template->parseCurrentBlock();
397  }
398  $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
399  $template->setVariable("CMD_UPLOAD", self::HANDLE_FILE_UPLOAD);
400  $template->setVariable("TEXT_UPLOAD", $this->object->prepareTextareaOutput($this->lng->txt('upload')));
401  $template->setVariable("TXT_UPLOAD_FILE", $this->object->prepareTextareaOutput($this->lng->txt('file_add')));
402  $template->setVariable("TXT_MAX_SIZE", $this->object->prepareTextareaOutput($this->lng->txt('file_notice') . " " . $this->object->getMaxFilesizeAsString()));
403 
404  $questionoutput = $template->get();
405  //if (!$show_question_only) {
406  // get page object output
407  $questionoutput = $this->getILIASPage($questionoutput);
408  //}
409  $questionoutput = $template->get();
410  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
411  return $pageoutput;
412  }
413 
414  public function getSpecificFeedbackOutput(array $userSolution): string
415  {
416  $output = "";
417  return $this->object->prepareTextareaOutput($output, true);
418  }
419 
430  {
431  return array();
432  }
433 
440  public function getAggregatedAnswersView(array $relevant_answers): string
441  {
442  // Empty implementation here since a feasible way to aggregate answer is not known.
443  return ''; //print_r($relevant_answers,true);
444  }
445 
446  // hey: prevPassSolutions - shown files needs to be chosen so upload can replace or complete fileset
451  {
452  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssFileUploadFileTableDeleteButton.php';
454  }
455 
460  {
461  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssFileUploadFileTableReuseButton.php';
463  }
464 
469  {
470  if ($this->object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
471  return $this->buildFileTableReuseButtonInstance();
472  }
473 
474  return $this->buildFileTableDeleteButtonInstance();
475  }
476 
477  protected function getTestPresentationFileTablePostVar(): string
478  {
479  if ($this->object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
481  }
482 
484  }
485  // hey.
486 
487  // hey: prevPassSolutions - overwrite common prevPassSolution-Checkbox
488  protected function getPreviousSolutionProvidedMessage(): string
489  {
490  return $this->lng->txt('use_previous_solution_advice_file_upload');
491  }
492 
493  protected function getPreviousSolutionConfirmationCheckboxHtml(): string
494  {
495  return '';
496  }
497  // hey.
498 
499  public function getFormEncodingType(): string
500  {
501  return self::FORM_ENCODING_MULTIPART;
502  }
503 
504  public function isAnswerFreuqencyStatisticSupported(): bool
505  {
506  return false;
507  }
508 
510  {
511  // points
512  $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
513  $points->allowDecimals(true);
514  $points->setValue(
515  is_numeric($this->object->getPoints()) && $this->object->getPoints(
516  ) >= 0 ? $this->object->getPoints() : ''
517  );
518  $points->setRequired(true);
519  $points->setSize(3);
520  $points->setMinValue(0.0);
521  $points->setMinvalueShouldBeGreater(true);
522  $form->addItem($points);
523 
524  $subcompl = new ilCheckboxInputGUI($this->lng->txt(
525  'ass_completion_by_submission'
526  ), 'completion_by_submission');
527  $subcompl->setInfo($this->lng->txt('ass_completion_by_submission_info'));
528  $subcompl->setValue(1);
529  $subcompl->setChecked($this->object->isCompletionBySubmissionEnabled());
530  $form->addItem($subcompl);
531  }
532 
537  {
538  $this->object->setPoints((float) str_replace(',', '.', $form->getInput('points')));
539  $this->object->setCompletionBySubmission((bool) $form->getInput('completion_by_submission'));
540  }
541 }
hasCorrectSolution($activeId, $passIndex)
writePostData(bool $always=false)
{}
generateCorrectnessIconsForCorrectness(int $correctness)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$errors
Definition: imgupload.php:65
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
getTestOutput($active_id, $pass, $is_postponed=false, $use_post_solutions=false, $show_feedback=false)
getSpecificFeedbackOutput(array $userSolution)
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
This class represents a checkbox property in a property form.
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
Class for file upload questions.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
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-...
addQuestionFormCommandButtons(ilPropertyFormGUI $form)
allowDecimals(bool $a_value)
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
setErrorMessage(string $errormessage)
This class represents a number property in a property form.
getAggregatedAnswersView(array $relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
populateQuestionSpecificFormPart(ilPropertyFormGUI $form)
Adds the question specific forms parts to a question property form gui.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getPreview($show_question_only=false, $showInlineFeedback=false)
getILIASPage(string $html="")
Returns the ILIAS Page around a question.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
__construct(Container $dic, ilPlugin $plugin)
__construct($id=-1)
assFileUploadGUI constructor
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $show_correct_solution=false, $show_manual_scoring=false, $show_question_text=true)
Get the question solution output.
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
getGenericFeedbackOutput(int $active_id, ?int $pass)