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')
283 'image/jpeg' => array(
'jpg',
'jpeg'),
'image/png' => array(
'png'),
'image/gif' => array(
'gif')
308 $ilDB = $DIC[
'ilDB'];
317 $this->original_id = null;
323 if (!$this->author) {
324 $this->author = $this->
ilias->account->fullname;
327 if ($this->owner <= 0) {
328 $this->owner = $this->
ilias->account->id;
332 $this->suggested_solutions = array();
334 $this->nr_of_tries = 0;
336 $this->arrData = array();
339 $this->questionActionCmd =
'handleQuestionAction';
341 $this->lastChange = null;
343 require_once
'Services/Randomization/classes/class.ilArrayElementOrderKeeper.php';
358 return self::$forcePassResultsUpdateEnabled;
363 return (
bool) count(self::getAllowedFileExtensionsForMimeType($mimeType));
368 return current(explode(
';', $contentTypeString));
373 foreach (self::$allowedFileExtensionsByMimeType as $allowedMimeType => $extensions) {
374 $rexCharsets = implode(
'|', self::$allowedCharsetsByMimeType[$allowedMimeType]);
375 $rexMimeType = preg_quote($allowedMimeType,
'/');
377 $rex =
'/^' . $rexMimeType .
'(;(\s)*charset=(' . $rexCharsets .
'))*$/';
379 if (!preg_match($rex, $mimeType)) {
392 strtolower($fileExtension),
393 self::getAllowedFileExtensionsForMimeType($mimeType)
404 if (!isset(
$_POST[
'cmd']) || !isset(
$_POST[
'cmd'][$this->questionActionCmd])) {
408 if (!is_array(
$_POST[
'cmd'][$this->questionActionCmd]) || !count(
$_POST[
'cmd'][$this->questionActionCmd])) {
412 return key(
$_POST[
'cmd'][$this->questionActionCmd]);
421 if (!isset(
$_POST[$postSubmissionFieldname])) {
425 if (!is_array(
$_POST[$postSubmissionFieldname])) {
429 if (!count(
$_POST[$postSubmissionFieldname])) {
457 require_once
'Modules/Test/classes/class.ilObjTest.php';
468 $ilDB = $DIC[
'ilDB'];
471 "SELECT test_fi FROM tst_active WHERE active_id = %s",
477 return $row[
"test_fi"];
488 protected function log($active_id, $langVar)
501 $extensions = array();
503 foreach (self::$allowedImageMaterialFileExtensionsByMimeType as $mimeType => $mimeExtensions) {
504 $extensions = array_merge($extensions, $mimeExtensions);
506 return array_unique($extensions);
559 array $solutionhints = []
561 include_once
"./Modules/TestQuestionPool/classes/import/qti12/class." . $this->
getQuestionType() .
"Import.php";
563 $import =
new $classname($this);
564 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
566 foreach ($solutionhints as $hint) {
568 $h->setQuestionId($import->getQuestionId());
569 $h->setIndex($hint[
'index']);
570 $h->setPoints($hint[
'points']);
571 $h->setText($hint[
'txt']);
582 public function toXML($a_include_header =
true, $a_include_binary =
true, $a_shuffle =
false, $test_output =
false, $force_image_references =
false)
584 include_once
"./Modules/TestQuestionPool/classes/export/qti12/class." . $this->
getQuestionType() .
"Export.php";
586 $export =
new $classname($this);
587 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
611 $ilDB = $DIC[
'ilDB'];
614 "SELECT * FROM qpl_questions WHERE obj_fi = %s AND title = %s",
615 array(
'integer',
'text'),
616 array($questionpool_id,
$title)
618 return (
$result->numRows() > 0) ?
true :
false;
654 $this->test_id =
$id;
710 $this->est_working_time = array(
"h" => (
int) $hour,
"m" => (
int) $min,
"s" => (
int) $sec);
721 $this->est_working_time = array(
722 'h' => (
int) substr($durationString, 0, 2),
723 'm' => (
int) substr($durationString, 3, 2),
724 's' => (
int) substr($durationString, 6, 2)
738 foreach ($array as $key => $value) {
739 if (strcmp($key, $searchkey) == 0) {
793 require_once
'Services/Utilities/classes/class.ilUtil.php';
859 return $this->refinery->string()->stripTags()->transform($this->
comment ??
'');
892 if (!$this->est_working_time) {
893 $this->est_working_time = array(
"h" => 0,
"m" => 0,
"s" => 0);
912 return $this->refinery->string()->stripTags()->transform($this->author);
980 if (!strlen($this->external_id)) {
981 if ($this->
getId() > 0) {
984 return uniqid(
'',
true);
1000 $ilDB = $DIC[
'ilDB'];
1004 "SELECT points FROM qpl_questions WHERE question_id = %s",
1008 if (
$result->numRows() == 1) {
1024 $ilDB = $DIC[
'ilDB'];
1027 "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",
1047 $ilDB = $DIC[
'ilDB'];
1050 "SELECT suggested_solution_id FROM qpl_sol_sug WHERE question_fi = %s",
1069 return $question->getSuggestedSolutionOutput();
1075 foreach ($this->suggested_solutions as $solution) {
1076 switch ($solution[
"type"]) {
1084 $possible_texts = array_values(array_filter(array(
1087 $this->lng->txt(
'tst_show_solution_suggested')
1090 require_once
'Services/WebAccessChecker/classes/class.ilWACSignedPath.php';
1095 $solutionValue = $solution[
"value"];
1096 $solutionValue = $this->
fixSvgToPng($solutionValue);
1102 return join(
"<br />", $output);
1116 $ilDB = $DIC[
'ilDB'];
1119 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
1120 array(
'integer',
'integer'),
1121 array($question_id, $subquestion_index)
1123 if (
$result->numRows() == 1) {
1126 "internal_link" => $row[
"internal_link"],
1127 "import_id" => $row[
"import_id"]
1154 $ilDB = $DIC[
'ilDB'];
1157 if (is_null(
$pass)) {
1158 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
1162 "SELECT * FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
1163 array(
'integer',
'integer',
'integer'),
1164 array($active_id, $question_id,
$pass)
1166 if (
$result->numRows() == 1) {
1183 return round(self::_getReachedPoints($active_id, $this->
getId(),
$pass), 2);
1210 if (is_null(
$pass)) {
1211 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1221 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
1223 $requestsStatisticData = $hintTracking->getRequestStatisticDataByQuestionAndTestpass();
1224 $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
1229 return $reached_points;
1244 $ilDB = $DIC[
'ilDB'];
1247 if (is_null(
$pass)) {
1248 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1256 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
1258 $requestsStatisticData = $questionHintTracking->getRequestStatisticDataByQuestionAndTestpass();
1259 $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
1270 if (is_null($reached_points)) {
1271 $reached_points = 0;
1275 $existingSolutions = $this->lookupForExistingSolutions($active_id,
$pass);
1277 $this->
getProcessLocker()->executeUserQuestionResultUpdateOperation(
function () use (
$ilDB, $active_id,
$pass, $reached_points, $requestsStatisticData, $isAnswered, $existingSolutions) {
1279 DELETE FROM tst_test_result 1281 WHERE active_fi = %s 1282 AND question_fi = %s 1286 $types = array(
'integer',
'integer',
'integer');
1287 $values = array($active_id, $this->
getId(),
$pass);
1289 if ($this->
getStep() !== null) {
1294 $types[] =
'integer';
1299 if ($existingSolutions[
'authorized']) {
1300 $next_id =
$ilDB->nextId(
"tst_test_result");
1302 'test_result_id' => array(
'integer', $next_id),
1303 'active_fi' => array(
'integer', $active_id),
1304 'question_fi' => array(
'integer', $this->
getId()),
1305 'pass' => array(
'integer',
$pass),
1306 'points' => array(
'float', $reached_points),
1307 'tstamp' => array(
'integer', time()),
1308 'hint_count' => array(
'integer', $requestsStatisticData->getRequestsCount()),
1309 'hint_points' => array(
'float', $requestsStatisticData->getRequestsPoints()),
1310 'answered' => array(
'integer', $isAnswered)
1313 if ($this->
getStep() !== null) {
1314 $fieldData[
'step'] = array(
'integer', $this->
getStep());
1317 $ilDB->insert(
'tst_test_result', $fieldData);
1322 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1329 "log_user_answered_question",
1343 include_once
'Modules/Course/classes/class.ilCourseObjectiveResult.php';
1361 $saveStatus =
false;
1363 $this->
getProcessLocker()->executePersistWorkingStateLockOperation(
function () use ($active_id,
$pass, $authorized, $obligationsEnabled, &$saveStatus) {
1364 if (
$pass === null) {
1365 require_once
'Modules/Test/classes/class.ilObjTest.php';
1417 $ilDB = $DIC[
'ilDB'];
1419 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1420 include_once
"./Modules/Test/classes/class.assMarkSchema.php";
1424 if (
$pass !== null) {
1426 SELECT tst_pass_result.* 1427 FROM tst_pass_result 1428 WHERE active_fi = %s 1434 array(
'integer',
'integer'),
1435 array($active_id,
$pass)
1440 $max = $row_result[
'maxpoints'];
1441 $reached = $row_result[
'points'];
1443 $obligationsAnswered = (int) $row_result[
'obligations_answered'];
1445 include_once
"./Modules/Test/classes/class.assMarkSchema.php";
1447 $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
1449 $mark = ASS_MarkSchema::_getMatchingMarkFromActiveId($active_id, $percentage);
1451 $isPassed = ($mark[
"passed"] ? 1 : 0);
1452 $isFailed = (!$mark[
"passed"] ? 1 : 0);
1454 $userTestResultUpdateCallback =
function () use (
1462 $obligationsAnswered,
1466 $passedOnceBefore = 0;
1467 $query =
"SELECT passed_once FROM tst_result_cache WHERE active_fi = %s";
1469 while ($row =
$ilDB->fetchAssoc(
$res)) {
1470 $passedOnceBefore = (int) $row[
'passed_once'];
1473 $passedOnce = (int) ($isPassed || $passedOnceBefore);
1476 "DELETE FROM tst_result_cache WHERE active_fi = %s",
1481 $ilDB->insert(
'tst_result_cache', array(
1482 'active_fi' => array(
'integer', $active_id),
1483 'pass' => array(
'integer', strlen(
$pass) ?
$pass : 0),
1484 'max_points' => array(
'float', strlen($max) ? $max : 0),
1485 'reached_points' => array(
'float', strlen($reached) ? $reached : 0),
1486 'mark_short' => array(
'text', strlen($mark[
"short_name"]) ? $mark[
"short_name"] :
" "),
1487 'mark_official' => array(
'text', strlen($mark[
"official_name"]) ? $mark[
"official_name"] :
" "),
1488 'passed_once' => array(
'integer', $passedOnce),
1489 'passed' => array(
'integer', $isPassed),
1490 'failed' => array(
'integer', $isFailed),
1491 'tstamp' => array(
'integer', time()),
1492 'hint_count' => array(
'integer', $row_result[
'hint_count']),
1493 'hint_points' => array(
'float', $row_result[
'hint_points']),
1494 'obligations_answered' => array(
'integer', $obligationsAnswered)
1499 $processLocker->executeUserTestResultUpdateLockOperation($userTestResultUpdateCallback);
1501 $userTestResultUpdateCallback();
1510 $ilDB = $DIC[
'ilDB'];
1512 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1514 if (self::getResultGateway() !== null) {
1515 $data = self::getResultGateway()->getQuestionCountAndPointsForPassOfParticipant($active_id,
$pass);
1516 $time = self::getResultGateway()->getWorkingTimeOfParticipantForPass($active_id,
$pass);
1527 SELECT SUM(points) reachedpoints, 1528 SUM(hint_count) hint_count, 1529 SUM(hint_points) hint_points, 1530 COUNT(DISTINCT(question_fi)) answeredquestions 1531 FROM tst_test_result 1532 WHERE active_fi = %s 1535 array(
'integer',
'integer'),
1536 array($active_id,
$pass)
1540 if ($obligationsEnabled) {
1542 SELECT answered answ 1543 FROM tst_test_question 1544 INNER JOIN tst_active 1546 AND tst_test_question.test_fi = tst_active.test_fi 1547 LEFT JOIN tst_test_result 1548 ON tst_test_result.active_fi = %s 1549 AND tst_test_result.pass = %s 1550 AND tst_test_question.question_fi = tst_test_result.question_fi 1551 WHERE obligatory = 1';
1553 $result_obligatory =
$ilDB->queryF(
1555 array(
'integer',
'integer',
'integer'),
1556 array($active_id, $active_id,
$pass)
1559 $obligations_answered = 1;
1561 while ($row_obligatory =
$ilDB->fetchAssoc($result_obligatory)) {
1562 if (!(
int) $row_obligatory[
'answ']) {
1563 $obligations_answered = 0;
1568 $obligations_answered = 1;
1573 if ($row[
'reachedpoints'] === null) {
1574 $row[
'reachedpoints'] = 0;
1576 if ($row[
'hint_count'] === null) {
1577 $row[
'hint_count'] = 0;
1579 if ($row[
'hint_points'] === null) {
1580 $row[
'hint_points'] = 0;
1585 $updatePassResultCallback =
function () use (
$ilDB,
$data, $active_id,
$pass, $row, $time, $obligations_answered, $exam_identifier) {
1591 'active_fi' => array(
'integer', $active_id),
1592 'pass' => array(
'integer', strlen(
$pass) ?
$pass : 0)),
1594 'points' => array(
'float', $row[
'reachedpoints'] ? $row[
'reachedpoints'] : 0),
1595 'maxpoints' => array(
'float',
$data[
'points']),
1596 'questioncount' => array(
'integer',
$data[
'count']),
1597 'answeredquestions' => array(
'integer', $row[
'answeredquestions']),
1598 'workingtime' => array(
'integer', $time),
1599 'tstamp' => array(
'integer', time()),
1600 'hint_count' => array(
'integer', $row[
'hint_count']),
1601 'hint_points' => array(
'float', $row[
'hint_points']),
1602 'obligations_answered' => array(
'integer', $obligations_answered),
1603 'exam_id' => array(
'text', $exam_identifier)
1609 $processLocker->executeUserPassResultUpdateLockOperation($updatePassResultCallback);
1611 $updatePassResultCallback();
1618 'active_fi' => $active_id,
1620 'points' => ($row[
"reachedpoints"]) ? $row[
"reachedpoints"] : 0,
1621 'maxpoints' =>
$data[
"points"],
1622 'questioncount' =>
$data[
"count"],
1623 'answeredquestions' => $row[
"answeredquestions"],
1624 'workingtime' => $time,
1626 'hint_count' => $row[
'hint_count'],
1627 'hint_points' => $row[
'hint_points'],
1628 'obligations_answered' => $obligations_answered,
1629 'exam_id' => $exam_identifier
1640 public static function logAction($logtext =
"", $active_id =
"", $question_id =
"")
1643 if (strlen($question_id)) {
1647 require_once
'Modules/Test/classes/class.ilObjAssessmentFolder.php';
1648 require_once
'Modules/Test/classes/class.ilObjTest.php';
1669 if (!@is_dir($mediatempdir)) {
1672 $temp_name = tempnam($mediatempdir,
$name .
"_____");
1673 $temp_name = str_replace(
"\\",
"/", $temp_name);
1674 @unlink($temp_name);
1689 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/solution/";
1700 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/java/";
1711 if ($question_id === null) {
1715 if ($object_id === null) {
1724 return CLIENT_WEB_DIR .
"/assessment/{$parentObjectId}/{$questionId}/images/";
1735 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/flash/";
1746 $relative_path =
"assessment/$this->obj_id/$this->id/java/";
1757 $relative_path =
"assessment/$this->obj_id/$this->id/solution/";
1771 if (!$this->export_image_path) {
1772 $relative_path =
"assessment/$this->obj_id/$this->id/images/";
1787 $relative_path =
"assessment/$this->obj_id/$this->id/flash/";
1808 if (!count($solution)) {
1821 $ilDB = $DIC[
'ilDB'];
1823 if (is_null(
$pass)) {
1827 if ($this->
getStep() !== null) {
1831 WHERE active_fi = %s 1832 AND question_fi = %s 1836 ORDER BY solution_id";
1840 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
1847 WHERE active_fi = %s 1848 AND question_fi = %s 1851 ORDER BY solution_id 1856 array(
'integer',
'integer',
'integer',
'integer'),
1857 array($active_id, $this->
getId(),
$pass, (
int) $authorized)
1879 $ilDB = $DIC[
'ilDB'];
1881 if ($question_id < 1) {
1882 $question_id = $this->
getId();
1885 "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",
1890 $count = $row[
"question_count"];
1894 SELECT tst_active.test_fi 1896 INNER JOIN tst_test_rnd_qst ON tst_test_rnd_qst.question_fi = qpl_questions.question_id 1897 INNER JOIN tst_active ON tst_active.active_id = tst_test_rnd_qst.active_fi 1898 WHERE qpl_questions.original_id = %s 1899 GROUP BY tst_active.test_fi",
1917 $ilDB = $DIC[
'ilDB'];
1919 if ($question_id < 1) {
1923 "SELECT original_id FROM qpl_questions WHERE question_id = %s",
1928 return ($row[
"original_id"] > 0) ? true :
false;
1939 $keys = array_keys($array);
1942 foreach (
$keys as $key) {
1956 $ilDB = $DIC[
'ilDB'];
1959 "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",
1964 return $data[
"type_tag"];
1998 $ilDB = $DIC[
'ilDB'];
2001 if (!is_array($answer_table_name)) {
2002 $answer_table_name = array($answer_table_name);
2005 foreach ($answer_table_name as $table) {
2006 if (strlen($table)) {
2007 $affectedRows =
$ilDB->manipulateF(
2008 "DELETE FROM $table WHERE question_fi = %s",
2025 $ilDB = $DIC[
'ilDB'];
2029 if (!is_array($additional_table_name)) {
2030 $additional_table_name = array($additional_table_name);
2033 foreach ($additional_table_name as $table) {
2034 if (strlen($table)) {
2035 $affectedRows =
$ilDB->manipulateF(
2036 "DELETE FROM $table WHERE question_fi = %s",
2052 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2064 public function delete($question_id)
2067 $ilDB = $DIC[
'ilDB'];
2068 $ilLog = $DIC[
'ilLog'];
2070 if ($question_id < 1) {
2075 "SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
2079 if (
$result->numRows() == 1) {
2088 $ilLog->write(
"EXCEPTION: Could not delete page of question $question_id: $e");
2092 $affectedRows =
$ilDB->manipulateF(
2093 "DELETE FROM qpl_questions WHERE question_id = %s",
2097 if ($affectedRows == 0) {
2107 $ilLog->write(
"EXCEPTION: Could not delete additional table data of question $question_id: $e");
2113 $affectedRows =
$ilDB->manipulateF(
2114 "DELETE FROM tst_test_question WHERE question_fi = %s",
2119 $ilLog->write(
"EXCEPTION: Could not delete delete question $question_id from a test: $e");
2125 $affectedRows =
$ilDB->manipulateF(
2126 "DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2131 $ilLog->write(
"EXCEPTION: Could not delete suggested solutions of question $question_id: $e");
2137 if (preg_match(
"/\d+/",
$obj_id) and preg_match(
"/\d+/", $question_id) and is_dir($directory)) {
2138 include_once
"./Services/Utilities/classes/class.ilUtil.php";
2142 $ilLog->write(
"EXCEPTION: Could not delete question file directory $directory of question $question_id: $e");
2147 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2153 foreach (
$mobs as $mob) {
2161 $ilLog->write(
"EXCEPTION: Error deleting the media objects of question $question_id: $e");
2165 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
2166 ilAssQuestionHintTracking::deleteRequestsByQuestionIds(array($question_id));
2168 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
2171 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
2173 $assignmentList->setParentObjId(
$obj_id);
2174 $assignmentList->setQuestionIdFilter($question_id);
2175 $assignmentList->loadFromDb();
2176 foreach ($assignmentList->getAssignmentsByQuestionId($question_id) as $assignment) {
2178 $assignment->deleteFromDb();
2185 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
2188 $ilLog->write(
"EXCEPTION: Error updating the question pool question count of question pool " . $this->
getObjId() .
" when deleting question $question_id: $e");
2199 require_once
'Services/Taxonomy/classes/class.ilObjTaxonomy.php';
2200 require_once
'Services/Taxonomy/classes/class.ilTaxNodeAssignment.php';
2203 foreach ($taxIds as $taxId) {
2205 $taxNodeAssignment->deleteAssignmentsOfItem($this->
getId());
2226 $ilDB = $DIC[
'ilDB'];
2230 "SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
2231 array(
'integer',
'integer'),
2232 array($a_q_id, $a_q_id)
2234 if (
$result->numRows() == 0) {
2237 $found_id = array();
2239 array_push($found_id, $row[
"question_id"]);
2242 $result =
$ilDB->query(
"SELECT * FROM tst_test_result WHERE " .
$ilDB->in(
'question_fi', $found_id,
false,
'integer'));
2257 $ilDB = $DIC[
'ilDB'];
2259 "SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
2260 array(
'integer',
'integer'),
2261 array($a_q_id, $a_q_id)
2263 if (
$result->numRows() == 0) {
2266 $found_id = array();
2268 array_push($found_id, $row[
"question_id"]);
2270 $result =
$ilDB->query(
"SELECT * FROM tst_test_result WHERE " .
$ilDB->in(
'question_fi', $found_id,
false,
'integer'));
2273 $reached = $row[
"points"];
2274 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
2276 array_push($answers, array(
"reached" => $reached,
"max" => $max));
2280 foreach ($answers as $key => $value) {
2281 $max += $value[
"max"];
2282 $reached += $value[
"reached"];
2285 return $reached / $max;
2299 $ilDB = $DIC[
'ilDB'];
2301 "SELECT title FROM qpl_questions WHERE question_id = %s",
2305 if (
$result->numRows() == 1) {
2307 return $row[
"title"];
2321 $ilDB = $DIC[
'ilDB'];
2323 "SELECT question_text FROM qpl_questions WHERE question_id = %s",
2327 if (
$result->numRows() == 1) {
2329 return $row[
"question_text"];
2337 if (!file_exists($file)) {
2341 if (!is_file($file)) {
2345 if (!is_readable($file)) {
2354 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2356 foreach (
$mobs as $mob) {
2363 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2365 foreach (
$mobs as $mob) {
2377 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2379 $this->page->setId($this->
getId());
2380 $this->page->setParentId($qpl_id);
2381 $this->page->setXMLContent(
"<PageObject><PageContent>" .
2382 "<Question QRef=\"il__qst_" . $this->
getId() .
"\"/>" .
2383 "</PageContent></PageObject>");
2384 $this->page->create();
2390 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2393 $xml = str_replace(
"il__qst_" . $a_q_id,
"il__qst_" . $this->
id,
$page->getXMLContent());
2394 $this->page->setXMLContent(
$xml);
2395 $this->page->updateFromXML();
2401 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2403 return $page->getXMLContent();
2414 $ilDB = $DIC[
'ilDB'];
2416 if ($question_id < 1) {
2420 "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",
2424 if (
$result->numRows() == 1) {
2426 return $data[
"type_tag"];
2442 $ilDB = $DIC[
'ilDB'];
2444 if ($question_id < 1) {
2449 "SELECT title FROM qpl_questions WHERE qpl_questions.question_id = %s",
2453 if (
$result->numRows() == 1) {
2455 return $data[
"title"];
2472 'ok.svg' =>
'ok.png',
'not_ok.svg' =>
'not_ok.png',
2473 'checkbox_checked.svg' =>
'checkbox_checked.png',
2474 'checkbox_unchecked.svg' =>
'checkbox_unchecked.png',
2475 'radiobutton_checked.svg' =>
'radiobutton_checked.png',
2476 'radiobutton_unchecked.svg' =>
'radiobutton_unchecked.png' 2481 $needles = array_keys(self::$imageSourceFixReplaceMap);
2482 $replacements = array_values(self::$imageSourceFixReplaceMap);
2483 return str_replace($needles, $replacements, $imageFilenameContainingString);
2490 if (preg_match_all(
'/src="(.*?)"/m', $html, $matches)) {
2491 $sources = $matches[1];
2493 $needleReplacementMap = array();
2495 foreach ($sources as $src) {
2498 if (file_exists($file)) {
2502 $levels = explode(DIRECTORY_SEPARATOR, $src);
2503 if (count($levels) < 5 || $levels[0] !=
'Customizing' || $levels[2] !=
'skin') {
2509 if ($levels[4] ==
'Modules' || $levels[4] ==
'Services') {
2510 $component = $levels[4] . DIRECTORY_SEPARATOR . $levels[5];
2516 if (count($needleReplacementMap)) {
2517 $html = str_replace(array_keys($needleReplacementMap), array_values($needleReplacementMap), $html);
2533 $ilDB = $DIC[
'ilDB'];
2536 "SELECT external_id FROM qpl_questions WHERE question_id = %s",
2540 if (
$result->numRows() == 1) {
2542 $this->external_id =
$data[
'external_id'];
2546 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
2548 array($this->
getId())
2550 $this->suggested_solutions = array();
2552 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"]
2574 $ilDB = $DIC[
'ilDB'];
2579 $estw_time = sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
2582 if ($a_create_page) {
2589 $next_id =
$ilDB->nextId(
'qpl_questions');
2590 $affectedRows =
$ilDB->insert(
"qpl_questions", array(
2591 "question_id" => array(
"integer", $next_id),
2593 "obj_fi" => array(
"integer",
$obj_id),
2594 "title" => array(
"text", null),
2595 "description" => array(
"text", null),
2596 "author" => array(
"text", $this->
getAuthor()),
2597 "owner" => array(
"integer",
$ilUser->getId()),
2598 "question_text" => array(
"clob", null),
2599 "points" => array(
"float", 0),
2601 "working_time" => array(
"text", $estw_time),
2602 "complete" => array(
"text", $complete),
2603 "created" => array(
"integer", time()),
2604 "original_id" => array(
"integer", null),
2605 "tstamp" => array(
"integer", $tstamp),
2609 $this->
setId($next_id);
2611 if ($a_create_page) {
2619 return $this->
getId();
2625 $ilDB = $DIC[
'ilDB'];
2628 $estw_time = sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
2631 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2632 if ($this->
getId() == -1) {
2634 $next_id =
$ilDB->nextId(
'qpl_questions');
2635 $affectedRows =
$ilDB->insert(
"qpl_questions", array(
2636 "question_id" => array(
"integer", $next_id),
2638 "obj_fi" => array(
"integer", $this->
getObjId()),
2639 "title" => array(
"text", $this->
getTitle()),
2640 "description" => array(
"text", $this->
getComment()),
2641 "author" => array(
"text", $this->
getAuthor()),
2642 "owner" => array(
"integer", $this->
getOwner()),
2645 "working_time" => array(
"text", $estw_time),
2646 "nr_of_tries" => array(
"integer", $this->
getNrOfTries()),
2647 "created" => array(
"integer", time()),
2649 "tstamp" => array(
"integer", time()),
2653 $this->
setId($next_id);
2658 $affectedRows =
$ilDB->update(
"qpl_questions", array(
2659 "obj_fi" => array(
"integer", $this->
getObjId()),
2660 "title" => array(
"text", $this->
getTitle()),
2661 "description" => array(
"text", $this->
getComment()),
2662 "author" => array(
"text", $this->
getAuthor()),
2665 "nr_of_tries" => array(
"integer", $this->
getNrOfTries()),
2666 "working_time" => array(
"text", $estw_time),
2667 "tstamp" => array(
"integer", time()),
2668 'complete' => array(
'integer', $this->
isComplete()),
2671 "question_id" => array(
"integer", $this->
getId())
2686 $this->updateSuggestedSolutions();
2696 $DIC->database()->update(
'qpl_questions', array(
2697 'tstamp' => array(
'integer', time()),
2698 'owner' => array(
'integer', ($this->
getOwner() <= 0 ? $this->
ilias->account->id : $this->getOwner())),
2699 'complete' => array(
'integer', $complete),
2700 'lifecycle' => array(
'text', $this->
getLifecycle()->getIdentifier()),
2702 'question_id' => array(
'integer', $this->
getId())
2706 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
2717 self::saveOriginalId($this->
getId(), $newId);
2722 $query =
"UPDATE qpl_questions SET tstamp = %s, original_id = %s WHERE question_id = %s";
2724 $GLOBALS[
'DIC'][
'ilDB']->manipulateF(
2726 array(
'integer',
'integer',
'text'),
2727 array(time(), $originalId, $questionId)
2733 $query =
"UPDATE qpl_questions SET tstamp = %s, original_id = NULL WHERE question_id = %s";
2735 $GLOBALS[
'DIC'][
'ilDB']->manipulateF(
2737 array(
'integer',
'text'),
2738 array(time(), $questionId)
2745 protected function onDuplicate($originalParentId, $originalQuestionId, $duplicateParentId, $duplicateQuestionId)
2750 $this->feedbackOBJ->duplicateFeedback($originalQuestionId, $duplicateQuestionId);
2766 $this->feedbackOBJ->syncFeedback($origQuestionId, $dupQuestionId);
2772 protected function onCopy($sourceParentId, $sourceQuestionId, $targetParentId, $targetQuestionId)
2777 $this->feedbackOBJ->duplicateFeedback($sourceQuestionId, $targetQuestionId);
2792 $ilDB = $DIC[
'ilDB'];
2794 $affectedRows =
$ilDB->manipulateF(
2795 "DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2797 array($this->
getId())
2800 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2802 $this->suggested_solutions = array();
2815 if (array_key_exists($subquestion_index, $this->suggested_solutions)) {
2816 return $this->suggested_solutions[$subquestion_index];
2832 if (array_key_exists($subquestion_index, $this->suggested_solutions)) {
2833 $title = $this->suggested_solutions[$subquestion_index][
"internal_link"];
2852 if (strcmp($solution_id,
"") != 0) {
2855 $import_id = $solution_id;
2858 $this->suggested_solutions[$subquestion_index] = array(
2859 "internal_link" => $solution_id,
2860 "import_id" => $import_id
2871 $ilLog = $DIC[
'ilLog'];
2873 foreach ($this->suggested_solutions as
$index => $solution) {
2874 if (strcmp($solution[
"type"],
"file") == 0) {
2876 $filepath_original = str_replace(
2877 "/{$this->obj_id}/{$this->id}/solution",
2878 "/$parent_id/$question_id/solution",
2881 if (!file_exists($filepath)) {
2886 if (!copy($filepath_original .
$filename, $filepath . $filename)) {
2887 $ilLog->write(
"File could not be duplicated!!!!", $ilLog->ERROR);
2888 $ilLog->write(
"object: " . print_r($this,
true), $ilLog->ERROR);
2901 $ilLog = $DIC[
'ilLog'];
2904 $filepath_original = str_replace(
"/$this->id/solution",
"/$original_id/solution", $filepath);
2906 foreach ($this->suggested_solutions as
$index => $solution) {
2907 if (strcmp($solution[
"type"],
"file") == 0) {
2908 if (!file_exists($filepath_original)) {
2913 if (!@copy($filepath .
$filename, $filepath_original . $filename)) {
2914 $ilLog->write(
"File could not be duplicated!!!!", $ilLog->ERROR);
2915 $ilLog->write(
"object: " . print_r($this,
true), $ilLog->ERROR);
2925 $ilLog = $DIC[
'ilLog'];
2927 foreach ($this->suggested_solutions as
$index => $solution) {
2928 if (strcmp($solution[
"type"],
"file") == 0) {
2930 $filepath_original = str_replace(
"/$this->obj_id/$this->id/solution",
"/$source_questionpool_id/$source_question_id/solution", $filepath);
2931 if (!file_exists($filepath)) {
2936 if (!copy($filepath_original .
$filename, $filepath . $filename)) {
2937 $ilLog->write(
"File could not be copied!!!!", $ilLog->ERROR);
2938 $ilLog->write(
"object: " . print_r($this,
true), $ilLog->ERROR);
2948 public function updateSuggestedSolutions(
$original_id =
"")
2951 $ilDB = $DIC[
'ilDB'];
2954 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2955 $affectedRows =
$ilDB->manipulateF(
2956 "DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2961 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2962 foreach ($this->suggested_solutions as
$index => $solution) {
2963 $next_id =
$ilDB->nextId(
'qpl_sol_sug');
2968 'suggested_solution_id' => array(
'integer', $next_id ),
2969 'question_fi' => array(
'integer',
$id ),
2970 'type' => array(
'text', $solution[
'type'] ),
2972 'internal_link' => array(
'text', $solution[
'internal_link'] ),
2973 'import_id' => array(
'text', null ),
2974 'subquestion_index' => array(
'integer',
$index ),
2975 'tstamp' => array(
'integer', time() ),
2978 if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/", $solution[
"internal_link"], $matches)) {
2997 public function saveSuggestedSolution(
$type, $solution_id =
"", $subquestion_index = 0, $value =
"")
3000 $ilDB = $DIC[
'ilDB'];
3002 $affectedRows =
$ilDB->manipulateF(
3003 "DELETE FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
3004 array(
"integer",
"integer"),
3011 $next_id =
$ilDB->nextId(
'qpl_sol_sug');
3012 include_once(
"./Services/RTE/classes/class.ilRTE.php");
3014 $affectedRows =
$ilDB->insert(
3017 'suggested_solution_id' => array(
'integer', $next_id ),
3018 'question_fi' => array(
'integer', $this->
getId() ),
3019 'type' => array(
'text',
$type ),
3021 'internal_link' => array(
'text', $solution_id ),
3022 'import_id' => array(
'text', null ),
3023 'subquestion_index' => array(
'integer', $subquestion_index ),
3024 'tstamp' => array(
'integer', time() ),
3027 if ($affectedRows == 1) {
3028 $this->suggested_solutions[$subquestion_index] = array(
3031 "internal_link" => $solution_id,
3040 if (preg_match(
"/il_(\d+)_(\w+)_(\d+)/", $internal_link, $matches)) {
3041 switch ($matches[2]) {
3058 if (strcmp($resolved_link,
"") == 0) {
3059 $resolved_link = $internal_link;
3062 $resolved_link = $internal_link;
3064 return $resolved_link;
3070 $ilDB = $DIC[
'ilDB'];
3073 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
3079 $internal_link = $row[
"internal_link"];
3080 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
3082 if (strcmp($internal_link, $resolved_link) != 0) {
3084 $affectedRows =
$ilDB->manipulateF(
3085 "UPDATE qpl_sol_sug SET internal_link = %s WHERE suggested_solution_id = %s",
3086 array(
'text',
'integer'),
3087 array($resolved_link, $row[
"suggested_solution_id"])
3093 if ($resolvedlinks) {
3097 include_once
"./Services/Link/classes/class.ilInternalLink.php";
3101 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
3107 if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/", $row[
"internal_link"], $matches)) {
3118 $ilDB = $DIC[
'ilDB'];
3120 "lm" =>
"LearningModule",
3121 "pg" =>
"PageObject",
3122 "st" =>
"StructureObject",
3123 "git" =>
"GlossaryItem",
3124 "mob" =>
"MediaObject" 3127 if (preg_match(
"/il__(\w+)_(\d+)/", $target, $matches)) {
3128 $type = $matches[1];
3130 include_once
"./Services/Utilities/classes/class.ilUtil.php";
3131 switch ($linktypes[$matches[1]]) {
3132 case "LearningModule":
3136 case "StructureObject":
3139 case "GlossaryItem":
3143 $href =
"./ilias.php?baseClass=ilLMPresentationGUI&obj_type=" . $linktypes[
$type] .
"&cmd=media&ref_id=" .
$_GET[
"ref_id"] .
"&mob_id=" .
$target_id;
3160 $ilDB = $DIC[
'ilDB'];
3162 "SELECT * FROM qpl_questions WHERE question_id = %s",
3168 if ($row[
"original_id"] > 0) {
3169 return $row[
"original_id"];
3171 return $row[
"question_id"];
3181 $ilDB = $DIC[
'ilDB'];
3184 SELECT COUNT(dupl.question_id) cnt 3185 FROM qpl_questions dupl 3186 INNER JOIN qpl_questions orig 3187 ON orig.question_id = dupl.original_id 3188 WHERE dupl.question_id = %s 3194 return $row[
'cnt'] > 0;
3200 $ilDB = $DIC[
'ilDB'];
3206 $originalObjId = self::lookupOriginalParentObjId($this->
getOriginalId());
3208 if (!$originalObjId) {
3218 $this->
setId($original);
3232 $this->updateSuggestedSolutions($original);
3249 $ilDB = $DIC[
'ilDB'];
3251 if ($question_id < 1) {
3256 "SELECT question_id FROM qpl_questions WHERE question_id = %s",
3260 if (
$result->numRows() == 1) {
3277 $ilDB = $DIC[
'ilDB'];
3279 if ($question_id < 1) {
3284 "SELECT question_id FROM qpl_questions INNER JOIN object_data ON obj_fi = obj_id WHERE question_id = %s AND type = 'qpl'",
3288 if (
$result->numRows() == 1) {
3304 return self::_instantiateQuestion($question_id);
3314 $ilCtrl = $DIC[
'ilCtrl'];
3315 $ilDB = $DIC[
'ilDB'];
3318 if (strcmp($question_id,
"") != 0) {
3320 if (!strlen($question_type)) {
3324 $objectClassname = self::getObjectClassNameByQuestionType($question_type);
3328 $feedbackObjectClassname = self::getFeedbackClassNameByQuestionType($question_type);
3343 if (strcmp($this->points,
"") == 0) {
3359 $this->points = $a_points;
3370 return self::_getSolutionMaxPass($this->
getId(), $active_id);
3389 $ilDB = $DIC[
'ilDB'];
3392 "SELECT MAX(pass) maxpass FROM tst_test_result WHERE active_fi = %s AND question_fi = %s",
3393 array(
'integer',
'integer'),
3394 array($active_id, $question_id)
3396 if (
$result->numRows() == 1) {
3398 return $row[
"maxpass"];
3415 $ilDB = $DIC[
'ilDB'];
3417 if (($question_id < 1) || ($user_id < 1)) {
3422 "SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
3426 if (
$result->numRows() == 1) {
3428 $qpl_object_id = $row[
"obj_fi"];
3429 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
3445 $ilDB = $DIC[
'ilDB'];
3447 if ($question_id < 1) {
3451 "SELECT test_random_question_id FROM tst_test_rnd_qst WHERE question_fi = %s",
3477 $reachedPoints = $reachedPoints - $requestsStatisticData->getRequestsPoints();
3479 return $reachedPoints;
3519 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3521 if ($count_system == 1) {
3527 if ($score_cutting == 0) {
3545 return self::lookupResultRecordExist($active_id, $question_id,
$pass);
3550 $ilDB = $DIC[
'ilDB'];
3553 if (is_null(
$pass)) {
3554 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
3558 "SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3559 array(
'integer',
'integer',
'integer'),
3560 array($active_id, $question_id,
$pass)
3579 $ilDB = $DIC[
'ilDB'];
3582 "SELECT DISTINCT(question_fi) FROM tst_test_result JOIN tst_active " .
3583 "ON (active_id = active_fi) " .
3584 "WHERE " .
$ilDB->in(
'question_fi', $a_question_ids,
false,
'integer') .
3585 " AND user_fi = %s",
3589 return (
$res->numRows() == count($a_question_ids)) ?
true :
false;
3613 include_once
"./Services/Utilities/classes/class.ilUtil.php";
3627 for (
$i = 0;
$i < $a_material->getMaterialCount();
$i++) {
3628 $material = $a_material->getMaterial(
$i);
3629 if (strcmp($material[
"type"],
"mattext") == 0) {
3630 $result .= $material[
"material"]->getContent();
3632 if (strcmp($material[
"type"],
"matimage") == 0) {
3633 $matimage = $material[
"material"];
3634 if (preg_match(
"/(il_([0-9]+)_mob_([0-9]+))/", $matimage->getLabel(), $matches)) {
3636 if (!is_array(
$_SESSION[
"import_mob_xhtml"])) {
3637 $_SESSION[
"import_mob_xhtml"] = array();
3639 array_push(
$_SESSION[
"import_mob_xhtml"], array(
"mob" => $matimage->getLabel(),
"uri" => $matimage->getUri()));
3654 public function addQTIMaterial(&$a_xml_writer, $a_material, $close_material_tag =
true, $add_mobs =
true)
3656 include_once
"./Services/RTE/classes/class.ilRTE.php";
3657 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
3659 $a_xml_writer->xmlStartTag(
"material");
3661 "texttype" =>
"text/plain" 3663 if ($this->
isHTML($a_material)) {
3664 $attrs[
"texttype"] =
"text/xhtml";
3669 foreach (
$mobs as $mob) {
3670 $moblabel =
"il_" .
IL_INST_ID .
"_mob_" . $mob;
3671 if (strpos($a_material,
"mm_$mob") !==
false) {
3675 "label" => $moblabel,
3676 "uri" =>
"objects/" .
"il_" .
IL_INST_ID .
"_mob_" . $mob .
"/" . $mob_obj->getTitle()
3679 $a_xml_writer->xmlElement(
"matimage", $imgattrs, null);
3683 if ($close_material_tag) {
3684 $a_xml_writer->xmlEndTag(
"material");
3692 if (preg_match(
"/.*\.(png|jpg|gif|jpeg)$/i", $plain_image_filename, $matches)) {
3693 $extension =
"." . $matches[1];
3697 $plain_image_filename = uniqid($plain_image_filename . microtime(
true));
3700 $hashed_filename = md5($plain_image_filename) . $extension;
3702 return $hashed_filename;
3718 $ilDB = $DIC[
'ilDB'];
3721 $float_trafo =
$refinery->kindlyTo()->float();
3729 if (is_null(
$pass)) {
3736 "SELECT points FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3737 array(
'integer',
'integer',
'integer'),
3738 array($active_id, $question_id,
$pass)
3740 $manual = ($manualscoring) ? 1 : 0;
3741 $rowsnum =
$result->numRows();
3744 $old_points = $row[
"points"];
3746 $affectedRows =
$ilDB->manipulateF(
3747 "UPDATE tst_test_result SET points = %s, manual = %s, tstamp = %s WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3748 array(
'float',
'integer',
'integer',
'integer',
'integer',
'integer'),
3749 array(
$points, $manual, time(), $active_id, $question_id,
$pass)
3753 $next_id =
$ilDB->nextId(
'tst_test_result');
3754 $affectedRows =
$ilDB->manipulateF(
3755 "INSERT INTO tst_test_result (test_result_id, active_fi, question_fi, points, pass, manual, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
3756 array(
'integer',
'integer',
'integer',
'float',
'integer',
'integer',
'integer'),
3757 array($next_id, $active_id, $question_id,
$points,
$pass, $manual, time())
3761 if (self::isForcePassResultUpdateEnabled() || $old_points !=
$points || !$rowsnum) {
3762 assQuestion::_updateTestPassResults($active_id,
$pass, $obligationsEnabled);
3764 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3765 include_once
'./Modules/Course/classes/class.ilCourseObjectiveResult.php';
3768 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
3773 include_once
"./Modules/Test/classes/class.ilObjTestAccess.php";
3818 || !(
new ilSetting(
'advanced_editing'))->
get(
'advanced_editing_javascript_editor') ===
'tinymce') {
3819 $purified_content = nl2br($purified_content);
3846 $ilDB = $DIC[
'ilDB'];
3849 "SELECT question_type_id FROM qpl_qst_type WHERE type_tag = %s",
3853 if (
$result->numRows() == 1) {
3855 return $row[
"question_type_id"];
3860 public function syncHints()
3863 $ilDB = $DIC[
'ilDB'];
3867 "DELETE FROM qpl_hints WHERE qht_question_fi = %s",
3869 array($this->original_id)
3874 "SELECT * FROM qpl_hints WHERE qht_question_fi = %s",
3876 array($this->
getId())
3882 $next_id =
$ilDB->nextId(
'qpl_hints');
3887 'qht_hint_id' => array(
'integer', $next_id),
3888 'qht_question_fi' => array(
'integer', $this->original_id),
3889 'qht_hint_index' => array(
'integer', $row[
"qht_hint_index"]),
3890 'qht_hint_points' => array(
'integer', $row[
"qht_hint_points"]),
3891 'qht_hint_text' => array(
'text', $row[
"qht_hint_text"]),
3907 $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(),
false);
3908 $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(),
true);
3909 $collected .= $this->feedbackOBJ->getAllSpecificAnswerFeedbackContents($this->
getId());
3911 foreach ($this->suggested_solutions as $solution_array) {
3912 $collected .= $solution_array[
"value"];
3915 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
3917 foreach ($questionHintList as $questionHint) {
3919 $collected .= $questionHint->getText();
3932 include_once(
"./Services/RTE/classes/class.ilRTE.php");
3944 $ilDB = $DIC[
'ilDB'];
3947 "SELECT question_id FROM qpl_questions WHERE original_id = %s",
3949 array($this->
getId())
3951 $instances = array();
3954 array_push($ids, $row[
"question_id"]);
3956 foreach ($ids as $question_id) {
3959 "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",
3968 "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",
3976 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3977 foreach ($instances as $key => $value) {
3985 include_once
"./Modules/Test/classes/class.ilObjAssessmentFolder.php";
3988 if (in_array($questiontype, $scoring)) {
4005 $ilDB = $DIC[
'ilDB'];
4007 "SELECT * FROM tst_active WHERE active_id = %s",
4013 return array(
"user_id" => $row[
"user_fi"],
"test_id" => $row[
"test_fi"]);
4028 if (self::isCoreQuestionType($question_type)) {
4029 self::includeCoreClass($question_type, $gui);
4031 self::includePluginClass($question_type, $gui);
4037 return $questionType .
'GUI';
4042 return $questionType;
4047 return str_replace(
'ass',
'ilAss', $questionType) .
'Feedback';
4052 $guiClassName = self::getGuiClassNameByQuestionType($questionType);
4053 return file_exists(
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php");
4058 if ($withGuiClass) {
4059 $guiClassName = self::getGuiClassNameByQuestionType($questionType);
4060 require_once
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php";
4064 $objectClassName = self::getObjectClassNameByQuestionType($questionType);
4065 require_once
"Modules/TestQuestionPool/classes/class.{$objectClassName}.php";
4068 $feedbackClassName = self::getFeedbackClassNameByQuestionType($questionType);
4069 require_once
"Modules/TestQuestionPool/classes/feedback/class.{$feedbackClassName}.php";
4075 $ilPluginAdmin = $DIC[
'ilPluginAdmin'];
4078 self::getObjectClassNameByQuestionType($questionType),
4079 self::getFeedbackClassNameByQuestionType($questionType)
4082 if ($withGuiClass) {
4083 $classes[] = self::getGuiClassNameByQuestionType($questionType);
4086 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
"TestQuestionPool",
"qst");
4087 foreach ($pl_names as $pl_name) {
4089 if (strcmp($pl->getQuestionType(), $questionType) == 0) {
4090 foreach ($classes as $class) {
4091 $pl->includeClass(
"class.{$class}.php");
4107 if (file_exists(
"./Modules/TestQuestionPool/classes/class." . $type_tag .
".php")) {
4110 return $lng->txt($type_tag);
4113 $ilPluginAdmin = $DIC[
'ilPluginAdmin'];
4114 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
"TestQuestionPool",
"qst");
4115 foreach ($pl_names as $pl_name) {
4117 if (strcmp($pl->getQuestionType(), $type_tag) == 0) {
4118 return $pl->getQuestionTypeTranslation();
4136 return self::instantiateQuestionGUI($question_id);
4149 $ilCtrl = $DIC[
'ilCtrl'];
4150 $ilDB = $DIC[
'ilDB'];
4154 if (strcmp($a_question_id,
"") != 0) {
4159 $question_type_gui = self::getGuiClassNameByQuestionType($question_type);
4160 $question_gui =
new $question_type_gui();
4161 $question_gui->object->loadFromDb($a_question_id);
4163 $feedbackObjectClassname = self::getFeedbackClassNameByQuestionType($question_type);
4164 $question_gui->object->feedbackOBJ =
new $feedbackObjectClassname($question_gui->object, $ilCtrl,
$ilDB,
$lng);
4166 $assSettings =
new ilSetting(
'assessment');
4167 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionProcessLockerFactory.php';
4169 $processLockerFactory->setQuestionId($question_gui->object->getId());
4170 $processLockerFactory->setUserId(
$ilUser->getId());
4171 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
4173 $question_gui->object->setProcessLocker($processLockerFactory->getLocker());
4176 $ilLog = $DIC[
'ilLog'];
4177 $ilLog->write(
'Instantiate question called without question id. (instantiateQuestionGUI@assQuestion)', $ilLog->WARNING);
4180 return $question_gui;
4195 $worksheet->setFormattedExcelTitle($worksheet->getColumnCoord(0) . $startrow, $this->lng->txt($this->
getQuestionType()));
4196 $worksheet->setFormattedExcelTitle($worksheet->getColumnCoord(1) . $startrow, $this->
getTitle());
4208 return $this->
getId();
4228 case "est_working_time":
4252 case "suggested_solutions":
4259 if (array_key_exists($value, $this->arrData)) {
4260 return $this->arrData[$value];
4275 $this->
setId($value);
4295 case "est_working_time":
4296 if (is_array($value)) {
4316 $this->page = &$value;
4319 $this->arrData[$key] = $value;
4331 $this->nr_of_tries = $a_nr_of_tries;
4336 $this->export_image_path = (string) $a_path;
4342 $ilDB = $DIC[
'ilDB'];
4344 if ($question_id < 1) {
4349 "SELECT question_fi FROM tst_test_question WHERE question_fi = %s AND test_fi = %s",
4350 array(
'integer',
'integer'),
4353 if (
$result->numRows() == 1) {
4376 require_once
'Modules/TestQuestionPool/classes/questions/class.ilAssSelfAssessmentQuestionFormatter.php';
4377 return new \ilAssSelfAssessmentQuestionFormatter();
4389 $this->prevent_rte_usage = $a_val;
4411 $this->feedbackOBJ->migrateContentForLearningModule($migrator, $this->
getId());
4437 $this->selfassessmenteditingmode = $a_selfassessmenteditingmode;
4457 $this->defaultnroftries = $a_defaultnroftries;
4480 $ilDB = $DIC[
'ilDB'];
4482 $query =
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s";
4484 $res =
$ilDB->queryF(
$query, array(
'integer'), array((
int) $questionId));
4487 return $row[
'obj_fi'];
4502 return self::lookupParentObjId($originalQuestionId);
4507 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
4511 require_once
'Modules/TestQuestionPool/classes/class.ilAssHintPage.php';
4513 foreach ($hintIds as $originalHintId => $duplicateHintId) {
4515 $originalXML = $originalPageObject->getXMLContent();
4518 $duplicatePageObject->setId($duplicateHintId);
4519 $duplicatePageObject->setParentId($this->
getId());
4520 $duplicatePageObject->setXMLContent($originalXML);
4521 $duplicatePageObject->createFromXML();
4529 $ilDB = $DIC[
'ilDB'];
4531 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
4533 $assignmentList->setParentObjId($srcParentId);
4534 $assignmentList->setQuestionIdFilter($srcQuestionId);
4535 $assignmentList->loadFromDb();
4537 foreach ($assignmentList->getAssignmentsByQuestionId($srcQuestionId) as $assignment) {
4540 $assignment->setParentObjId($trgParentId);
4541 $assignment->setQuestionId($trgQuestionId);
4542 $assignment->saveToDb();
4549 $ilDB = $DIC[
'ilDB'];
4551 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
4553 $assignmentList->setParentObjId($trgParentId);
4554 $assignmentList->setQuestionIdFilter($trgQuestionId);
4555 $assignmentList->loadFromDb();
4557 foreach ($assignmentList->getAssignmentsByQuestionId($trgQuestionId) as $assignment) {
4560 $assignment->deleteFromDb();
4620 $ilDB = $DIC[
'ilDB'];
4623 SELECT count(active_fi) cnt 4627 WHERE active_fi = %s 4628 AND question_fi = %s 4634 array(
'integer',
'integer',
'integer'),
4635 array($activeId, $questionId,
$pass)
4640 return (
int) $row[
'cnt'];
4663 require_once
'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
4706 self::ADDITIONAL_CONTENT_EDITING_MODE_RTE,
4707 self::ADDITIONAL_CONTENT_EDITING_MODE_IPE
4716 $this->questionChangeListeners[] = $listener;
4730 $listener->notifyQuestionCreated($this);
4737 $listener->notifyQuestionEdited($this);
4744 $listener->notifyQuestionDeleted($this);
4753 require_once
'Services/Html/classes/class.ilHtmlPurifierFactory.php';
4765 SELECT qpl_questions.*, 4766 {$this->getAdditionalTableName()}.* 4768 LEFT JOIN {$this->getAdditionalTableName()} 4769 ON {$this->getAdditionalTableName()}.question_fi = qpl_questions.question_id 4770 WHERE qpl_questions.question_id = %s 4797 $ilDB = $DIC[
'ilDB'];
4799 if ($this->
getStep() !== null) {
4803 WHERE active_fi = %s 4804 AND question_fi = %s 4810 return $ilDB->queryF(
4812 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
4819 WHERE active_fi = %s 4820 AND question_fi = %s 4825 return $ilDB->queryF(
4827 array(
'integer',
'integer',
'integer',
'integer'),
4828 array($active_id, $this->
getId(),
$pass, (
int) $authorized)
4842 $ilDB = $DIC[
'ilDB'];
4844 return $ilDB->manipulateF(
4845 "DELETE FROM tst_solutions WHERE solution_id = %s",
4861 $ilDB = $DIC[
'ilDB'];
4864 "SELECT * FROM tst_solutions WHERE solution_id = %s",
4869 while ($row =
$ilDB->fetchAssoc(
$res)) {
4885 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use ($active_id,
$pass) {
4901 $ilDB = $DIC[
'ilDB'];
4903 if ($this->
getStep() !== null) {
4905 DELETE FROM tst_solutions 4906 WHERE active_fi = %s 4907 AND question_fi = %s 4913 return $ilDB->manipulateF(
4915 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
4920 DELETE FROM tst_solutions 4921 WHERE active_fi = %s 4922 AND question_fi = %s 4927 return $ilDB->manipulateF(
4929 array(
'integer',
'integer',
'integer',
'integer'),
4930 array($active_id, $this->
getId(),
$pass, (
int) $authorized)
4950 $ilDB = $DIC[
'ilDB'];
4952 $next_id =
$ilDB->nextId(
"tst_solutions");
4955 "solution_id" => array(
"integer", $next_id),
4956 "active_fi" => array(
"integer", $active_id),
4957 "question_fi" => array(
"integer", $this->
getId()),
4958 "value1" => array(
"clob", $value1),
4959 "value2" => array(
"clob", $value2),
4960 "pass" => array(
"integer",
$pass),
4961 "tstamp" => array(
"integer", isset($tstamp) ? $tstamp : time()),
4962 'authorized' => array(
'integer', (
int) $authorized)
4965 if ($this->
getStep() !== null) {
4966 $fieldData[
'step'] = array(
"integer", $this->
getStep());
4969 return $ilDB->insert(
"tst_solutions", $fieldData);
4986 $ilDB = $DIC[
'ilDB'];
4989 "value1" => array(
"clob", $value1),
4990 "value2" => array(
"clob", $value2),
4991 "tstamp" => array(
"integer", time()),
4992 'authorized' => array(
'integer', (
int) $authorized)
4995 if ($this->
getStep() !== null) {
4996 $fieldData[
'step'] = array(
"integer", $this->
getStep());
4999 return $ilDB->update(
"tst_solutions", $fieldData, array(
5000 'solution_id' => array(
'integer', $solutionId)
5008 $ilDB = $DIC[
'ilDB'];
5011 'authorized' => array(
'integer', (
int) $authorized)
5015 $fieldData[
'tstamp'] = array(
'integer', time());
5019 'question_fi' => array(
'integer', $this->
getId()),
5020 'active_fi' => array(
'integer', $activeId),
5021 'pass' => array(
'integer',
$pass)
5024 if ($this->
getStep() !== null) {
5025 $whereData[
'step'] = array(
"integer", $this->
getStep());
5028 return $ilDB->update(
'tst_solutions', $fieldData, $whereData);
5036 return self::KEY_VALUES_IMPLOSION_SEPARATOR;
5040 return implode(self::getKeyValuesImplosionSeparator(), $keyValues);
5044 return explode(self::getKeyValuesImplosionSeparator(), $keyValues);
5049 foreach ($this->
getSolutionValues($activeId, $passIndex,
false) as $solutionRec) {
5050 if (0 == strlen($solutionRec[
'value1']) && 0 == strlen($solutionRec[
'value2'])) {
5058 return !strlen($solutionRecord[
'value1']) && !strlen($solutionRecord[
'value2']);
5064 $ilDB = $DIC[
'ilDB'];
5066 $types = array(
"integer",
"integer",
"integer",
"integer");
5067 $values = array($activeId, $this->
getId(), $passIndex, (
int) $authorized);
5068 $valuesCondition = array();
5070 foreach ($matchValues as $valueField => $value) {
5071 switch ($valueField) {
5074 $valuesCondition[] =
"{$valueField} = %s";
5080 require_once
'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
5085 $valuesCondition = implode(
' AND ', $valuesCondition);
5088 DELETE FROM tst_solutions 5089 WHERE active_fi = %s 5090 AND question_fi = %s 5093 AND $valuesCondition 5096 if ($this->
getStep() !== null) {
5097 $query .=
" AND step = %s ";
5098 $types[] =
'integer';
5108 $this->
saveCurrentSolution($activeId, $passIndex, $rec[
'value1'], $rec[
'value2'],
true, $rec[
'tstamp']);
5116 if (!count($intermediateSolution)) {
5124 if ($considerDummyRecordCreation) {
5146 return self::$resultGateway;
5154 $this->step =
$step;
5174 return gmdate(
'H:i:s', $time);
5184 $time_array = explode(
':', $time);
5185 if (
sizeof($time_array) == 3) {
5186 $sec += $time_array[0] * 3600;
5187 $sec += $time_array[1] * 60;
5188 $sec += $time_array[2];
5195 return json_encode(array());
5203 $solutionAvailability = $this->lookupForExistingSolutions($active_id,
$pass);
5204 return (
bool) $solutionAvailability[
'intermediate'];
5208 $solutionAvailability = $this->lookupForExistingSolutions($active_id,
$pass);
5209 return (
bool) $solutionAvailability[
'authorized'];
5213 $solutionAvailability = $this->lookupForExistingSolutions($active_id,
$pass);
5214 return (
bool) $solutionAvailability[
'authorized'] || (bool) $solutionAvailability[
'intermediate'];
5223 protected function lookupMaxStep($active_id,
$pass)
5227 $ilDB = $DIC[
'ilDB'];
5230 "SELECT MAX(step) max_step FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
5231 array(
"integer",
"integer",
"integer"),
5237 $maxStep = $row[
'max_step'];
5249 public function lookupForExistingSolutions($activeId,
$pass)
5253 $ilDB = $DIC[
'ilDB'];
5256 'authorized' =>
false,
5257 'intermediate' =>
false 5261 SELECT authorized, COUNT(*) cnt 5263 WHERE active_fi = %s 5264 AND question_fi = %s 5268 if ($this->
getStep() !== null) {
5279 if ($row[
'authorized']) {
5280 $return[
'authorized'] = $row[
'cnt'] > 0;
5282 $return[
'intermediate'] = $row[
'cnt'] > 0;
5302 $query =
"DELETE FROM tst_solutions WHERE question_fi = %s";
5304 $DIC->database()->manipulateF(
$query, array(
'integer'), array($this->
getId()));
5310 $ilDB = $DIC[
'ilDB'];
5313 DELETE FROM tst_solutions 5314 WHERE active_fi = %s 5315 AND question_fi = %s 5319 if ($this->
getStep() !== null) {
5323 return $ilDB->manipulateF(
5325 array(
'integer',
'integer',
'integer'),
5335 $this->
log($activeId,
"log_user_solution_willingly_deleted");
5337 self::_updateTestPassResults(
5349 $ilDB = $DIC[
'ilDB'];
5352 DELETE FROM tst_test_result 5353 WHERE active_fi = %s 5354 AND question_fi = %s 5358 if ($this->
getStep() !== null) {
5362 return $ilDB->manipulateF(
5364 array(
'integer',
'integer',
'integer'),
5372 $ilDB = $DIC[
'ilDB'];
5374 $IN_questionIds =
$ilDB->in(
'question_fi', $questionIds,
false,
'integer');
5378 FROM tst_test_result 5379 WHERE active_fi = %s 5386 array(
'integer',
'integer'),
5387 array($activeId,
$pass)
5390 return $row[
'cnt'] < count($questionIds);
5396 $ilDB = $DIC[
'ilDB'];
5398 $IN_questionIds =
$ilDB->in(
'question_fi', $questionIds,
false,
'integer');
5402 FROM tst_test_result 5403 WHERE active_fi = %s 5410 array(
'integer',
'integer'),
5411 array($activeId,
$pass)
5414 $questionsHavingResultRecord = array();
5416 while ($row =
$ilDB->fetchAssoc(
$res)) {
5417 $questionsHavingResultRecord[] = $row[
'question_fi'];
5420 $questionsMissingResultRecordt = array_diff(
5422 $questionsHavingResultRecord
5425 return $questionsMissingResultRecordt;
5431 $ilDB = $DIC[
'ilDB'];
5435 FROM tst_test_result 5436 WHERE active_fi = %s 5437 AND question_fi = %s 5441 $row =
$ilDB->fetchAssoc(
$ilDB->queryF(
$query, array(
'integer',
'integer',
'integer'), array($activeId, $questionId,
$pass)));
5443 return $row[
'cnt'] > 0;
5452 $valuePairs = array();
5454 foreach ($indexedValues as $value1 => $value2) {
5455 $valuePairs[] = array(
'value1' => $value1,
'value2' => $value2);
5467 $indexedValues = array();
5469 foreach ($valuePairs as $valuePair) {
5470 $indexedValues[ $valuePair[
'value1'] ] = $valuePair[
'value2'];
5473 return $indexedValues;
5495 $ilDB = $DIC[
'ilDB'];
5498 "UPDATE qpl_questions SET tstamp = %s WHERE question_id = %s",
5499 array(
'integer',
'integer'),
5500 array(time(), $this->
getId())
5521 if ($this->testQuestionConfigInstance === null) {
5538 include_once(
'Modules/TestQuestionPool/classes/class.ilTestQuestionConfig.php');
5552 $query =
'SELECT user_fi FROM tst_active ' . PHP_EOL
5553 .
'JOIN tst_test_question ON tst_test_question.test_fi = tst_active.test_fi ' . PHP_EOL
5554 .
'JOIN qpl_questions ON qpl_questions.question_id = tst_test_question.question_fi ' . PHP_EOL
5555 .
'WHERE qpl_questions.obj_fi = ' . $this->db->quote($this->
getObjId(),
'integer');
5558 return $res->numRows() > 0;
static _getUserIdFromActiveId($active_id)
const ADDITIONAL_CONTENT_EDITING_MODE_IPE
constant for additional content editing mode "pageobject"
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.
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.
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.
Class ChatMainBarProvider .
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)
static getDataWebPath(string $relative_path='')
This is originally a fix for https://mantis.ilias.de/view.php?id=35707; in general, the handling of those pathes shold be improved or better, avoided entirely (e.g.
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()
beforeSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping, array $solutionhints=[])
Receives parameters from a QTI parser and creates a valid ILIAS question object.
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)
getQuestionForHTMLOutput()
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
purifyAndPrepareTextAreaOutput(string $content)
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...
getDescriptionForHTMLOutput()
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
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)
__construct(Container $dic, ilPlugin $plugin)
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)
const ADDITIONAL_CONTENT_EDITING_MODE_RTE
constant for additional content editing mode "default"
$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)