4 include_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')
278 'image/jpeg' => array(
'jpg',
'jpeg'),
'image/png' => array(
'png'),
'image/gif' => array(
'gif')
302 $ilDB = $DIC[
'ilDB'];
309 $this->original_id = null;
315 if (!$this->author) {
316 $this->author = $this->
ilias->account->fullname;
319 if ($this->owner <= 0) {
320 $this->owner = $this->
ilias->account->id;
324 $this->suggested_solutions = array();
326 $this->nr_of_tries = 0;
328 $this->arrData = array();
331 $this->questionActionCmd =
'handleQuestionAction';
333 $this->lastChange = null;
335 require_once
'Services/Randomization/classes/class.ilArrayElementOrderKeeper.php';
350 return self::$forcePassResultsUpdateEnabled;
355 return (
bool) count(self::getAllowedFileExtensionsForMimeType($mimeType));
360 return current(explode(
';', $contentTypeString));
365 foreach (self::$allowedFileExtensionsByMimeType as $allowedMimeType => $extensions) {
366 $rexCharsets = implode(
'|', self::$allowedCharsetsByMimeType[$allowedMimeType]);
367 $rexMimeType = preg_quote($allowedMimeType,
'/');
369 $rex =
'/^' . $rexMimeType .
'(;(\s)*charset=(' . $rexCharsets .
'))*$/';
371 if (!preg_match($rex, $mimeType)) {
384 strtolower($fileExtension),
385 self::getAllowedFileExtensionsForMimeType($mimeType)
396 if (!isset(
$_POST[
'cmd']) || !isset(
$_POST[
'cmd'][$this->questionActionCmd])) {
400 if (!is_array(
$_POST[
'cmd'][$this->questionActionCmd]) || !count(
$_POST[
'cmd'][$this->questionActionCmd])) {
404 return key(
$_POST[
'cmd'][$this->questionActionCmd]);
413 if (!isset(
$_POST[$postSubmissionFieldname])) {
417 if (!is_array(
$_POST[$postSubmissionFieldname])) {
421 if (!count(
$_POST[$postSubmissionFieldname])) {
449 require_once
'Modules/Test/classes/class.ilObjTest.php';
460 $ilDB = $DIC[
'ilDB'];
463 "SELECT test_fi FROM tst_active WHERE active_id = %s",
469 return $row[
"test_fi"];
480 protected function log($active_id, $langVar)
493 $extensions = array();
495 foreach (self::$allowedImageMaterialFileExtensionsByMimeType as $mimeType => $mimeExtensions) {
496 $extensions = array_merge($extensions, $mimeExtensions);
498 return array_unique($extensions);
544 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
546 include_once
"./Modules/TestQuestionPool/classes/import/qti12/class." . $this->
getQuestionType() .
"Import.php";
548 $import =
new $classname($this);
549 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
558 public function toXML($a_include_header =
true, $a_include_binary =
true, $a_shuffle =
false, $test_output =
false, $force_image_references =
false)
560 include_once
"./Modules/TestQuestionPool/classes/export/qti12/class." . $this->
getQuestionType() .
"Export.php";
562 $export =
new $classname($this);
563 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
587 $ilDB = $DIC[
'ilDB'];
590 "SELECT * FROM qpl_questions WHERE obj_fi = %s AND title = %s",
591 array(
'integer',
'text'),
592 array($questionpool_id,
$title)
594 return (
$result->numRows() > 0) ?
true :
false;
630 $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)
714 foreach ($array as $key => $value) {
715 if (strcmp($key, $searchkey) == 0) {
769 require_once
'Services/Utilities/classes/class.ilUtil.php';
863 if (!$this->est_working_time) {
864 $this->est_working_time = array(
"h" => 0,
"m" => 0,
"s" => 0);
946 if (!strlen($this->external_id)) {
947 if ($this->
getId() > 0) {
948 return 'il_' . IL_INST_ID .
'_qst_' . $this->
getId();
950 return uniqid(
'',
true);
966 $ilDB = $DIC[
'ilDB'];
970 "SELECT points FROM qpl_questions WHERE question_id = %s",
990 $ilDB = $DIC[
'ilDB'];
993 "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",
1013 $ilDB = $DIC[
'ilDB'];
1016 "SELECT suggested_solution_id FROM qpl_sol_sug WHERE question_fi = %s",
1035 return $question->getSuggestedSolutionOutput();
1041 foreach ($this->suggested_solutions as $solution) {
1042 switch ($solution[
"type"]) {
1050 $possible_texts = array_values(array_filter(array(
1053 $this->lng->txt(
'tst_show_solution_suggested')
1056 require_once
'Services/WebAccessChecker/classes/class.ilWACSignedPath.php';
1061 $solutionValue = $solution[
"value"];
1062 $solutionValue = $this->
fixSvgToPng($solutionValue);
1068 return join(
"<br />", $output);
1082 $ilDB = $DIC[
'ilDB'];
1085 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
1086 array(
'integer',
'integer'),
1087 array($question_id, $subquestion_index)
1089 if (
$result->numRows() == 1) {
1092 "internal_link" => $row[
"internal_link"],
1093 "import_id" => $row[
"import_id"]
1120 $ilDB = $DIC[
'ilDB'];
1123 if (is_null(
$pass)) {
1124 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
1128 "SELECT * FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
1129 array(
'integer',
'integer',
'integer'),
1130 array($active_id, $question_id,
$pass)
1132 if (
$result->numRows() == 1) {
1149 return round(self::_getReachedPoints($active_id, $this->
getId(),
$pass), 2);
1176 if (is_null(
$pass)) {
1177 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1187 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
1189 $requestsStatisticData = $hintTracking->getRequestStatisticDataByQuestionAndTestpass();
1190 $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
1195 return $reached_points;
1210 $ilDB = $DIC[
'ilDB'];
1213 if (is_null(
$pass)) {
1214 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1222 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
1224 $requestsStatisticData = $questionHintTracking->getRequestStatisticDataByQuestionAndTestpass();
1225 $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
1236 if (is_null($reached_points)) {
1237 $reached_points = 0;
1241 $existingSolutions = $this->lookupForExistingSolutions($active_id,
$pass);
1243 $this->
getProcessLocker()->executeUserQuestionResultUpdateOperation(
function () use (
$ilDB, $active_id,
$pass, $reached_points, $requestsStatisticData, $isAnswered, $existingSolutions) {
1245 DELETE FROM tst_test_result 1247 WHERE active_fi = %s 1248 AND question_fi = %s 1252 $types = array(
'integer',
'integer',
'integer');
1253 $values = array($active_id, $this->
getId(),
$pass);
1255 if ($this->
getStep() !== null) {
1260 $types[] =
'integer';
1265 if ($existingSolutions[
'authorized']) {
1266 $next_id =
$ilDB->nextId(
"tst_test_result");
1268 'test_result_id' => array(
'integer', $next_id),
1269 'active_fi' => array(
'integer', $active_id),
1270 'question_fi' => array(
'integer', $this->
getId()),
1271 'pass' => array(
'integer',
$pass),
1272 'points' => array(
'float', $reached_points),
1273 'tstamp' => array(
'integer', time()),
1274 'hint_count' => array(
'integer', $requestsStatisticData->getRequestsCount()),
1275 'hint_points' => array(
'float', $requestsStatisticData->getRequestsPoints()),
1276 'answered' => array(
'integer', $isAnswered)
1279 if ($this->
getStep() !== null) {
1280 $fieldData[
'step'] = array(
'integer', $this->
getStep());
1283 $ilDB->insert(
'tst_test_result', $fieldData);
1288 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1295 "log_user_answered_question",
1309 include_once
'Modules/Course/classes/class.ilCourseObjectiveResult.php';
1327 $saveStatus =
false;
1329 $this->
getProcessLocker()->executePersistWorkingStateLockOperation(
function () use ($active_id,
$pass, $authorized, $obligationsEnabled, &$saveStatus) {
1331 if (
$pass === null) {
1332 require_once
'Modules/Test/classes/class.ilObjTest.php';
1384 $ilDB = $DIC[
'ilDB'];
1386 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1387 include_once
"./Modules/Test/classes/class.assMarkSchema.php";
1392 SELECT tst_pass_result.* 1393 FROM tst_pass_result 1394 WHERE active_fi = %s 1400 array(
'integer',
'integer'),
1401 array($active_id,
$pass)
1406 $max = $row[
'maxpoints'];
1407 $reached = $row[
'points'];
1409 $obligationsAnswered = (int) $row[
'obligations_answered'];
1411 include_once
"./Modules/Test/classes/class.assMarkSchema.php";
1413 $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
1415 $mark = ASS_MarkSchema::_getMatchingMarkFromActiveId($active_id, $percentage);
1417 $isPassed = ($mark[
"passed"] ? 1 : 0);
1418 $isFailed = (!$mark[
"passed"] ? 1 : 0);
1420 $userTestResultUpdateCallback =
function () use (
$ilDB, $active_id,
$pass, $max, $reached, $isFailed, $isPassed, $obligationsAnswered, $row, $mark) {
1421 $passedOnceBefore = 0;
1422 $query =
"SELECT passed_once FROM tst_result_cache WHERE active_fi = %s";
1424 while ($row =
$ilDB->fetchAssoc(
$res)) {
1425 $passedOnceBefore = (int) $row[
'passed_once'];
1428 $passedOnce = (int) ($isPassed || $passedOnceBefore);
1431 "DELETE FROM tst_result_cache WHERE active_fi = %s",
1436 $ilDB->insert(
'tst_result_cache', array(
1437 'active_fi' => array(
'integer', $active_id),
1438 'pass' => array(
'integer', strlen(
$pass) ?
$pass : 0),
1439 'max_points' => array(
'float', strlen($max) ? $max : 0),
1440 'reached_points' => array(
'float', strlen($reached) ? $reached : 0),
1441 'mark_short' => array(
'text', strlen($mark[
"short_name"]) ? $mark[
"short_name"] :
" "),
1442 'mark_official' => array(
'text', strlen($mark[
"official_name"]) ? $mark[
"official_name"] :
" "),
1443 'passed_once' => array(
'integer', $passedOnce),
1444 'passed' => array(
'integer', $isPassed),
1445 'failed' => array(
'integer', $isFailed),
1446 'tstamp' => array(
'integer', time()),
1447 'hint_count' => array(
'integer', $row[
'hint_count']),
1448 'hint_points' => array(
'float', $row[
'hint_points']),
1449 'obligations_answered' => array(
'integer', $obligationsAnswered)
1454 $processLocker->executeUserTestResultUpdateLockOperation($userTestResultUpdateCallback);
1456 $userTestResultUpdateCallback();
1464 $ilDB = $DIC[
'ilDB'];
1466 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1468 if (self::getResultGateway() !== null) {
1469 $data = self::getResultGateway()->getQuestionCountAndPointsForPassOfParticipant($active_id,
$pass);
1470 $time = self::getResultGateway()->getWorkingTimeOfParticipantForPass($active_id,
$pass);
1481 SELECT SUM(points) reachedpoints, 1482 SUM(hint_count) hint_count, 1483 SUM(hint_points) hint_points, 1484 COUNT(DISTINCT(question_fi)) answeredquestions 1485 FROM tst_test_result 1486 WHERE active_fi = %s 1489 array(
'integer',
'integer'),
1490 array($active_id,
$pass)
1494 if ($obligationsEnabled) {
1496 SELECT answered answ 1497 FROM tst_test_question 1498 INNER JOIN tst_active 1500 AND tst_test_question.test_fi = tst_active.test_fi 1501 LEFT JOIN tst_test_result 1502 ON tst_test_result.active_fi = %s 1503 AND tst_test_result.pass = %s 1504 AND tst_test_question.question_fi = tst_test_result.question_fi 1505 WHERE obligatory = 1';
1507 $result_obligatory =
$ilDB->queryF(
1509 array(
'integer',
'integer',
'integer'),
1510 array($active_id, $active_id,
$pass)
1513 $obligations_answered = 1;
1515 while ($row_obligatory =
$ilDB->fetchAssoc($result_obligatory)) {
1516 if (!(
int) $row_obligatory[
'answ']) {
1517 $obligations_answered = 0;
1522 $obligations_answered = 1;
1527 if ($row[
'reachedpoints'] === null) {
1528 $row[
'reachedpoints'] = 0;
1530 if ($row[
'hint_count'] === null) {
1531 $row[
'hint_count'] = 0;
1533 if ($row[
'hint_points'] === null) {
1534 $row[
'hint_points'] = 0;
1539 $updatePassResultCallback =
function () use (
$ilDB,
$data, $active_id,
$pass, $row, $time, $obligations_answered, $exam_identifier) {
1545 'active_fi' => array(
'integer', $active_id),
1546 'pass' => array(
'integer', strlen(
$pass) ?
$pass : 0)),
1548 'points' => array(
'float', $row[
'reachedpoints'] ? $row[
'reachedpoints'] : 0),
1549 'maxpoints' => array(
'float',
$data[
'points']),
1550 'questioncount' => array(
'integer',
$data[
'count']),
1551 'answeredquestions' => array(
'integer', $row[
'answeredquestions']),
1552 'workingtime' => array(
'integer', $time),
1553 'tstamp' => array(
'integer', time()),
1554 'hint_count' => array(
'integer', $row[
'hint_count']),
1555 'hint_points' => array(
'float', $row[
'hint_points']),
1556 'obligations_answered' => array(
'integer', $obligations_answered),
1557 'exam_id' => array(
'text', $exam_identifier)
1563 $processLocker->executeUserPassResultUpdateLockOperation($updatePassResultCallback);
1565 $updatePassResultCallback();
1572 'active_fi' => $active_id,
1574 'points' => ($row[
"reachedpoints"]) ? $row[
"reachedpoints"] : 0,
1575 'maxpoints' =>
$data[
"points"],
1576 'questioncount' =>
$data[
"count"],
1577 'answeredquestions' => $row[
"answeredquestions"],
1578 'workingtime' => $time,
1580 'hint_count' => $row[
'hint_count'],
1581 'hint_points' => $row[
'hint_points'],
1582 'obligations_answered' => $obligations_answered,
1583 'exam_id' => $exam_identifier
1594 public static function logAction($logtext =
"", $active_id =
"", $question_id =
"")
1597 if (strlen($question_id)) {
1601 require_once
'Modules/Test/classes/class.ilObjAssessmentFolder.php';
1602 require_once
'Modules/Test/classes/class.ilObjTest.php';
1622 $mediatempdir = CLIENT_WEB_DIR .
"/assessment/temp";
1623 if (!@is_dir($mediatempdir)) {
1626 $temp_name = tempnam($mediatempdir,
$name .
"_____");
1627 $temp_name = str_replace(
"\\",
"/", $temp_name);
1628 @unlink($temp_name);
1643 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/solution/";
1654 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/java/";
1665 if ($question_id === null) {
1669 if ($object_id === null) {
1678 return CLIENT_WEB_DIR .
"/assessment/{$parentObjectId}/{$questionId}/images/";
1689 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/flash/";
1700 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1712 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1727 if (!$this->export_image_path) {
1728 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1744 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1766 if (!count($solution)) {
1779 $ilDB = $DIC[
'ilDB'];
1781 if (is_null(
$pass)) {
1785 if ($this->
getStep() !== null) {
1789 WHERE active_fi = %s 1790 AND question_fi = %s 1794 ORDER BY solution_id";
1798 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
1805 WHERE active_fi = %s 1806 AND question_fi = %s 1809 ORDER BY solution_id 1814 array(
'integer',
'integer',
'integer',
'integer'),
1815 array($active_id, $this->
getId(),
$pass, (
int) $authorized)
1837 $ilDB = $DIC[
'ilDB'];
1839 if ($question_id < 1) {
1840 $question_id = $this->
getId();
1843 "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",
1848 $count = $row[
"question_count"];
1852 SELECT tst_active.test_fi 1854 INNER JOIN tst_test_rnd_qst ON tst_test_rnd_qst.question_fi = qpl_questions.question_id 1855 INNER JOIN tst_active ON tst_active.active_id = tst_test_rnd_qst.active_fi 1856 WHERE qpl_questions.original_id = %s 1857 GROUP BY tst_active.test_fi",
1875 $ilDB = $DIC[
'ilDB'];
1877 if ($question_id < 1) {
1881 "SELECT original_id FROM qpl_questions WHERE question_id = %s",
1886 return ($row[
"original_id"] > 0) ? true :
false;
1897 $keys = array_keys($array);
1900 foreach (
$keys as $key) {
1914 $ilDB = $DIC[
'ilDB'];
1917 "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",
1922 return $data[
"type_tag"];
1956 $ilDB = $DIC[
'ilDB'];
1959 if (!is_array($answer_table_name)) {
1960 $answer_table_name = array($answer_table_name);
1963 foreach ($answer_table_name as $table) {
1964 if (strlen($table)) {
1965 $affectedRows =
$ilDB->manipulateF(
1966 "DELETE FROM $table WHERE question_fi = %s",
1983 $ilDB = $DIC[
'ilDB'];
1987 if (!is_array($additional_table_name)) {
1988 $additional_table_name = array($additional_table_name);
1991 foreach ($additional_table_name as $table) {
1992 if (strlen($table)) {
1993 $affectedRows =
$ilDB->manipulateF(
1994 "DELETE FROM $table WHERE question_fi = %s",
2010 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2022 public function delete($question_id)
2025 $ilDB = $DIC[
'ilDB'];
2028 if ($question_id < 1) {
2033 "SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
2037 if (
$result->numRows() == 1) {
2046 $ilLog->write(
"EXCEPTION: Could not delete page of question $question_id: $e");
2050 $affectedRows =
$ilDB->manipulateF(
2051 "DELETE FROM qpl_questions WHERE question_id = %s",
2055 if ($affectedRows == 0) {
2065 $ilLog->write(
"EXCEPTION: Could not delete additional table data of question $question_id: $e");
2071 $affectedRows =
$ilDB->manipulateF(
2072 "DELETE FROM tst_test_question WHERE question_fi = %s",
2077 $ilLog->write(
"EXCEPTION: Could not delete delete question $question_id from a test: $e");
2083 $affectedRows =
$ilDB->manipulateF(
2084 "DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2089 $ilLog->write(
"EXCEPTION: Could not delete suggested solutions of question $question_id: $e");
2094 $directory = CLIENT_WEB_DIR .
"/assessment/" .
$obj_id .
"/$question_id";
2095 if (preg_match(
"/\d+/",
$obj_id) and preg_match(
"/\d+/", $question_id) and is_dir($directory)) {
2096 include_once
"./Services/Utilities/classes/class.ilUtil.php";
2100 $ilLog->write(
"EXCEPTION: Could not delete question file directory $directory of question $question_id: $e");
2105 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2111 foreach (
$mobs as $mob) {
2119 $ilLog->write(
"EXCEPTION: Error deleting the media objects of question $question_id: $e");
2123 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
2124 ilAssQuestionHintTracking::deleteRequestsByQuestionIds(array($question_id));
2126 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
2129 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
2131 $assignmentList->setParentObjId(
$obj_id);
2132 $assignmentList->setQuestionIdFilter($question_id);
2133 $assignmentList->loadFromDb();
2134 foreach ($assignmentList->getAssignmentsByQuestionId($question_id) as $assignment) {
2136 $assignment->deleteFromDb();
2143 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
2146 $ilLog->write(
"EXCEPTION: Error updating the question pool question count of question pool " . $this->
getObjId() .
" when deleting question $question_id: $e");
2157 require_once
'Services/Taxonomy/classes/class.ilObjTaxonomy.php';
2158 require_once
'Services/Taxonomy/classes/class.ilTaxNodeAssignment.php';
2161 foreach ($taxIds as $taxId) {
2163 $taxNodeAssignment->deleteAssignmentsOfItem($this->
getId());
2184 $ilDB = $DIC[
'ilDB'];
2188 "SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
2189 array(
'integer',
'integer'),
2190 array($a_q_id, $a_q_id)
2192 if (
$result->numRows() == 0) {
2195 $found_id = array();
2197 array_push($found_id, $row[
"question_id"]);
2200 $result =
$ilDB->query(
"SELECT * FROM tst_test_result WHERE " .
$ilDB->in(
'question_fi', $found_id,
false,
'integer'));
2215 $ilDB = $DIC[
'ilDB'];
2217 "SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
2218 array(
'integer',
'integer'),
2219 array($a_q_id, $a_q_id)
2221 if (
$result->numRows() == 0) {
2224 $found_id = array();
2226 array_push($found_id, $row[
"question_id"]);
2228 $result =
$ilDB->query(
"SELECT * FROM tst_test_result WHERE " .
$ilDB->in(
'question_fi', $found_id,
false,
'integer'));
2231 $reached = $row[
"points"];
2232 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
2234 array_push($answers, array(
"reached" => $reached,
"max" => $max));
2238 foreach ($answers as $key => $value) {
2239 $max += $value[
"max"];
2240 $reached += $value[
"reached"];
2243 return $reached / $max;
2257 $ilDB = $DIC[
'ilDB'];
2259 "SELECT title FROM qpl_questions WHERE question_id = %s",
2263 if (
$result->numRows() == 1) {
2265 return $row[
"title"];
2279 $ilDB = $DIC[
'ilDB'];
2281 "SELECT question_text FROM qpl_questions WHERE question_id = %s",
2285 if (
$result->numRows() == 1) {
2287 return $row[
"question_text"];
2295 if (!file_exists($file)) {
2299 if (!is_file($file)) {
2303 if (!is_readable($file)) {
2312 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2314 foreach (
$mobs as $mob) {
2321 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2323 foreach (
$mobs as $mob) {
2335 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2337 $this->page->setId($this->
getId());
2338 $this->page->setParentId($qpl_id);
2339 $this->page->setXMLContent(
"<PageObject><PageContent>" .
2340 "<Question QRef=\"il__qst_" . $this->
getId() .
"\"/>" .
2341 "</PageContent></PageObject>");
2342 $this->page->create();
2348 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2351 $xml = str_replace(
"il__qst_" . $a_q_id,
"il__qst_" . $this->
id,
$page->getXMLContent());
2352 $this->page->setXMLContent(
$xml);
2353 $this->page->updateFromXML();
2359 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2361 return $page->getXMLContent();
2372 $ilDB = $DIC[
'ilDB'];
2374 if ($question_id < 1) {
2378 "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",
2382 if (
$result->numRows() == 1) {
2384 return $data[
"type_tag"];
2400 $ilDB = $DIC[
'ilDB'];
2402 if ($question_id < 1) {
2407 "SELECT title FROM qpl_questions WHERE qpl_questions.question_id = %s",
2411 if (
$result->numRows() == 1) {
2413 return $data[
"title"];
2430 'ok.svg' =>
'ok.png',
'not_ok.svg' =>
'not_ok.png',
2431 'checkbox_checked.svg' =>
'checkbox_checked.png',
2432 'checkbox_unchecked.svg' =>
'checkbox_unchecked.png',
2433 'radiobutton_checked.svg' =>
'radiobutton_checked.png',
2434 'radiobutton_unchecked.svg' =>
'radiobutton_unchecked.png' 2439 $needles = array_keys(self::$imageSourceFixReplaceMap);
2440 $replacements = array_values(self::$imageSourceFixReplaceMap);
2441 return str_replace($needles, $replacements, $imageFilenameContainingString);
2448 if (preg_match_all(
'/src="(.*?)"/m', $html, $matches)) {
2449 $sources = $matches[1];
2451 $needleReplacementMap = array();
2453 foreach ($sources as $src) {
2456 if (file_exists($file)) {
2460 $levels = explode(DIRECTORY_SEPARATOR, $src);
2461 if (count($levels) < 5 || $levels[0] !=
'Customizing' || $levels[2] !=
'skin') {
2467 if ($levels[4] ==
'Modules' || $levels[4] ==
'Services') {
2468 $component = $levels[4] . DIRECTORY_SEPARATOR . $levels[5];
2474 if (count($needleReplacementMap)) {
2475 $html = str_replace(array_keys($needleReplacementMap), array_values($needleReplacementMap), $html);
2491 $ilDB = $DIC[
'ilDB'];
2494 "SELECT external_id FROM qpl_questions WHERE question_id = %s",
2498 if (
$result->numRows() == 1) {
2500 $this->external_id =
$data[
'external_id'];
2504 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
2506 array($this->
getId())
2508 $this->suggested_solutions = array();
2510 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2513 $this->suggested_solutions[$row[
"subquestion_index"]] = array(
2514 "type" => $row[
"type"],
2516 "internal_link" => $row[
"internal_link"],
2517 "import_id" => $row[
"import_id"]
2532 $ilDB = $DIC[
'ilDB'];
2537 $estw_time = sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
2540 if ($a_create_page) {
2547 $next_id =
$ilDB->nextId(
'qpl_questions');
2548 $affectedRows =
$ilDB->insert(
"qpl_questions", array(
2549 "question_id" => array(
"integer", $next_id),
2551 "obj_fi" => array(
"integer",
$obj_id),
2552 "title" => array(
"text", null),
2553 "description" => array(
"text", null),
2554 "author" => array(
"text", $this->
getAuthor()),
2555 "owner" => array(
"integer",
$ilUser->getId()),
2556 "question_text" => array(
"clob", null),
2557 "points" => array(
"float", 0),
2559 "working_time" => array(
"text", $estw_time),
2560 "complete" => array(
"text", $complete),
2561 "created" => array(
"integer", time()),
2562 "original_id" => array(
"integer", null),
2563 "tstamp" => array(
"integer", $tstamp),
2567 $this->
setId($next_id);
2569 if ($a_create_page) {
2577 return $this->
getId();
2583 $ilDB = $DIC[
'ilDB'];
2586 $estw_time = sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
2589 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2590 if ($this->
getId() == -1) {
2592 $next_id =
$ilDB->nextId(
'qpl_questions');
2593 $affectedRows =
$ilDB->insert(
"qpl_questions", array(
2594 "question_id" => array(
"integer", $next_id),
2596 "obj_fi" => array(
"integer", $this->
getObjId()),
2597 "title" => array(
"text", $this->
getTitle()),
2598 "description" => array(
"text", $this->
getComment()),
2599 "author" => array(
"text", $this->
getAuthor()),
2600 "owner" => array(
"integer", $this->
getOwner()),
2603 "working_time" => array(
"text", $estw_time),
2604 "nr_of_tries" => array(
"integer", $this->
getNrOfTries()),
2605 "created" => array(
"integer", time()),
2607 "tstamp" => array(
"integer", time()),
2611 $this->
setId($next_id);
2616 $affectedRows =
$ilDB->update(
"qpl_questions", array(
2617 "obj_fi" => array(
"integer", $this->
getObjId()),
2618 "title" => array(
"text", $this->
getTitle()),
2619 "description" => array(
"text", $this->
getComment()),
2620 "author" => array(
"text", $this->
getAuthor()),
2623 "nr_of_tries" => array(
"integer", $this->
getNrOfTries()),
2624 "working_time" => array(
"text", $estw_time),
2625 "tstamp" => array(
"integer", time()),
2626 'complete' => array(
'integer', $this->
isComplete()),
2629 "question_id" => array(
"integer", $this->
getId())
2644 $this->updateSuggestedSolutions();
2654 $DIC->database()->update(
'qpl_questions', array(
2655 'tstamp' => array(
'integer', time()),
2656 'owner' => array(
'integer', ($this->
getOwner() <= 0 ? $this->
ilias->account->id : $this->getOwner())),
2657 'complete' => array(
'integer', $complete),
2658 'lifecycle' => array(
'text', $this->
getLifecycle()->getIdentifier()),
2660 'question_id' => array(
'integer', $this->
getId())
2664 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
2675 self::saveOriginalId($this->
getId(), $newId);
2680 $query =
"UPDATE qpl_questions SET tstamp = %s, original_id = %s WHERE question_id = %s";
2682 $GLOBALS[
'DIC'][
'ilDB']->manipulateF(
2684 array(
'integer',
'integer',
'text'),
2685 array(time(), $originalId, $questionId)
2691 $query =
"UPDATE qpl_questions SET tstamp = %s, original_id = NULL WHERE question_id = %s";
2693 $GLOBALS[
'DIC'][
'ilDB']->manipulateF(
2695 array(
'integer',
'text'),
2696 array(time(), $questionId)
2703 protected function onDuplicate($originalParentId, $originalQuestionId, $duplicateParentId, $duplicateQuestionId)
2708 $this->feedbackOBJ->duplicateFeedback($originalQuestionId, $duplicateQuestionId);
2724 $this->feedbackOBJ->syncFeedback($origQuestionId, $dupQuestionId);
2730 protected function onCopy($sourceParentId, $sourceQuestionId, $targetParentId, $targetQuestionId)
2735 $this->feedbackOBJ->duplicateFeedback($sourceQuestionId, $targetQuestionId);
2750 $ilDB = $DIC[
'ilDB'];
2752 $affectedRows =
$ilDB->manipulateF(
2753 "DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2755 array($this->
getId())
2758 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2760 $this->suggested_solutions = array();
2773 if (array_key_exists($subquestion_index, $this->suggested_solutions)) {
2774 return $this->suggested_solutions[$subquestion_index];
2790 if (array_key_exists($subquestion_index, $this->suggested_solutions)) {
2791 $title = $this->suggested_solutions[$subquestion_index][
"internal_link"];
2810 if (strcmp($solution_id,
"") != 0) {
2813 $import_id = $solution_id;
2816 $this->suggested_solutions[$subquestion_index] = array(
2817 "internal_link" => $solution_id,
2818 "import_id" => $import_id
2831 foreach ($this->suggested_solutions as
$index => $solution) {
2832 if (strcmp($solution[
"type"],
"file") == 0) {
2834 $filepath_original = str_replace(
2835 "/{$this->obj_id}/{$this->id}/solution",
2836 "/$parent_id/$question_id/solution",
2839 if (!file_exists($filepath)) {
2844 if (!copy($filepath_original .
$filename, $filepath . $filename)) {
2845 $ilLog->write(
"File could not be duplicated!!!!",
$ilLog->ERROR);
2846 $ilLog->write(
"object: " . print_r($this,
true),
$ilLog->ERROR);
2862 $filepath_original = str_replace(
"/$this->id/solution",
"/$original_id/solution", $filepath);
2864 foreach ($this->suggested_solutions as
$index => $solution) {
2865 if (strcmp($solution[
"type"],
"file") == 0) {
2866 if (!file_exists($filepath_original)) {
2871 if (!@copy($filepath .
$filename, $filepath_original . $filename)) {
2872 $ilLog->write(
"File could not be duplicated!!!!",
$ilLog->ERROR);
2873 $ilLog->write(
"object: " . print_r($this,
true),
$ilLog->ERROR);
2885 foreach ($this->suggested_solutions as
$index => $solution) {
2886 if (strcmp($solution[
"type"],
"file") == 0) {
2888 $filepath_original = str_replace(
"/$this->obj_id/$this->id/solution",
"/$source_questionpool_id/$source_question_id/solution", $filepath);
2889 if (!file_exists($filepath)) {
2894 if (!copy($filepath_original .
$filename, $filepath . $filename)) {
2895 $ilLog->write(
"File could not be copied!!!!",
$ilLog->ERROR);
2896 $ilLog->write(
"object: " . print_r($this,
true),
$ilLog->ERROR);
2906 public function updateSuggestedSolutions(
$original_id =
"")
2909 $ilDB = $DIC[
'ilDB'];
2912 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2913 $affectedRows =
$ilDB->manipulateF(
2914 "DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2919 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2920 foreach ($this->suggested_solutions as
$index => $solution) {
2921 $next_id =
$ilDB->nextId(
'qpl_sol_sug');
2926 'suggested_solution_id' => array(
'integer', $next_id ),
2927 'question_fi' => array(
'integer',
$id ),
2928 'type' => array(
'text', $solution[
'type'] ),
2930 'internal_link' => array(
'text', $solution[
'internal_link'] ),
2931 'import_id' => array(
'text', null ),
2932 'subquestion_index' => array(
'integer',
$index ),
2933 'tstamp' => array(
'integer', time() ),
2936 if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/", $solution[
"internal_link"], $matches)) {
2955 public function saveSuggestedSolution(
$type, $solution_id =
"", $subquestion_index = 0, $value =
"")
2958 $ilDB = $DIC[
'ilDB'];
2960 $affectedRows =
$ilDB->manipulateF(
2961 "DELETE FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
2962 array(
"integer",
"integer"),
2969 $next_id =
$ilDB->nextId(
'qpl_sol_sug');
2970 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2972 $affectedRows =
$ilDB->insert(
2975 'suggested_solution_id' => array(
'integer', $next_id ),
2976 'question_fi' => array(
'integer', $this->
getId() ),
2977 'type' => array(
'text',
$type ),
2979 'internal_link' => array(
'text', $solution_id ),
2980 'import_id' => array(
'text', null ),
2981 'subquestion_index' => array(
'integer', $subquestion_index ),
2982 'tstamp' => array(
'integer', time() ),
2985 if ($affectedRows == 1) {
2986 $this->suggested_solutions[$subquestion_index] = array(
2989 "internal_link" => $solution_id,
2998 if (preg_match(
"/il_(\d+)_(\w+)_(\d+)/", $internal_link, $matches)) {
2999 switch ($matches[2]) {
3016 if (strcmp($resolved_link,
"") == 0) {
3017 $resolved_link = $internal_link;
3020 $resolved_link = $internal_link;
3022 return $resolved_link;
3028 $ilDB = $DIC[
'ilDB'];
3031 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
3037 $internal_link = $row[
"internal_link"];
3038 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
3040 if (strcmp($internal_link, $resolved_link) != 0) {
3042 $affectedRows =
$ilDB->manipulateF(
3043 "UPDATE qpl_sol_sug SET internal_link = %s WHERE suggested_solution_id = %s",
3044 array(
'text',
'integer'),
3045 array($resolved_link, $row[
"suggested_solution_id"])
3051 if ($resolvedlinks) {
3055 include_once
"./Services/Link/classes/class.ilInternalLink.php";
3059 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
3065 if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/", $row[
"internal_link"], $matches)) {
3076 $ilDB = $DIC[
'ilDB'];
3078 "lm" =>
"LearningModule",
3079 "pg" =>
"PageObject",
3080 "st" =>
"StructureObject",
3081 "git" =>
"GlossaryItem",
3082 "mob" =>
"MediaObject" 3085 if (preg_match(
"/il__(\w+)_(\d+)/", $target, $matches)) {
3086 $type = $matches[1];
3088 include_once
"./Services/Utilities/classes/class.ilUtil.php";
3089 switch ($linktypes[$matches[1]]) {
3090 case "LearningModule":
3094 case "StructureObject":
3097 case "GlossaryItem":
3101 $href =
"./ilias.php?baseClass=ilLMPresentationGUI&obj_type=" . $linktypes[
$type] .
"&cmd=media&ref_id=" .
$_GET[
"ref_id"] .
"&mob_id=" .
$target_id;
3118 $ilDB = $DIC[
'ilDB'];
3120 "SELECT * FROM qpl_questions WHERE question_id = %s",
3126 if ($row[
"original_id"] > 0) {
3127 return $row[
"original_id"];
3129 return $row[
"question_id"];
3139 $ilDB = $DIC[
'ilDB'];
3142 SELECT COUNT(dupl.question_id) cnt 3143 FROM qpl_questions dupl 3144 INNER JOIN qpl_questions orig 3145 ON orig.question_id = dupl.original_id 3146 WHERE dupl.question_id = %s 3152 return $row[
'cnt'] > 0;
3158 $ilDB = $DIC[
'ilDB'];
3164 $originalObjId = self::lookupOriginalParentObjId($this->
getOriginalId());
3166 if (!$originalObjId) {
3176 $this->
setId($original);
3190 $this->updateSuggestedSolutions($original);
3207 $ilDB = $DIC[
'ilDB'];
3209 if ($question_id < 1) {
3214 "SELECT question_id FROM qpl_questions WHERE question_id = %s",
3218 if (
$result->numRows() == 1) {
3235 $ilDB = $DIC[
'ilDB'];
3237 if ($question_id < 1) {
3242 "SELECT question_id FROM qpl_questions INNER JOIN object_data ON obj_fi = obj_id WHERE question_id = %s AND type = 'qpl'",
3246 if (
$result->numRows() == 1) {
3262 return self::_instantiateQuestion($question_id);
3273 $ilDB = $DIC[
'ilDB'];
3276 if (strcmp($question_id,
"") != 0) {
3278 if (!strlen($question_type)) {
3282 $objectClassname = self::getObjectClassNameByQuestionType($question_type);
3286 $feedbackObjectClassname = self::getFeedbackClassNameByQuestionType($question_type);
3301 if (strcmp($this->points,
"") == 0) {
3317 $this->points = $a_points;
3328 return self::_getSolutionMaxPass($this->
getId(), $active_id);
3347 $ilDB = $DIC[
'ilDB'];
3350 "SELECT MAX(pass) maxpass FROM tst_test_result WHERE active_fi = %s AND question_fi = %s",
3351 array(
'integer',
'integer'),
3352 array($active_id, $question_id)
3354 if (
$result->numRows() == 1) {
3356 return $row[
"maxpass"];
3373 $ilDB = $DIC[
'ilDB'];
3375 if (($question_id < 1) || ($user_id < 1)) {
3380 "SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
3384 if (
$result->numRows() == 1) {
3386 $qpl_object_id = $row[
"obj_fi"];
3387 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
3403 $ilDB = $DIC[
'ilDB'];
3405 if ($question_id < 1) {
3409 "SELECT test_random_question_id FROM tst_test_rnd_qst WHERE question_fi = %s",
3435 $reachedPoints = $reachedPoints - $requestsStatisticData->getRequestsPoints();
3437 return $reachedPoints;
3477 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3479 if ($count_system == 1) {
3485 if ($score_cutting == 0) {
3503 return self::lookupResultRecordExist($active_id, $question_id,
$pass);
3508 $ilDB = $DIC[
'ilDB'];
3511 if (is_null(
$pass)) {
3512 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
3516 "SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3517 array(
'integer',
'integer',
'integer'),
3518 array($active_id, $question_id,
$pass)
3537 $ilDB = $DIC[
'ilDB'];
3540 "SELECT DISTINCT(question_fi) FROM tst_test_result JOIN tst_active " .
3541 "ON (active_id = active_fi) " .
3542 "WHERE " .
$ilDB->in(
'question_fi', $a_question_ids,
false,
'integer') .
3543 " AND user_fi = %s",
3547 return (
$res->numRows() == count($a_question_ids)) ?
true :
false;
3571 include_once
"./Services/Utilities/classes/class.ilUtil.php";
3585 for (
$i = 0;
$i < $a_material->getMaterialCount();
$i++) {
3586 $material = $a_material->getMaterial(
$i);
3587 if (strcmp($material[
"type"],
"mattext") == 0) {
3588 $result .= $material[
"material"]->getContent();
3590 if (strcmp($material[
"type"],
"matimage") == 0) {
3591 $matimage = $material[
"material"];
3592 if (preg_match(
"/(il_([0-9]+)_mob_([0-9]+))/", $matimage->getLabel(), $matches)) {
3594 if (!is_array(
$_SESSION[
"import_mob_xhtml"])) {
3595 $_SESSION[
"import_mob_xhtml"] = array();
3597 array_push(
$_SESSION[
"import_mob_xhtml"], array(
"mob" => $matimage->getLabel(),
"uri" => $matimage->getUri()));
3612 public function addQTIMaterial(&$a_xml_writer, $a_material, $close_material_tag =
true, $add_mobs =
true)
3614 include_once
"./Services/RTE/classes/class.ilRTE.php";
3615 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
3617 $a_xml_writer->xmlStartTag(
"material");
3619 "texttype" =>
"text/plain" 3621 if ($this->
isHTML($a_material)) {
3622 $attrs[
"texttype"] =
"text/xhtml";
3627 foreach (
$mobs as $mob) {
3628 $moblabel =
"il_" . IL_INST_ID .
"_mob_" . $mob;
3629 if (strpos($a_material,
"mm_$mob") !==
false) {
3633 "label" => $moblabel,
3634 "uri" =>
"objects/" .
"il_" . IL_INST_ID .
"_mob_" . $mob .
"/" . $mob_obj->getTitle()
3637 $a_xml_writer->xmlElement(
"matimage", $imgattrs, null);
3641 if ($close_material_tag) {
3642 $a_xml_writer->xmlEndTag(
"material");
3650 if (preg_match(
"/.*\.(png|jpg|gif|jpeg)$/i", $plain_image_filename, $matches)) {
3651 $extension =
"." . $matches[1];
3655 $plain_image_filename = uniqid($plain_image_filename . microtime(
true));
3658 $hashed_filename = md5($plain_image_filename) . $extension;
3660 return $hashed_filename;
3676 $ilDB = $DIC[
'ilDB'];
3679 if (is_null(
$pass)) {
3686 "SELECT points FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3687 array(
'integer',
'integer',
'integer'),
3688 array($active_id, $question_id,
$pass)
3690 $manual = ($manualscoring) ? 1 : 0;
3691 $rowsnum =
$result->numRows();
3694 $old_points = $row[
"points"];
3696 $affectedRows =
$ilDB->manipulateF(
3697 "UPDATE tst_test_result SET points = %s, manual = %s, tstamp = %s WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3698 array(
'float',
'integer',
'integer',
'integer',
'integer',
'integer'),
3699 array(
$points, $manual, time(), $active_id, $question_id,
$pass)
3703 $next_id =
$ilDB->nextId(
'tst_test_result');
3704 $affectedRows =
$ilDB->manipulateF(
3705 "INSERT INTO tst_test_result (test_result_id, active_fi, question_fi, points, pass, manual, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
3706 array(
'integer',
'integer',
'integer',
'float',
'integer',
'integer',
'integer'),
3707 array($next_id, $active_id, $question_id,
$points,
$pass, $manual, time())
3711 if (self::isForcePassResultUpdateEnabled() || $old_points !=
$points || !$rowsnum) {
3712 assQuestion::_updateTestPassResults($active_id,
$pass, $obligationsEnabled);
3714 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3715 include_once
'./Modules/Course/classes/class.ilCourseObjectiveResult.php';
3718 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
3723 include_once
"./Modules/Test/classes/class.ilObjTestAccess.php";
3780 $ilDB = $DIC[
'ilDB'];
3783 "SELECT question_type_id FROM qpl_qst_type WHERE type_tag = %s",
3787 if (
$result->numRows() == 1) {
3789 return $row[
"question_type_id"];
3794 public function syncHints()
3797 $ilDB = $DIC[
'ilDB'];
3801 "DELETE FROM qpl_hints WHERE qht_question_fi = %s",
3803 array($this->original_id)
3808 "SELECT * FROM qpl_hints WHERE qht_question_fi = %s",
3810 array($this->
getId())
3816 $next_id =
$ilDB->nextId(
'qpl_hints');
3821 'qht_hint_id' => array(
'integer', $next_id),
3822 'qht_question_fi' => array(
'integer', $this->original_id),
3823 'qht_hint_index' => array(
'integer', $row[
"qht_hint_index"]),
3824 'qht_hint_points' => array(
'integer', $row[
"qht_hint_points"]),
3825 'qht_hint_text' => array(
'text', $row[
"qht_hint_text"]),
3841 $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(),
false);
3842 $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(),
true);
3843 $collected .= $this->feedbackOBJ->getAllSpecificAnswerFeedbackContents($this->
getId());
3845 foreach ($this->suggested_solutions as $solution_array) {
3846 $collected .= $solution_array[
"value"];
3849 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
3851 foreach ($questionHintList as $questionHint) {
3853 $collected .= $questionHint->getText();
3866 include_once(
"./Services/RTE/classes/class.ilRTE.php");
3878 $ilDB = $DIC[
'ilDB'];
3881 "SELECT question_id FROM qpl_questions WHERE original_id = %s",
3883 array($this->
getId())
3885 $instances = array();
3888 array_push($ids, $row[
"question_id"]);
3890 foreach ($ids as $question_id) {
3893 "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",
3902 "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",
3910 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3911 foreach ($instances as $key => $value) {
3919 include_once
"./Modules/Test/classes/class.ilObjAssessmentFolder.php";
3922 if (in_array($questiontype, $scoring)) {
3939 $ilDB = $DIC[
'ilDB'];
3941 "SELECT * FROM tst_active WHERE active_id = %s",
3947 return array(
"user_id" => $row[
"user_fi"],
"test_id" => $row[
"test_fi"]);
3962 if (self::isCoreQuestionType($question_type)) {
3963 self::includeCoreClass($question_type, $gui);
3965 self::includePluginClass($question_type, $gui);
3971 return $questionType .
'GUI';
3976 return $questionType;
3981 return str_replace(
'ass',
'ilAss', $questionType) .
'Feedback';
3986 $guiClassName = self::getGuiClassNameByQuestionType($questionType);
3987 return file_exists(
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php");
3992 if ($withGuiClass) {
3993 $guiClassName = self::getGuiClassNameByQuestionType($questionType);
3994 require_once
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php";
3998 $objectClassName = self::getObjectClassNameByQuestionType($questionType);
3999 require_once
"Modules/TestQuestionPool/classes/class.{$objectClassName}.php";
4002 $feedbackClassName = self::getFeedbackClassNameByQuestionType($questionType);
4003 require_once
"Modules/TestQuestionPool/classes/feedback/class.{$feedbackClassName}.php";
4009 $ilPluginAdmin = $DIC[
'ilPluginAdmin'];
4012 self::getObjectClassNameByQuestionType($questionType),
4013 self::getFeedbackClassNameByQuestionType($questionType)
4016 if ($withGuiClass) {
4017 $classes[] = self::getGuiClassNameByQuestionType($questionType);
4020 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
"TestQuestionPool",
"qst");
4021 foreach ($pl_names as $pl_name) {
4023 if (strcmp($pl->getQuestionType(), $questionType) == 0) {
4024 foreach ($classes as $class) {
4025 $pl->includeClass(
"class.{$class}.php");
4041 if (file_exists(
"./Modules/TestQuestionPool/classes/class." . $type_tag .
".php")) {
4044 return $lng->txt($type_tag);
4047 $ilPluginAdmin = $DIC[
'ilPluginAdmin'];
4048 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
"TestQuestionPool",
"qst");
4049 foreach ($pl_names as $pl_name) {
4051 if (strcmp($pl->getQuestionType(), $type_tag) == 0) {
4052 return $pl->getQuestionTypeTranslation();
4070 return self::instantiateQuestionGUI($question_id);
4084 $ilDB = $DIC[
'ilDB'];
4088 if (strcmp($a_question_id,
"") != 0) {
4093 $question_type_gui = self::getGuiClassNameByQuestionType($question_type);
4094 $question_gui =
new $question_type_gui();
4095 $question_gui->object->loadFromDb($a_question_id);
4097 $feedbackObjectClassname = self::getFeedbackClassNameByQuestionType($question_type);
4098 $question_gui->object->feedbackOBJ =
new $feedbackObjectClassname($question_gui->object,
$ilCtrl,
$ilDB,
$lng);
4100 $assSettings =
new ilSetting(
'assessment');
4101 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionProcessLockerFactory.php';
4103 $processLockerFactory->setQuestionId($question_gui->object->getId());
4104 $processLockerFactory->setUserId(
$ilUser->getId());
4105 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
4107 $question_gui->object->setProcessLocker($processLockerFactory->getLocker());
4111 $ilLog->write(
'Instantiate question called without question id. (instantiateQuestionGUI@assQuestion)',
$ilLog->WARNING);
4114 return $question_gui;
4129 $worksheet->setFormattedExcelTitle($worksheet->getColumnCoord(0) . $startrow, $this->lng->txt($this->
getQuestionType()));
4130 $worksheet->setFormattedExcelTitle($worksheet->getColumnCoord(1) . $startrow, $this->
getTitle());
4142 return $this->
getId();
4162 case "est_working_time":
4186 case "suggested_solutions":
4193 if (array_key_exists($value, $this->arrData)) {
4194 return $this->arrData[$value];
4209 $this->
setId($value);
4229 case "est_working_time":
4230 if (is_array($value)) {
4250 $this->page = &$value;
4253 $this->arrData[$key] = $value;
4265 $this->nr_of_tries = $a_nr_of_tries;
4270 $this->export_image_path = (string) $a_path;
4276 $ilDB = $DIC[
'ilDB'];
4278 if ($question_id < 1) {
4283 "SELECT question_fi FROM tst_test_question WHERE question_fi = %s AND test_fi = %s",
4284 array(
'integer',
'integer'),
4287 if (
$result->numRows() == 1) {
4310 require_once
'Modules/TestQuestionPool/classes/questions/class.ilAssSelfAssessmentQuestionFormatter.php';
4311 return new \ilAssSelfAssessmentQuestionFormatter();
4323 $this->prevent_rte_usage = $a_val;
4345 $this->feedbackOBJ->migrateContentForLearningModule($migrator, $this->
getId());
4371 $this->selfassessmenteditingmode = $a_selfassessmenteditingmode;
4391 $this->defaultnroftries = $a_defaultnroftries;
4414 $ilDB = $DIC[
'ilDB'];
4416 $query =
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s";
4418 $res =
$ilDB->queryF(
$query, array(
'integer'), array((
int) $questionId));
4421 return $row[
'obj_fi'];
4436 return self::lookupParentObjId($originalQuestionId);
4441 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
4445 require_once
'Modules/TestQuestionPool/classes/class.ilAssHintPage.php';
4447 foreach ($hintIds as $originalHintId => $duplicateHintId) {
4449 $originalXML = $originalPageObject->getXMLContent();
4452 $duplicatePageObject->setId($duplicateHintId);
4453 $duplicatePageObject->setParentId($this->
getId());
4454 $duplicatePageObject->setXMLContent($originalXML);
4455 $duplicatePageObject->createFromXML();
4463 $ilDB = $DIC[
'ilDB'];
4465 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
4467 $assignmentList->setParentObjId($srcParentId);
4468 $assignmentList->setQuestionIdFilter($srcQuestionId);
4469 $assignmentList->loadFromDb();
4471 foreach ($assignmentList->getAssignmentsByQuestionId($srcQuestionId) as $assignment) {
4474 $assignment->setParentObjId($trgParentId);
4475 $assignment->setQuestionId($trgQuestionId);
4476 $assignment->saveToDb();
4483 $ilDB = $DIC[
'ilDB'];
4485 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
4487 $assignmentList->setParentObjId($trgParentId);
4488 $assignmentList->setQuestionIdFilter($trgQuestionId);
4489 $assignmentList->loadFromDb();
4491 foreach ($assignmentList->getAssignmentsByQuestionId($trgQuestionId) as $assignment) {
4494 $assignment->deleteFromDb();
4554 $ilDB = $DIC[
'ilDB'];
4557 SELECT count(active_fi) cnt 4561 WHERE active_fi = %s 4562 AND question_fi = %s 4568 array(
'integer',
'integer',
'integer'),
4569 array($activeId, $questionId,
$pass)
4574 return (
int) $row[
'cnt'];
4597 require_once
'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
4640 self::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT,
4641 self::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
4650 $this->questionChangeListeners[] = $listener;
4664 $listener->notifyQuestionCreated($this);
4671 $listener->notifyQuestionEdited($this);
4678 $listener->notifyQuestionDeleted($this);
4687 require_once
'Services/Html/classes/class.ilHtmlPurifierFactory.php';
4699 SELECT qpl_questions.*, 4700 {$this->getAdditionalTableName()}.* 4702 LEFT JOIN {$this->getAdditionalTableName()} 4703 ON {$this->getAdditionalTableName()}.question_fi = qpl_questions.question_id 4704 WHERE qpl_questions.question_id = %s 4731 $ilDB = $DIC[
'ilDB'];
4733 if ($this->
getStep() !== null) {
4737 WHERE active_fi = %s 4738 AND question_fi = %s 4744 return $ilDB->queryF(
4746 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
4753 WHERE active_fi = %s 4754 AND question_fi = %s 4759 return $ilDB->queryF(
4761 array(
'integer',
'integer',
'integer',
'integer'),
4762 array($active_id, $this->
getId(),
$pass, (
int) $authorized)
4776 $ilDB = $DIC[
'ilDB'];
4778 return $ilDB->manipulateF(
4779 "DELETE FROM tst_solutions WHERE solution_id = %s",
4795 $ilDB = $DIC[
'ilDB'];
4798 "SELECT * FROM tst_solutions WHERE solution_id = %s",
4803 while ($row =
$ilDB->fetchAssoc(
$res)) {
4819 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use ($active_id,
$pass) {
4835 $ilDB = $DIC[
'ilDB'];
4837 if ($this->
getStep() !== null) {
4839 DELETE FROM tst_solutions 4840 WHERE active_fi = %s 4841 AND question_fi = %s 4847 return $ilDB->manipulateF(
4849 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
4854 DELETE FROM tst_solutions 4855 WHERE active_fi = %s 4856 AND question_fi = %s 4861 return $ilDB->manipulateF(
4863 array(
'integer',
'integer',
'integer',
'integer'),
4864 array($active_id, $this->
getId(),
$pass, (
int) $authorized)
4884 $ilDB = $DIC[
'ilDB'];
4886 $next_id =
$ilDB->nextId(
"tst_solutions");
4889 "solution_id" => array(
"integer", $next_id),
4890 "active_fi" => array(
"integer", $active_id),
4891 "question_fi" => array(
"integer", $this->
getId()),
4892 "value1" => array(
"clob", $value1),
4893 "value2" => array(
"clob", $value2),
4894 "pass" => array(
"integer",
$pass),
4895 "tstamp" => array(
"integer", isset($tstamp) ? $tstamp : time()),
4896 'authorized' => array(
'integer', (
int) $authorized)
4899 if ($this->
getStep() !== null) {
4900 $fieldData[
'step'] = array(
"integer", $this->
getStep());
4903 return $ilDB->insert(
"tst_solutions", $fieldData);
4920 $ilDB = $DIC[
'ilDB'];
4923 "value1" => array(
"clob", $value1),
4924 "value2" => array(
"clob", $value2),
4925 "tstamp" => array(
"integer", time()),
4926 'authorized' => array(
'integer', (
int) $authorized)
4929 if ($this->
getStep() !== null) {
4930 $fieldData[
'step'] = array(
"integer", $this->
getStep());
4933 return $ilDB->update(
"tst_solutions", $fieldData, array(
4934 'solution_id' => array(
'integer', $solutionId)
4942 $ilDB = $DIC[
'ilDB'];
4945 'authorized' => array(
'integer', (
int) $authorized)
4949 $fieldData[
'tstamp'] = array(
'integer', time());
4953 'question_fi' => array(
'integer', $this->
getId()),
4954 'active_fi' => array(
'integer', $activeId),
4955 'pass' => array(
'integer',
$pass)
4958 if ($this->
getStep() !== null) {
4959 $whereData[
'step'] = array(
"integer", $this->
getStep());
4962 return $ilDB->update(
'tst_solutions', $fieldData, $whereData);
4970 return self::KEY_VALUES_IMPLOSION_SEPARATOR;
4974 return implode(self::getKeyValuesImplosionSeparator(), $keyValues);
4978 return explode(self::getKeyValuesImplosionSeparator(), $keyValues);
4983 foreach ($this->
getSolutionValues($activeId, $passIndex,
false) as $solutionRec) {
4984 if (0 == strlen($solutionRec[
'value1']) && 0 == strlen($solutionRec[
'value2'])) {
4992 return !strlen($solutionRecord[
'value1']) && !strlen($solutionRecord[
'value2']);
4998 $ilDB = $DIC[
'ilDB'];
5000 $types = array(
"integer",
"integer",
"integer",
"integer");
5001 $values = array($activeId, $this->
getId(), $passIndex, (
int) $authorized);
5002 $valuesCondition = array();
5004 foreach ($matchValues as $valueField => $value) {
5005 switch ($valueField) {
5008 $valuesCondition[] =
"{$valueField} = %s";
5014 require_once
'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
5019 $valuesCondition = implode(
' AND ', $valuesCondition);
5022 DELETE FROM tst_solutions 5023 WHERE active_fi = %s 5024 AND question_fi = %s 5027 AND $valuesCondition 5030 if ($this->
getStep() !== null) {
5031 $query .=
" AND step = %s ";
5032 $types[] =
'integer';
5042 $this->
saveCurrentSolution($activeId, $passIndex, $rec[
'value1'], $rec[
'value2'],
true, $rec[
'tstamp']);
5050 if (!count($intermediateSolution)) {
5058 if ($considerDummyRecordCreation) {
5080 return self::$resultGateway;
5088 $this->step =
$step;
5108 return gmdate(
'H:i:s', $time);
5118 $time_array = explode(
':', $time);
5119 if (
sizeof($time_array) == 3) {
5120 $sec += $time_array[0] * 3600;
5121 $sec += $time_array[1] * 60;
5122 $sec += $time_array[2];
5129 return json_encode(array());
5137 $solutionAvailability = $this->lookupForExistingSolutions($active_id,
$pass);
5138 return (
bool) $solutionAvailability[
'intermediate'];
5142 $solutionAvailability = $this->lookupForExistingSolutions($active_id,
$pass);
5143 return (
bool) $solutionAvailability[
'authorized'];
5147 $solutionAvailability = $this->lookupForExistingSolutions($active_id,
$pass);
5148 return (
bool) $solutionAvailability[
'authorized'] || (bool) $solutionAvailability[
'intermediate'];
5157 protected function lookupMaxStep($active_id,
$pass)
5161 $ilDB = $DIC[
'ilDB'];
5164 "SELECT MAX(step) max_step FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
5165 array(
"integer",
"integer",
"integer"),
5171 $maxStep = $row[
'max_step'];
5183 public function lookupForExistingSolutions($activeId,
$pass)
5187 $ilDB = $DIC[
'ilDB'];
5190 'authorized' =>
false,
5191 'intermediate' =>
false 5195 SELECT authorized, COUNT(*) cnt 5197 WHERE active_fi = %s 5198 AND question_fi = %s 5202 if ($this->
getStep() !== null) {
5213 if ($row[
'authorized']) {
5214 $return[
'authorized'] = $row[
'cnt'] > 0;
5216 $return[
'intermediate'] = $row[
'cnt'] > 0;
5236 $query =
"DELETE FROM tst_solutions WHERE question_fi = %s";
5238 $DIC->database()->manipulateF(
$query, array(
'integer'), array($this->
getId()));
5244 $ilDB = $DIC[
'ilDB'];
5247 DELETE FROM tst_solutions 5248 WHERE active_fi = %s 5249 AND question_fi = %s 5253 if ($this->
getStep() !== null) {
5257 return $ilDB->manipulateF(
5259 array(
'integer',
'integer',
'integer'),
5269 $this->
log($activeId,
"log_user_solution_willingly_deleted");
5271 self::_updateTestPassResults(
5283 $ilDB = $DIC[
'ilDB'];
5286 DELETE FROM tst_test_result 5287 WHERE active_fi = %s 5288 AND question_fi = %s 5292 if ($this->
getStep() !== null) {
5296 return $ilDB->manipulateF(
5298 array(
'integer',
'integer',
'integer'),
5306 $ilDB = $DIC[
'ilDB'];
5308 $IN_questionIds =
$ilDB->in(
'question_fi', $questionIds,
false,
'integer');
5312 FROM tst_test_result 5313 WHERE active_fi = %s 5320 array(
'integer',
'integer'),
5321 array($activeId,
$pass)
5324 return $row[
'cnt'] < count($questionIds);
5330 $ilDB = $DIC[
'ilDB'];
5332 $IN_questionIds =
$ilDB->in(
'question_fi', $questionIds,
false,
'integer');
5336 FROM tst_test_result 5337 WHERE active_fi = %s 5344 array(
'integer',
'integer'),
5345 array($activeId,
$pass)
5348 $questionsHavingResultRecord = array();
5350 while ($row =
$ilDB->fetchAssoc(
$res)) {
5351 $questionsHavingResultRecord[] = $row[
'question_fi'];
5354 $questionsMissingResultRecordt = array_diff(
5356 $questionsHavingResultRecord
5359 return $questionsMissingResultRecordt;
5365 $ilDB = $DIC[
'ilDB'];
5369 FROM tst_test_result 5370 WHERE active_fi = %s 5371 AND question_fi = %s 5375 $row =
$ilDB->fetchAssoc(
$ilDB->queryF(
$query, array(
'integer',
'integer',
'integer'), array($activeId, $questionId,
$pass)));
5377 return $row[
'cnt'] > 0;
5386 $valuePairs = array();
5388 foreach ($indexedValues as $value1 => $value2) {
5389 $valuePairs[] = array(
'value1' => $value1,
'value2' => $value2);
5401 $indexedValues = array();
5403 foreach ($valuePairs as $valuePair) {
5404 $indexedValues[ $valuePair[
'value1'] ] = $valuePair[
'value2'];
5407 return $indexedValues;
5429 $ilDB = $DIC[
'ilDB'];
5432 "UPDATE qpl_questions SET tstamp = %s WHERE question_id = %s",
5433 array(
'integer',
'integer'),
5434 array(time(), $this->
getId())
5455 if ($this->testQuestionConfigInstance === null) {
5472 include_once(
'Modules/TestQuestionPool/classes/class.ilTestQuestionConfig.php');
static _getUserIdFromActiveId($active_id)
isInUse($question_id="")
Checks whether the question is in use or not.
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
static isCoreQuestionType($questionType)
static resetOriginalId($questionId)
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
deletePageOfQuestion($question_id)
Deletes the page object of a question with a given ID.
afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
getId()
Gets the id of the assQuestion object.
static _getManualScoringTypes()
Retrieve the manual scoring settings as type strings.
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms public
saveToDb($original_id="")
Saves the question to the database.
static getListByQuestionId($questionId)
instantiates a question hint list for the passed question id
static _getWorkingTimeOfParticipantForPass($active_id, $pass)
Returns the complete working time in seconds for a test participant.
static isFileAvailable($file)
$export_image_path
(Web) Path to images
Test Question configuration.
static _getQuestionText($a_q_id)
Returns question text.
getFlashPathWeb()
Returns the web image path for web accessable flash applications of a question.
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
static getAllowedImageMaterialFileExtensions()
static _getOriginalId($question_id)
Returns the original id of a question.
static getPluginObject(string $a_ctype, string $a_cname, string $a_slot_id, string $a_pname)
formatSAQuestion($a_q)
Format self assessment question.
setSuggestedSolution($solution_id="", $subquestion_index=0, $is_import=false)
Sets a suggested solution for the question.
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.
static getObjectClassNameByQuestionType($questionType)
Taxonomy node <-> item assignment.
migrateContentForLearningModule(ilAssSelfAssessmentMigrator $migrator)
static _includeClass($question_type, $gui=0)
Include the php class file for a given question type.
static _updateTestResultCache($active_id, ilAssQuestionProcessLocker $processLocker=null)
Move this to a proper place.
static getQuestionTypeFromDb($question_id)
get question type for question id
static _isWriteable($object_id, $user_id)
Returns true, if the question pool is writeable by a given user.
forceExistingIntermediateSolution($activeId, $passIndex, $considerDummyRecordCreation)
_getTotalAnswers($a_q_id)
get number of answers for question id (static) note: do not use $this inside this method ...
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static sumTimesInISO8601FormatH_i_s_Extended($time1, $time2)
static _getParticipantData($active_id)
Retrieves a participant name from active id.
_questionExistsInPool($question_id)
Returns true if the question already exists in the database and is assigned to a question pool...
copySuggestedSolutionFiles($source_questionpool_id, $source_question_id)
static getNumExistingSolutionRecords($activeId, $pass, $questionId)
returns the number of existing solution records for the given test active / pass and given question i...
duplicateIntermediateSolutionAuthorized($activeId, $passIndex)
buildHashedImageFilename($plain_image_filename, $unique=false)
getSuggestedSolutionPath()
Returns the path for a suggested solution.
getTitleFilenameCompliant()
returns the object title prepared to be used as a filename
static _getQuestionType($question_id)
Returns the question type of a question with a given id.
static _getSolutionMaxPass($question_id, $active_id)
Returns the maximum pass a users question solution.
static getUsageOfObject($a_obj_id, $a_include_titles=false)
Get usage of object.
static lookupResultRecordExist($activeId, $questionId, $pass)
getQuestionType()
Returns the question type of the question.
static includeCoreClass($questionType, $withGuiClass)
syncSkillAssignments($srcParentId, $srcQuestionId, $trgParentId, $trgQuestionId)
static _getTotalRightAnswers($a_q_id)
get number of answers for question id (static) note: do not use $this inside this method ...
getPoints()
Returns the maximum available points for the question.
static originalQuestionExists($questionId)
static _isUsedInRandomTest($question_id="")
Checks whether the question is used in a random test or not.
copyPageOfQuestion($a_q_id)
questionTitleExists($questionpool_id, $title)
Returns TRUE if the question title exists in the database.
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.
const ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
constant for additional content editing mode "pageobject"
buildTestPresentationConfig()
build basic test question configuration instance
static getQuestionsMissingResultRecord($activeId, $pass, $questionIds)
__set($key, $value)
Object setter.
__get($value)
Object getter.
Abstract basic class which is to be extended by the concrete assessment question type classes...
static _needsManualScoring($question_id)
& _getSuggestedSolution($question_id, $subquestion_index=0)
Returns a suggested solution for a given subquestion index.
setDefaultNrOfTries($a_defaultnroftries)
Set Default Nr of Tries.
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 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 _getIdForImportId($a_import_id)
get current object id for import id (static)
createPageObject()
create page object of question
intermediateSolutionExists($active_id, $pass)
adjustReachedPointsByScoringOptions($points, $active_id, $pass=null)
Adjust the given reached points by checks for all special scoring options in the test container...
ensureNonNegativePoints($points)
deleteAnswers($question_id)
Deletes datasets from answers tables.
deleteDummySolutionRecord($activeId, $passIndex)
calculateResultsFromSolution($active_id, $pass=null, $obligationsEnabled=false)
Calculates the question results from a previously saved question solution.
static & _instanciateQuestionGUI($question_id)
Creates an instance of a question gui with a given question id.
static _areAnswered($a_user_id, $a_question_ids)
Checks if an array of question ids is answered by an user or not.
getSuggestedSolutionTitle($subquestion_index=0)
Returns the title of a suggested solution at a given subquestion_index.
$additinalContentEditingMode
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
getQuestionChangeListeners()
setId($id=-1)
Sets the id of the assQuestion object.
copyXHTMLMediaObjectsOfQuestion($a_q_id)
static _getQuestionTypeName($type_tag)
Return the translation for a given question type tag.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
duplicateSkillAssignments($srcParentId, $srcQuestionId, $trgParentId, $trgQuestionId)
static isForcePassResultUpdateEnabled()
static _getSuggestedSolutionCount($question_id)
Returns the number of suggested solutions associated with a question.
getUserSolutionPreferingIntermediate($active_id, $pass=null)
getImagePathWeb()
Returns the web image path for web accessable images of a question.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
removeResultRecord($activeId, $pass)
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...
static includePluginClass($questionType, $withGuiClass)
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
migrateToLmContent($content)
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
static _lookupTitle($a_id)
lookup object title
static _getIdForImportId($a_type, $a_target)
Get current id for an import id.
syncSuggestedSolutionFiles($original_id)
Syncs the files of a suggested solution if the question is synced.
syncXHTMLMediaObjectsOfQuestion()
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assQuestion constructor
beforeSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
getAdditionalContentEditingMode()
getter for additional content editing mode for this question
getJavaPath()
Returns the image path for web accessable images of a question.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
deleteAdditionalTableData($question_id)
Deletes datasets from the additional question table in the database.
getParticipantsSolution()
isAnswered($active_id, $pass=null)
returns boolean wether the question is answered during test pass or not
setEstimatedWorkingTimeFromDurationString($durationString)
Sets the estimated working time of a question from a given datetime string.
getSelfAssessmentEditingMode()
Get Self-Assessment Editing Mode.
isAddableAnswerOptionValue($qIndex, $answerOptionValue)
setNrOfTries($a_nr_of_tries)
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
static lookupParentObjId($questionId)
ilDBInterface $ilDB
isHTML($a_text)
Checks if a given string contains HTML or not.
static _getObjectIDFromActiveID($active_id)
Returns the ILIAS test object id for a given active id.
loadFromDb($question_id)
Loads the question from the database.
persistPreviewState(ilAssQuestionPreviewSession $previewSession)
persists the preview state for current user and question
authorizedSolutionExists($active_id, $pass)
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
setShuffle($shuffle=true)
Sets the shuffle flag.
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...
getObjId()
Get the object id of the container object.
getValidAdditionalContentEditingModes()
getter for valid additional content editing modes
static _getMaximumPoints($question_id)
Returns the maximum points, a learner can reach answering the question.
getShuffle()
Gets the shuffle flag.
$arrData
Associative array to store properties.
static _getAllReferences($a_id)
get all reference ids of object
isValidAdditionalContentEditingMode($additionalContentEditingMode)
returns the fact wether the passed additional content mode is valid or not
& getInstances()
Gets all instances of the question.
fetchIndexedValuesFromValuePairs(array $valuePairs)
setParticipantsSolution($participantSolution)
setProcessLocker($processLocker)
static _getInternalLinkHref($target="")
isPreviewSolutionCorrect(ilAssQuestionPreviewSession $previewSession)
static _getQuestionInfo($question_id)
Returns question information from the database.
static convertISO8601FormatH_i_s_ExtendedToSeconds($time)
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
static deleteHintsByQuestionIds($questionIds)
Deletes all question hints relating to questions included in given question ids.
getSuggestedSolution($subquestion_index=0)
Returns a suggested solution for a given subquestion index.
authorizedOrIntermediateSolutionExists($active_id, $pass)
removeSolutionRecordById($solutionId)
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
duplicateQuestionHints($originalQuestionId, $duplicateQuestionId)
addAnswerOptionValue($qIndex, $answerOptionValue, $points)
static _getLogLanguage()
retrieve the log language for assessment logging
persistWorkingState($active_id, $pass=null, $obligationsEnabled=false, $authorized=true)
persists the working state for current testactive and testpass
supportsJavascriptOutput()
Returns true if the question type supports JavaScript output.
getJavaPathWeb()
Returns the web image path for web accessable java applets of a question.
getFlashPath()
Returns the image path for web accessable flash files of a question.
static isAllowedImageMimeType($mimeType)
getTestId()
Gets the test id of the assQuestion object.
setAuthor($author="")
Sets the authors name of the assQuestion object.
setObligationsToBeConsidered($obligationsToBeConsidered)
Assessment hint page object.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
getAuthor()
Gets the authors name of the assQuestion object.
getTotalAnswers()
get total number of answers
getQuestionTypeID()
Returns the question type of the question.
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
static _updateQuestionCount($object_id)
Updates the number of available questions for a question pool in the database.
foreach($_POST as $key=> $value) $res
static _getQuestionCountAndPointsForPassOfParticipant($active_id, $pass)
areObligationsToBeConsidered()
static setForcePassResultUpdateEnabled($forcePassResultsUpdateEnabled)
updateCurrentSolutionsAuthorization($activeId, $pass, $authorized, $keepTime=false)
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 ...
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
static _addLog($user_id, $object_id, $logtext, $question_id="", $original_id="", $test_only=false, $test_ref_id=null)
Add an assessment log entry.
log($active_id, $langVar)
static _getScoreCutting($active_id)
Determines if the score of a question should be cut at 0 points or the score of the whole test...
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static _getResultPass($active_id)
Retrieves the pass number that should be counted for a given user.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
static explodeKeyValues($keyValues)
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
static _lookupObjId($a_id)
setOutputType($outputType=OUTPUT_HTML)
Sets the output type.
isComplete()
Returns true, if a question is complete for use.
static _getCountSystem($active_id)
Gets the count system for the calculation of points.
static setResultGateway($resultGateway)
static implodeKeyValues($keyValues)
static $forcePassResultsUpdateEnabled
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
getQuestion()
Gets the question string of the question object.
getComment()
Gets the comment string of the assQuestion object.
static lookupOriginalParentObjId($originalQuestionId)
returns the parent object id for given original question id (should be a qpl id, but theoretically it...
redirection script todo: (a better solution should control the processing via a xml file) ...
getHtmlUserSolutionPurifier()
static createDirectory($a_dir, $a_mod=0755)
create directory
static saveOriginalId($questionId, $originalId)
$nr_of_tries
Number of tries.
static _lookupAuthor($obj_id)
Gets the authors name of the ilObjTest object.
getSuggestedSolutionPathWeb()
Returns the web path for a suggested solution.
static _updateObjectiveResult($a_user_id, $a_active_id, $a_question_id)
static signFile($path_to_file)
moveUploadedMediaFile($file, $name)
Move an uploaded media file to an public accessible temp dir to present it.
getDefaultNrOfTries()
Get Default Nr of Tries.
isClone($question_id="")
Checks whether the question is a clone of another question or not.
updateCurrentSolution($solutionId, $value1, $value2, $authorized=true)
static removeTrailingPathSeparators($path)
cleanupMediaObjectUsage()
synchronises appearances of media objects in the question with media object usage table ...
deleteSuggestedSolutions()
Deletes all suggestes solutions in the database.
setPreventRteUsage($a_val)
Set prevent rte usage.
fixSvgToPng($imageFilenameContainingString)
static _instantiateQuestion($question_id)
isDummySolutionRecord($solutionRecord)
setExternalId($external_id)
fetchValuePairsFromIndexedValues(array $indexedValues)
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
static duplicateListForQuestion($originalQuestionId, $duplicateQuestionId)
duplicates a hint list from given original question id to given duplicate question id and returns an ...
isAdditionalContentEditingModePageObject()
isser for additional "pageobject" content editing mode
getTestOutputSolutions($activeId, $pass)
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
static $allowedCharsetsByMimeType
const ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT
constant for additional content editing mode "default"
static _questionExistsInTest($question_id, $test_id)
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
_resolveIntLinks($question_id)
static _getSuggestedSolutionOutput($question_id)
Returns the output of the suggested solution.
const KEY_VALUES_IMPLOSION_SEPARATOR
onDuplicate($originalParentId, $originalQuestionId, $duplicateParentId, $duplicateQuestionId)
Will be called when a question is duplicated (inside a question pool or for insertion in a test) ...
_questionExists($question_id)
Returns true if the question already exists in the database.
static $imageSourceFixReplaceMap
getOwner()
Gets the creator/owner ID of the assQuestion object.
static isAllowedImageFileExtension($mimeType, $fileExtension)
lmMigrateQuestionTypeGenericContent(ilAssSelfAssessmentMigrator $migrator)
lookupCurrentTestPass($active_id, $pass)
resetUsersAnswer($activeId, $pass)
getEstimatedWorkingTime()
Gets the estimated working time of a question.
setQuestion($question="")
Sets the question string of the question object.
removeCurrentSolution($active_id, $pass, $authorized=true)
setTestId($id=-1)
Sets the test id of the assQuestion object.
ensureCurrentTestPass($active_id, $pass)
prepareTextareaOutput($txt_output, $prepare_for_latex_output=false, $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output in tests.
deleteSolutionRecordByValues($activeId, $passIndex, $authorized, $matchValues)
$testQuestionConfigInstance
getTestPresentationConfig()
Get the test question configuration (initialised once)
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
Creates an Excel worksheet for the detailed cumulated results of this question.
buildImagePath($questionId, $parentObjectId)
getRequestStatisticData()
removeExistingSolutions($activeId, $pass)
setOriginalId($original_id)
static getResultGateway()
static _getInstanceByType(string $type)
Factory method for creating purifier instances.
setLastChange($lastChange)
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass...
getAnswerTableName()
Returns the name of the answer table in the database.
static _deleteAllLinksOfSource($a_source_type, $a_source_id, $a_lang="-")
Delete all links of a given source.
static buildExamId($active_id, $pass, $test_obj_id=null)
setLifecycle(ilAssQuestionLifecycle $lifecycle)
removeIntermediateSolution($active_id, $pass)
getReachedPoints($active_id, $pass=null)
Returns the points, a learner has reached answering the question This is the fast way to get the poin...
$selfassessmenteditingmode
static getGuiClassNameByQuestionType($questionType)
getTitle()
Gets the title string of the assQuestion object.
static _cleanupMediaObjectUsage($a_text, $a_usage_type, $a_usage_id)
Synchronises appearances of media objects in $a_text with media object usage table.
static setTokenMaxLifetimeInSeconds($token_max_lifetime_in_seconds)
getAdjustedReachedPoints($active_id, $pass=null, $authorizedSolution=true)
returns the reached points ...
deleteTaxonomyAssignments()
addQuestionChangeListener(ilQuestionChangeListener $listener)
static isHTML($a_text)
Checks if a given string contains HTML or not.
static fetchMimeTypeIdentifier($contentTypeString)
$obligationsToBeConsidered
static _getReachedPoints($active_id, $question_id, $pass=null)
Returns the points, a learner has reached answering the question.
pcArrayShuffle($array)
Shuffles the values of a given array.
duplicateSuggestedSolutionFiles($parent_id, $question_id)
Duplicates the files of a suggested solution if the question is duplicated.
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
getOutputType()
Gets the output type.
onCopy($sourceParentId, $sourceQuestionId, $targetParentId, $targetQuestionId)
Will be called when a question is copied (into another question pool)
getSuggestedSolutions()
Return the suggested solutions.
getHtmlQuestionContentPurifier()
static $allowedImageMaterialFileExtensionsByMimeType
_resolveInternalLink($internal_link)
setTitle($title="")
Sets the title string of the assQuestion object.
fixUnavailableSkinImageSources($html)
setObjId($obj_id=0)
Set the object id of the container object.
getActiveUserData($active_id)
Returns the user id and the test id for a given active id.
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
setExportImagePath($a_path)
setComment($comment="")
Sets the comment string of the assQuestion object.
setShuffler(ilArrayElementShuffler $shuffler)
static $allowedFileExtensionsByMimeType
static getFeedbackClassNameByQuestionType($questionType)
static _getQuestionTitle($question_id)
Returns the question title of a question with a given id.
static getKeyValuesImplosionSeparator()
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...
static _getTitle($a_q_id)
Returns the title of a question.
static instantiateQuestionGUI($a_question_id)
Creates an instance of a question gui with a given question id.
static getDraftInstance()
keyInArray($searchkey, $array)
returns TRUE if the key occurs in an array
removeAllExistingSolutions()
QTIMaterialToString($a_material)
Reads an QTI material tag an creates a text string.
getSuggestedSolutionOutput()
getSelfAssessmentFormatter()
isNonEmptyItemListPostSubmission($postSubmissionFieldname)
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
setSelfAssessmentEditingMode($a_selfassessmenteditingmode)
Set Self-Assessment Editing Mode.
static missingResultRecordExists($activeId, $pass, $questionIds)
getSolutionRecordById($solutionId)
getPreventRteUsage()
Get prevent rte usage.
static _isWriteable($question_id, $user_id)
Returns true if the question is writeable by a certain user.
static getAllowedFileExtensionsForMimeType($mimeType)