4include_once 
"./Modules/Test/classes/inc.AssessmentConstants.php";
 
   27                self::IMG_MIME_TYPE_JPG => array(
'jpg', 
'jpeg'),
 
   28                self::IMG_MIME_TYPE_PNG => array(
'png'),
 
   29                self::IMG_MIME_TYPE_GIF => array(
'gif')
 
   33                self::IMG_MIME_TYPE_JPG => array(
'binary'),
 
   34                self::IMG_MIME_TYPE_PNG => array(
'binary'),
 
   35                self::IMG_MIME_TYPE_GIF => array(
'binary')
 
  273                'image/jpeg' => array(
'jpg', 
'jpeg'), 
'image/png' => array(
'png'), 
'image/gif' => array(
'gif')
 
  301                $this->original_id = 
null;
 
  309                        $this->author = $this->
ilias->account->fullname;
 
  312                if ($this->owner <= 0)
 
  314                        $this->owner = $this->
ilias->account->id;
 
  318                $this->suggested_solutions = array();
 
  320                $this->nr_of_tries = 0;
 
  322                $this->arrData = array();
 
  325                $this->questionActionCmd = 
'handleQuestionAction';
 
  327                $this->lastChange = 
null;
 
  329                require_once 
'Services/Randomization/classes/class.ilArrayElementOrderKeeper.php';
 
  347                return (
bool)count(self::getAllowedFileExtensionsForMimeType($mimeType));
 
  352                return current(explode(
';', $contentTypeString));
 
  357                foreach(self::$allowedFileExtensionsByMimeType as $allowedMimeType => $extensions)
 
  359                        $rexCharsets = implode(
'|', self::$allowedCharsetsByMimeType[$allowedMimeType]);
 
  360                        $rexMimeType = preg_quote($allowedMimeType, 
'/');
 
  362                        $rex = 
'/^'.$rexMimeType.
'(;(\s)*charset=('.$rexCharsets.
'))*$/';
 
  364                        if( !preg_match($rex, $mimeType) )
 
  378                        strtolower($fileExtension), self::getAllowedFileExtensionsForMimeType($mimeType)
 
  389                if( !isset(
$_POST[
'cmd']) || !isset(
$_POST[
'cmd'][$this->questionActionCmd]) )
 
  394                if( !is_array(
$_POST[
'cmd'][$this->questionActionCmd]) || !count(
$_POST[
'cmd'][$this->questionActionCmd]) )
 
  399                return key(
$_POST[
'cmd'][$this->questionActionCmd]);
 
  408                if( !isset(
$_POST[$postSubmissionFieldname]) )
 
  413                if( !is_array(
$_POST[$postSubmissionFieldname]) )
 
  418                if( !count(
$_POST[$postSubmissionFieldname]) )
 
  448                require_once 
'Modules/Test/classes/class.ilObjTest.php';
 
  460                $result = 
