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';
92 array( $this->
getId() )
96 ) .
" (question_fi, maxsize, allowedextensions, compl_by_submission) VALUES (%s, %s, %s, %s)",
97 array(
"integer",
"float",
"text",
"integer" ),
123 $this->
setId($question_id);
134 include_once(
"./Services/RTE/classes/class.ilRTE.php");
152 parent::loadFromDb($question_id);
160 if ($this->
id <= 0) {
165 $this_id = $this->
getId();
169 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
173 if ((
int) $testObjId > 0) {
174 $clone->setObjId($testObjId);
195 $clone->copyPageOfQuestion($this_id);
197 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
199 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
209 if ($this->
id <= 0) {
215 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
218 $source_questionpool_id = $this->
getObjId();
219 $clone->setObjId($target_questionpool_id);
230 $clone->onCopy($source_questionpool_id,
$original_id, $clone->getObjId(), $clone->getId());
237 if ($this->
id <= 0) {
242 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
245 $sourceParentId = $this->
getObjId();
251 $clone->setObjId($targetParentId);
253 if ($targetQuestionTitle) {
254 $clone->setTitle($targetQuestionTitle);
259 $clone->copyPageOfQuestion($sourceQuestionId);
261 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
263 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
290 if ($returndetails) {
291 throw new ilTestException(
'return details not implemented for ' . __METHOD__);
295 if (is_null(
$pass)) {
331 $this->lng->loadLanguageModule(
"form");
333 $_FILES[
"upload"][
"name"] = rtrim($_FILES[
"upload"][
"name"],
'/');
336 $filename_arr = pathinfo($_FILES[
"upload"][
"name"]);
337 $suffix = $filename_arr[
"extension"];
338 $mimetype = $_FILES[
"upload"][
"type"];
339 $size_bytes = $_FILES[
"upload"][
"size"];
340 $temp_name = $_FILES[
"upload"][
"tmp_name"];
341 $error = $_FILES[
"upload"][
"error"];
351 case UPLOAD_ERR_INI_SIZE:
356 case UPLOAD_ERR_FORM_SIZE:
361 case UPLOAD_ERR_PARTIAL:
366 case UPLOAD_ERR_NO_FILE:
371 case UPLOAD_ERR_NO_TMP_DIR:
376 case UPLOAD_ERR_CANT_WRITE:
381 case UPLOAD_ERR_EXTENSION:
390 if (!strlen($suffix)) {
402 if (strlen($temp_name)) {
404 if ($vir[0] ==
false) {
405 ilUtil::sendFailure($this->lng->txt(
"form_msg_file_virus_found") .
"<br />" . $vir[1],
true);
417 if (is_null($question_id)) {
418 $question_id = $this->
getId();
420 return CLIENT_WEB_DIR .
"/assessment/tst_$test_id/$active_id/$question_id/files/";
428 return CLIENT_WEB_DIR .
"/assessment/qst_preview/$userId/{$this->getId()}/fileuploads/";
438 if (is_null($question_id)) {
439 $question_id = $this->
getId();
441 include_once
"./Services/Utilities/classes/class.ilUtil.php";
451 include_once
"./Services/Utilities/classes/class.ilUtil.php";
466 if (is_null(
$pass)) {
471 "SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s AND authorized = %s AND value1 IS NOT NULL ORDER BY tstamp",
472 array(
"integer",
"integer",
"integer",
'integer'),
473 array($active_id, $this->
getId(),
$pass, (
int) $authorized)
479 array_push($found,
$data);
502 "SELECT test_fi FROM tst_active WHERE active_id = %s",
510 foreach ($found as $idx =>
$data) {
511 $found[$idx][
'webpath'] = $path;
529 foreach ($files as $solution_id) {
531 "SELECT * FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
532 array(
"integer",
'integer'),
533 array($solution_id, (
int) $authorized)
538 $active_id =
$data[
'active_fi'];
542 foreach ($files as $solution_id) {
543 $affectedRows =
$ilDB->manipulateF(
544 "DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
545 array(
"integer",
'integer'),
546 array($solution_id, $authorized)
558 protected function deleteUnusedFiles(
$test_id, $active_id,
$pass)
563 $solutions = array_merge(
570 $used_files = array();
571 foreach ($solutions as $solution) {
572 $used_files[] = $solution[
'value1'];
578 if (is_dir($uploadPath) && is_readable($uploadPath)) {
579 $iter = new \RegexIterator(
new \DirectoryIterator($uploadPath),
'/^file_' . $active_id .
'_' .
$pass .
'_(.*)/');
580 foreach ($iter as $file) {
582 if ($file->isFile() && !in_array($file->getFilename(), $used_files)) {
583 unlink($file->getPathname());
592 foreach ($files as
$name) {
593 if (isset($userSolution[
$name])) {
594 unset($userSolution[
$name]);
599 return $userSolution;
611 $max_filesize = sprintf(
"%d Bytes",
$size);
612 } elseif (
$size < 1024 * 1024) {
613 $max_filesize = sprintf(
"%.1f KB",
$size / 1024);
615 $max_filesize = sprintf(
"%.1f MB",
$size / 1024 / 1024);
618 return $max_filesize;
632 $umf = get_cfg_var(
"upload_max_filesize");
634 $pms = get_cfg_var(
"post_max_size");
637 $multiplier_a = array(
"K" => 1024,
"M" => 1024 * 1024,
"G" => 1024 * 1024 * 1024);
639 $umf_parts = preg_split(
"/(\d+)([K|G|M])/", $umf, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
640 $pms_parts = preg_split(
"/(\d+)([K|G|M])/", $pms, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
642 if (count($umf_parts) == 2) {
643 $umf = $umf_parts[0] * $multiplier_a[$umf_parts[1]];
645 if (count($pms_parts) == 2) {
646 $pms = $pms_parts[0] * $multiplier_a[$pms_parts[1]];
650 $max_filesize = min($umf, $pms);
652 if (!$max_filesize) {
653 $max_filesize = max($umf, $pms);
655 return $max_filesize;
677 $entered_values =
false;
679 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use (&$entered_values, $uploadHandlingRequired,
$test_id, $active_id,
$pass, $authorized) {
680 if ($authorized ==
false) {
686 foreach (
$_POST[self::DELETE_FILES_TBL_POSTVAR] as $solution_id) {
694 foreach (
$_POST[self::REUSE_FILES_TBL_POSTVAR] as $solutionId) {
708 if ($uploadHandlingRequired) {
713 $solutionFileVersioningUploadTS = time();
714 $filename_arr = pathinfo($_FILES[
"upload"][
"name"]);
715 $extension = $filename_arr[
"extension"];
716 $newfile =
"file_" . $active_id .
"_" .
$pass .
"_" . $solutionFileVersioningUploadTS .
"." . $extension;
718 include_once
'Services/Utilities/classes/class.ilFileUtils.php';
730 $solutionFileVersioningUploadTS
733 $entered_values =
true;
749 if ($entered_values) {
750 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
755 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
776 if (!count($solution)) {
780 foreach ($solution as $row) {
781 if (!empty($row[
'value1'])) {
785 $solution = $cleaned;
805 $result = parent::removeIntermediateSolution($active_id,
$pass);
823 if (!is_array($userSolution)) {
824 $userSolution = array();
847 $filename_arr = pathinfo($_FILES[
"upload"][
"name"]);
848 $extension = $filename_arr[
"extension"];
849 $newfile =
"file_" . md5($_FILES[
"upload"][
"name"]) .
"_" . $version .
"." . $extension;
852 $userSolution[$newfile] = array(
853 'solution_id' => $newfile,
854 'value1' => $newfile,
855 'value2' => $_FILES[
'upload'][
'name'],
856 'tstamp' => $version,
895 include_once
'Modules/Test/classes/class.ilObjTestAccess.php';
896 include_once
'Services/Tracking/classes/class.ilLPStatusWrapper.php';
911 return "assFileUpload";
921 return "qpl_qst_fileupload";
949 $text = parent::getRTETextWithMediaObjects();
958 parent::setExportDetailsXLS($worksheet, $startrow, $active_id,
$pass);
962 foreach ($solutions as $solution) {
963 $worksheet->setCell($startrow +
$i, 0, $this->lng->txt(
"result"));
964 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow +
$i));
965 if (strlen($solution[
"value1"])) {
966 $worksheet->setCell($startrow +
$i, 1, $solution[
"value1"]);
967 $worksheet->setCell($startrow +
$i, 2, $solution[
"value2"]);
972 return $startrow +
$i + 1;
987 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
989 include_once
"./Modules/TestQuestionPool/classes/import/qti12/class.assFileUploadImport.php";
991 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
1000 public function toXML($a_include_header =
true, $a_include_binary =
true, $a_shuffle =
false, $test_output =
false, $force_image_references =
false)
1002 include_once
"./Modules/TestQuestionPool/classes/export/qti12/class.assFileUploadExport.php";
1004 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
1014 $user_solution = array();
1015 return $user_solution;
1035 $this->maxsize = $a_value;
1045 if (strlen($this->allowedextensions)) {
1046 return array_filter(array_map(
'trim', explode(
",", $this->allowedextensions)));
1068 $this->allowedextensions = strtolower(trim($a_value));
1080 case "allowedextensions":
1083 case 'completion_by_submission':
1087 return parent::__get($value);
1101 case "allowedextensions":
1104 case 'completion_by_submission':
1108 parent::__set($key, $value);
1125 SELECT tst_solutions.solution_id
1126 FROM tst_solutions, tst_active, qpl_questions
1127 WHERE tst_solutions.active_fi = tst_active.active_id
1128 AND tst_solutions.question_fi = qpl_questions.question_id
1129 AND tst_solutions.question_fi = %s AND tst_active.test_fi = %s";
1132 array(
"integer",
"integer"),
1153 require_once
'Modules/TestQuestionPool/classes/class.ilAssFileUploadUploadsExporter.php';
1156 $exporter->setRefId($ref_id);
1158 $exporter->setTestTitle($test_title);
1159 $exporter->setQuestion($this);
1164 $exporter->getFinalZipFilePath(),
1165 $exporter->getDispoZipFileName(),
1166 $exporter->getZipFileMimeType(),
1196 $this->completion_by_submission = (bool) $bool;
1215 return $numExistingSolutionRecords > 0;
1250 return parent::buildTestPresentationConfig()
1252 ->setFormChangeDetectionEnabled(
false);
1262 require_once
'Modules/TestQuestionPool/classes/questions/class.ilAssFileUploadFileTableDeleteButton.php';
1303 if (!isset($_FILES[
'upload'])) {
1307 if (!isset($_FILES[
'upload'][
'tmp_name'])) {
1311 return strlen($_FILES[
'upload'][
'tmp_name']) > 0;
An exception for terminatinating execution or to throw for unit testing.
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.
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.
getUserSolutionPreferingIntermediate($active_id, $pass=null)
Get the user solution preferring the intermediate solution.
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
hasFileUploads($test_id)
Checks if file uploads exist for a given test and the original id of the question.
deleteUploadedFiles($files, $test_id, $active_id, $authorized)
Delete uploaded files.
$completion_by_submission
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.
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.
getUploadedFiles($active_id, $pass=null, $authorized=true)
Returns the uploaded files for an active user in a given pass.
copyObject($target_questionpool_id, $title="")
Copies an assFileUpload object.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
removeIntermediateSolution($active_id, $pass)
Remove an intermediate soluton (overridden to remove unused fies)
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
calculateReachedPointsForSolution($userSolution)
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{Creates an Excel worksheet for the detailed cumulated results of this question.object}
deliverFileUploadZIPFile($ref_id, $test_id, $test_title)
Generates a ZIP file containing all file uploads for a given test and the original id of the question...
const REUSE_FILES_TBL_POSTVAR
isFileDeletionSubmitAvailable()
handleSubmission($active_id, $pass, $obligationsAnswered, $authorized)
This method is called after an user submitted one or more files.
getBestSolution($active_id, $pass)
Returns the best solution for a given pass of a participant.
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
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.
getMaxFilesizeAsString()
Return the maximum allowed file size as string.
setAllowedExtensions($a_value)
Set allowed file extensions.
getAnswerTableName()
Returns the name of the answer table in the database.
isAnswered($active_id, $pass=null)
returns boolean wether the question is answered during test pass or not
setCompletionBySubmission($bool)
Enabled/Disable completion by submission.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assFileUpload constructor
isFileReuseSubmitAvailable()
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...
isFileReuseHandlingRequired()
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.
getMaxFilesizeInBytes()
Return the maximum allowed file size in bytes.
checkUpload()
Check file upload.
const DELETE_FILES_TBL_POSTVAR
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
buildTestPresentationConfig()
Get the test question configuration Overridden from parent to disable the form change detection Other...
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.
isNonEmptyItemListPostSubmission($postSubmissionFieldname)
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass.
getSolutionValues($active_id, $pass=null, $authorized=true)
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.
static _getMaximumPoints($question_id)
Returns the maximum points, a learner can reach answering the question.
saveQuestionDataToDb($original_id="")
deleteDummySolutionRecord($activeId, $passIndex)
getId()
Gets the id of the assQuestion object.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
getObjId()
Get the object id of the container object.
isDummySolutionRecord($solutionRecord)
setTitle($title="")
Sets the title string of the assQuestion object.
getSolutionRecordById($solutionId)
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 logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
removeCurrentSolution($active_id, $pass, $authorized=true)
removeSolutionRecordById($solutionId)
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.
ensureCurrentTestPass($active_id, $pass)
intermediateSolutionExists($active_id, $pass)
getTestPresentationConfig()
Get the test question configuration (initialised once)
forceExistingIntermediateSolution($activeId, $passIndex, $considerDummyRecordCreation)
static _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...
setLifecycle(ilAssQuestionLifecycle $lifecycle)
updateCurrentSolutionsAuthorization($activeId, $pass, $authorized, $keepTime=false)
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.
static getDraftInstance()
static getInstance($identifier)
getParticipantsSolution()
setParticipantsSolution($participantSolution)
static getValidFilename($a_filename)
Get valid filename.
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
static _getLogLanguage()
retrieve the log language for assessment logging
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static _getParticipantId($active_id)
Get user id for active id.
static _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 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 deliverFile( $a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
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)
Interface ilObjFileHandlingQuestionType.
Interface ilObjQuestionScoringAdjustable.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc