19require_once 
'./Modules/TestQuestionPool/classes/class.assQuestion.php';
 
   20require_once 
'./Modules/Test/classes/inc.AssessmentConstants.php';
 
   21require_once 
'./Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
 
   22require_once 
'./Modules/TestQuestionPool/interfaces/interface.ilObjFileHandlingQuestionType.php';
 
  107            array( $this->
getId() )
 
  111                                                                                             ) . 
" (question_fi, maxsize, allowedextensions, compl_by_submission) VALUES (%s, %s, %s, %s)",
 
  112            array( 
"integer", 
"float", 
"text", 
"integer" ),
 
  138            $this->
setId($question_id);
 
  149            include_once(
"./Services/RTE/classes/class.ilRTE.php");
 
  167        parent::loadFromDb($question_id);
 
  175        if ($this->
id <= 0) {
 
  180        $this_id = $this->
getId();
 
  184        include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
 
  188        if ((
int) $testObjId > 0) {
 
  189            $clone->setObjId($testObjId);
 
  210        $clone->copyPageOfQuestion($this_id);
 
  212        $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
 
  214        $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
 
  224        if ($this->
id <= 0) {
 
  230        include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
 
  233        $source_questionpool_id = $this->
getObjId();
 
  234        $clone->setObjId($target_questionpool_id);
 
  245        $clone->onCopy($source_questionpool_id, 
$original_id, $clone->getObjId(), $clone->getId());
 
  252        if ($this->
id <= 0) {
 
  257        include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
 
  260        $sourceParentId = $this->
getObjId();
 
  266        $clone->setObjId($targetParentId);
 
  268        if ($targetQuestionTitle) {
 
  269            $clone->setTitle($targetQuestionTitle);
 
  274        $clone->copyPageOfQuestion($sourceQuestionId);
 
  276        $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
 
  278        $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
 
  305        if ($returndetails) {
 
  306            throw new ilTestException(
'return details not implemented for ' . __METHOD__);
 
  310            if (is_null(
$pass)) {
 
  346        $this->lng->loadLanguageModule(
"form");
 
  348        $_FILES[
"upload"][
"name"] = rtrim($_FILES[
"upload"][
"name"], 
'/');
 
  351        $filename_arr = pathinfo($_FILES[
"upload"][
"name"]);
 
  352        $suffix = $filename_arr[
"extension"];
 
  353        $mimetype = $_FILES[
"upload"][
"type"];
 
  354        $size_bytes = $_FILES[
"upload"][
"size"];
 
  355        $temp_name = $_FILES[
"upload"][
"tmp_name"];
 
  356        $error = $_FILES[
"upload"][
"error"];
 
  366                case UPLOAD_ERR_INI_SIZE:
 
  371                case UPLOAD_ERR_FORM_SIZE:
 
  376                case UPLOAD_ERR_PARTIAL:
 
  381                case UPLOAD_ERR_NO_FILE:
 
  386                case UPLOAD_ERR_NO_TMP_DIR:
 
  391                case UPLOAD_ERR_CANT_WRITE:
 
  396                case UPLOAD_ERR_EXTENSION:
 
  405            if (!strlen($suffix)) {
 
  417        if (strlen($temp_name)) {
 
  419            if ($vir[0] == 
false) {
 
  420                ilUtil::sendFailure($this->lng->txt(
"form_msg_file_virus_found") . 
"<br />" . $vir[1], 
true);
 
  432        if (is_null($question_id)) {
 
  433            $question_id = $this->
getId();
 
  435        return CLIENT_WEB_DIR . 
"/assessment/tst_$test_id/$active_id/$question_id/files/";
 
  443        return CLIENT_WEB_DIR . 
"/assessment/qst_preview/$userId/{$this->getId()}/fileuploads/";
 
  453        if (is_null($question_id)) {
 
  454            $question_id = $this->
getId();
 
  456        include_once 
"./Services/Utilities/classes/class.ilUtil.php";
 
  466        include_once 
"./Services/Utilities/classes/class.ilUtil.php";
 
  481        if (is_null(
$pass)) {
 
  486            "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",
 
  487            array(
"integer", 
"integer", 
"integer", 
'integer'),
 
  488            array($active_id, $this->
getId(), 
$pass, (
int) $authorized)
 
  494            array_push($found, 
$data);
 
  517            "SELECT test_fi FROM tst_active WHERE active_id = %s",
 
  525            foreach ($found as $idx => 
$data) {
 
  526                $found[$idx][
'webpath'] = $path;
 
  544        foreach ($files as $solution_id) {
 
  546                "SELECT * FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
 
  547                array(
"integer", 
'integer'),
 
  548                array($solution_id, (
int) $authorized)
 
  553                $active_id = 
$data[
'active_fi'];
 
  557        foreach ($files as $solution_id) {
 
  558            $affectedRows = 
$ilDB->manipulateF(
 
  559                "DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
 
  560                array(
"integer", 
'integer'),
 
  561                array($solution_id, $authorized)
 
  573    protected function deleteUnusedFiles(
$test_id, $active_id, 
$pass)
 
  578        $solutions = array_merge(
 
  585        $used_files = array();
 
  586        foreach ($solutions as $solution) {
 
  587            $used_files[] = $solution[
'value1'];
 
  593        if (is_dir($uploadPath) && is_readable($uploadPath)) {
 
  594            $iter = new \RegexIterator(
new \DirectoryIterator($uploadPath), 
'/^file_' . $active_id . 
'_' . 
$pass . 
'_(.*)/');
 
  595            foreach ($iter as $file) {
 
  597                if ($file->isFile() && !in_array($file->getFilename(), $used_files)) {
 
  598                    unlink($file->getPathname());
 
  607        foreach ($files as 
$name) {
 
  608            if (isset($userSolution[
$name])) {
 
  609                unset($userSolution[
$name]);
 
  614        return $userSolution;
 
  626            $max_filesize = sprintf(
"%d Bytes", 
$size);
 
  627        } elseif (
$size < 1024 * 1024) {
 
  628            $max_filesize = sprintf(
"%.1f KB", 
$size / 1024);
 
  630            $max_filesize = sprintf(
"%.1f MB", 
$size / 1024 / 1024);
 
  633        return $max_filesize;
 
  647            $umf = get_cfg_var(
"upload_max_filesize");
 
  649            $pms = get_cfg_var(
"post_max_size");
 
  652            $multiplier_a = array(
"K" => 1024, 
"M" => 1024 * 1024, 
"G" => 1024 * 1024 * 1024);
 
  654            $umf_parts = preg_split(
"/(\d+)([K|G|M])/", $umf, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
 
  655            $pms_parts = preg_split(
"/(\d+)([K|G|M])/", $pms, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
 
  657            if (count($umf_parts) == 2) {
 
  658                $umf = $umf_parts[0] * $multiplier_a[$umf_parts[1]];
 
  660            if (count($pms_parts) == 2) {
 
  661                $pms = $pms_parts[0] * $multiplier_a[$pms_parts[1]];
 
  665            $max_filesize = min($umf, $pms);
 
  667            if (!$max_filesize) {
 
  668                $max_filesize = max($umf, $pms);
 
  670            return $max_filesize;
 
  692        $entered_values = 
false;
 
  694        $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use (&$entered_values, $uploadHandlingRequired, 
$test_id, $active_id, 
$pass, $authorized) {
 
  695            if ($authorized == 
false) {
 
  701                    foreach (
$_POST[self::DELETE_FILES_TBL_POSTVAR] as $solution_id) {
 
  709                    foreach (
$_POST[self::REUSE_FILES_TBL_POSTVAR] as $solutionId) {
 
  723                if ($uploadHandlingRequired) {
 
  728                    $solutionFileVersioningUploadTS = time();
 
  729                    $filename_arr = pathinfo($_FILES[
"upload"][
"name"]);
 
  730                    $extension = $filename_arr[
"extension"];
 
  731                    $newfile = 
"file_" . $active_id . 
"_" . 
$pass . 
"_" . $solutionFileVersioningUploadTS . 
"." . $extension;
 
  733                    include_once 
'Services/Utilities/classes/class.ilFileUtils.php';
 
  745                        $solutionFileVersioningUploadTS
 
  748                    $entered_values = 
true;
 
  764        if ($entered_values) {
 
  765            include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
 
  770            include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
 
  791        if (!count($solution)) {
 
  795            foreach ($solution as $row) {
 
  796                if (!empty($row[
'value1'])) {
 
  800            $solution = $cleaned;
 
  820        $result = parent::removeIntermediateSolution($active_id, 
$pass);
 
  838        if (!is_array($userSolution)) {
 
  839            $userSolution = array();
 
  862                    $filename_arr = pathinfo($_FILES[
"upload"][
"name"]);
 
  863                    $extension = $filename_arr[
"extension"];
 
  864                    $newfile = 
"file_" . md5($_FILES[
"upload"][
"name"]) . 
"_" . $version . 
"." . $extension;
 
  867                    $userSolution[$newfile] = array(
 
  868                        'solution_id' => $newfile,
 
  869                        'value1' => $newfile,
 
  870                        'value2' => $_FILES[
'upload'][
'name'],
 
  871                        'tstamp' => $version,
 
  910            include_once 
'Modules/Test/classes/class.ilObjTestAccess.php';
 
  911            include_once 
'Services/Tracking/classes/class.ilLPStatusWrapper.php';
 
  926        return "assFileUpload";
 
  936        return "qpl_qst_fileupload";
 
  964        $text = parent::getRTETextWithMediaObjects();
 
  973        parent::setExportDetailsXLS($worksheet, $startrow, $active_id, 
$pass);
 
  977        foreach ($solutions as $solution) {
 
  978            $worksheet->setCell($startrow + 
$i, 0, $this->lng->txt(
"result"));
 
  979            $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + 
$i));
 
  980            if (strlen($solution[
"value1"])) {
 
  981                $worksheet->setCell($startrow + 
$i, 2, $solution[
"value1"]);
 
  982                $worksheet->setCell($startrow + 
$i, 3, $solution[
"value2"]);
 
  987        return $startrow + 
$i + 1;
 
 1002    public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping, array $solutionhints = [])
 
 1004        include_once 
"./Modules/TestQuestionPool/classes/import/qti12/class.assFileUploadImport.php";
 
 1006        $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
 
 1015    public function toXML($a_include_header = 
true, $a_include_binary = 
true, $a_shuffle = 
false, $test_output = 
false, $force_image_references = 
false)
 
 1017        include_once 
"./Modules/TestQuestionPool/classes/export/qti12/class.assFileUploadExport.php";
 
 1019        return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
 
 1029        $user_solution = array();
 
 1030        return $user_solution;
 
 1050        $this->maxsize = $a_value;
 
 1060        if (strlen($this->allowedextensions)) {
 
 1061            return array_filter(array_map(
'trim', explode(
",", $this->allowedextensions)));
 
 1083        $this->allowedextensions = strtolower(trim($a_value));
 
 1095            case "allowedextensions":
 
 1098            case 'completion_by_submission':
 
 1102                return parent::__get($value);
 
 1116            case "allowedextensions":
 
 1119            case 'completion_by_submission':
 
 1123                parent::__set($key, $value);
 
 1140                SELECT tst_solutions.solution_id 
 1141                FROM tst_solutions, tst_active, qpl_questions 
 1142                WHERE tst_solutions.active_fi = tst_active.active_id 
 1143                AND tst_solutions.question_fi = qpl_questions.question_id 
 1144                AND tst_solutions.question_fi = %s AND tst_active.test_fi = %s 
 1145                AND tst_solutions.value1 is not null";
 
 1148            array(
"integer", 
"integer"),
 
 1169        require_once 
'Modules/TestQuestionPool/classes/class.ilAssFileUploadUploadsExporter.php';
 
 1172        $exporter->setRefId($ref_id);
 
 1174        $exporter->setTestTitle($test_title);
 
 1175        $exporter->setQuestion($this);
 
 1180            $exporter->getFinalZipFilePath(),
 
 1181            $exporter->getDispoZipFileName(),
 
 1182            $exporter->getZipFileMimeType(),
 
 1212        $this->completion_by_submission = (bool) $bool;
 
 1231        return $numExistingSolutionRecords > 0;
 
 1266        return parent::buildTestPresentationConfig()
 
 1268            ->setFormChangeDetectionEnabled(
false);
 
 1278        require_once 
'Modules/TestQuestionPool/classes/questions/class.ilAssFileUploadFileTableDeleteButton.php';
 
 1319        if (!isset($_FILES[
'upload'])) {
 
 1323        if (!isset($_FILES[
'upload'][
'tmp_name'])) {
 
 1327        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.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping, array $solutionhints=[])
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