$ilDB->queryF(
"SELECT test_fi FROM tst_active WHERE active_id = %s",
 
  461                        array(
'integer'), array($active_id)
 
  466                        return $row[
"test_fi"];
 
  477        protected function log($active_id, $langVar)
 
  491                $extensions = array();
 
  493                foreach (self::$allowedImageMaterialFileExtensionsByMimeType as $mimeType => $mimeExtensions)
 
  495                        $extensions = array_merge($extensions, $mimeExtensions);
 
  497                return array_unique($extensions);
 
  543        function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
 
  545                include_once 
"./Modules/TestQuestionPool/classes/import/qti12/class." . $this->
getQuestionType() . 
"Import.php";
 
  547                $import = 
new $classname($this);
 
  548                $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
 
  557        function toXML($a_include_header = 
true, $a_include_binary = 
true, $a_shuffle = 
false, $test_output = 
false, $force_image_references = 
false)
 
  559                include_once 
"./Modules/TestQuestionPool/classes/export/qti12/class." . $this->
getQuestionType() . 
"Export.php";
 
  561                $export = 
new $classname($this);
 
  562                return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
 
  587                $result = 
$ilDB->queryF(
"SELECT * FROM qpl_questions WHERE obj_fi = %s AND title = %s",
 
  588                        array(
'integer',
'text'),
 
  589                        array($questionpool_id, 
$title)
 
  591                return (
$result->numRows() > 0) ? TRUE : FALSE;
 
  627                $this->test_id = 
$id;
 
  686                $this->est_working_time = array(
"h" => (
int)$hour, 
"m" => (
int)$min, 
"s" => (
int)$sec);
 
  697                $this->est_working_time = array(
 
  698                        'h' => (
int)substr($durationString, 0, 2),
 
  699                        'm' => (
int)substr($durationString, 3, 2),
 
  700                        's' => (
int)substr($durationString, 6, 2)
 
  715                        foreach ($array as $key => $value)
 
  717                                if (strcmp($key, $searchkey)==0)
 
  773                require_once 
'Services/Utilities/classes/class.ilUtil.php';
 
  867                if (!$this->est_working_time)
 
  869                        $this->est_working_time = array(
"h" => 0, 
"m" => 0, 
"s" => 0);
 
  935                if(!strlen($this->external_id))
 
  937                        if($this->
getId() > 0)
 
  939                                return 'il_' . IL_INST_ID . 
'_qst_' . $this->
getId();
 
  943                                return uniqid(
'', 
true);
 
  963                $result = 
$ilDB->queryF(
"SELECT points FROM qpl_questions WHERE question_id = %s",
 
  985                $result = 
$ilDB->queryF(
"SELECT qpl_questions.*, qpl_qst_type.type_tag FROM qpl_qst_type, qpl_questions WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
 
 1006                $result = 
$ilDB->queryF(
"SELECT suggested_solution_id FROM qpl_sol_sug WHERE question_fi = %s",
 
 1023                return $question->getSuggestedSolutionOutput();
 
 1029                foreach ($this->suggested_solutions as $solution)
 
 1031                        switch ($solution[
"type"])
 
 1040                                        $possible_texts = array_values(array_filter(array(
 
 1043                                                $this->lng->txt(
'tst_show_solution_suggested')
 
 1046                                        require_once 
'Services/WebAccessChecker/classes/class.ilWACSignedPath.php';
 
 1051                                        $solutionValue = $solution[
"value"];
 
 1052                                        $solutionValue = $this->
fixSvgToPng($solutionValue);
 
 1058                return join(
$output, 
"<br />");
 
 1073                $result = 
$ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
 
 1074                        array(
'integer',
'integer'),
 
 1075                        array($question_id, $subquestion_index)
 
 1081                                "internal_link" => 
$row[
"internal_link"],
 
 1082                                "import_id" => 
$row[
"import_id"]
 
 1115                        include_once 
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
 
 1118                $result = 
$ilDB->queryF(
"SELECT * FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
 
 1119                        array(
'integer',
'integer',
'integer'),
 
 1120                        array($active_id, $question_id, 
$pass)
 
 1140                return round(self::_getReachedPoints($active_id, $this->
getId(), 
$pass), 2);
 
 1169                    include_once 
"./Modules/Test/classes/class.ilObjTest.php";
 
 1179            require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
 
 1181            $requestsStatisticData = $hintTracking->getRequestStatisticDataByQuestionAndTestpass();
 
 1182            $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
 
 1187            return $reached_points;
 
 1203                if( is_null(
$pass) )
 
 1205                        include_once 
"./Modules/Test/classes/class.ilObjTest.php";
 
 1213                require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
 
 1215                $requestsStatisticData = $questionHintTracking->getRequestStatisticDataByQuestionAndTestpass();
 
 1216                $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
 
 1230                if( is_null($reached_points) ) $reached_points = 0;
 
 1233                $existingSolutions = $this->lookupForExistingSolutions($active_id, 
$pass);
 
 1235                $this->
getProcessLocker()->executeUserQuestionResultUpdateOperation(
function() use(
$ilDB, $active_id, 
$pass, $reached_points, $requestsStatisticData, $isAnswered, $existingSolutions) {
 
 1238                        DELETE FROM             tst_test_result 
 1240                        WHERE                   active_fi = %s 
 1241                        AND                             question_fi = %s 
 1245                        $types = array(
'integer', 
'integer', 
'integer');
 
 1246                        $values = array($active_id, $this->
getId(), 
$pass);
 
 1248                        if( $this->
getStep() !== NULL )
 
 1254                                $types[] = 
'integer';
 
 1257                        $ilDB->manipulateF(
$query, $types, $values);
 
 1259                        if ($existingSolutions[
'authorized'])
 
 1261                                $next_id = 
$ilDB->nextId(
"tst_test_result");
 
 1263                                        'test_result_id'        => array(
'integer', $next_id),
 
 1264                                        'active_fi'                     => array(
'integer', $active_id),
 
 1265                                        'question_fi'           => array(
'integer', $this->
getId()),
 
 1266                                        'pass'                          => array(
'integer', 
$pass),
 
 1267                                        'points'                        => array(
'float', $reached_points),
 
 1268                                        'tstamp'                        => array(
'integer', time()),
 
 1269                                        'hint_count'            => array(
'integer', $requestsStatisticData->getRequestsCount()),
 
 1270                                        'hint_points'           => array(
'float', $requestsStatisticData->getRequestsPoints()),
 
 1271                                        'answered'                      => array(
'integer', $isAnswered)
 
 1274                                if( $this->
getStep() !== NULL )
 
 1276                                        $fieldData[
'step'] = array(
'integer', $this->
getStep());
 
 1279                                $ilDB->insert(
'tst_test_result', $fieldData);
 
 1285                include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
 
 1305                include_once 
'Modules/Course/classes/class.ilCourseObjectiveResult.php';
 
 1319                if( 
$pass === 
null )
 
 1321                        require_once 
'Modules/Test/classes/class.ilObjTest.php';
 
 1330                $saveStatus = 
false;
 
 1332                $this->
getProcessLocker()->executePersistWorkingStateLockOperation(
function() use ($active_id, 
$pass, $authorized, $obligationsEnabled, &$saveStatus) {
 
 1396                include_once 
"./Modules/Test/classes/class.ilObjTest.php";
 
 1397                include_once 
"./Modules/Test/classes/class.assMarkSchema.php";
 
 1402                        SELECT          tst_pass_result.* 
 1403                        FROM            tst_pass_result 
 1404                        WHERE           active_fi = %s 
 1409                        $query, array(
'integer',
'integer'), array($active_id, 
$pass)
 
 1414                $max = 
$row[
'maxpoints'];
 
 1415                $reached = 
$row[
'points'];
 
 1417                $obligationsAnswered = (int)
$row[
'obligations_answered'];
 
 1419                include_once 
"./Modules/Test/classes/class.assMarkSchema.php";
 
 1421                $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
 
 1423                $mark = ASS_MarkSchema::_getMatchingMarkFromActiveId($active_id, $percentage);
 
 1425                $isPassed = (  $mark[
"passed"] ? 1 : 0 );
 
 1426                $isFailed = ( !$mark[
"passed"] ? 1 : 0 );
 
 1428                $userTestResultUpdateCallback = 
function() use (
$ilDB, $active_id, 
$pass, $max, $reached, $isFailed, $isPassed, $obligationsAnswered, 
$row, $mark) {
 
 1431                                DELETE FROM             tst_result_cache 
 1432                                WHERE                   active_fi = %s 
 1435                                $query, array(
'integer'), array($active_id)
 
 1438                        $ilDB->insert(
'tst_result_cache', array(
 
 1439                                'active_fi'=> array(
'integer', $active_id),
 
 1440                                'pass'=> array(
'integer', strlen(
$pass) ? 
$pass : 0),
 
 1441                                'max_points'=> array(
'float', strlen($max) ? $max : 0),
 
 1442                                'reached_points'=> array(
'float', strlen($reached) ? $reached : 0),
 
 1443                                'mark_short'=> array(
'text', strlen($mark[
"short_name"]) ? $mark[
"short_name"] : 
" "),
 
 1444                                'mark_official'=> array(
'text', strlen($mark[
"official_name"]) ? $mark[
"official_name"] : 
" "),
 
 1445                                'passed'=> array(
'integer', $isPassed),
 
 1446                                'failed'=> array(
'integer', $isFailed),
 
 1447                                'tstamp'=> array(
'integer', time()),
 
 1448                                'hint_count'=> array(
'integer', 
$row[
'hint_count']),
 
 1449                                'hint_points'=> array(
'float', 
$row[
'hint_points']),
 
 1450                                'obligations_answered' => array(
'integer', $obligationsAnswered)
 
 1457                        $processLocker->executeUserTestResultUpdateLockOperation($userTestResultUpdateCallback);
 
 1461                        $userTestResultUpdateCallback();
 
 1470                include_once 
"./Modules/Test/classes/class.ilObjTest.php";
 
 1472                if( self::getResultGateway() !== 
null )
 
 1487                        SELECT          SUM(points) reachedpoints, 
 1488                                                SUM(hint_count) hint_count, 
 1489                                                SUM(hint_points) hint_points, 
 1490                                                COUNT(DISTINCT(question_fi)) answeredquestions 
 1491                        FROM            tst_test_result 
 1492                        WHERE           active_fi = %s 
 1495                        array(
'integer',
'integer'),
 
 1496                        array($active_id, 
$pass)
 
 1501                        if( $obligationsEnabled )
 
 1504                                        SELECT          answered answ 
 1505                                        FROM            tst_test_question 
 1506                                          INNER JOIN    tst_active 
 1508                                                AND                     tst_test_question.test_fi = tst_active.test_fi 
 1509                                        LEFT JOIN       tst_test_result 
 1510                                                ON                      tst_test_result.active_fi = %s 
 1511                                                AND                     tst_test_result.pass = %s 
 1512                                                AND                     tst_test_question.question_fi = tst_test_result.question_fi 
 1513                                        WHERE           obligatory = 1';
 
 1515                                $result_obligatory = 
$ilDB->queryF(
 
 1516                                        $query, array(
'integer',
'integer',
'integer'), array($active_id, $active_id, 
$pass)
 
 1519                                $obligations_answered = 1;
 
 1521                                while($row_obligatory = 
$ilDB->fetchAssoc($result_obligatory))
 
 1523                                        if(!(
int)$row_obligatory[
'answ'])
 
 1525                                                $obligations_answered = 0;
 
 1532                                $obligations_answered = 1;
 
 1537                        if( 
$row[
'hint_count'] === 
null ) 
$row[
'hint_count'] = 0;
 
 1538                        if( 
$row[
'hint_points'] === 
null ) 
$row[
'hint_points'] = 0;
 
 1542                        $updatePassResultCallback = 
function() use (
$ilDB, 
$data, $active_id, 
$pass, 
$row, $time, $obligations_answered, $exam_identifier) {
 
 1545                                $ilDB->replace(
'tst_pass_result',
 
 1547                                                'active_fi' => array(
'integer', $active_id),
 
 1548                                                'pass'      => array(
'integer', strlen(
$pass) ? 
$pass : 0)),
 
 1550                                                'points'               => array(
'float', 
$row[
'reachedpoints'] ? 
$row[
'reachedpoints'] : 0),
 
 1551                                                'maxpoints'            => array(
'float', 
$data[
'points']),
 
 1552                                                'questioncount'        => array(
'integer', 
$data[
'count']),
 
 1553                                                'answeredquestions'    => array(
'integer', 
$row[
'answeredquestions']),
 
 1554                                                'workingtime'          => array(
'integer', $time),
 
 1555                                                'tstamp'               => array(
'integer', time()),
 
 1556                                                'hint_count'           => array(
'integer', 
$row[
'hint_count']),
 
 1557                                                'hint_points'          => array(
'float', 
$row[
'hint_points']),
 
 1558                                                'obligations_answered' => array(
'integer', $obligations_answered),
 
 1559                                                'exam_id'              => array(
'text', $exam_identifier)
 
 1567                                $processLocker->executeUserPassResultUpdateLockOperation($updatePassResultCallback);
 
 1571                                $updatePassResultCallback();
 
 1578                        'active_fi' => $active_id,
 
 1580                        'points' => (
$row[
"reachedpoints"]) ? 
$row[
"reachedpoints"] : 0,
 
 1581                        'maxpoints' => 
$data[
"points"],
 
 1582                        'questioncount' => 
$data[
"count"],
 
 1583                        'answeredquestions' => 
$row[
"answeredquestions"],
 
 1584                        'workingtime' => $time,
 
 1586                        'hint_count' => 
$row[
'hint_count'],
 
 1587                        'hint_points' => 
$row[
'hint_points'],
 
 1588                        'obligations_answered' => $obligations_answered,
 
 1589                        'exam_id' => $exam_identifier
 
 1600        public static function logAction($logtext = 
"", $active_id = 
"", $question_id = 
"")
 
 1603                if( strlen($question_id) )
 
 1608                require_once 
'Modules/Test/classes/class.ilObjAssessmentFolder.php';
 
 1609                require_once 
'Modules/Test/classes/class.ilObjTest.php';
 
 1629                $mediatempdir = CLIENT_WEB_DIR . 
"/assessment/temp";
 
 1631                $temp_name = tempnam($mediatempdir, $name . 
"_____");
 
 1632                $temp_name = str_replace(
"\\", 
"/", $temp_name);
 
 1633                @unlink($temp_name);
 
 1650                return CLIENT_WEB_DIR . 
"/assessment/$this->obj_id/$this->id/solution/";
 
 1660                return CLIENT_WEB_DIR . 
"/assessment/$this->obj_id/$this->id/java/";
 
 1671                if( $question_id === 
null)
 
 1676                if( $object_id === 
null)
 
 1686                return CLIENT_WEB_DIR . 
"/assessment/{$parentObjectId}/{$questionId}/images/";
 
 1697                return CLIENT_WEB_DIR . 
"/assessment/$this->obj_id/$this->id/flash/";
 
 1708                include_once 
"./Services/Utilities/classes/class.ilUtil.php";
 
 1720                include_once 
"./Services/Utilities/classes/class.ilUtil.php";
 
 1735                if(!$this->export_image_path)
 
 1737                        include_once 
"./Services/Utilities/classes/class.ilUtil.php";
 
 1755                include_once 
"./Services/Utilities/classes/class.ilUtil.php";
 
 1778                if( !count($solution) )
 
 1798                if( $this->
getStep() !== NULL )
 
 1803                                WHERE active_fi = %s 
 1804                                AND question_fi = %s 
 1808                                ORDER BY solution_id";
 
 1810                        $result = 
$ilDB->queryF(
$query, array(
'integer', 
'integer', 
'integer', 
'integer', 
'integer'),
 
 1811                                array($active_id, $this->
getId(), $pass, $this->
getStep(), (
int)$authorized)
 
 1819                                WHERE active_fi = %s 
 1820                                AND question_fi = %s  
 1823                                ORDER BY solution_id 
 1827                                array($active_id, $this->
getId(), $pass, (
int)$authorized)
 
 1851                if ($question_id < 1) $question_id = $this->
getId();
 
 1852                $result = $ilDB->queryF(
"SELECT COUNT(qpl_questions.question_id) question_count FROM qpl_questions, tst_test_question WHERE qpl_questions.original_id = %s AND qpl_questions.question_id = tst_test_question.question_fi",
 
 1857                $count = 
$row[
"question_count"];
 
 1860                        SELECT tst_active.test_fi 
 1862                        INNER JOIN tst_test_rnd_qst ON tst_test_rnd_qst.question_fi = qpl_questions.question_id 
 1863                        INNER JOIN tst_active ON tst_active.active_id = tst_test_rnd_qst.active_fi 
 1864                        WHERE qpl_questions.original_id = %s 
 1865                        GROUP BY tst_active.test_fi",
 
 1884                if ($question_id < 1) $question_id = 
$this->id;
 
 1885                $result = 
$ilDB->queryF(
"SELECT original_id FROM qpl_questions WHERE question_id = %s",
 
 1890                return (
$row[
"original_id"] > 0) ? TRUE : FALSE;
 
 1901                $keys = array_keys($array);
 
 1904                foreach ($keys as $key)
 
 1920                $result = 
$ilDB->queryF(
"SELECT qpl_qst_type.type_tag FROM qpl_qst_type, qpl_questions WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
 
 1925                return $data[
"type_tag"];
 
 1961                if( !is_array($answer_table_name) )
 
 1963                        $answer_table_name = array($answer_table_name);
 
 1966                foreach ($answer_table_name as $table)
 
 1970                                $affectedRows = 
$ilDB->manipulateF(
"DELETE FROM $table WHERE question_fi = %s",
 
 1990                if( !is_array($additional_table_name) )
 
 1992                        $additional_table_name = array($additional_table_name);
 
 1995                foreach ($additional_table_name as $table)
 
 1999                                $affectedRows = 
$ilDB->manipulateF(
"DELETE FROM $table WHERE question_fi = %s",
 
 2015                include_once 
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
 
 2027        public function delete($question_id)
 
 2031                if ($question_id < 1) 
return true; 
 
 2033                $result = 
$ilDB->queryF(
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
 
 2050                catch (Exception $e)
 
 2052                        $ilLog->write(
"EXCEPTION: Could not delete page of question $question_id: $e");
 
 2056                $affectedRows = 
$ilDB->manipulateF(
"DELETE FROM qpl_questions WHERE question_id = %s",
 
 2060                if ($affectedRows == 0) 
return false;
 
 2069                catch (Exception $e)
 
 2071                        $ilLog->write(
"EXCEPTION: Could not delete additional table data of question $question_id: $e");
 
 2078                        $affectedRows = 
$ilDB->manipulateF(
"DELETE FROM tst_test_question WHERE question_fi = %s", 
 
 2083                catch (Exception $e)
 
 2085                        $ilLog->write(
"EXCEPTION: Could not delete delete question $question_id from a test: $e");
 
 2092                        $affectedRows = 
$ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s", 
 
 2097                catch (Exception $e)
 
 2099                        $ilLog->write(
"EXCEPTION: Could not delete suggested solutions of question $question_id: $e");
 
 2105                        $directory = CLIENT_WEB_DIR . 
"/assessment/" . 
$obj_id . 
"/$question_id";
 
 2106                        if (preg_match(
"/\d+/", 
$obj_id) and preg_match(
"/\d+/", $question_id) and is_dir($directory))
 
 2108                                include_once 
"./Services/Utilities/classes/class.ilUtil.php";
 
 2112                catch (Exception $e)
 
 2114                        $ilLog->write(
"EXCEPTION: Could not delete question file directory $directory of question $question_id: $e");
 
 2120                        include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
 
 2126                        foreach(
$mobs as $mob)
 
 2136                catch (Exception $e)
 
 2138                        $ilLog->write(
"EXCEPTION: Error deleting the media objects of question $question_id: $e");
 
 2142                require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
 
 2143                ilAssQuestionHintTracking::deleteRequestsByQuestionIds(array($question_id));
 
 2145                require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
 
 2148                require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
 
 2150                $assignmentList->setParentObjId(
$obj_id);
 
 2151                $assignmentList->setQuestionIdFilter($question_id);
 
 2152                $assignmentList->loadFromDb();
 
 2153                foreach($assignmentList->getAssignmentsByQuestionId($question_id) as $assignment)
 
 2156                        $assignment->deleteFromDb();
 
 2164                        include_once 
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
 
 2167                catch (Exception $e)
 
 2169                        $ilLog->write(
"EXCEPTION: Error updating the question pool question count of question pool " . $this->
getObjId() . 
" when deleting question $question_id: $e");
 
 2180                require_once 
'Services/Taxonomy/classes/class.ilObjTaxonomy.php';
 
 2181                require_once 
'Services/Taxonomy/classes/class.ilTaxNodeAssignment.php';
 
 2184                foreach($taxIds as $taxId)
 
 2187                        $taxNodeAssignment->deleteAssignmentsOfItem($this->
getId());
 
 2210                $result = 
$ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
 
 2211                        array(
'integer',
'integer'),
 
 2212                        array($a_q_id, $a_q_id)
 
 2218                $found_id = array();
 
 2221                        array_push($found_id, 
$row[
"question_id"]);
 
 2224                $result = 
$ilDB->query(
"SELECT * FROM tst_test_result WHERE " . 
$ilDB->in(
'question_fi', $found_id, 
false, 
'integer'));
 
 2239                $result = 
$ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
 
 2240                        array(
'integer',
'integer'),
 
 2241                        array($a_q_id, $a_q_id)
 
 2247                $found_id = array();
 
 2250                        array_push($found_id, 
$row[
"question_id"]);
 
 2252                $result = 
$ilDB->query(
"SELECT * FROM tst_test_result WHERE " . 
$ilDB->in(
'question_fi', $found_id, 
false, 
'integer'));
 
 2256                        $reached = 
$row[
"points"]; 
 
 2257                        include_once 
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
 
 2259                        array_push($answers, array(
"reached" => $reached, 
"max" => $max));
 
 2263                foreach ($answers as $key => $value)
 
 2265                        $max += $value[
"max"];
 
 2266                        $reached += $value[
"reached"];
 
 2270                        return $reached / $max;
 
 2286                $result = 
$ilDB->queryF(
"SELECT title FROM qpl_questions WHERE question_id = %s",
 
 2293                        return $row[
"title"];
 
 2309                $result = 
$ilDB->queryF(
"SELECT question_text FROM qpl_questions WHERE question_id = %s",
 
 2316                        return $row[
"question_text"];
 
 2326                if( !file_exists(
$file) )
 
 2331                if( !is_file(
$file) )
 
 2336                if( !is_readable(
$file) )
 
 2346                include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
 
 2348                foreach (
$mobs as $mob)
 
 2356                include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
 
 2358                foreach (
$mobs as $mob)
 
 2371                include_once 
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
 
 2373                $this->page->setId($this->
getId());
 
 2374                $this->page->setParentId($qpl_id);
 
 2375                $this->page->setXMLContent(
"<PageObject><PageContent>".
 
 2376                        "<Question QRef=\"il__qst_".$this->
getId().
"\"/>".
 
 2377                        "</PageContent></PageObject>");
 
 2378                $this->page->create();
 
 2385                        include_once 
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
 
 2388                        $xml = str_replace(
"il__qst_".$a_q_id, 
"il__qst_".$this->
id, 
$page->getXMLContent());
 
 2389                        $this->page->setXMLContent($xml);
 
 2390                        $this->page->updateFromXML();
 
 2396                include_once 
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
 
 2398                return $page->getXMLContent();
 
 2410                if ($question_id < 1) 
return "";
 
 2411                $result = 
$ilDB->queryF(
"SELECT type_tag FROM qpl_questions, qpl_qst_type WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
 
 2418                        return $data[
"type_tag"];
 
 2437                if ($question_id < 1) 
return "";
 
 2439                $result = 
$ilDB->queryF(
"SELECT title FROM qpl_questions WHERE qpl_questions.question_id = %s",
 
 2446                        return $data[
"title"];
 
 2465                'ok.svg' => 
'ok.png', 
'not_ok.svg' => 
'not_ok.png',
 
 2466                'checkbox_checked.svg' => 
'checkbox_checked.png',
 
 2467                'checkbox_unchecked.svg' => 
'checkbox_unchecked.png',
 
 2468                'radiobutton_checked.svg' => 
'radiobutton_checked.png',
 
 2469                'radiobutton_unchecked.svg' => 
'radiobutton_unchecked.png' 
 2474                $needles = array_keys(self::$imageSourceFixReplaceMap);
 
 2475                $replacements = array_values(self::$imageSourceFixReplaceMap);
 
 2476                return str_replace($needles, $replacements, $imageFilenameContainingString);
 
 2483                if( preg_match_all(
'/src="(.*?)"/m', 
$html, $matches) )
 
 2485                        $sources = $matches[1];
 
 2487                        $needleReplacementMap = array();
 
 2489                        foreach($sources as $src)
 
 2493                                if( file_exists(
$file) )
 
 2498                                $levels = explode(DIRECTORY_SEPARATOR, $src);
 
 2499                                if( count($levels) < 5 || $levels[0] != 
'Customizing' || $levels[2] != 
'skin' )
 
 2506                                if( $levels[4] == 
'Modules' || $levels[4] == 
'Services' )
 
 2508                                        $component = $levels[4] . DIRECTORY_SEPARATOR . $levels[5];
 
 2514                        if( count($needleReplacementMap) )
 
 2516                                $html = str_replace(array_keys($needleReplacementMap), array_values($needleReplacementMap), 
$html);
 
 2534                        "SELECT external_id FROM qpl_questions WHERE question_id = %s",
 
 2541                        $this->external_id = 
$data[
'external_id'];
 
 2544                $result = 
$ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
 
 2546                        array($this->
getId())
 
 2548                $this->suggested_solutions = array();
 
 2551                        include_once(
"./Services/RTE/classes/class.ilRTE.php");
 
 2555                                $this->suggested_solutions[
$row[
"subquestion_index"]] = array(
 
 2556                                        "type" => 
$row[
"type"],
 
 2558                                        "internal_link" => 
$row[
"internal_link"],
 
 2559                                        "import_id" => 
$row[
"import_id"]
 
 2577                $estw_time = 
sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
 
 2591                        $next_id = 
$ilDB->nextId(
'qpl_questions');
 
 2592                        $affectedRows = 
$ilDB->insert(
"qpl_questions", array(
 
 2593                                "question_id" => array(
"integer", $next_id),
 
 2595                                "obj_fi" => array(
"integer", 
$obj_id),
 
 2596                                "title" => array(
"text", NULL),
 
 2597                                "description" => array(
"text", NULL),
 
 2598                                "author" => array(
"text", $this->
getAuthor()),
 
 2599                                "owner" => array(
"integer", 
$ilUser->getId()),
 
 2600                                "question_text" => array(
"clob", NULL),
 
 2601                                "points" => array(
"float", 0),
 
 2603                                "working_time" => array(
"text", $estw_time),
 
 2604                                "complete" => array(
"text", $complete),
 
 2605                                "created" => array(
"integer", time()),
 
 2606                                "original_id" => array(
"integer", NULL),
 
 2607                                "tstamp" => array(
"integer", $tstamp),
 
 2611                        $this->
setId($next_id);
 
 2622                return $this->
getId();
 
 2630                $estw_time = 
sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
 
 2633                include_once(
"./Services/RTE/classes/class.ilRTE.php");
 
 2634                if ($this->
getId() == -1)
 
 2637                        $next_id = 
$ilDB->nextId(
'qpl_questions');
 
 2638                        $affectedRows = 
$ilDB->insert(
"qpl_questions", array(
 
 2639                                "question_id" => array(
"integer", $next_id),
 
 2641                                "obj_fi" => array(
"integer", $this->
getObjId()),
 
 2642                                "title" => array(
"text", $this->
getTitle()),
 
 2643                                "description" => array(
"text", $this->
getComment()),
 
 2644                                "author" => array(
"text", $this->
getAuthor()),
 
 2645                                "owner" => array(
"integer", $this->
getOwner()),
 
 2648                                "working_time" => array(
"text", $estw_time),
 
 2649                                "nr_of_tries" => array(
"integer", $this->
getNrOfTries()),
 
 2650                                "created" => array(
"integer", time()),
 
 2652                                "tstamp" => array(
"integer", time()),
 
 2656                        $this->
setId($next_id);
 
 2663                        $affectedRows = 
$ilDB->update(
"qpl_questions", array(
 
 2664                                "obj_fi" => array(
"integer", $this->
getObjId()),
 
 2665                                "title" => array(
"text", $this->
getTitle()),
 
 2666                                "description" => array(
"text", $this->
getComment()),
 
 2667                                "author" => array(
"text", $this->
getAuthor()),
 
 2670                                "nr_of_tries" => array(
"integer", $this->
getNrOfTries()),
 
 2671                                "working_time" => array(
"text", $estw_time),
 
 2672                                "tstamp" => array(
"integer", time()),
 
 2673                                'complete' => array(
'integer', $this->
isComplete()),
 
 2676                        "question_id" => array(
"integer", $this->
getId())
 
 2691                $this->updateSuggestedSolutions();
 
 2703                $affectedRows = 
$ilDB->manipulateF(
"UPDATE qpl_questions SET tstamp = %s, owner = %s, complete = %s WHERE question_id = %s",
 
 2704                        array(
'integer',
'integer', 
'integer',
'text'),
 
 2705                        array(time(), ($this->
getOwner() <= 0) ? $this->
ilias->account->id : $this->getOwner(), $complete, $this->getId())
 
 2709                include_once 
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
 
 2724                $query = 
"UPDATE qpl_questions SET tstamp = %s, original_id = %s WHERE question_id = %s";
 
 2726                $GLOBALS[
'DIC'][
'ilDB']->manipulateF(
 
 2727                        $query, array(
'integer',
'integer', 
'text'), array(time(), $originalId, $questionId)
 
 2733                $query = 
"UPDATE qpl_questions SET tstamp = %s, original_id = NULL WHERE question_id = %s";
 
 2735                $GLOBALS[
'DIC'][
'ilDB']->manipulateF(
 
 2736                        $query, array(
'integer', 
'text'), array(time(), $questionId)
 
 2743        protected function onDuplicate($originalParentId, $originalQuestionId, $duplicateParentId, $duplicateQuestionId)
 
 2748                $this->feedbackOBJ->duplicateFeedback($originalQuestionId, $duplicateQuestionId);
 
 2765                $this->feedbackOBJ->syncFeedback($origQuestionId, $dupQuestionId);
 
 2771        protected function onCopy($sourceParentId, $sourceQuestionId, $targetParentId, $targetQuestionId)
 
 2776                $this->feedbackOBJ->duplicateFeedback($sourceQuestionId, $targetQuestionId);
 
 2792                $affectedRows = 
$ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s",
 
 2794                        array($this->
getId())
 
 2797                include_once 
"./Services/Link/classes/class.ilInternalLink.php";
 
 2799                $this->suggested_solutions = array();
 
 2812                if (array_key_exists($subquestion_index, $this->suggested_solutions))
 
 2814                        return $this->suggested_solutions[$subquestion_index];
 
 2832                if (array_key_exists($subquestion_index, $this->suggested_solutions))
 
 2834                        $title = $this->suggested_solutions[$subquestion_index][
"internal_link"];
 
 2855                if (strcmp($solution_id, 
"") != 0)
 
 2860                                $import_id = $solution_id;
 
 2863                        $this->suggested_solutions[$subquestion_index] = array(
 
 2864                                "internal_link" => $solution_id,
 
 2865                                "import_id" => $import_id
 
 2877                foreach ($this->suggested_solutions as $index => $solution)
 
 2879                        if (strcmp($solution[
"type"], 
"file") == 0)
 
 2882                                $filepath_original = str_replace(
 
 2883                                        "/{$this->obj_id}/{$this->id}/solution",
 
 2884                                        "/$parent_id/$question_id/solution",
 
 2887                                if (!file_exists($filepath))
 
 2896                                                $ilLog->write(
"File could not be duplicated!!!!", 
$ilLog->ERROR);
 
 2897                                                $ilLog->write(
"object: " . print_r($this, TRUE), 
$ilLog->ERROR);
 
 2912                $filepath_original = str_replace(
"/$this->id/solution", 
"/$original_id/solution", $filepath);
 
 2914                foreach ($this->suggested_solutions as $index => $solution)
 
 2916                        if (strcmp($solution[
"type"], 
"file") == 0)
 
 2918                                if (!file_exists($filepath_original))
 
 2927                                                $ilLog->write(
"File could not be duplicated!!!!", 
$ilLog->ERROR);
 
 2928                                                $ilLog->write(
"object: " . print_r($this, TRUE), 
$ilLog->ERROR);
 
 2939                foreach ($this->suggested_solutions as $index => $solution)
 
 2941                        if (strcmp($solution[
"type"], 
"file") == 0)
 
 2944                                $filepath_original = str_replace(
"/$this->obj_id/$this->id/solution", 
"/$source_questionpool_id/$source_question_id/solution", $filepath);
 
 2945                                if (!file_exists($filepath))
 
 2954                                                $ilLog->write(
"File could not be copied!!!!", 
$ilLog->ERROR);
 
 2955                                                $ilLog->write(
"object: " . print_r($this, TRUE), 
$ilLog->ERROR);
 
 2965        public function updateSuggestedSolutions(
$original_id = 
"")
 
 2970                include_once 
"./Services/Link/classes/class.ilInternalLink.php";
 
 2971                $affectedRows = 
$ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s",
 
 2976                include_once(
"./Services/RTE/classes/class.ilRTE.php");
 
 2977                foreach ($this->suggested_solutions as $index => $solution)
 
 2979                        $next_id = 
$ilDB->nextId(
'qpl_sol_sug');
 
 2981                        $ilDB->insert(
'qpl_sol_sug', array(
 
 2982                                                                                   'suggested_solution_id'      => array( 
'integer',    $next_id ),
 
 2983                                                                                   'question_fi'                        => array( 
'integer',    
$id ),
 
 2984                                                                                   'type'                                       => array( 
'text',               $solution[
'type'] ),
 
 2986                                                                                   'internal_link'                      => array( 
'text',               $solution[
'internal_link'] ),
 
 2987                                                                                   'import_id'                          => array( 
'text',               
null ),
 
 2988                                                                                   'subquestion_index'          => array( 
'integer',    $index ),
 
 2989                                                                                   'tstamp'                             => array( 
'integer',    time() ),
 
 2992                        if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/", $solution[
"internal_link"], $matches))
 
 3010        function saveSuggestedSolution($type, $solution_id = 
"", $subquestion_index = 0, $value = 
"")
 
 3014                $affectedRows = 
$ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s", 
 
 3015                        array(
"integer", 
"integer"),
 
 3022                $next_id = 
$ilDB->nextId(
'qpl_sol_sug');
 
 3023                include_once(
"./Services/RTE/classes/class.ilRTE.php");
 
 3025                $affectedRows = 
$ilDB->insert(
'qpl_sol_sug', array(
 
 3026                                                                                                           'suggested_solution_id'      => array( 
'integer',    $next_id ),
 
 3027                                                                                                           'question_fi'                        => array( 
'integer',    $this->
getId() ),
 
 3028                                                                                                           'type'                                       => array( 
'text',               $type ),
 
 3030                                                                                                           'internal_link'                      => array( 
'text',               $solution_id ),
 
 3031                                                                                                           'import_id'                          => array( 
'text',               
null ),
 
 3032                                                                                                           'subquestion_index'          => array( 
'integer',    $subquestion_index ),
 
 3033                                                                                                           'tstamp'                                     => array( 
'integer',    time() ),
 
 3036                if ($affectedRows == 1)
 
 3038                        $this->suggested_solutions[$subquestion_index] = array(
 
 3041                                "internal_link" => $solution_id,
 
 3050                if (preg_match(
"/il_(\d+)_(\w+)_(\d+)/", $internal_link, $matches))
 
 3052                        include_once 
"./Services/Link/classes/class.ilInternalLink.php";
 
 3053                        include_once 
"./Modules/LearningModule/classes/class.ilLMObject.php";
 
 3054                        include_once 
"./Modules/Glossary/classes/class.ilGlossaryTerm.php";
 
 3055                        switch ($matches[2])
 
 3073                        if (strcmp($resolved_link, 
"") == 0)
 
 3075                                $resolved_link = $internal_link;
 
 3080                        $resolved_link = $internal_link;
 
 3082                return $resolved_link;
 
 3089                $result = 
$ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
 
 3097                                $internal_link = 
$row[
"internal_link"];
 
 3098                                include_once 
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
 
 3100                                if (strcmp($internal_link, $resolved_link) != 0)
 
 3103                                        $affectedRows = 
$ilDB->manipulateF(
"UPDATE qpl_sol_sug SET internal_link = %s WHERE suggested_solution_id = %s",
 
 3104                                                array(
'text',
'integer'),
 
 3105                                                array($resolved_link, 
$row[
"suggested_solution_id"])
 
 3116                        include_once 
"./Services/Link/classes/class.ilInternalLink.php";
 
 3119                        $result = 
$ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
 
 3127                                        if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/", 
$row[
"internal_link"], $matches))
 
 3140                        "lm" => 
"LearningModule",
 
 3141                        "pg" => 
"PageObject",
 
 3142                        "st" => 
"StructureObject",
 
 3143                        "git" => 
"GlossaryItem",
 
 3144                        "mob" => 
"MediaObject" 
 3147                if (preg_match(
"/il__(\w+)_(\d+)/", 
$target, $matches))
 
 3149                        $type = $matches[1];
 
 3151                        include_once 
"./Services/Utilities/classes/class.ilUtil.php";
 
 3152                        switch($linktypes[$matches[1]])
 
 3154                                case "LearningModule":
 
 3155                                        $href = 
"./goto.php?target=" . $type . 
"_" . 
$target_id;
 
 3158                                case "StructureObject":
 
 3159                                        $href = 
"./goto.php?target=" . $type . 
"_" . 
$target_id;
 
 3161                                case "GlossaryItem":
 
 3162                                        $href = 
"./goto.php?target=" . $type . 
"_" . 
$target_id;
 
 3165                                        $href = 
"./ilias.php?baseClass=ilLMPresentationGUI&obj_type=" . $linktypes[$type] . 
"&cmd=media&ref_id=".$_GET[
"ref_id"].
"&mob_id=".
$target_id;
 
 3182                $result = 
$ilDB->queryF(
"SELECT * FROM qpl_questions WHERE question_id = %s",
 
 3189                        if (
$row[
"original_id"] > 0)
 
 3191                                return $row[
"original_id"];
 
 3195                                return $row[
"question_id"];
 
 3209                        SELECT COUNT(dupl.question_id) cnt 
 3210                        FROM qpl_questions dupl 
 3211                        INNER JOIN qpl_questions orig 
 3212                        ON orig.question_id = dupl.original_id 
 3213                        WHERE dupl.question_id = %s 
 3219                return $row[
'cnt'] > 0;
 
 3233                if ( !$originalObjId )
 
 3244                $this->
setId($original);
 
 3258                $this->updateSuggestedSolutions($original);
 
 3280                if ($question_id < 1)
 
 3285                $result = 
$ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE question_id = %s",
 
 3310                if ($question_id < 1)
 
 3315                $result = 
$ilDB->queryF(
"SELECT question_id FROM qpl_questions INNER JOIN object_data ON obj_fi = obj_id WHERE question_id = %s AND type = 'qpl'",
 
 3349                if (strcmp($question_id, 
"") != 0)
 
 3352                        if (!strlen($question_type)) 
return null;
 
 3373                if (strcmp($this->points, 
"") == 0)
 
 3392                $this->points = $a_points;
 
 3423                $result = 
$ilDB->queryF(
"SELECT MAX(pass) maxpass FROM tst_test_result WHERE active_fi = %s AND question_fi = %s",
 
 3424                        array(
'integer',
'integer'),
 
 3425                        array($active_id, $question_id)
 
 3430                        return $row[
"maxpass"];
 
 3450                if (($question_id < 1) || ($user_id < 1))
 
 3455                $result = 
$ilDB->queryF(
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
 
 3462                        $qpl_object_id = 
$row[
"obj_fi"];
 
 3463                        include_once 
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
 
 3482                if ($question_id < 1) 
return 0;
 
 3483                $result = 
$ilDB->queryF(
"SELECT test_random_question_id FROM tst_test_rnd_qst WHERE question_fi = %s",
 
 3508                $requestsStatisticData = $hintTracking->getRequestStatisticData();
 
 3509                $reachedPoints = $reachedPoints - $requestsStatisticData->getRequestsPoints();
 
 3511                return $reachedPoints;
 
 3552                include_once 
"./Modules/Test/classes/class.ilObjTest.php";
 
 3554                if ($count_system == 1)
 
 3562                if ($score_cutting == 0)
 
 3591                        include_once 
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
 
 3594                $result = 
$ilDB->queryF(
"SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
 
 3595                        array(
'integer',
'integer',
'integer'),
 
 3596                        array($active_id, $question_id, 
$pass)
 
 3619                $res = 
$ilDB->queryF(
"SELECT DISTINCT(question_fi) FROM tst_test_result JOIN tst_active ".
 
 3620                        "ON (active_id = active_fi) ".
 
 3621                        "WHERE " . 
$ilDB->in(
'question_fi', $a_question_ids, 
false, 
'integer') .
 
 3622                        " AND user_fi = %s",
 
 3626                return (
$res->numRows() == count($a_question_ids)) ? true : 
false;
 
 3650                include_once 
"./Services/Utilities/classes/class.ilUtil.php";
 
 3664                for ($i = 0; $i < $a_material->getMaterialCount(); $i++)
 
 3666                        $material = $a_material->getMaterial($i);
 
 3667                        if (strcmp($material[
"type"], 
"mattext") == 0)
 
 3669                                $result .= $material[
"material"]->getContent();
 
 3671                        if (strcmp($material[
"type"], 
"matimage") == 0)
 
 3673                                $matimage = $material[
"material"];
 
 3674                                if (preg_match(
"/(il_([0-9]+)_mob_([0-9]+))/", $matimage->getLabel(), $matches))
 
 3677                                        if (!is_array(
$_SESSION[
"import_mob_xhtml"])) 
$_SESSION[
"import_mob_xhtml"] = array();
 
 3678                                        array_push(
$_SESSION[
"import_mob_xhtml"], array(
"mob" => $matimage->getLabel(), 
"uri" => $matimage->getUri()));
 
 3693        function addQTIMaterial(&$a_xml_writer, $a_material, $close_material_tag = TRUE, $add_mobs = TRUE)
 
 3695                include_once 
"./Services/RTE/classes/class.ilRTE.php";
 
 3696                include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
 
 3698                $a_xml_writer->xmlStartTag(
"material");
 
 3700                        "texttype" => 
"text/plain" 
 3702                if ($this->
isHTML($a_material))
 
 3704                        $attrs[
"texttype"] = 
"text/xhtml";
 
 3710                        foreach (
$mobs as $mob)
 
 3712                                $moblabel = 
"il_" . IL_INST_ID . 
"_mob_" . $mob;
 
 3713                                if (strpos($a_material, 
"mm_$mob") !== FALSE)
 
 3719                                                        "label" => $moblabel,
 
 3720                                                        "uri" => 
"objects/" . 
"il_" . IL_INST_ID . 
"_mob_" . $mob . 
"/" . $mob_obj->getTitle()
 
 3723                                        $a_xml_writer->xmlElement(
"matimage", $imgattrs, NULL);
 
 3727                if ($close_material_tag) $a_xml_writer->xmlEndTag(
"material");
 
 3734                if (preg_match(
"/.*\.(png|jpg|gif|jpeg)$/i", $plain_image_filename, $matches))
 
 3736                        $extension = 
"." . $matches[1];
 
 3741                        $plain_image_filename = uniqid($plain_image_filename.microtime(
true));
 
 3744                $hashed_filename = md5($plain_image_filename) . $extension;
 
 3746                return $hashed_filename;
 
 3772                        $result = 
$ilDB->queryF(
"SELECT points FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
 
 3773                                array(
'integer',
'integer',
'integer'),
 
 3774                                array($active_id, $question_id, 
$pass)
 
 3776                        $manual = ($manualscoring) ? 1 : 0;
 
 3777                        $rowsnum = 
$result->numRows();
 
 3781                                $old_points = 
$row[
"points"];
 
 3784                                        $affectedRows = 
$ilDB->manipulateF(
"UPDATE tst_test_result SET points = %s, manual = %s, tstamp = %s WHERE active_fi = %s AND question_fi = %s AND pass = %s",
 
 3785                                                array(
'float', 
'integer', 
'integer', 
'integer', 
'integer', 
'integer'),
 
 3786                                                array(
$points, $manual, time(), $active_id, $question_id, 
$pass)
 
 3792                                $next_id = 
$ilDB->nextId(
'tst_test_result');
 
 3793                                $affectedRows = 
$ilDB->manipulateF(
"INSERT INTO tst_test_result (test_result_id, active_fi, question_fi, points, pass, manual, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
 
 3794                                        array(
'integer', 
'integer',
'integer', 
'float', 
'integer', 
'integer',
'integer'),
 
 3795                                        array($next_id, $active_id, $question_id, 
$points, 
$pass, $manual, time())
 
 3799                        if(self::isForcePassResultUpdateEnabled() || $old_points != 
$points || !$rowsnum)
 
 3801                                assQuestion::_updateTestPassResults($active_id, 
$pass, $obligationsEnabled);
 
 3803                                include_once 
"./Modules/Test/classes/class.ilObjTest.php";
 
 3804                                include_once 
'./Modules/Course/classes/class.ilCourseObjectiveResult.php';
 
 3807                                include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
 
 3811                                        include_once 
"./Modules/Test/classes/class.ilObjTestAccess.php";
 
 3868                $result = 
$ilDB->queryF(
"SELECT question_type_id FROM qpl_qst_type WHERE type_tag = %s",
 
 3875                        return $row[
"question_type_id"];
 
 3880        public function syncHints()
 
 3885                $ilDB->manipulateF(
"DELETE FROM qpl_hints WHERE qht_question_fi = %s",
 
 3887                        array($this->original_id)
 
 3891                $result = 
$ilDB->queryF(
"SELECT * FROM qpl_hints WHERE qht_question_fi = %s",
 
 3893                        array($this->
getId())
 
 3901                                $next_id = 
$ilDB->nextId(
'qpl_hints');
 
 3903                                $ilDB->insert(
'qpl_hints', array(
 
 3904                                                'qht_hint_id'     => array(
'integer', $next_id),
 
 3905                                                'qht_question_fi' => array(
'integer', $this->original_id),
 
 3906                                                'qht_hint_index'  => array(
'integer', 
$row[
"qht_hint_index"]),
 
 3907                                                'qht_hint_points' => array(
'integer', 
$row[
"qht_hint_points"]),
 
 3908                                                'qht_hint_text'   => array(
'text', 
$row[
"qht_hint_text"]),
 
 3924                $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(), 
false);
 
 3925                $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(), 
true);
 
 3926                $collected .= $this->feedbackOBJ->getAllSpecificAnswerFeedbackContents($this->
getId());
 
 3928                foreach ($this->suggested_solutions as $solution_array)
 
 3930                        $collected .= $solution_array[
"value"];
 
 3933                require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
 
 3935                foreach($questionHintList as $questionHint)
 
 3938                        $collected .= $questionHint->getText();
 
 3951                include_once(
"./Services/RTE/classes/class.ilRTE.php");
 
 3964                $result = 
$ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE original_id = %s",
 
 3966                        array($this->
getId())
 
 3968                $instances = array();
 
 3972                        array_push($ids, 
$row[
"question_id"]);
 
 3974                foreach ($ids as $question_id)
 
 3977                        $result = 
$ilDB->queryF(
"SELECT tst_tests.obj_fi FROM tst_tests, tst_test_question WHERE tst_test_question.question_fi = %s AND tst_test_question.test_fi = tst_tests.test_id",
 
 3986                        $result = 
$ilDB->queryF(
"SELECT tst_tests.obj_fi FROM tst_tests, tst_test_rnd_qst, tst_active WHERE tst_test_rnd_qst.active_fi = tst_active.active_id AND tst_test_rnd_qst.question_fi = %s AND tst_tests.test_id = tst_active.test_fi",
 
 3995                include_once 
"./Modules/Test/classes/class.ilObjTest.php";
 
 3996                foreach ($instances as $key => $value)
 
 4005                include_once 
"./Modules/Test/classes/class.ilObjAssessmentFolder.php";
 
 4008                if (in_array($questiontype, $scoring))
 
 4028                $result = 
$ilDB->queryF(
"SELECT * FROM tst_active WHERE active_id = %s",
 
 4035                        return array(
"user_id" => 
$row[
"user_fi"], 
"test_id" => 
$row[
"test_fi"]);
 
 4052                if( self::isCoreQuestionType($question_type) )
 
 4064                return $questionType.
'GUI';
 
 4069                return $questionType;
 
 4074                return str_replace(
'ass', 
'ilAss', $questionType).
'Feedback';
 
 4080                return file_exists(
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php");
 
 4088                        require_once 
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php";
 
 4095                        require_once 
"Modules/TestQuestionPool/classes/class.{$objectClassName}.php";
 
 4099                require_once 
"Modules/TestQuestionPool/classes/feedback/class.{$feedbackClassName}.php";
 
 4104                global $ilPluginAdmin;
 
 4107                        self::getObjectClassNameByQuestionType($questionType),
 
 4108                        self::getFeedbackClassNameByQuestionType($questionType)
 
 4116                $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE, 
"TestQuestionPool", 
"qst");
 
 4117                foreach ($pl_names as $pl_name)
 
 4120                        if (strcmp($pl->getQuestionType(), $questionType) == 0)
 
 4122                                foreach($classes as $class)
 
 4124                                        $pl->includeClass(
"class.{$class}.php");
 
 4140                if (file_exists(
"./Modules/TestQuestionPool/classes/class.".$type_tag.
".php"))
 
 4143                        return $lng->txt($type_tag);
 
 4147                        global $ilPluginAdmin;
 
 4148                        $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE, 
"TestQuestionPool", 
"qst");
 
 4149                        foreach ($pl_names as $pl_name)
 
 4152                                if (strcmp($pl->getQuestionType(), $type_tag) == 0)
 
 4154                                        return $pl->getQuestionTypeTranslation();
 
 4186                if (strcmp($a_question_id, 
"") != 0)
 
 4193                        $question_gui = 
new $question_type_gui();
 
 4194                        $question_gui->object->loadFromDb($a_question_id);
 
 4197                        $question_gui->object->feedbackOBJ = 
new $feedbackObjectClassname($question_gui->object, 
$ilCtrl, 
$ilDB, 
$lng);
 
 4199                        $assSettings = 
new ilSetting(
'assessment');
 
 4200                        require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionProcessLockerFactory.php';
 
 4202                        $processLockerFactory->setQuestionId($question_gui->object->getId());
 
 4203                        $processLockerFactory->setUserId(
$ilUser->getId());
 
 4204                        include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
 
 4206                        $question_gui->object->setProcessLocker($processLockerFactory->getLocker());
 
 4211                        $ilLog->write(
'Instantiate question called without question id. (instantiateQuestionGUI@assQuestion)', 
$ilLog->WARNING);
 
 4214                return $question_gui;
 
 4229                $worksheet->setFormattedExcelTitle(
$worksheet->getColumnCoord(0) . $startrow, $this->lng->txt($this->getQuestionType()));
 
 4230                $worksheet->setFormattedExcelTitle(
$worksheet->getColumnCoord(1) . $startrow, $this->getTitle());
 
 4243                                return $this->
getId();
 
 4263                        case "est_working_time":
 
 4287                        case "suggested_solutions":
 
 4294                                if (array_key_exists($value, $this->arrData))
 
 4296                                        return $this->arrData[$value];
 
 4314                                $this->
setId($value);
 
 4334                        case "est_working_time":
 
 4335                                if (is_array($value))
 
 4356                                $this->page =& $value;
 
 4359                                $this->arrData[$key] = $value;
 
 4371                $this->nr_of_tries = $a_nr_of_tries;
 
 4376                $this->export_image_path = (string)$a_path;
 
 4383                if ($question_id < 1)
 
 4388                $result = 
$ilDB->queryF(
"SELECT question_fi FROM tst_test_question WHERE question_fi = %s AND test_fi = %s",
 
 4389                        array(
'integer', 
'integer'),
 
 4418                require_once 
'Modules/TestQuestionPool/classes/questions/class.ilAssSelfAssessmentQuestionFormatter.php';
 
 4419                return new \ilAssSelfAssessmentQuestionFormatter();
 
 4431                $this->prevent_rte_usage = $a_val;
 
 4453                $this->feedbackOBJ->migrateContentForLearningModule($migrator, $this->
getId());
 
 4479                $this->selfassessmenteditingmode = $a_selfassessmenteditingmode;
 
 4499                $this->defaultnroftries = $a_defaultnroftries;
 
 4523                $query = 
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s";
 
 4525                $res = 
$ilDB->queryF(
$query, array(
'integer'), array((
int)$questionId));
 
 4528                return $row[
'obj_fi'];
 
 4548                require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
 
 4553                        require_once 
'Modules/TestQuestionPool/classes/class.ilAssHintPage.php';
 
 4555                        foreach($hintIds as $originalHintId => $duplicateHintId)
 
 4558                                $originalXML = $originalPageObject->getXMLContent();
 
 4561                                $duplicatePageObject->setId($duplicateHintId);
 
 4562                                $duplicatePageObject->setParentId($this->
getId());
 
 4563                                $duplicatePageObject->setXMLContent($originalXML);                              
 
 4564                                $duplicatePageObject->createFromXML();
 
 4573                require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
 
 4575                $assignmentList->setParentObjId($srcParentId);
 
 4576                $assignmentList->setQuestionIdFilter($srcQuestionId);
 
 4577                $assignmentList->loadFromDb();
 
 4579                foreach($assignmentList->getAssignmentsByQuestionId($srcQuestionId) as $assignment)
 
 4583                        $assignment->setParentObjId($trgParentId);
 
 4584                        $assignment->setQuestionId($trgQuestionId);
 
 4585                        $assignment->saveToDb();
 
 4593                require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
 
 4595                $assignmentList->setParentObjId($trgParentId);
 
 4596                $assignmentList->setQuestionIdFilter($trgQuestionId);
 
 4597                $assignmentList->loadFromDb();
 
 4599                foreach($assignmentList->getAssignmentsByQuestionId($trgQuestionId) as $assignment)
 
 4603                        $assignment->deleteFromDb();
 
 4665                        SELECT          count(active_fi) cnt 
 4669                        WHERE           active_fi = %s 
 4670                        AND                     question_fi = %s 
 4675                        $query, array(
'integer',
'integer',
'integer'),
 
 4676                        array($activeId, $questionId, 
$pass)
 
 4681                return (
int)
$row[
'cnt'];
 
 4705                        require_once 
'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
 
 4749                        self::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT,
 
 4750                        self::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
 
 4759                $this->questionChangeListeners[] = $listener;
 
 4774                        $listener->notifyQuestionCreated($this);
 
 4782                        $listener->notifyQuestionEdited($this);
 
 4790                        $listener->notifyQuestionDeleted($this);
 
 4799                require_once 
'Services/Html/classes/class.ilHtmlPurifierFactory.php';
 
 4808                require_once 
'Services/Html/classes/class.ilHtmlPurifierFactory.php';
 
 4815                        SELECT          qpl_questions.*, 
 4816                                                {$this->getAdditionalTableName()}.* 
 4818                        LEFT JOIN       {$this->getAdditionalTableName()} 
 4819                        ON                      {$this->getAdditionalTableName()}.question_fi = qpl_questions.question_id 
 4820                        WHERE                   qpl_questions.question_id = %s 
 4853                                WHERE active_fi = %s 
 4854                                AND question_fi = %s 
 4860                        return $ilDB->queryF(
$query, array(
'integer', 
'integer', 
'integer', 
'integer', 
'integer'),
 
 4861                                array($active_id, $this->
getId(), $pass, $this->
getStep(), (
int)$authorized)
 
 4869                                WHERE active_fi = %s 
 4870                                AND question_fi = %s 
 4875                        return $ilDB->queryF(
$query, array(
'integer', 
'integer', 
'integer', 
'integer'),
 
 4876                                array($active_id, $this->
getId(), $pass, (
int)$authorized)
 
 4892                return $ilDB->manipulateF(
"DELETE FROM tst_solutions WHERE solution_id = %s",
 
 4893                        array(
'integer'), array($solutionId)
 
 4908                $res = 
$ilDB->queryF(
"SELECT * FROM tst_solutions WHERE solution_id = %s",
 
 4909                        array(
'integer'), array($solutionId)
 
 4929                $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function() use ($active_id, 
$pass) {
 
 4949                                DELETE FROM tst_solutions 
 4950                                WHERE active_fi = %s 
 4951                                AND question_fi = %s 
 4957                        return $ilDB->manipulateF(
$query, array(
'integer', 
'integer', 
'integer', 
'integer', 
'integer'),
 
 4958                                array($active_id, $this->
getId(), $pass, $this->
getStep(), (
int)$authorized)
 
 4964                                DELETE FROM tst_solutions 
 4965                                WHERE active_fi = %s 
 4966                                AND question_fi = %s 
 4971                        return $ilDB->manipulateF(
$query, array(
'integer', 
'integer', 
'integer', 
'integer'),
 
 4972                                array($active_id, $this->
getId(), $pass, (
int)$authorized)
 
 4993                $next_id = 
$ilDB->nextId(
"tst_solutions");
 
 4996                        "solution_id" => array(
"integer", $next_id),
 
 4997                        "active_fi" => array(
"integer", $active_id),
 
 4998                        "question_fi" => array(
"integer", $this->
getId()),
 
 4999                        "value1" => array(
"clob", $value1),
 
 5000                        "value2" => array(
"clob", $value2),
 
 5001                        "pass" => array(
"integer", 
$pass),
 
 5002                        "tstamp" => array(
"integer", isset($tstamp) ? $tstamp : time()),
 
 5003                        'authorized' => array(
'integer', (
int)$authorized)
 
 5006                if( $this->
getStep() !== 
null )
 
 5008                        $fieldData[
'step'] = array(
"integer", $this->
getStep());
 
 5011                return $ilDB->insert(
"tst_solutions", $fieldData);
 
 5030                        "value1" => array(
"clob", $value1),
 
 5031                        "value2" => array(
"clob", $value2),
 
 5032                        "tstamp" => array(
"integer", time()),
 
 5033                        'authorized' => array(
'integer', (
int)$authorized)
 
 5036                if( $this->
getStep() !== 
null )
 
 5038                        $fieldData[
'step'] = array(
"integer", $this->
getStep());
 
 5041                return $ilDB->update(
"tst_solutions", $fieldData, array(
 
 5042                        'solution_id' => array(
'integer', $solutionId)
 
 5052                        'authorized' => array(
'integer', (
int)$authorized)
 
 5057                        $fieldData[
'tstamp'] = array(
'integer', time());
 
 5061                        'question_fi' => array(
'integer', $this->
getId()),
 
 5062                        'active_fi' => array(
'integer', $activeId),
 
 5063                        'pass' => array(
'integer', 
$pass)
 
 5066                if( $this->
getStep() !== NULL )
 
 5068                        $whereData[
'step'] = array(
"integer", $this->
getStep());
 
 5071                return $ilDB->update(
'tst_solutions', $fieldData, $whereData);
 
 5083                return implode(self::getKeyValuesImplosionSeparator(), $keyValues);
 
 5087                return explode(self::getKeyValuesImplosionSeparator(), $keyValues);
 
 5092                foreach( $this->
getSolutionValues($activeId, $passIndex, 
false) as $solutionRec )
 
 5094                        if( 0 == strlen($solutionRec[
'value1']) && 0 == strlen($solutionRec[
'value2']) )
 
 5105                $types = array(
"integer", 
"integer", 
"integer", 
"integer");
 
 5106                $values = array($activeId, $this->
getId(), $passIndex, (
int)$authorized);
 
 5107                $valuesCondition = array();
 
 5109                foreach($matchValues as $valueField => $value)
 
 5115                                        $valuesCondition[] = 
"{$valueField} = %s";
 
 5121                                        require_once 
'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
 
 5126                $valuesCondition = implode(
' AND ', $valuesCondition);
 
 5129                        DELETE FROM tst_solutions 
 5130                        WHERE active_fi = %s 
 5131                        AND question_fi = %s 
 5134                        AND $valuesCondition 
 5137                if( $this->
getStep() !== NULL )
 
 5139                        $query .= 
" AND step = %s ";
 
 5140                        $types[] = 
'integer';
 
 5144                $ilDB->manipulateF(
$query, $types, $values);
 
 5151                        $this->
saveCurrentSolution($activeId, $passIndex, $rec[
'value1'], $rec[
'value2'], 
true, $rec[
'tstamp']);
 
 5159                if( !count($intermediateSolution) )
 
 5168                        if( $considerDummyRecordCreation )
 
 5199                $this->step = 
$step;
 
 5219                return gmdate(
'H:i:s', $time);
 
 5229                $time_array = explode(
':',$time);
 
 5230                if(     
sizeof($time_array) == 3)
 
 5232                        $sec += $time_array[0] * 3600;
 
 5233                        $sec += $time_array[1] * 60;
 
 5234                        $sec += $time_array[2];
 
 5241                return json_encode(array());
 
 5249                $solutionAvailability = $this->lookupForExistingSolutions($active_id, 
$pass);
 
 5250                return (
bool)$solutionAvailability[
'intermediate'];
 
 5254                $solutionAvailability = $this->lookupForExistingSolutions($active_id, 
$pass);
 
 5255                return (
bool)$solutionAvailability[
'authorized'];
 
 5259                $solutionAvailability = $this->lookupForExistingSolutions($active_id, 
$pass);
 
 5260                return (
bool)$solutionAvailability[
'authorized'] || (bool)$solutionAvailability[
'intermediate'];
 
 5269        protected function lookupMaxStep($active_id, 
$pass)
 
 5275                        "SELECT MAX(step) max_step FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
 
 5276                        array(
"integer", 
"integer", 
"integer"), array($active_id, 
$pass, $this->
getId())
 
 5281                $maxStep = 
$row[
'max_step'];
 
 5293        public function lookupForExistingSolutions($activeId, 
$pass)
 
 5299                        'authorized' => 
false,
 
 5300                        'intermediate' => 
false 
 5304                        SELECT authorized, COUNT(*) cnt 
 5306                        WHERE active_fi = %s 
 5307                        AND question_fi = %s 
 5311                if( $this->
getStep() !== NULL )
 
 5320                $result = $ilDB->queryF(
$query, array(
'integer', 
'integer', 
'integer'), array($activeId, $this->
getId(), $pass));
 
 5324                        if (
$row[
'authorized']) {
 
 5325                                $return[
'authorized'] = 
$row[
'cnt'] > 0;
 
 5329                                $return[
'intermediate'] = 
$row[
'cnt'] > 0;
 
 5341                        DELETE FROM tst_solutions 
 5342                        WHERE active_fi = %s 
 5343                        AND question_fi = %s 
 5347                if( $this->
getStep() !== NULL )
 
 5352                return $ilDB->manipulateF(
$query, array(
'integer', 
'integer', 
'integer'),
 
 5353                        array($activeId, $this->
getId(), $pass)
 
 5362                $this->
log($activeId, 
"log_user_solution_willingly_deleted");
 
 5364                self::_updateTestPassResults(
 
 5374                        DELETE FROM tst_test_result 
 5375                        WHERE active_fi = %s 
 5376                        AND question_fi = %s 
 5380                if( $this->
getStep() !== NULL )
 
 5385                return $ilDB->manipulateF(
$query, array(
'integer', 
'integer', 
'integer'),
 
 5386                        array($activeId, $this->
getId(), $pass)
 
 5394                $IN_questionIds = 
$ilDB->in(
'question_fi', $questionIds, 
false, 
'integer');
 
 5398                        FROM tst_test_result 
 5399                        WHERE active_fi = %s 
 5405                        $query, array(
'integer', 
'integer'), array($activeId, 
$pass)
 
 5408                return $row[
'cnt'] < count($questionIds);
 
 5415                $IN_questionIds = 
$ilDB->in(
'question_fi', $questionIds, 
false, 
'integer');
 
 5419                        FROM tst_test_result 
 5420                        WHERE active_fi = %s 
 5426                        $query, array(
'integer', 
'integer'), array($activeId, 
$pass)
 
 5429                $questionsHavingResultRecord = array();
 
 5433                        $questionsHavingResultRecord[] = 
$row[
'question_fi'];
 
 5436                $questionsMissingResultRecordt = array_diff(
 
 5437                        $questionIds, $questionsHavingResultRecord
 
 5440                return $questionsMissingResultRecordt;
 
 5449                        FROM tst_test_result 
 5450                        WHERE active_fi = %s 
 5451                        AND question_fi = %s 
 5455                $row = 
$ilDB->fetchAssoc(
$ilDB->queryF(
$query, array(
'integer', 
'integer', 
'integer'), array($activeId, $questionId, 
$pass)));
 
 5457                return $row[
'cnt'] > 0;
 
 5466                $valuePairs = array();
 
 5468                foreach($indexedValues as $value1 => $value2)
 
 5470                        $valuePairs[] = array(
'value1' => $value1, 
'value2' => $value2);
 
 5482                $indexedValues = array();
 
 5484                foreach($valuePairs as $valuePair)
 
 5486                        $indexedValues[ $valuePair[
'value1'] ] = $valuePair[
'value2'];
 
 5489                return $indexedValues;
 
 5512                $ilDB->manipulateF(
"UPDATE qpl_questions SET tstamp = %s  WHERE question_id = %s",
 
 5513                        array(
'integer', 
'integer'),
 
 5514                        array(time(), $this->
getId())
 
 5535                if( $this->testQuestionConfigInstance === 
null )
 
 5553                include_once(
'Modules/TestQuestionPool/classes/class.ilTestQuestionConfig.php');
 
sprintf('%.4f', $callTime)
An exception for terminatinating execution or to throw for unit testing.
Abstract basic class which is to be extended by the concrete assessment question type classes.
getTotalAnswers()
get total number of answers
$export_image_path
(Web) Path to images
moveUploadedMediaFile($file, $name)
Move an uploaded media file to an public accessible temp dir to present it.
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.
static includePluginClass($questionType, $withGuiClass)
static getFeedbackClassNameByQuestionType($questionType)
setPreventRteUsage($a_val)
Set prevent rte usage.
removeResultRecord($activeId, $pass)
static _getOriginalId($question_id)
Returns the original id of a question.
$additinalContentEditingMode
const KEY_VALUES_IMPLOSION_SEPARATOR
setProcessLocker($processLocker)
formatSAQuestion($a_q)
Format self assessment question.
setShuffle($shuffle=true)
Sets the shuffle flag.
setId($id=-1)
Sets the id of the assQuestion object.
keyInArray($searchkey, $array)
returns TRUE if the key occurs in an array
setOriginalId($original_id)
static _instantiateQuestion($question_id)
getQuestionTypeID()
Returns the question type of the question.
setObjId($obj_id=0)
Set the object id of the container object.
static sumTimesInISO8601FormatH_i_s_Extended($time1, $time2)
static instantiateQuestionGUI($a_question_id)
Creates an instance of a question gui with a given question id.
static isAllowedImageFileExtension($mimeType, $fileExtension)
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
Creates an Excel worksheet for the detailed cumulated results of this question.
copySuggestedSolutionFiles($source_questionpool_id, $source_question_id)
static originalQuestionExists($questionId)
beforeSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
static setForcePassResultUpdateEnabled($forcePassResultsUpdateEnabled)
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.
static _getReachedPoints($active_id, $question_id, $pass=NULL)
Returns the points, a learner has reached answering the question.
saveQuestionDataToDb($original_id="")
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
Receives parameters from a QTI parser and creates a valid ILIAS question object.
QTIMaterialToString($a_material)
Reads an QTI material tag an creates a text string.
syncSuggestedSolutionFiles($original_id)
Syncs the files of a suggested solution if the question is synced.
static _getSolutionMaxPass($question_id, $active_id)
Returns the maximum pass a users question solution.
isClone($question_id="")
Checks whether the question is a clone of another question or not.
static fetchMimeTypeIdentifier($contentTypeString)
fixUnavailableSkinImageSources($html)
adjustReachedPointsByScoringOptions($points, $active_id, $pass=NULL)
Adjust the given reached points by checks for all special scoring options in the test container.
deletePageOfQuestion($question_id)
Deletes the page object of a question with a given ID.
lmMigrateQuestionTypeGenericContent(ilAssSelfAssessmentMigrator $migrator)
duplicateSkillAssignments($srcParentId, $srcQuestionId, $trgParentId, $trgQuestionId)
savePreviewData(ilAssQuestionPreviewSession $previewSession)
deleteSolutionRecordByValues($activeId, $passIndex, $authorized, $matchValues)
isComplete()
Returns true, if a question is complete for use.
getHtmlQuestionContentPurifier()
const ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT
constant for additional content editing mode "default"
log($active_id, $langVar)
static _getSuggestedSolutionCount($question_id)
Returns the number of suggested solutions associated with a question.
isInUse($question_id="")
Checks whether the question is in use or not.
static resetOriginalId($questionId)
static _areAnswered($a_user_id, $a_question_ids)
Checks if an array of question ids is answered by an user or not.
isPreviewSolutionCorrect(ilAssQuestionPreviewSession $previewSession)
cleanupMediaObjectUsage()
synchronises appearances of media objects in the question with media object usage table
deleteDummySolutionRecord($activeId, $passIndex)
getUserSolutionPreferingIntermediate($active_id, $pass=NULL)
getId()
Gets the id of the assQuestion object.
static saveOriginalId($questionId, $originalId)
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
fetchValuePairsFromIndexedValues(array $indexedValues)
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
getObjId()
Get the object id of the container object.
questionTitleExists($questionpool_id, $title)
Returns TRUE if the question title exists in the database.
supportsJavascriptOutput()
Returns true if the question type supports JavaScript output.
persistWorkingState($active_id, $pass=NULL, $obligationsEnabled=false, $authorized=true)
persists the working state for current testactive and testpass
static _getQuestionTypeName($type_tag)
Return the translation for a given question type tag.
getSuggestedSolutionPath()
Returns the path for a suggested solution.
removeExistingSolutions($activeId, $pass)
areObligationsToBeConsidered()
setTitle($title="")
Sets the title string of the assQuestion object.
static _getTitle($a_q_id)
Returns the title of a question.
getOwner()
Gets the creator/owner ID of the assQuestion object.
getAdditionalContentEditingMode()
getter for additional content editing mode for this question
static _isUsedInRandomTest($question_id="")
Checks whether the question is used in a random test or not.
getSolutionRecordById($solutionId)
$testQuestionConfigInstance
isHTML($a_text)
Checks if a given string contains HTML or not.
buildTestPresentationConfig()
build basic test question configuration instance
setObligationsToBeConsidered($obligationsToBeConsidered)
persistPreviewState(ilAssQuestionPreviewSession $previewSession)
persists the preview state for current user and question
static $forcePassResultsUpdateEnabled
addQuestionChangeListener(ilQuestionChangeListener $listener)
syncXHTMLMediaObjectsOfQuestion()
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
onCopy($sourceParentId, $sourceQuestionId, $targetParentId, $targetQuestionId)
Will be called when a question is copied (into another question pool)
duplicateIntermediateSolutionAuthorized($activeId, $passIndex)
authorizedOrIntermediateSolutionExists($active_id, $pass)
prepareTextareaOutput($txt_output, $prepare_for_latex_output=FALSE, $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output in tests.
resetUsersAnswer($activeId, $pass)
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
getJavaPath()
Returns the image path for web accessable images of a question.
createNewQuestion($a_create_page=true)
Creates a new question without an owner when a new question is created This assures that an ID is giv...
migrateContentForLearningModule(ilAssSelfAssessmentMigrator $migrator)
getAdditionalTableName()
Returns the name of the additional question data table in the database.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second.
getHtmlUserSolutionPurifier()
fetchIndexedValuesFromValuePairs(array $valuePairs)
getSuggestedSolutionTitle($subquestion_index=0)
Returns the title of a suggested solution at a given subquestion_index.
static getObjectClassNameByQuestionType($questionType)
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
static $allowedImageMaterialFileExtensionsByMimeType
setExportImagePath($a_path)
isValidAdditionalContentEditingMode($additionalContentEditingMode)
returns the fact wether the passed additional content mode is valid or not
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.
setEstimatedWorkingTimeFromDurationString($durationString)
Sets the estimated working time of a question from a given datetime string.
getSuggestedSolutionPathWeb()
Returns the web path for a suggested solution.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
buildImagePath($questionId, $parentObjectId)
addQTIMaterial(&$a_xml_writer, $a_material, $close_material_tag=TRUE, $add_mobs=TRUE)
Creates a QTI material tag from a plain text or xhtml text.
static explodeKeyValues($keyValues)
getFlashPath()
Returns the image path for web accessable flash files of a question.
__get($value)
Object getter.
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
removeCurrentSolution($active_id, $pass, $authorized=true)
getSuggestedSolution($subquestion_index=0)
Returns a suggested solution for a given subquestion index.
$obligationsToBeConsidered
buildHashedImageFilename($plain_image_filename, $unique=false)
updateCurrentSolution($solutionId, $value1, $value2, $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...
static implodeKeyValues($keyValues)
static convertISO8601FormatH_i_s_ExtendedToSeconds($time)
duplicateSuggestedSolutionFiles($parent_id, $question_id)
Duplicates the files of a suggested solution if the question is duplicated.
setAuthor($author="")
Sets the authors name of the assQuestion object.
$arrData
Associative array to store properties.
static isFileAvailable($file)
getQuestionType()
Returns the question type of the question.
deleteSuggestedSolutions()
Deletes all suggestes solutions in the database.
getPoints()
Returns the maximum available points for the question.
getOutputType()
Gets the output type.
ensureCurrentTestPass($active_id, $pass)
static isCoreQuestionType($questionType)
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
getActiveUserData($active_id)
Returns the user id and the test id for a given active id.
static _updateTestResultCache($active_id, ilAssQuestionProcessLocker $processLocker=null)
@TODO Move this to a proper place.
setExternalId($external_id)
getValidAdditionalContentEditingModes()
getter for valid additional content editing modes
deleteTaxonomyAssignments()
static _getSuggestedSolutionOutput($question_id)
Returns the output of the suggested solution.
static _needsManualScoring($question_id)
getQuestionChangeListeners()
intermediateSolutionExists($active_id, $pass)
_getTotalAnswers($a_q_id)
get number of answers for question id (static) note: do not use $this inside this method
static _questionExistsInTest($question_id, $test_id)
authorizedSolutionExists($active_id, $pass)
getJavaPathWeb()
Returns the web image path for web accessable java applets of a question.
onDuplicate($originalParentId, $originalQuestionId, $duplicateParentId, $duplicateQuestionId)
Will be called when a question is duplicated (inside a question pool or for insertion in a test)
getTestId()
Gets the test id of the assQuestion object.
setShuffler(ilArrayElementShuffler $shuffler)
__set($key, $value)
Object setter.
getTestOutputSolutions($activeId, $pass)
calculateResultsFromSolution($active_id, $pass=NULL, $obligationsEnabled=false)
Calculates the question results from a previously saved question solution.
removeIntermediateSolution($active_id, $pass)
_resolveIntLinks($question_id)
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
static _getInternalLinkHref($target="")
getSelfAssessmentEditingMode()
Get Self-Assessment Editing Mode.
static $allowedCharsetsByMimeType
getTitleFilenameCompliant()
returns the object title prepared to be used as a filename
copyPageOfQuestion($a_q_id)
static isForcePassResultUpdateEnabled()
static lookupOriginalParentObjId($originalQuestionId)
returns the parent object id for given original question id (should be a qpl id, but theoretically it...
_resolveInternalLink($internal_link)
getTestPresentationConfig()
Get the test question configuration (initialised once)
static & _instanciateQuestionGUI($question_id)
Creates an instance of a question gui with a given question id.
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
_questionExistsInPool($question_id)
Returns true if the question already exists in the database and is assigned to a question pool.
setOutputType($outputType=OUTPUT_HTML)
Sets the output type.
static lookupParentObjId($questionId)
@global ilDBInterface $ilDB
forceExistingIntermediateSolution($activeId, $passIndex, $considerDummyRecordCreation)
static _getTotalRightAnswers($a_q_id)
get number of answers for question id (static) note: do not use $this inside this method
getSelfAssessmentFormatter()
static _getQuestionText($a_q_id)
Returns question text.
static $imageSourceFixReplaceMap
static getGuiClassNameByQuestionType($questionType)
getDefaultNrOfTries()
Get Default Nr of Tries.
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...
setSelfAssessmentEditingMode($a_selfassessmenteditingmode)
Set Self-Assessment Editing Mode.
static $allowedFileExtensionsByMimeType
static setResultGateway($resultGateway)
getShuffle()
Gets the shuffle flag.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
getFlashPathWeb()
Returns the web image path for web accessable flash applications of a question.
static includeCoreClass($questionType, $withGuiClass)
createPageObject()
create page object of question
static missingResultRecordExists($activeId, $pass, $questionIds)
static getKeyValuesImplosionSeparator()
copyXHTMLMediaObjectsOfQuestion($a_q_id)
const ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
constant for additional content editing mode "pageobject"
static _isWorkedThrough($active_id, $question_id, $pass=NULL)
Returns true if the question was worked through in the given pass Worked through means that the user ...
getSuggestedSolutions()
Return the suggested solutions.
& _getSuggestedSolution($question_id, $subquestion_index=0)
Returns a suggested solution for a given subquestion index.
getAnswerTableName()
Returns the name of the answer table in the database.
fixSvgToPng($imageFilenameContainingString)
syncSkillAssignments($srcParentId, $srcQuestionId, $trgParentId, $trgQuestionId)
updateCurrentSolutionsAuthorization($activeId, $pass, $authorized, $keepTime=false)
static getQuestionsMissingResultRecord($activeId, $pass, $questionIds)
deleteAdditionalTableData($question_id)
Deletes datasets from the additional question table in the database.
static _includeClass($question_type, $gui=0)
Include the php class file for a given question type.
$selfassessmenteditingmode
getTitle()
Gets the title string of the assQuestion object.
static _getQuestionTitle($question_id)
Returns the question title of a question with a given id.
setPoints($a_points)
Sets the maximum available points for the question.
afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
isAdditionalContentEditingModePageObject()
isser for additional "pageobject" content editing mode
duplicateQuestionHints($originalQuestionId, $duplicateQuestionId)
setComment($comment="")
Sets the comment string of the assQuestion object.
static _getQuestionInfo($question_id)
Returns question information from the database.
getSuggestedSolutionOutput()
getComment()
Gets the comment string of the assQuestion object.
setTestId($id=-1)
Sets the test id of the assQuestion object.
getAdjustedReachedPoints($active_id, $pass=NULL, $authorizedSolution=true)
returns the reached points ...
getAuthor()
Gets the authors name of the assQuestion object.
static getQuestionTypeFromDb($question_id)
get question type for question id
setNrOfTries($a_nr_of_tries)
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assQuestion constructor
getReachedPoints($active_id, $pass=NULL)
Returns the points, a learner has reached answering the question This is the fast way to get the poin...
$nr_of_tries
Number of tries.
static _getQuestionType($question_id)
Returns the question type of a question with a given id.
getQuestion()
Gets the question string of the question object.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
static isAllowedImageMimeType($mimeType)
isAnswered($active_id, $pass=null)
returns boolean wether the question is answered during test pass or not
saveToDb($original_id="")
Saves the question to the database.
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
static _isWriteable($question_id, $user_id)
Returns true if the question is writeable by a certain user.
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
Reworks the allready saved working data if neccessary.
_questionExists($question_id)
Returns true if the question already exists in the database.
pcArrayShuffle($array)
Shuffles the values of a given array.
setQuestion($question="")
Sets the question string of the question object.
getImagePathWeb()
Returns the web image path for web accessable images of a question.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
loadFromDb($question_id)
Loads the question from the database.
static getAllowedFileExtensionsForMimeType($mimeType)
static lookupResultRecordExist($activeId, $questionId, $pass)
setLastChange($lastChange)
static getResultGateway()
& getInstances()
Gets all instances of the question.
static getAllowedImageMaterialFileExtensions()
lookupCurrentTestPass($active_id, $pass)
createRandomSolution($test_id, $user_id)
getEstimatedWorkingTime()
Gets the estimated working time of a question.
getPreventRteUsage()
Get prevent rte usage.
deleteAnswers($question_id)
Deletes datasets from answers tables.
setDefaultNrOfTries($a_defaultnroftries)
Set Default Nr of Tries.
ensureNonNegativePoints($points)
Assessment hint page object.
static deleteHintsByQuestionIds($questionIds)
Deletes all question hints relating to questions included in given question ids.
static duplicateListForQuestion($originalQuestionId, $duplicateQuestionId)
duplicates a hint list from given original question id to given duplicate question id and returns an ...
static getListByQuestionId($questionId)
instantiates a question hint list for the passed question id
getParticipantsSolution()
setParticipantsSolution($participantSolution)
static _updateObjectiveResult($a_user_id, $a_active_id, $a_question_id)
static _getInstanceByType($a_type)
Factory method for creating purifier instances.
static _deleteAllLinksOfSource($a_source_type, $a_source_id, $a_lang="-")
Delete all links of a given source.
static _saveLink($a_source_type, $a_source_id, $a_target_type, $a_target_id, $a_target_inst=0, $a_source_lang="-")
save internal link information
static _getIdForImportId($a_type, $a_target)
Get current id for an import id.
static _getIdForImportId($a_import_id)
get current object id for import id (static)
static _addLog($user_id, $object_id, $logtext, $question_id="", $original_id="", $test_only=FALSE, $test_ref_id=NULL)
Add an assessment log entry.
static _getLogLanguage()
retrieve the log language for assessment logging
static _getManualScoringTypes()
Retrieve the manual scoring settings as type strings.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static _isWriteable($object_id, $user_id)
Returns true, if the question pool is writeable by a given user.
static _updateQuestionCount($object_id)
Updates the number of available questions for a question pool in the database.
static getUsageOfObject($a_obj_id, $a_include_titles=false)
Get usage of object.
static _getParticipantData($active_id)
Retrieves a participant name from active id.
static _getResultPass($active_id)
Retrieves the pass number that should be counted for a given user.
static _getObjectIDFromActiveID($active_id)
Returns the ILIAS test object id for a given active id.
static _getCountSystem($active_id)
Gets the count system for the calculation of points.
static _lookupAuthor($obj_id)
Gets the authors name of the ilObjTest object.
static _getQuestionCountAndPointsForPassOfParticipant($active_id, $pass)
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static buildExamId($active_id, $pass, $test_obj_id=null)
static _getWorkingTimeOfParticipantForPass($active_id, $pass)
Returns the complete working time in seconds for a test participant.
static _getUserIdFromActiveId($active_id)
static _getScoreCutting($active_id)
Determines if the score of a question should be cut at 0 points or the score of the whole test.
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
static _lookupObjId($a_id)
static _lookupTitle($a_id)
lookup object title
static _getAllReferences($a_id)
get all reference ids of object
static getPluginObject($a_ctype, $a_cname, $a_slot_id, $a_pname)
Get plugin object.
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...
static _cleanupMediaObjectUsage($a_text, $a_usage_type, $a_usage_id)
Synchronises appearances of media objects in $a_text with media object usage table.
Taxonomy node <-> item assignment.
Test Question configuration.
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 isHTML($a_text)
Checks if a given string contains HTML or not.
static prepareTextareaOutput($txt_output, $prepare_for_latex_output=FALSE, $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output where latex code may be in it If the text is HTML-free,...
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static removeTrailingPathSeparators($path)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
static createDirectory($a_dir, $a_mod=0755)
create directory
static signFile($path_to_file)
static setTokenMaxLifetimeInSeconds($token_max_lifetime_in_seconds)
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
migrateToLmContent($content)
redirection script todo: (a better solution should control the processing via a xml file)
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file