ILIAS  release_5-0 Revision 5.0.0-1144-gc4397b1f870
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
4require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
5require_once './Modules/Test/classes/inc.AssessmentConstants.php';
6require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7require_once './Modules/TestQuestionPool/interfaces/interface.ilObjFileHandlingQuestionType.php';
8
21{
22 protected $maxsize;
23
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, $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 protected 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)
452 {
453 global $ilDB;
454 if (is_null($pass))
455 {
456 $pass = $this->getSolutionMaxPass($active_id);
457 }
458 $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s ORDER BY tstamp",
459 array("integer", "integer", "integer"),
460 array($active_id, $this->getId(), $pass)
461 );
462 $found = array();
463 while ($data = $ilDB->fetchAssoc($result))
464 {
465 array_push($found, $data);
466 }
467 return $found;
468 }
469
470 public function getPreviewFileUploads(ilAssQuestionPreviewSession $previewSession)
471 {
472 return (array)$previewSession->getParticipantsSolution();
473 }
474
480 public function getUploadedFilesForWeb($active_id, $pass)
481 {
482 global $ilDB;
483
484 $found = $this->getUploadedFiles($active_id, $pass);
485 $result = $ilDB->queryF("SELECT test_fi FROM tst_active WHERE active_id = %s",
486 array('integer'),
487 array($active_id)
488 );
489 if ($result->numRows() == 1)
490 {
491 $row = $ilDB->fetchAssoc($result);
492 $test_id = $row["test_fi"];
493 $path = $this->getFileUploadPathWeb($test_id, $active_id);
494 foreach ($found as $idx => $data)
495 {
496 $found[$idx]['webpath'] = $path;
497 }
498 }
499 return $found;
500 }
501
507 protected function deleteUploadedFiles($files, $test_id, $active_id)
508 {
509 global $ilDB;
510
511 $pass = null;
512 $active_id = null;
513 foreach ($files as $solution_id)
514 {
515 $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE solution_id = %s",
516 array("integer"),
517 array($solution_id)
518 );
519 if ($result->numRows() == 1)
520 {
521 $data = $ilDB->fetchAssoc($result);
522 $pass = $data['pass'];
523 $active_id = $data['active_fi'];
524 @unlink($this->getFileUploadPath($test_id, $active_id) . $data['value1']);
525 }
526 }
527 foreach ($files as $solution_id)
528 {
529 $affectedRows = $ilDB->manipulateF("DELETE FROM tst_solutions WHERE solution_id = %s",
530 array("integer"),
531 array($solution_id)
532 );
533 }
534 }
535
536 protected function deletePreviewFileUploads($userId, $userSolution, $files)
537 {
538 foreach($files as $name)
539 {
540 if( isset($userSolution[$name]) )
541 {
542 unset($userSolution[$name]);
543 @unlink($this->getPreviewFileUploadPath($userId) . $name);
544 }
545 }
546
547 return $userSolution;
548 }
549
555 public function getMaxFilesizeAsString()
556 {
557 $size = $this->getMaxFilesizeInBytes();
558 if ($size < 1024)
559 {
560 $max_filesize = sprintf("%d Bytes",$size);
561 }
562 else if ($size < 1024*1024)
563 {
564 $max_filesize = sprintf("%.1f KB",$size/1024);
565 }
566 else
567 {
568 $max_filesize = sprintf("%.1f MB",$size/1024/1024);
569 }
570
571 return $max_filesize;
572 }
573
579 public function getMaxFilesizeInBytes()
580 {
581 if (strlen($this->getMaxSize()))
582 {
583 return $this->getMaxSize();
584 }
585 else
586 {
587 // get the value for the maximal uploadable filesize from the php.ini (if available)
588 $umf = get_cfg_var("upload_max_filesize");
589 // get the value for the maximal post data from the php.ini (if available)
590 $pms = get_cfg_var("post_max_size");
591
592 //convert from short-string representation to "real" bytes
593 $multiplier_a=array("K"=>1024, "M"=>1024*1024, "G"=>1024*1024*1024);
594
595 $umf_parts=preg_split("/(\d+)([K|G|M])/", $umf, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
596 $pms_parts=preg_split("/(\d+)([K|G|M])/", $pms, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
597
598 if (count($umf_parts) == 2) { $umf = $umf_parts[0]*$multiplier_a[$umf_parts[1]]; }
599 if (count($pms_parts) == 2) { $pms = $pms_parts[0]*$multiplier_a[$pms_parts[1]]; }
600
601 // use the smaller one as limit
602 $max_filesize = min($umf, $pms);
603
604 if (!$max_filesize) $max_filesize=max($umf, $pms);
605 return $max_filesize;
606 }
607 }
608
617 public function saveWorkingData($active_id, $pass = NULL)
618 {
619 global $ilDB;
620 global $ilUser;
621
622 if (is_null($pass))
623 {
624 include_once "./Modules/Test/classes/class.ilObjTest.php";
625 $pass = ilObjTest::_getPass($active_id);
626 }
627
628 if( $_POST['cmd'][$this->questionActionCmd] != $this->lng->txt('delete')
629 && strlen($_FILES["upload"]["tmp_name"]) )
630 {
631 $checkUploadResult = $this->checkUpload();
632 }
633 else
634 {
635 $checkUploadResult = false;
636 }
637
638 $result = $ilDB->queryF("SELECT test_fi FROM tst_active WHERE active_id = %s",
639 array('integer'),
640 array($active_id)
641 );
642 $test_id = 0;
643 if ($result->numRows() == 1)
644 {
645 $row = $ilDB->fetchAssoc($result);
646 $test_id = $row["test_fi"];
647 }
648
649 $this->getProcessLocker()->requestUserSolutionUpdateLock();
650
651 $entered_values = false;
652 if( $_POST['cmd'][$this->questionActionCmd] == $this->lng->txt('delete') )
653 {
654 if (is_array($_POST['deletefiles']) && count($_POST['deletefiles']) > 0)
655 {
656 $this->deleteUploadedFiles($_POST['deletefiles'], $test_id, $active_id);
657 }
658 else
659 {
660 ilUtil::sendInfo($this->lng->txt('no_checkbox'), true);
661 }
662 }
663 elseif( $checkUploadResult )
664 {
665 if (!@file_exists($this->getFileUploadPath($test_id, $active_id))) ilUtil::makeDirParents($this->getFileUploadPath($test_id, $active_id));
666 $version = time();
667 $filename_arr = pathinfo($_FILES["upload"]["name"]);
668 $extension = $filename_arr["extension"];
669 $newfile = "file_" . $active_id . "_" . $pass . "_" . $version . "." . $extension;
670 ilUtil::moveUploadedFile($_FILES["upload"]["tmp_name"], $_FILES["upload"]["name"], $this->getFileUploadPath($test_id, $active_id) . $newfile);
671 $next_id = $ilDB->nextId('tst_solutions');
672 $affectedRows = $ilDB->insert("tst_solutions", array(
673 "solution_id" => array("integer", $next_id),
674 "active_fi" => array("integer", $active_id),
675 "question_fi" => array("integer", $this->getId()),
676 "value1" => array("clob", $newfile),
677 "value2" => array("clob", $_FILES['upload']['name']),
678 "pass" => array("integer", $pass),
679 "tstamp" => array("integer", time())
680 ));
681 $entered_values = true;
682 }
683
684 $this->getProcessLocker()->releaseUserSolutionUpdateLock();
685
686 if ($entered_values)
687 {
688 include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
690 {
691 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
692 }
693 }
694 else
695 {
696 include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
698 {
699 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
700 }
701 }
702
703 return true;
704 }
705
706 protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
707 {
708 $userSolution = $previewSession->getParticipantsSolution();
709
710 if( !is_array($userSolution) )
711 {
712 $userSolution = array();
713 }
714
715 if (strcmp($_POST['cmd'][$this->questionActionCmd], $this->lng->txt('delete')) == 0)
716 {
717 if (is_array($_POST['deletefiles']) && count($_POST['deletefiles']) > 0)
718 {
719 $userSolution = $this->deletePreviewFileUploads($previewSession->getUserId(), $userSolution, $_POST['deletefiles']);
720 }
721 else
722 {
723 ilUtil::sendInfo($this->lng->txt('no_checkbox'), true);
724 }
725 }
726 else
727 {
728 if (strlen($_FILES["upload"]["tmp_name"]))
729 {
730 if ($this->checkUpload())
731 {
732 if( !@file_exists($this->getPreviewFileUploadPath($previewSession->getUserId())) )
733 {
735 }
736
737 $version = time();
738 $filename_arr = pathinfo($_FILES["upload"]["name"]);
739 $extension = $filename_arr["extension"];
740 $newfile = "file_".md5($_FILES["upload"]["name"])."_" . $version . "." . $extension;
741 ilUtil::moveUploadedFile($_FILES["upload"]["tmp_name"], $_FILES["upload"]["name"], $this->getPreviewFileUploadPath($previewSession->getUserId()) . $newfile);
742
743 $userSolution[$newfile] = array(
744 'solution_id' => $newfile,
745 'value1' => $newfile,
746 'value2' => $_FILES['upload']['name'],
747 'tstamp' => $version,
748 'webpath' => $this->getPreviewFileUploadPathWeb($previewSession->getUserId())
749 );
750 }
751 }
752 }
753
754 $previewSession->setParticipantsSolution($userSolution);
755 }
756
765 protected function reworkWorkingData($active_id, $pass, $obligationsAnswered)
766 {
767 $this->handleSubmission($active_id, $pass, $obligationsAnswered);
768 }
769
779 protected function handleSubmission($active_id, $pass, $obligationsAnswered)
780 {
781 global $ilObjDataCache;
782
784 {
785 $maxpoints = assQuestion::_getMaximumPoints($this->getId());
786
787 if($this->getUploadedFiles($active_id, $pass))
788 {
789 $points = $maxpoints;
790 }
791 else
792 {
793 $points = 0;
794 }
795
796 assQuestion::_setReachedPoints($active_id, $this->getId(), $points, $maxpoints, $pass, 1, $obligationsAnswered);
797
798 // update learning progress
799 include_once 'Modules/Test/classes/class.ilObjTestAccess.php';
800 include_once 'Services/Tracking/classes/class.ilLPStatusWrapper.php';
803 ilObjTestAccess::_getParticipantId((int) $active_id)
804 );
805 }
806 }
807
813 public function getQuestionType()
814 {
815 return "assFileUpload";
816 }
817
823 public function getAdditionalTableName()
824 {
825 return "qpl_qst_fileupload";
826 }
827
833 public function getAnswerTableName()
834 {
835 return "";
836 }
837
843 public function deleteAnswers($question_id)
844 {
845 }
846
852 {
853 $text = parent::getRTETextWithMediaObjects();
854 return $text;
855 }
856
868 public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
869 {
870 include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
871 $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
872 $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
873 $i = 1;
874 $solutions = $this->getSolutionValues($active_id, $pass);
875 foreach ($solutions as $solution)
876 {
877 $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($this->lng->txt("result")), $format_bold);
878 if (strlen($solution["value1"]))
879 {
880 $worksheet->write($startrow + $i, 1, ilExcelUtils::_convert_text($solution["value1"]));
881 $worksheet->write($startrow + $i, 2, ilExcelUtils::_convert_text($solution["value2"]));
882 }
883 $i++;
884 }
885 return $startrow + $i + 1;
886 }
887
900 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
901 {
902 include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assFileUploadImport.php";
903 $import = new assFileUploadImport($this);
904 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
905 }
906
913 public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
914 {
915 include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assFileUploadExport.php";
916 $export = new assFileUploadExport($this);
917 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
918 }
919
925 public function getBestSolution($active_id, $pass)
926 {
927 $user_solution = array();
928 return $user_solution;
929 }
930
936 public function getMaxSize()
937 {
938 return $this->maxsize;
939 }
940
946 public function setMaxSize($a_value)
947 {
948 $this->maxsize = $a_value;
949 }
950
957 {
958 if (strlen($this->allowedextensions))
959 {
960 return array_filter(array_map('trim', explode(",", $this->allowedextensions)));
961 }
962 return array();
963 }
964
970 public function getAllowedExtensions()
971 {
973 }
974
980 public function setAllowedExtensions($a_value)
981 {
982 $this->allowedextensions = strtolower(trim($a_value));
983 }
984
988 public function __get($value)
989 {
990 switch ($value)
991 {
992 case "maxsize":
993 return $this->getMaxSize();
994 break;
995 case "allowedextensions":
996 return $this->getAllowedExtensions();
997 break;
998 case 'completion_by_submission':
999 return $this->isCompletionBySubmissionEnabled();
1000 break;
1001 default:
1002 return parent::__get($value);
1003 break;
1004 }
1005 }
1006
1010 public function __set($key, $value)
1011 {
1012 switch ($key)
1013 {
1014 case "maxsize":
1015 $this->setMaxSize($value);
1016 break;
1017 case "allowedextensions":
1018 $this->setAllowedExtensions($value);
1019 break;
1020 case 'completion_by_submission':
1021 $this->setCompletionBySubmission($value);
1022 break;
1023 default:
1024 parent::__set($key, $value);
1025 break;
1026 }
1027 }
1028
1036 public function hasFileUploads($test_id)
1037 {
1038 global $ilDB;
1039 $query = "
1040 SELECT tst_solutions.solution_id
1041 FROM tst_solutions, tst_active, qpl_questions
1042 WHERE tst_solutions.active_fi = tst_active.active_id
1043 AND tst_solutions.question_fi = qpl_questions.question_id
1044 AND tst_solutions.question_fi = %s AND tst_active.test_fi = %s";
1045 $result = $ilDB->queryF( $query,
1046 array("integer", "integer"),
1047 array($this->getId(), $test_id)
1048 );
1049 if ($result->numRows() > 0)
1050 {
1051 return true;
1052 }
1053 else
1054 {
1055 return false;
1056 }
1057 }
1058
1064 public function getFileUploadZIPFile($test_id)
1065 {
1067 global $ilDB;
1068 $query = "
1069 SELECT
1070 tst_solutions.solution_id, tst_solutions.pass, tst_solutions.active_fi, tst_solutions.question_fi,
1071 tst_solutions.value1, tst_solutions.value2, tst_solutions.tstamp
1072 FROM tst_solutions, tst_active, qpl_questions
1073 WHERE tst_solutions.active_fi = tst_active.active_id
1074 AND tst_solutions.question_fi = qpl_questions.question_id
1075 AND tst_solutions.question_fi = %s
1076 AND tst_active.test_fi = %s
1077 ORDER BY tst_solutions.active_fi, tst_solutions.tstamp";
1078
1079 $result = $ilDB->queryF( $query,
1080 array("integer", "integer"),
1081 array($this->getId(), $test_id)
1082 );
1083 $zipfile = ilUtil::ilTempnam() . ".zip";
1084 $tempdir = ilUtil::ilTempnam();
1085 if ($result->numRows())
1086 {
1087 $userdata = array();
1088 $data .= "<html><head>";
1089 $data .= '<meta http-equiv="content-type" content="text/html; charset=UTF-8" />';
1090 $data .= '<style>
1091 table { border: 1px #333 solid; border-collapse:collapse;}
1092 td, th { border: 1px #333 solid; padding: 0.25em;}
1093 th { color: #fff; background-color: #666;}
1094 </style>
1095 ';
1096 $data .= "<title>" . $this->getTitle() . "</title></head><body>\n";
1097 $data .= "<h1>" . $this->getTitle() . "</h1>\n";
1098 $data .= "<table><thead>\n";
1099 $data .= "<tr><th>" . $this->lng->txt("name") . "</th><th>" . $this->lng->txt("filename") . "</th><th>" . $this->lng->txt("pass") . "</th><th>" . $this->lng->txt("location") . "</th><th>" . $this->lng->txt("date") . "</th></tr></thead><tbody>\n";
1100 while ($row = $ilDB->fetchAssoc($result))
1101 {
1102 ilUtil::makeDirParents($tempdir . "/" . $row["active_fi"]."/".$row["question_fi"]);
1103 @copy($this->getFileUploadPath($test_id, $row["active_fi"], $row["question_fi"]) . $row["value1"], $tempdir . "/" . $row["active_fi"]."/".$row["question_fi"] . "/" . $row["value1"]);
1104 if (!array_key_exists($row["active_fi"], $userdata))
1105 {
1106 include_once "./Modules/Test/classes/class.ilObjTestAccess.php";
1107 $userdata[$row["active_fi"]] = ilObjTestAccess::_getParticipantData($row["active_fi"]);
1108 }
1109 $data .= "<tr><td>".$userdata[$row["active_fi"]]."</td><td><a href=\"".$row["active_fi"]."/".$row["question_fi"]."/".$row["value1"]."\" target=\"_blank\">".$row["value2"]."</a></td><td>".$row["pass"]."</td><td>".$row["active_fi"]."/".$row["question_fi"]."/".$row["value1"]."</td>";
1110 $data .= "<td>" . ilFormat::fmtDateTime(ilFormat::unixtimestamp2datetime($row["tstamp"]), $this->lng->txt("lang_dateformat"), $this->lng->txt("lang_timeformat"), "datetime", FALSE) . "</td>";
1111 $data .= "</tr>\n";
1112 }
1113 $data .= "</tbody></table>\n";
1114 $data .= "</body></html>\n";
1115
1116 $indexfile = $tempdir . "/index.html";
1117 $fh = fopen($indexfile, 'w');
1118 fwrite($fh, $data);
1119 fclose($fh);
1120 }
1121 ilUtil::zip($tempdir, $zipfile);
1122 ilUtil::delDir($tempdir);
1123 ilUtil::deliverFile($zipfile, ilUtil::getASCIIFilename($this->getTitle().".zip"), "application/zip", false, true);
1124 }
1125
1135 {
1137 }
1138
1148 public function setCompletionBySubmission($bool)
1149 {
1150 $this->completion_by_submission = (bool)$bool;
1151 return $this;
1152 }
1153
1165 public function isAnswered($active_id, $pass)
1166 {
1167 $numExistingSolutionRecords = assQuestion::getNumExistingSolutionRecords($active_id, $pass, $this->getId());
1168
1169 return $numExistingSolutionRecords > 0;
1170 }
1171
1182 public static function isObligationPossible($questionId)
1183 {
1184 return true;
1185 }
1186
1187 public function isAutosaveable()
1188 {
1189 return FALSE;
1190 }
1191}
$result
$size
Definition: RandomTest.php:79
$filename
Definition: buildRTE.php:89
Class for file upload question exports.
Class for file upload question imports.
Class for file upload questions.
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
Creates a question from a QTI file.
__set($key, $value)
Object setter.
isCompletionBySubmissionEnabled()
Checks whether completion by submission is enabled or not.
isAnswered($active_id, $pass)
returns boolean wether the question is answered during test pass or not
deleteAnswers($question_id)
Deletes datasets from answers tables.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
setMaxSize($a_value)
Set max file size.
getUploadedFiles($active_id, $pass=null)
Returns the uploaded files for an active user in a given pass.
hasFileUploads($test_id)
Checks if file uploads exist for a given test and the original id of the question.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
getPreviewFileUploadPathWeb($userId)
Returns the filesystem path for file uploads.
getFileUploadPathWeb($test_id, $active_id, $question_id=null)
Returns the file upload path for web accessible files of a question.
calculateReachedPoints($active_id, $pass=NULL, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
deletePreviewFileUploads($userId, $userSolution, $files)
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assFileUpload.
saveToDb($original_id="")
Saves a assFileUpload object to a database.
copyObject($target_questionpool_id, $title="")
Copies an assFileUpload object.
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
deleteUploadedFiles($files, $test_id, $active_id)
calculateReachedPointsForSolution($userSolution)
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
saveWorkingData($active_id, $pass=NULL)
Saves the learners input of the question to the database.
getBestSolution($active_id, $pass)
Returns the best solution for a given pass of a participant.
getPreviewFileUploadPath($userId)
Returns the filesystem path for file uploads.
isComplete()
Returns true, if the question is complete for use.
getAllowedExtensions()
Get allowed file extensions.
getMaxSize()
Get max file size.
setAllowedExtensions($a_value)
Set allowed file extensions.
getAnswerTableName()
Returns the name of the answer table in the database.
handleSubmission($active_id, $pass, $obligationsAnswered)
This method is called after an user submitted one or more files.
setCompletionBySubmission($bool)
Enabled/Disable completion by submission.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assFileUpload constructor
getFileUploadPath($test_id, $active_id, $question_id=null)
Returns the filesystem path for file uploads.
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...
savePreviewData(ilAssQuestionPreviewSession $previewSession)
loadFromDb($question_id)
Loads a assFileUpload object from a database.
getPreviewFileUploads(ilAssQuestionPreviewSession $previewSession)
__get($value)
Object getter.
getAllowedExtensionsArray()
Get allowed file extensions.
getQuestionType()
Returns the question type of the question.
getUploadedFilesForWeb($active_id, $pass)
Returns the web accessible uploaded files for an active user in a given pass.
checkUpload()
Check file upload.
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
getAdditionalTableName()
Returns the name of the additional question data table in the database.
Abstract basic class which is to be extended by the concrete assessment question type classes.
& getSolutionValues($active_id, $pass=NULL)
Loads solutions of a given user from the database an returns it.
static _getOriginalId($question_id)
Returns the original id of a question.
setId($id=-1)
Sets the id of the assQuestion object.
setOriginalId($original_id)
setObjId($obj_id=0)
Set the object id of the container object.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
setSuggestedSolution($solution_id="", $subquestion_index=0, $is_import=false)
Sets a suggested solution for the question.
saveQuestionDataToDb($original_id="")
_getMaximumPoints($question_id)
Returns the maximum points, a learner can reach answering the question.
getId()
Gets the id of the assQuestion object.
getObjId()
Get the object id of the container object.
setTitle($title="")
Sets the title string of the assQuestion object.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second.
static getNumExistingSolutionRecords($activeId, $pass, $questionId)
returns the number of existing solution records for the given test active / pass and given question i...
setAuthor($author="")
Sets the authors name of the assQuestion object.
getPoints()
Returns the maximum available points for the question.
_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...
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getTitle()
Gets the title string of the assQuestion object.
setPoints($a_points)
Sets the maximum available points for the question.
setComment($comment="")
Sets the comment string of the assQuestion object.
setNrOfTries($a_nr_of_tries)
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
setQuestion($question="")
Sets the question string of the question object.
_convert_text($a_text, $a_target="has been removed")
static fmtDateTime($a_str, $a_dateformat, $a_timeformat, $a_mode="datetime", $a_relative=TRUE)
formatting function for dates
unixtimestamp2datetime($a_unix_timestamp="")
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_no_raise=false, $a_force_raise=false)
Update status.
_getLogLanguage()
retrieve the log language for assessment logging
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
_getParticipantId($active_id)
Get user id for active id.
_getParticipantData($active_id)
Retrieves a participant name from active id.
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
_getObjectIDFromActiveID($active_id)
Returns the ILIAS test object id for a given active id.
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...
Base Exception for all Exceptions relating to Modules/Test.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static virusHandling($a_file, $a_orig_name="", $a_clean=true)
scan file for viruses and clean files if possible
static zip($a_dir, $a_file, $compress_content=false)
static ilTempnam()
Create a temporary file in an ILIAS writable directory.
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
static removeTrailingPathSeparators($path)
static deliverFile($a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
$_POST['username']
Definition: cron.php:12
Interface ilObjFileHandlingQuestionType.
getFileUploadZIPFile($test_id)
Generates a ZIP file containing all file uploads for a given test and the original id of the question...
Interface ilObjQuestionScoringAdjustable.
echo;exit;}function LogoutNotification($SessionID){ global $ilDB;$q="SELECT session_id, data FROM usr_session WHERE expires > (\w+)\|/" PREG_SPLIT_NO_EMPTY PREG_SPLIT_DELIM_CAPTURE
$path
Definition: index.php:22
global $ilDB
global $ilUser
Definition: imgupload.php:15
const ILIAS_ABSOLUTE_PATH