ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
class.assFileUpload.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
5 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
6 require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7 require_once './Modules/TestQuestionPool/interfaces/interface.ilObjFileHandlingQuestionType.php';
8 
21 {
22  protected $maxsize;
23 
24  protected $allowedextensions;
25 
27  protected $completion_by_submission = false;
28 
42  function __construct(
43  $title = "",
44  $comment = "",
45  $author = "",
46  $owner = -1,
47  $question = ""
48  )
49  {
50  parent::__construct($title, $comment, $author, $owner, $question);
51  }
52 
58  public function isComplete()
59  {
60  if (
61  strlen($this->title)
62  && ($this->author)
63  && ($this->question)
64  && ($this->getMaximumPoints() >= 0)
65  && is_numeric($this->getMaximumPoints()))
66  {
67  return true;
68  }
69  return false;
70  }
71 
75  public function saveToDb($original_id = "")
76  {
79  parent::saveToDb();
80  }
81 
83  {
84  global $ilDB;
85  $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
86  array( "integer" ),
87  array( $this->getId() )
88  );
89  $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName(
90  ) . " (question_fi, maxsize, allowedextensions, compl_by_submission) VALUES (%s, %s, %s, %s)",
91  array( "integer", "float", "text", "integer" ),
92  array(
93  $this->getId(),
94  (strlen( $this->getMaxSize() )) ? $this->getMaxSize() : NULL,
95  (strlen( $this->getAllowedExtensions() )) ? $this->getAllowedExtensions() : NULL,
97  )
98  );
99  }
100 
106  public function loadFromDb($question_id)
107  {
108  global $ilDB;
109  $result = $ilDB->queryF("SELECT qpl_questions.*, " . $this->getAdditionalTableName() . ".* FROM qpl_questions LEFT JOIN " . $this->getAdditionalTableName() . " ON " . $this->getAdditionalTableName() . ".question_fi = qpl_questions.question_id WHERE qpl_questions.question_id = %s",
110  array("integer"),
111  array($question_id)
112  );
113  if ($result->numRows() == 1)
114  {
115  $data = $ilDB->fetchAssoc($result);
116  $this->setId($question_id);
117  $this->setTitle($data["title"]);
118  $this->setComment($data["description"]);
119  $this->setNrOfTries($data['nr_of_tries']);
120  $this->setSuggestedSolution($data["solution_hint"]);
121  $this->setOriginalId($data["original_id"]);
122  $this->setObjId($data["obj_fi"]);
123  $this->setAuthor($data["author"]);
124  $this->setOwner($data["owner"]);
125  $this->setPoints($data["points"]);
126 
127  include_once("./Services/RTE/classes/class.ilRTE.php");
128  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
129  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
130  $this->setMaxSize($data["maxsize"]);
131  $this->setAllowedExtensions($data["allowedextensions"]);
132  $this->setCompletionBySubmission($data['compl_by_submission'] == 1 ? true : false);
133 
134  try
135  {
136  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
137  }
139  {
140  }
141  }
142  parent::loadFromDb($question_id);
143  }
144 
148  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
149  {
150  if ($this->id <= 0)
151  {
152  // The question has not been saved. It cannot be duplicated
153  return;
154  }
155  // duplicate the question in database
156  $this_id = $this->getId();
157  $thisObjId = $this->getObjId();
158 
159  $clone = $this;
160  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
162  $clone->id = -1;
163 
164  if( (int)$testObjId > 0 )
165  {
166  $clone->setObjId($testObjId);
167  }
168 
169  if ($title)
170  {
171  $clone->setTitle($title);
172  }
173 
174  if ($author)
175  {
176  $clone->setAuthor($author);
177  }
178  if ($owner)
179  {
180  $clone->setOwner($owner);
181  }
182 
183  if ($for_test)
184  {
185  $clone->saveToDb($original_id);
186  }
187  else
188  {
189  $clone->saveToDb();
190  }
191 
192  // copy question page content
193  $clone->copyPageOfQuestion($this_id);
194  // copy XHTML media objects
195  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
196 
197  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
198 
199  return $clone->id;
200  }
201 
205  public function copyObject($target_questionpool_id, $title = "")
206  {
207  if ($this->id <= 0)
208  {
209  // The question has not been saved. It cannot be duplicated
210  return;
211  }
212  // duplicate the question in database
213  $clone = $this;
214  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
216  $clone->id = -1;
217  $source_questionpool_id = $this->getObjId();
218  $clone->setObjId($target_questionpool_id);
219  if ($title)
220  {
221  $clone->setTitle($title);
222  }
223  $clone->saveToDb();
224 
225  // copy question page content
226  $clone->copyPageOfQuestion($original_id);
227  // copy XHTML media objects
228  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
229 
230  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
231 
232  return $clone->id;
233  }
234 
235  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
236  {
237  if ($this->id <= 0)
238  {
239  // The question has not been saved. It cannot be duplicated
240  return;
241  }
242 
243  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
244 
245  $sourceQuestionId = $this->id;
246  $sourceParentId = $this->getObjId();
247 
248  // duplicate the question in database
249  $clone = $this;
250  $clone->id = -1;
251 
252  $clone->setObjId($targetParentId);
253 
254  if ($targetQuestionTitle)
255  {
256  $clone->setTitle($targetQuestionTitle);
257  }
258 
259  $clone->saveToDb();
260  // copy question page content
261  $clone->copyPageOfQuestion($sourceQuestionId);
262  // copy XHTML media objects
263  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
264 
265  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
266 
267  return $clone->id;
268  }
269 
275  public function getMaximumPoints()
276  {
277  return $this->getPoints();
278  }
279 
290  public function calculateReachedPoints($active_id, $pass = NULL, $authorizedSolution = true, $returndetails = FALSE)
291  {
292  if( $returndetails )
293  {
294  throw new ilTestException('return details not implemented for '.__METHOD__);
295  }
296 
297  global $ilDB;
298 
299  if (is_null($pass))
300  {
301  $pass = $this->getSolutionMaxPass($active_id);
302  }
303  $points = 0;
304  return $points;
305  }
306 
307  protected function calculateReachedPointsForSolution($userSolution)
308  {
309  $points = 0;
310  return $points;
311  }
312 
318  function checkUpload()
319  {
320  $this->lng->loadLanguageModule("form");
321  // remove trailing '/'
322  while (substr($_FILES["upload"]["name"],-1) == '/')
323  {
324  $_FILES["upload"]["name"] = substr($_FILES["upload"]["name"],0,-1);
325  }
326 
327  $filename = $_FILES["upload"]["name"];
328  $filename_arr = pathinfo($_FILES["upload"]["name"]);
329  $suffix = $filename_arr["extension"];
330  $mimetype = $_FILES["upload"]["type"];
331  $size_bytes = $_FILES["upload"]["size"];
332  $temp_name = $_FILES["upload"]["tmp_name"];
333  $error = $_FILES["upload"]["error"];
334 
335  if ($size_bytes > $this->getMaxFilesizeInBytes())
336  {
337  ilUtil::sendFailure($this->lng->txt("form_msg_file_size_exceeds"), true);
338  return false;
339  }
340 
341  // error handling
342  if ($error > 0)
343  {
344  switch ($error)
345  {
346  case UPLOAD_ERR_INI_SIZE:
347  ilUtil::sendFailure($this->lng->txt("form_msg_file_size_exceeds"), true);
348  return false;
349  break;
350 
351  case UPLOAD_ERR_FORM_SIZE:
352  ilUtil::sendFailure($this->lng->txt("form_msg_file_size_exceeds"), true);
353  return false;
354  break;
355 
356  case UPLOAD_ERR_PARTIAL:
357  ilUtil::sendFailure($this->lng->txt("form_msg_file_partially_uploaded"), true);
358  return false;
359  break;
360 
361  case UPLOAD_ERR_NO_FILE:
362  ilUtil::sendFailure($this->lng->txt("form_msg_file_no_upload"), true);
363  return false;
364  break;
365 
366  case UPLOAD_ERR_NO_TMP_DIR:
367  ilUtil::sendFailure($this->lng->txt("form_msg_file_missing_tmp_dir"), true);
368  return false;
369  break;
370 
371  case UPLOAD_ERR_CANT_WRITE:
372  ilUtil::sendFailure($this->lng->txt("form_msg_file_cannot_write_to_disk"), true);
373  return false;
374  break;
375 
376  case UPLOAD_ERR_EXTENSION:
377  ilUtil::sendFailure($this->lng->txt("form_msg_file_upload_stopped_ext"), true);
378  return false;
379  break;
380  }
381  }
382 
383  // check suffixes
384  if (strlen($suffix) && count($this->getAllowedExtensionsArray()))
385  {
386  if (!in_array(strtolower($suffix), $this->getAllowedExtensionsArray()))
387  {
388  ilUtil::sendFailure($this->lng->txt("form_msg_file_wrong_file_type"), true);
389  return false;
390  }
391  }
392 
393  // virus handling
394  if (strlen($temp_name))
395  {
396  $vir = ilUtil::virusHandling($temp_name, $filename);
397  if ($vir[0] == false)
398  {
399  ilUtil::sendFailure($this->lng->txt("form_msg_file_virus_found")."<br />".$vir[1], true);
400  return false;
401  }
402  }
403  return true;
404  }
405 
409  public function getFileUploadPath($test_id, $active_id, $question_id = null)
410  {
411  if (is_null($question_id)) $question_id = $this->getId();
412  return CLIENT_WEB_DIR . "/assessment/tst_$test_id/$active_id/$question_id/files/";
413  }
414 
418  protected function getPreviewFileUploadPath($userId)
419  {
420  return CLIENT_WEB_DIR . "/assessment/qst_preview/$userId/{$this->getId()}/fileuploads/";
421  }
422 
428  function getFileUploadPathWeb($test_id, $active_id, $question_id = null)
429  {
430  if (is_null($question_id)) $question_id = $this->getId();
431  include_once "./Services/Utilities/classes/class.ilUtil.php";
432  $webdir = ilUtil::removeTrailingPathSeparators(CLIENT_WEB_DIR) . "/assessment/tst_$test_id/$active_id/$question_id/files/";
434  }
435 
439  protected function getPreviewFileUploadPathWeb($userId)
440  {
441  include_once "./Services/Utilities/classes/class.ilUtil.php";
442  $webdir = ilUtil::removeTrailingPathSeparators(CLIENT_WEB_DIR) . "/assessment/qst_preview/$userId/{$this->getId()}/fileuploads/";
444  }
445 
451  public function getUploadedFiles($active_id, $pass = null, $authorized = true)
452  {
453  global $ilDB;
454 
455  if (is_null($pass))
456  {
457  $pass = $this->getSolutionMaxPass($active_id);
458  }
459 
460  $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s AND authorized = %s ORDER BY tstamp",
461  array("integer", "integer", "integer", 'integer'),
462  array($active_id, $this->getId(), $pass, (int)$authorized)
463  );
464 
465  $found = array();
466 
467  while ($data = $ilDB->fetchAssoc($result))
468  {
469  array_push($found, $data);
470  }
471 
472  return $found;
473  }
474 
475  public function getPreviewFileUploads(ilAssQuestionPreviewSession $previewSession)
476  {
477  return (array)$previewSession->getParticipantsSolution();
478  }
479 
485  public function getUploadedFilesForWeb($active_id, $pass)
486  {
487  global $ilDB;
488 
489  $found = $this->getUploadedFiles($active_id, $pass);
490  $result = $ilDB->queryF("SELECT test_fi FROM tst_active WHERE active_id = %s",
491  array('integer'),
492  array($active_id)
493  );
494  if ($result->numRows() == 1)
495  {
496  $row = $ilDB->fetchAssoc($result);
497  $test_id = $row["test_fi"];
498  $path = $this->getFileUploadPathWeb($test_id, $active_id);
499  foreach ($found as $idx => $data)
500  {
501  $found[$idx]['webpath'] = $path;
502  }
503  }
504  return $found;
505  }
506 
512  protected function deleteUploadedFiles($files, $test_id, $active_id, $authorized)
513  {
514  global $ilDB;
515 
516  $pass = null;
517  $active_id = null;
518  foreach ($files as $solution_id)
519  {
520  $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
521  array("integer", 'integer'),
522  array($solution_id, (int)$authorized)
523  );
524  if ($result->numRows() == 1)
525  {
526  $data = $ilDB->fetchAssoc($result);
527  $pass = $data['pass'];
528  $active_id = $data['active_fi'];
529  @unlink($this->getFileUploadPath($test_id, $active_id) . $data['value1']);
530  }
531  }
532  foreach ($files as $solution_id)
533  {
534  $affectedRows = $ilDB->manipulateF("DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
535  array("integer", 'integer'),
536  array($solution_id, $authorized)
537  );
538  }
539  }
540 
541  protected function deletePreviewFileUploads($userId, $userSolution, $files)
542  {
543  foreach($files as $name)
544  {
545  if( isset($userSolution[$name]) )
546  {
547  unset($userSolution[$name]);
548  @unlink($this->getPreviewFileUploadPath($userId) . $name);
549  }
550  }
551 
552  return $userSolution;
553  }
554 
560  public function getMaxFilesizeAsString()
561  {
562  $size = $this->getMaxFilesizeInBytes();
563  if ($size < 1024)
564  {
565  $max_filesize = sprintf("%d Bytes",$size);
566  }
567  else if ($size < 1024*1024)
568  {
569  $max_filesize = sprintf("%.1f KB",$size/1024);
570  }
571  else
572  {
573  $max_filesize = sprintf("%.1f MB",$size/1024/1024);
574  }
575 
576  return $max_filesize;
577  }
578 
584  public function getMaxFilesizeInBytes()
585  {
586  if (strlen($this->getMaxSize()))
587  {
588  return $this->getMaxSize();
589  }
590  else
591  {
592  // get the value for the maximal uploadable filesize from the php.ini (if available)
593  $umf = get_cfg_var("upload_max_filesize");
594  // get the value for the maximal post data from the php.ini (if available)
595  $pms = get_cfg_var("post_max_size");
596 
597  //convert from short-string representation to "real" bytes
598  $multiplier_a=array("K"=>1024, "M"=>1024*1024, "G"=>1024*1024*1024);
599 
600  $umf_parts=preg_split("/(\d+)([K|G|M])/", $umf, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
601  $pms_parts=preg_split("/(\d+)([K|G|M])/", $pms, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
602 
603  if (count($umf_parts) == 2) { $umf = $umf_parts[0]*$multiplier_a[$umf_parts[1]]; }
604  if (count($pms_parts) == 2) { $pms = $pms_parts[0]*$multiplier_a[$pms_parts[1]]; }
605 
606  // use the smaller one as limit
607  $max_filesize = min($umf, $pms);
608 
609  if (!$max_filesize) $max_filesize=max($umf, $pms);
610  return $max_filesize;
611  }
612  }
613 
622  public function saveWorkingData($active_id, $pass = NULL, $authorized = true)
623  {
624  global $ilDB;
625  global $ilUser;
626 
627  if (is_null($pass))
628  {
629  include_once "./Modules/Test/classes/class.ilObjTest.php";
630  $pass = ilObjTest::_getPass($active_id);
631  }
632 
633  if( $_POST['cmd'][$this->questionActionCmd] != $this->lng->txt('delete')
634  && strlen($_FILES["upload"]["tmp_name"]) )
635  {
636  $checkUploadResult = $this->checkUpload();
637  }
638  else
639  {
640  $checkUploadResult = false;
641  }
642 
643  $result = $ilDB->queryF("SELECT test_fi FROM tst_active WHERE active_id = %s",
644  array('integer'),
645  array($active_id)
646  );
647  $test_id = 0;
648  if ($result->numRows() == 1)
649  {
650  $row = $ilDB->fetchAssoc($result);
651  $test_id = $row["test_fi"];
652  }
653 
654  $this->getProcessLocker()->requestUserSolutionUpdateLock();
655 
656  $this->updateCurrentSolutionsAuthorization($active_id, $pass, $authorized);
657 
658  $entered_values = false;
659  if( $_POST['cmd'][$this->questionActionCmd] == $this->lng->txt('delete') )
660  {
661  if (is_array($_POST['deletefiles']) && count($_POST['deletefiles']) > 0)
662  {
663  $this->deleteUploadedFiles($_POST['deletefiles'], $test_id, $active_id, $authorized);
664  }
665  else
666  {
667  ilUtil::sendInfo($this->lng->txt('no_checkbox'), true);
668  }
669  }
670  elseif( $checkUploadResult )
671  {
672  if(!@file_exists($this->getFileUploadPath($test_id, $active_id)))
673  {
675  }
676 
677  $version = time();
678  $filename_arr = pathinfo($_FILES["upload"]["name"]);
679  $extension = $filename_arr["extension"];
680  $newfile = "file_" . $active_id . "_" . $pass . "_" . $version . "." . $extension;
681 
682  ilUtil::moveUploadedFile($_FILES["upload"]["tmp_name"], $_FILES["upload"]["name"], $this->getFileUploadPath($test_id, $active_id) . $newfile);
683 
684  $this->saveCurrentSolution($active_id, $pass, $newfile, $_FILES['upload']['name'], $authorized);
685 
686  $entered_values = true;
687  }
688 
689  $this->getProcessLocker()->releaseUserSolutionUpdateLock();
690 
691  if ($entered_values)
692  {
693  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
695  {
696  $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
697  }
698  }
699  else
700  {
701  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
703  {
704  $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
705  }
706  }
707 
708  return true;
709  }
710 
711  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
712  {
713  $userSolution = $previewSession->getParticipantsSolution();
714 
715  if( !is_array($userSolution) )
716  {
717  $userSolution = array();
718  }
719 
720  if (strcmp($_POST['cmd'][$this->questionActionCmd], $this->lng->txt('delete')) == 0)
721  {
722  if (is_array($_POST['deletefiles']) && count($_POST['deletefiles']) > 0)
723  {
724  $userSolution = $this->deletePreviewFileUploads($previewSession->getUserId(), $userSolution, $_POST['deletefiles']);
725  }
726  else
727  {
728  ilUtil::sendInfo($this->lng->txt('no_checkbox'), true);
729  }
730  }
731  else
732  {
733  if (strlen($_FILES["upload"]["tmp_name"]))
734  {
735  if ($this->checkUpload())
736  {
737  if( !@file_exists($this->getPreviewFileUploadPath($previewSession->getUserId())) )
738  {
739  ilUtil::makeDirParents($this->getPreviewFileUploadPath($previewSession->getUserId()));
740  }
741 
742  $version = time();
743  $filename_arr = pathinfo($_FILES["upload"]["name"]);
744  $extension = $filename_arr["extension"];
745  $newfile = "file_".md5($_FILES["upload"]["name"])."_" . $version . "." . $extension;
746  ilUtil::moveUploadedFile($_FILES["upload"]["tmp_name"], $_FILES["upload"]["name"], $this->getPreviewFileUploadPath($previewSession->getUserId()) . $newfile);
747 
748  $userSolution[$newfile] = array(
749  'solution_id' => $newfile,
750  'value1' => $newfile,
751  'value2' => $_FILES['upload']['name'],
752  'tstamp' => $version,
753  'webpath' => $this->getPreviewFileUploadPathWeb($previewSession->getUserId())
754  );
755  }
756  }
757  }
758 
759  $previewSession->setParticipantsSolution($userSolution);
760  }
761 
770  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
771  {
772  $this->handleSubmission($active_id, $pass, $obligationsAnswered, $authorized);
773  }
774 
784  protected function handleSubmission($active_id, $pass, $obligationsAnswered, $authorized)
785  {
786  if(!$authorized)
787  {
788  return;
789  }
790 
792  {
793  $maxpoints = assQuestion::_getMaximumPoints($this->getId());
794 
795  if($this->getUploadedFiles($active_id, $pass, $authorized))
796  {
797  $points = $maxpoints;
798  }
799  else
800  {
801  $points = 0;
802  }
803 
804  assQuestion::_setReachedPoints($active_id, $this->getId(), $points, $maxpoints, $pass, 1, $obligationsAnswered);
805 
806  // update learning progress
807  include_once 'Modules/Test/classes/class.ilObjTestAccess.php';
808  include_once 'Services/Tracking/classes/class.ilLPStatusWrapper.php';
810  ilObjTest::_getObjectIDFromActiveID((int)$active_id),
811  ilObjTestAccess::_getParticipantId((int) $active_id)
812  );
813  }
814  }
815 
821  public function getQuestionType()
822  {
823  return "assFileUpload";
824  }
825 
831  public function getAdditionalTableName()
832  {
833  return "qpl_qst_fileupload";
834  }
835 
841  public function getAnswerTableName()
842  {
843  return "";
844  }
845 
851  public function deleteAnswers($question_id)
852  {
853  }
854 
859  public function getRTETextWithMediaObjects()
860  {
861  $text = parent::getRTETextWithMediaObjects();
862  return $text;
863  }
864 
876  public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
877  {
878  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
879  $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
880  $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
881  $i = 1;
882  $solutions = $this->getSolutionValues($active_id, $pass);
883  foreach ($solutions as $solution)
884  {
885  $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($this->lng->txt("result")), $format_bold);
886  if (strlen($solution["value1"]))
887  {
888  $worksheet->write($startrow + $i, 1, ilExcelUtils::_convert_text($solution["value1"]));
889  $worksheet->write($startrow + $i, 2, ilExcelUtils::_convert_text($solution["value2"]));
890  }
891  $i++;
892  }
893  return $startrow + $i + 1;
894  }
895 
908  public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
909  {
910  include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assFileUploadImport.php";
911  $import = new assFileUploadImport($this);
912  $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
913  }
914 
921  public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
922  {
923  include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assFileUploadExport.php";
924  $export = new assFileUploadExport($this);
925  return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
926  }
927 
933  public function getBestSolution($active_id, $pass)
934  {
935  $user_solution = array();
936  return $user_solution;
937  }
938 
944  public function getMaxSize()
945  {
946  return $this->maxsize;
947  }
948 
954  public function setMaxSize($a_value)
955  {
956  $this->maxsize = $a_value;
957  }
958 
964  public function getAllowedExtensionsArray()
965  {
966  if (strlen($this->allowedextensions))
967  {
968  return array_filter(array_map('trim', explode(",", $this->allowedextensions)));
969  }
970  return array();
971  }
972 
978  public function getAllowedExtensions()
979  {
981  }
982 
988  public function setAllowedExtensions($a_value)
989  {
990  $this->allowedextensions = strtolower(trim($a_value));
991  }
992 
996  public function __get($value)
997  {
998  switch ($value)
999  {
1000  case "maxsize":
1001  return $this->getMaxSize();
1002  break;
1003  case "allowedextensions":
1004  return $this->getAllowedExtensions();
1005  break;
1006  case 'completion_by_submission':
1007  return $this->isCompletionBySubmissionEnabled();
1008  break;
1009  default:
1010  return parent::__get($value);
1011  break;
1012  }
1013  }
1014 
1018  public function __set($key, $value)
1019  {
1020  switch ($key)
1021  {
1022  case "maxsize":
1023  $this->setMaxSize($value);
1024  break;
1025  case "allowedextensions":
1026  $this->setAllowedExtensions($value);
1027  break;
1028  case 'completion_by_submission':
1029  $this->setCompletionBySubmission($value);
1030  break;
1031  default:
1032  parent::__set($key, $value);
1033  break;
1034  }
1035  }
1036 
1044  public function hasFileUploads($test_id)
1045  {
1046  global $ilDB;
1047  $query = "
1048  SELECT tst_solutions.solution_id
1049  FROM tst_solutions, tst_active, qpl_questions
1050  WHERE tst_solutions.active_fi = tst_active.active_id
1051  AND tst_solutions.question_fi = qpl_questions.question_id
1052  AND tst_solutions.question_fi = %s AND tst_active.test_fi = %s";
1053  $result = $ilDB->queryF( $query,
1054  array("integer", "integer"),
1055  array($this->getId(), $test_id)
1056  );
1057  if ($result->numRows() > 0)
1058  {
1059  return true;
1060  }
1061  else
1062  {
1063  return false;
1064  }
1065  }
1066 
1072  public function deliverFileUploadZIPFile($test_id, $test_title)
1073  {
1074  global $ilDB, $lng;
1075 
1076  require_once 'Modules/TestQuestionPool/classes/class.ilAssFileUploadUploadsExporter.php';
1077  $exporter = new ilAssFileUploadUploadsExporter($ilDB, $lng);
1078 
1079  $exporter->setTestId($test_id);
1080  $exporter->setTestTitle($test_title);
1081  $exporter->setQuestion($this);
1082 
1083  $exporter->build();
1084 
1086  $exporter->getFinalZipFilePath(), $exporter->getDispoZipFileName(),
1087  $exporter->getZipFileMimeType(), false, true
1088  );
1089  }
1090 
1100  {
1102  }
1103 
1113  public function setCompletionBySubmission($bool)
1114  {
1115  $this->completion_by_submission = (bool)$bool;
1116  return $this;
1117  }
1118 
1130  public function isAnswered($active_id, $pass = null)
1131  {
1132  $numExistingSolutionRecords = assQuestion::getNumExistingSolutionRecords($active_id, $pass, $this->getId());
1133 
1134  return $numExistingSolutionRecords > 0;
1135  }
1136 
1147  public static function isObligationPossible($questionId)
1148  {
1149  return true;
1150  }
1151 
1152  public function isAutosaveable()
1153  {
1154  return FALSE;
1155  }
1156 }
getPreviewFileUploadPathWeb($userId)
Returns the filesystem path for file uploads.
static makeDirParents($a_dir)
Create a new directory and all parent directories.
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
getId()
Gets the id of the assQuestion object.
getAllowedExtensions()
Get allowed file extensions.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
static _getOriginalId($question_id)
Returns the original id of a question.
setSuggestedSolution($solution_id="", $subquestion_index=0, $is_import=false)
Sets a suggested solution for the question.
$size
Definition: RandomTest.php:79
Class for file upload question exports.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
setAllowedExtensions($a_value)
Set allowed file extensions.
$_POST['username']
Definition: cron.php:12
deleteUploadedFiles($files, $test_id, $active_id, $authorized)
Delete uploaded files.
static getNumExistingSolutionRecords($activeId, $pass, $questionId)
returns the number of existing solution records for the given test active / pass and given question i...
__set($key, $value)
Object setter.
static virusHandling($a_file, $a_orig_name="", $a_clean=true)
scan file for viruses and clean files if possible
$result
hasFileUploads($test_id)
Checks if file uploads exist for a given test and the original id of the question.
getPoints()
Returns the maximum available points for the question.
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
Reworks the allready saved working data if neccessary.
getBestSolution($active_id, $pass)
Returns the best solution for a given pass of a participant.
Abstract basic class which is to be extended by the concrete assessment question type classes...
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
_convert_text($a_text, $a_target="has been removed")
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
setId($id=-1)
Sets the id of the assQuestion object.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
Interface ilObjFileHandlingQuestionType.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
isComplete()
Returns true, if the question is complete for use.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true)
deletePreviewFileUploads($userId, $userSolution, $files)
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
Creates a question from a QTI file.
setNrOfTries($a_nr_of_tries)
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
copyObject($target_questionpool_id, $title="")
Copies an assFileUpload object.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
getFileUploadPathWeb($test_id, $active_id, $question_id=null)
Returns the file upload path for web accessible files of a question.
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
Class for file upload questions.
getMaxSize()
Get max file size.
handleSubmission($active_id, $pass, $obligationsAnswered, $authorized)
This method is called after an user submitted one or more files.
getObjId()
Get the object id of the container object.
getAllowedExtensionsArray()
Get allowed file extensions.
Class for file upload question imports.
Base Exception for all Exceptions relating to Modules/Test.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assFileUpload.
saveToDb($original_id="")
Saves a assFileUpload object to a database.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
updateCurrentSolutionsAuthorization($activeId, $pass, $authorized)
_getObjectIDFromActiveID($active_id)
Returns the ILIAS test object id for a given active id.
setAuthor($author="")
Sets the authors name of the assQuestion object.
$data
deliverFileUploadZIPFile($test_id, $test_title)
Generates a ZIP file containing all file uploads for a given test and the original id of the question...
const ILIAS_ABSOLUTE_PATH
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
getMaxFilesizeAsString()
Return the maximum allowed file size as string.
checkUpload()
Check file upload.
calculateReachedPointsForSolution($userSolution)
getPreviewFileUploads(ilAssQuestionPreviewSession $previewSession)
getQuestionType()
Returns the question type of the question.
setMaxSize($a_value)
Set max file size.
_getParticipantId($active_id)
Get user id for active id.
_getMaximumPoints($question_id)
Returns the maximum points, a learner can reach answering the question.
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
static deliverFile($a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
static removeTrailingPathSeparators($path)
getUploadedFilesForWeb($active_id, $pass)
Returns the web accessible uploaded files for an active user in a given pass.
_getLogLanguage()
retrieve the log language for assessment logging
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
$filename
Definition: buildRTE.php:89
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
toXML($a_include_header=true, $a_include_binary=true, $a_shuffle=false, $test_output=false, $force_image_references=false)
Returns a QTI xml representation of the question and sets the internal domxml variable with the DOM X...
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
getPreviewFileUploadPath($userId)
Returns the filesystem path for file uploads.
getFileUploadPath($test_id, $active_id, $question_id=null)
Returns the filesystem path for file uploads.
global $ilUser
Definition: imgupload.php:15
getAnswerTableName()
Returns the name of the answer table in the database.
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
$path
Definition: index.php:22
global $ilDB
setOriginalId($original_id)
_setReachedPoints($active_id, $question_id, $points, $maxpoints, $pass, $manualscoring, $obligationsEnabled)
Sets the points, a learner has reached answering the question Additionally objective results are upda...
$text
getAdditionalTableName()
Returns the name of the additional question data table in the database.
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
loadFromDb($question_id)
Loads a assFileUpload object from a database.
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getTitle()
Gets the title string of the assQuestion object.
getUploadedFiles($active_id, $pass=null, $authorized=true)
Returns the uploaded files for an active user in a given pass.
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assFileUpload constructor
getMaxFilesizeInBytes()
Return the maximum allowed file size in bytes.
setCompletionBySubmission($bool)
Enabled/Disable completion by submission.
setTitle($title="")
Sets the title string of the assQuestion object.
setObjId($obj_id=0)
Set the object id of the container object.
setComment($comment="")
Sets the comment string of the assQuestion object.
__get($value)
Object getter.
deleteAnswers($question_id)
Deletes datasets from answers tables.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
isCompletionBySubmissionEnabled()
Checks whether completion by submission is enabled or not.
isAnswered($active_id, $pass=null)
returns boolean wether the question is answered during test pass or not