4 include_once
"./Modules/Test/classes/inc.AssessmentConstants.php";
258 $this->original_id = null;
266 $this->author = $this->ilias->account->fullname;
269 if ($this->owner <= 0)
271 $this->owner = $this->ilias->account->id;
275 $this->suggested_solutions = array();
277 $this->nr_of_tries =
"";
280 $this->arrData = array();
311 function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
313 include_once
"./Modules/TestQuestionPool/classes/import/qti12/class." . $this->
getQuestionType() .
"Import.php";
315 $import =
new $classname($this);
316 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
325 function toXML($a_include_header =
true, $a_include_binary =
true, $a_shuffle =
false, $test_output =
false, $force_image_references =
false)
327 include_once
"./Modules/TestQuestionPool/classes/export/qti12/class." . $this->
getQuestionType() .
"Export.php";
329 $export =
new $classname($this);
330 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
355 $result = $ilDB->queryF(
"SELECT * FROM qpl_questions WHERE obj_fi = %s AND title = %s",
356 array(
'integer',
'text'),
357 array($questionpool_id,
$title)
359 return (
$result->numRows() == 1) ? TRUE : FALSE;
395 $this->test_id =
$id;
453 $this->est_working_time = array(
"h" => (
int)$hour,
"m" => (
int)$min,
"s" => (
int)$sec);
467 foreach ($array as $key => $value)
469 if (strcmp($key, $searchkey)==0)
489 $author = $this->ilias->account->fullname;
608 if (!$this->est_working_time)
610 $this->est_working_time = array(
"h" => 0,
"m" => 0,
"s" => 0);
676 if(!strlen($this->external_id))
678 if($this->
getId() > 0)
680 return 'il_' . IL_INST_ID .
'_qst_' . $this->
getId();
684 return uniqid(
'',
true);
704 $result = $ilDB->queryF(
"SELECT points FROM qpl_questions WHERE question_id = %s",
726 $result = $ilDB->queryF(
"SELECT qpl_questions.*, qpl_qst_type.type_tag FROM qpl_qst_type, qpl_questions WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
732 return $ilDB->fetchAssoc(
$result);
747 $result = $ilDB->queryF(
"SELECT suggested_solution_id FROM qpl_sol_sug WHERE question_fi = %s",
764 return $question->getSuggestedSolutionOutput();
770 foreach ($this->suggested_solutions as $solution)
772 switch ($solution[
"type"])
781 $possible_texts = array_values(array_filter(array(
784 $this->lng->txt(
'tst_show_solution_suggested')
786 array_push($output,
'<a href="' . $this->
getSuggestedSolutionPathWeb() . $solution[
"value"][
"name"] .
'">' . $possible_texts[0] .
'</a>');
793 return join($output,
"<br />");
808 $result = $ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
809 array(
'integer',
'integer'),
810 array($question_id, $subquestion_index)
816 "internal_link" =>
$row[
"internal_link"],
817 "import_id" =>
$row[
"import_id"]
850 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
853 $result = $ilDB->queryF(
"SELECT * FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
854 array(
'integer',
'integer',
'integer'),
855 array($active_id, $question_id,
$pass)
904 include_once
"./Modules/Test/classes/class.ilObjTest.php";
912 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
914 $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
919 return $reached_points;
937 include_once
"./Modules/Test/classes/class.ilObjTest.php";
945 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
947 $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
961 if( is_null($reached_points) ) $reached_points = 0;
966 DELETE FROM tst_test_result
973 $affectedRows = $ilDB->manipulateF(
974 $query, array(
"integer",
"integer",
"integer"), array($active_id, $this->
getId(),
$pass)
977 $next_id = $ilDB->nextId(
"tst_test_result");
979 $ilDB->insert(
'tst_test_result', array(
980 'test_result_id' => array(
'integer', $next_id),
981 'active_fi' => array(
'integer', $active_id),
982 'question_fi' => array(
'integer', $this->
getId()),
983 'pass' => array(
'integer',
$pass),
984 'points' => array(
'float', $reached_points),
985 'tstamp' => array(
'integer', time()),
986 'hint_count' => array(
'integer', $requestsStatisticData->getRequestsCount()),
987 'hint_points' => array(
'float', $requestsStatisticData->getRequestsPoints()),
988 'answered' => array(
'integer', $isAnswered)
993 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1013 include_once
'Modules/Course/classes/class.ilCourseObjectiveResult.php';
1027 if(
$pass === null )
1029 require_once
'Modules/Test/classes/class.ilObjTest.php';
1073 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1074 include_once
"./Modules/Test/classes/class.assMarkSchema.php";
1079 SELECT tst_pass_result.*
1080 FROM tst_pass_result
1081 WHERE active_fi = %s
1086 $query, array(
'integer',
'integer'), array($active_id,
$pass)
1091 $max =
$row[
'maxpoints'];
1092 $reached =
$row[
'points'];
1094 $obligationsAnswered = (int)
$row[
'obligations_answered'];
1096 include_once
"./Modules/Test/classes/class.assMarkSchema.php";
1098 $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
1100 $mark = ASS_MarkSchema::_getMatchingMarkFromActiveId($active_id, $percentage);
1102 $isPassed = ( $mark[
"passed"] ? 1 : 0 );
1103 $isFailed = ( !$mark[
"passed"] ? 1 : 0 );
1111 DELETE FROM tst_result_cache
1112 WHERE active_fi = %s
1115 $affectedRows = $ilDB->manipulateF(
1116 $query, array(
'integer'), array($active_id)
1119 $ilDB->insert(
'tst_result_cache', array(
1120 'active_fi'=> array(
'integer', $active_id),
1121 'pass'=> array(
'integer', strlen(
$pass) ?
$pass : 0),
1122 'max_points'=> array(
'float', strlen($max) ? $max : 0),
1123 'reached_points'=> array(
'float', strlen($reached) ? $reached : 0),
1124 'mark_short'=> array(
'text', strlen($mark[
"short_name"]) ? $mark[
"short_name"] :
" "),
1125 'mark_official'=> array(
'text', strlen($mark[
"official_name"]) ? $mark[
"official_name"] :
" "),
1126 'passed'=> array(
'integer', $isPassed),
1127 'failed'=> array(
'integer', $isFailed),
1128 'tstamp'=> array(
'integer', time()),
1129 'hint_count'=> array(
'integer',
$row[
'hint_count']),
1130 'hint_points'=> array(
'float',
$row[
'hint_points']),
1131 'obligations_answered' => array(
'integer', $obligationsAnswered)
1145 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1153 SELECT SUM(points) reachedpoints,
1154 SUM(hint_count) hint_count,
1155 SUM(hint_points) hint_points,
1156 COUNT(DISTINCT(question_fi)) answeredquestions
1157 FROM tst_test_result
1158 WHERE active_fi = %s
1161 array(
'integer',
'integer'),
1162 array($active_id,
$pass)
1167 if( $obligationsEnabled )
1170 SELECT count(*) cnt,
1171 min( answered ) answ
1172 FROM tst_test_question
1173 INNER JOIN tst_active
1175 AND tst_test_question.test_fi = tst_active.test_fi
1176 LEFT JOIN tst_test_result
1177 ON tst_test_result.active_fi = %s
1178 AND tst_test_result.pass = %s
1179 AND tst_test_question.question_fi = tst_test_result.question_fi
1180 WHERE obligatory = 1';
1182 $result_obligatory = $ilDB->queryF(
1183 $query, array(
'integer',
'integer',
'integer'), array($active_id, $active_id,
$pass)
1186 $row_obligatory = $ilDB->fetchAssoc($result_obligatory);
1188 if ($row_obligatory[
'cnt'] == 0)
1190 $obligations_answered = 1;
1194 $obligations_answered = (int) $row_obligatory[
'answ'];
1199 $obligations_answered = 1;
1204 if(
$row[
'hint_count'] === null )
$row[
'hint_count'] = 0;
1205 if(
$row[
'hint_points'] === null )
$row[
'hint_points'] = 0;
1227 $ilDB->replace(
'tst_pass_result',
1229 'active_fi' => array(
'integer', $active_id),
1230 'pass' => array(
'integer', strlen(
$pass) ?
$pass : 0)),
1232 'points' => array(
'float',
$row[
'reachedpoints'] ?
$row[
'reachedpoints'] : 0),
1233 'maxpoints' => array(
'float', $data[
'points']),
1234 'questioncount' => array(
'integer', $data[
'count']),
1235 'answeredquestions' => array(
'integer', $row[
'answeredquestions']),
1236 'workingtime' => array(
'integer', $time),
1237 'tstamp' => array(
'integer', time()),
1238 'hint_count' => array(
'integer', $row[
'hint_count']),
1239 'hint_points' => array(
'float', $row[
'hint_points']),
1240 'obligations_answered' => array(
'integer', $obligations_answered),
1241 'exam_id' => array(
'text', $exam_identifier)
1271 'active_fi' => $active_id,
1273 'points' => ($row[
"reachedpoints"]) ? $row[
"reachedpoints"] : 0,
1274 'maxpoints' => $data[
"points"],
1275 'questioncount' => $data[
"count"],
1276 'answeredquestions' => $row[
"answeredquestions"],
1277 'workingtime' => $time,
1279 'hint_count' => $row[
'hint_count'],
1280 'hint_points' => $row[
'hint_points'],
1281 'obligations_answered' => $obligations_answered,
1282 'exam_id' => $exam_identifier
1293 function logAction($logtext =
"", $active_id =
"", $question_id =
"")
1298 if (strcmp($question_id,
"") != 0)
1300 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
1303 include_once
"./Modules/Test/classes/class.ilObjAssessmentFolder.php";
1304 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1315 function _logAction($logtext =
"", $active_id =
"", $question_id =
"")
1320 if (strcmp($question_id,
"") != 0)
1322 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
1325 include_once
"./Modules/Test/classes/class.ilObjAssessmentFolder.php";
1326 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1339 $mediatempdir = CLIENT_WEB_DIR .
"/assessment/temp";
1341 $temp_name = tempnam($mediatempdir, $name .
"_____");
1342 $temp_name = str_replace(
"\\",
"/", $temp_name);
1343 @unlink($temp_name);
1360 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/solution/";
1370 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/java/";
1381 if( $question_id === null)
1386 if( $object_id === null)
1391 return CLIENT_WEB_DIR .
"/assessment/$object_id/$question_id/images/";
1402 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/flash/";
1413 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1425 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1438 if(!$this->export_image_path)
1440 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1458 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1481 $result = $ilDB->queryF(
"SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s ORDER BY solution_id",
1482 array(
'integer',
'integer',
'integer'),
1483 array($active_id, $this->
getId(), $pass)
1485 while ($row = $ilDB->fetchAssoc(
$result))
1487 array_push($values, $row);
1503 if ($question_id < 1) $question_id = $this->
getId();
1504 $result = $ilDB->queryF(
"SELECT COUNT(qpl_questions.question_id) question_count FROM qpl_questions, tst_test_question WHERE qpl_questions.original_id = %s AND qpl_questions.question_id = tst_test_question.question_fi",
1508 $row = $ilDB->fetchAssoc(
$result);
1509 $count = $row[
"question_count"];
1511 $result = $ilDB->queryF(
"SELECT DISTINCT tst_active.test_fi, qpl_questions.question_id FROM qpl_questions, tst_test_rnd_qst, tst_active WHERE qpl_questions.original_id = %s AND qpl_questions.question_id = tst_test_rnd_qst.question_fi AND tst_test_rnd_qst.active_fi = tst_active.active_id",
1530 if ($question_id < 1) $question_id =
$this->id;
1531 $result = $ilDB->queryF(
"SELECT original_id FROM qpl_questions WHERE question_id = %s",
1535 $row = $ilDB->fetchAssoc(
$result);
1536 return ($row[
"original_id"] > 0) ? TRUE : FALSE;
1547 $keys = array_keys($array);
1550 foreach ($keys as $key)
1566 $result = $ilDB->queryF(
"SELECT qpl_qst_type.type_tag FROM qpl_qst_type, qpl_questions WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
1570 $data = $ilDB->fetchAssoc(
$result);
1571 return $data[
"type_tag"];
1606 if (is_array($answer_table_name))
1608 foreach ($answer_table_name as $table)
1612 $affectedRows = $ilDB->manipulateF(
"DELETE FROM $table WHERE question_fi = %s",
1621 if (strlen($answer_table_name))
1623 $affectedRows = $ilDB->manipulateF(
"DELETE FROM $answer_table_name WHERE question_fi = %s",
1641 if (is_array($additional_table_name))
1643 foreach ($additional_table_name as $table)
1647 $affectedRows = $ilDB->manipulateF(
"DELETE FROM $table WHERE question_fi = %s",
1656 if (strlen($additional_table_name))
1658 $affectedRows = $ilDB->manipulateF(
"DELETE FROM $additional_table_name WHERE question_fi = %s",
1674 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
1686 public function delete($question_id)
1690 if ($question_id < 1)
return true;
1692 $result = $ilDB->queryF(
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
1698 $row = $ilDB->fetchAssoc(
$result);
1711 $ilLog->write(
"EXCEPTION: Could not delete page of question $question_id: $e");
1715 $affectedRows = $ilDB->manipulateF(
"DELETE FROM qpl_questions WHERE question_id = %s",
1719 if ($affectedRows == 0)
return false;
1730 $ilLog->write(
"EXCEPTION: Could not delete additional table data of question $question_id: $e");
1737 $affectedRows = $ilDB->manipulateF(
"DELETE FROM tst_test_question WHERE question_fi = %s",
1744 $ilLog->write(
"EXCEPTION: Could not delete delete question $question_id from a test: $e");
1751 $affectedRows = $ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s",
1758 $ilLog->write(
"EXCEPTION: Could not delete suggested solutions of question $question_id: $e");
1764 $directory = CLIENT_WEB_DIR .
"/assessment/" .
$obj_id .
"/$question_id";
1765 if (preg_match(
"/\d+/",
$obj_id) and preg_match(
"/\d+/", $question_id) and is_dir($directory))
1767 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1773 $ilLog->write(
"EXCEPTION: Could not delete question file directory $directory of question $question_id: $e");
1779 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1785 foreach(
$mobs as $mob)
1797 $ilLog->write(
"EXCEPTION: Error deleting the media objects of question $question_id: $e");
1801 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
1804 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
1810 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
1815 $ilLog->write(
"EXCEPTION: Error updating the question pool question count of question pool " . $this->
getObjId() .
" when deleting question $question_id: $e");
1843 $result = $ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
1844 array(
'integer',
'integer'),
1845 array($a_q_id, $a_q_id)
1851 $found_id = array();
1852 while ($row = $ilDB->fetchAssoc(
$result))
1854 array_push($found_id, $row[
"question_id"]);
1857 $result = $ilDB->query(
"SELECT * FROM tst_test_result WHERE " . $ilDB->in(
'question_fi', $found_id,
false,
'integer'));
1872 $result = $ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
1873 array(
'integer',
'integer'),
1874 array($a_q_id, $a_q_id)
1880 $found_id = array();
1881 while ($row = $ilDB->fetchAssoc(
$result))
1883 array_push($found_id, $row[
"question_id"]);
1885 $result = $ilDB->query(
"SELECT * FROM tst_test_result WHERE " . $ilDB->in(
'question_fi', $found_id,
false,
'integer'));
1887 while ($row = $ilDB->fetchAssoc(
$result))
1889 $reached = $row[
"points"];
1890 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
1892 array_push($answers, array(
"reached" => $reached,
"max" => $max));
1896 foreach ($answers as $key => $value)
1898 $max += $value[
"max"];
1899 $reached += $value[
"reached"];
1903 return $reached / $max;
1919 $result = $ilDB->queryF(
"SELECT title FROM qpl_questions WHERE question_id = %s",
1925 $row = $ilDB->fetchAssoc(
$result);
1926 return $row[
"title"];
1942 $result = $ilDB->queryF(
"SELECT question_text FROM qpl_questions WHERE question_id = %s",
1948 $row = $ilDB->fetchAssoc(
$result);
1949 return $row[
"question_text"];
1960 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1962 foreach (
$mobs as $mob)
1970 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1972 foreach (
$mobs as $mob)
1985 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
1987 $this->page->setId($this->
getId());
1988 $this->page->setParentId($qpl_id);
1989 $this->page->setXMLContent(
"<PageObject><PageContent>".
1990 "<Question QRef=\"il__qst_".$this->
getId().
"\"/>".
1991 "</PageContent></PageObject>");
1992 $this->page->create();
1999 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2002 $xml = str_replace(
"il__qst_".$a_q_id,
"il__qst_".$this->
id,
$page->getXMLContent());
2003 $this->page->setXMLContent($xml);
2004 $this->page->updateFromXML();
2010 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2012 return $page->getXMLContent();
2026 if ($question_id < 1)
return "";
2027 $result = $ilDB->queryF(
"SELECT type_tag FROM qpl_questions, qpl_qst_type WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
2033 $data = $ilDB->fetchAssoc(
$result);
2034 return $data[
"type_tag"];
2053 if ($question_id < 1)
return "";
2055 $result = $ilDB->queryF(
"SELECT title FROM qpl_questions WHERE qpl_questions.question_id = %s",
2061 $data = $ilDB->fetchAssoc(
$result);
2062 return $data[
"title"];
2091 "SELECT external_id FROM qpl_questions WHERE question_id = %s",
2097 $data = $ilDB->fetchAssoc(
$result);
2098 $this->external_id = $data[
'external_id'];
2101 $result = $ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
2103 array($this->
getId())
2105 $this->suggested_solutions = array();
2108 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2109 while ($row = $ilDB->fetchAssoc(
$result))
2112 $this->suggested_solutions[$row[
"subquestion_index"]] = array(
2113 "type" => $row[
"type"],
2115 "internal_link" => $row[
"internal_link"],
2116 "import_id" => $row[
"import_id"]
2134 $estw_time = sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
2148 $next_id = $ilDB->nextId(
'qpl_questions');
2149 $affectedRows = $ilDB->insert(
"qpl_questions", array(
2150 "question_id" => array(
"integer", $next_id),
2152 "obj_fi" => array(
"integer",
$obj_id),
2153 "title" => array(
"text", NULL),
2154 "description" => array(
"text", NULL),
2155 "author" => array(
"text", $this->
getAuthor()),
2156 "owner" => array(
"integer", $ilUser->getId()),
2157 "question_text" => array(
"clob", NULL),
2158 "points" => array(
"float", 0),
2159 "nr_of_tries" => array(
"integer", 1),
2160 "working_time" => array(
"text", $estw_time),
2161 "complete" => array(
"text", $complete),
2162 "created" => array(
"integer", time()),
2163 "original_id" => array(
"integer", NULL),
2164 "tstamp" => array(
"integer", $tstamp),
2168 $this->
setId($next_id);
2179 return $this->
getId();
2187 $estw_time = sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
2190 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2191 if ($this->
getId() == -1)
2194 $next_id = $ilDB->nextId(
'qpl_questions');
2195 $affectedRows = $ilDB->insert(
"qpl_questions", array(
2196 "question_id" => array(
"integer", $next_id),
2198 "obj_fi" => array(
"integer", $this->
getObjId()),
2199 "title" => array(
"text", $this->
getTitle()),
2200 "description" => array(
"text", $this->
getComment()),
2201 "author" => array(
"text", $this->
getAuthor()),
2202 "owner" => array(
"integer", $this->
getOwner()),
2205 "working_time" => array(
"text", $estw_time),
2207 "created" => array(
"integer", time()),
2209 "tstamp" => array(
"integer", time()),
2213 $this->
setId($next_id);
2220 $affectedRows = $ilDB->update(
"qpl_questions", array(
2221 "obj_fi" => array(
"integer", $this->
getObjId()),
2222 "title" => array(
"text", $this->
getTitle()),
2223 "description" => array(
"text", $this->
getComment()),
2224 "author" => array(
"text", $this->
getAuthor()),
2228 "working_time" => array(
"text", $estw_time),
2229 "tstamp" => array(
"integer", time()),
2232 "question_id" => array(
"integer", $this->
getId())
2247 $this->updateSuggestedSolutions();
2259 $affectedRows = $ilDB->manipulateF(
"UPDATE qpl_questions SET tstamp = %s, owner = %s, complete = %s WHERE question_id = %s",
2260 array(
'integer',
'integer',
'integer',
'text'),
2261 array(time(), ($this->
getOwner() <= 0) ? $this->ilias->account->id : $this->getOwner(), $complete, $this->
getId())
2265 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
2273 $ilDB->manipulateF(
"UPDATE qpl_questions SET tstamp = %s, original_id = %s WHERE question_id = %s",
2274 array(
'integer',
'integer',
'text'),
2275 array(time(), $newId, $this->
getId())
2282 protected function onDuplicate($originalParentId, $originalQuestionId, $duplicateParentId, $duplicateQuestionId)
2287 $this->feedbackOBJ->duplicateFeedback($originalQuestionId, $duplicateQuestionId);
2296 $this->feedbackOBJ->syncFeedback($originalQuestionId, $duplicateQuestionId);
2302 protected function onCopy($sourceParentId, $sourceQuestionId, $targetParentId, $targetQuestionId)
2307 $this->feedbackOBJ->duplicateFeedback($sourceQuestionId, $targetQuestionId);
2320 $affectedRows = $ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2322 array($this->
getId())
2325 include_once
"./Services/COPage/classes/class.ilInternalLink.php";
2327 $this->suggested_solutions = array();
2340 if (array_key_exists($subquestion_index, $this->suggested_solutions))
2342 return $this->suggested_solutions[$subquestion_index];
2360 if (array_key_exists($subquestion_index, $this->suggested_solutions))
2362 $title = $this->suggested_solutions[$subquestion_index][
"internal_link"];
2383 if (strcmp($solution_id,
"") != 0)
2388 $import_id = $solution_id;
2391 $this->suggested_solutions[$subquestion_index] = array(
2392 "internal_link" => $solution_id,
2393 "import_id" => $import_id
2405 foreach ($this->suggested_solutions as $index => $solution)
2407 if (strcmp($solution[
"type"],
"file") == 0)
2410 $filepath_original = str_replace(
2411 "/{$this->obj_id}/{$this->id}/solution",
2412 "/$parent_id/$question_id/solution",
2415 if (!file_exists($filepath))
2422 if (!copy($filepath_original .
$filename, $filepath . $filename))
2424 $ilLog->write(
"File could not be duplicated!!!!", $ilLog->ERROR);
2425 $ilLog->write(
"object: " . print_r($this, TRUE), $ilLog->ERROR);
2440 $filepath_original = str_replace(
"/$this->id/solution",
"/$original_id/solution", $filepath);
2442 foreach ($this->suggested_solutions as $index => $solution)
2444 if (strcmp($solution[
"type"],
"file") == 0)
2446 if (!file_exists($filepath_original))
2453 if (!@copy($filepath .
$filename, $filepath_original . $filename))
2455 $ilLog->write(
"File could not be duplicated!!!!", $ilLog->ERROR);
2456 $ilLog->write(
"object: " . print_r($this, TRUE), $ilLog->ERROR);
2467 foreach ($this->suggested_solutions as $index => $solution)
2469 if (strcmp($solution[
"type"],
"file") == 0)
2472 $filepath_original = str_replace(
"/$this->obj_id/$this->id/solution",
"/$source_questionpool_id/$source_question_id/solution", $filepath);
2473 if (!file_exists($filepath))
2480 if (!copy($filepath_original .
$filename, $filepath . $filename))
2482 $ilLog->write(
"File could not be copied!!!!", $ilLog->ERROR);
2483 $ilLog->write(
"object: " . print_r($this, TRUE), $ilLog->ERROR);
2493 public function updateSuggestedSolutions(
$original_id =
"")
2498 include_once
"./Services/COPage/classes/class.ilInternalLink.php";
2499 $affectedRows = $ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2504 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2505 foreach ($this->suggested_solutions as $index => $solution)
2507 $next_id = $ilDB->nextId(
'qpl_sol_sug');
2509 $ilDB->insert(
'qpl_sol_sug', array(
2510 'suggested_solution_id' => array(
'integer', $next_id ),
2511 'question_fi' => array(
'integer',
$id ),
2512 'type' => array(
'text', $solution[
'type'] ),
2514 'internal_link' => array(
'text', $solution[
'internal_link'] ),
2515 'import_id' => array(
'text', null ),
2516 'subquestion_index' => array(
'integer', $index ),
2517 'tstamp' => array(
'integer', time() ),
2520 if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/", $solution[
"internal_link"], $matches))
2538 function saveSuggestedSolution($type, $solution_id =
"", $subquestion_index = 0, $value =
"")
2542 $affectedRows = $ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
2543 array(
"integer",
"integer"),
2550 $next_id = $ilDB->nextId(
'qpl_sol_sug');
2551 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2553 $affectedRows = $ilDB->insert(
'qpl_sol_sug', array(
2554 'suggested_solution_id' => array(
'integer', $next_id ),
2555 'question_fi' => array(
'integer', $this->
getId() ),
2556 'type' => array(
'text', $type ),
2558 'internal_link' => array(
'text', $solution_id ),
2559 'import_id' => array(
'text', null ),
2560 'subquestion_index' => array(
'integer', $subquestion_index ),
2561 'tstamp' => array(
'integer', time() ),
2564 if ($affectedRows == 1)
2566 $this->suggested_solutions[
"subquestion_index"] = array(
2569 "internal_link" => $solution_id,
2578 if (preg_match(
"/il_(\d+)_(\w+)_(\d+)/", $internal_link, $matches))
2580 include_once
"./Services/COPage/classes/class.ilInternalLink.php";
2581 include_once
"./Modules/LearningModule/classes/class.ilLMObject.php";
2582 include_once
"./Modules/Glossary/classes/class.ilGlossaryTerm.php";
2583 switch ($matches[2])
2601 if (strcmp($resolved_link,
"") == 0)
2603 $resolved_link = $internal_link;
2608 $resolved_link = $internal_link;
2610 return $resolved_link;
2617 $result = $ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
2623 while ($row = $ilDB->fetchAssoc(
$result))
2625 $internal_link = $row[
"internal_link"];
2626 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
2628 if (strcmp($internal_link, $resolved_link) != 0)
2631 $affectedRows = $ilDB->manipulateF(
"UPDATE qpl_sol_sug SET internal_link = %s WHERE suggested_solution_id = %s",
2632 array(
'text',
'integer'),
2633 array($resolved_link, $row[
"suggested_solution_id"])
2644 include_once
"./Services/COPage/classes/class.ilInternalLink.php";
2647 $result = $ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
2653 while ($row = $ilDB->fetchAssoc(
$result))
2655 if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/", $row[
"internal_link"], $matches))
2668 "lm" =>
"LearningModule",
2669 "pg" =>
"PageObject",
2670 "st" =>
"StructureObject",
2671 "git" =>
"GlossaryItem",
2672 "mob" =>
"MediaObject"
2675 if (preg_match(
"/il__(\w+)_(\d+)/", $target, $matches))
2677 $type = $matches[1];
2679 include_once
"./Services/Utilities/classes/class.ilUtil.php";
2680 switch($linktypes[$matches[1]])
2682 case "LearningModule":
2683 $href =
"./goto.php?target=" . $type .
"_" .
$target_id;
2686 case "StructureObject":
2687 $href =
"./goto.php?target=" . $type .
"_" .
$target_id;
2689 case "GlossaryItem":
2690 $href =
"./goto.php?target=" . $type .
"_" .
$target_id;
2693 $href =
"./ilias.php?baseClass=ilLMPresentationGUI&obj_type=" . $linktypes[$type] .
"&cmd=media&ref_id=".$_GET[
"ref_id"].
"&mob_id=".
$target_id;
2710 $result = $ilDB->queryF(
"SELECT * FROM qpl_questions WHERE question_id = %s",
2716 $row = $ilDB->fetchAssoc(
$result);
2717 if ($row[
"original_id"] > 0)
2719 return $row[
"original_id"];
2723 return $row[
"question_id"];
2737 SELECT COUNT(dupl.question_id) cnt
2738 FROM qpl_questions dupl
2739 INNER JOIN qpl_questions orig
2740 ON orig.question_id = dupl.original_id
2741 WHERE dupl.question_id = %s
2744 $res = $ilDB->queryF(
$query, array(
'integer'), array($questionId));
2745 $row = $ilDB->fetchAssoc(
$res);
2747 return $row[
'cnt'] > 0;
2761 if ( !$originalObjId )
2779 $this->updateSuggestedSolutions($original);
2801 if ($question_id < 1)
2806 $result = $ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE question_id = %s",
2831 if ($question_id < 1)
2836 $result = $ilDB->queryF(
"SELECT question_id FROM qpl_questions INNER JOIN object_data ON obj_fi = obj_id WHERE question_id = %s AND type = 'qpl'",
2866 if (strcmp($question_id,
"") != 0)
2869 if (!strlen($question_type))
return null;
2876 $question->feedbackOBJ =
new $feedbackObjectClassname(
$question, $ilCtrl, $ilDB, $lng);
2890 if (strcmp($this->points,
"") == 0)
2909 $this->points = $a_points;
2940 $result = $ilDB->queryF(
"SELECT MAX(pass) maxpass FROM tst_test_result WHERE active_fi = %s AND question_fi = %s",
2941 array(
'integer',
'integer'),
2942 array($active_id, $question_id)
2946 $row = $ilDB->fetchAssoc(
$result);
2947 return $row[
"maxpass"];
2967 if (($question_id < 1) || ($user_id < 1))
2972 $result = $ilDB->queryF(
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
2978 $row = $ilDB->fetchAssoc(
$result);
2979 $qpl_object_id = $row[
"obj_fi"];
2980 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
2999 if ($question_id < 1)
return 0;
3000 $result = $ilDB->queryF(
"SELECT test_random_question_id FROM tst_test_rnd_qst WHERE question_fi = %s",
3032 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3034 if ($count_system == 1)
3042 if ($score_cutting == 0)
3067 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
3070 $result = $ilDB->queryF(
"SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3071 array(
'integer',
'integer',
'integer'),
3072 array($active_id, $question_id, $pass)
3095 $res = $ilDB->queryF(
"SELECT DISTINCT(question_fi) FROM tst_test_result JOIN tst_active ".
3096 "ON (active_id = active_fi) ".
3097 "WHERE " . $ilDB->in(
'question_fi', $a_question_ids,
false,
'integer') .
3098 " AND user_fi = %s",
3102 return (
$res->numRows() == count($a_question_ids)) ?
true :
false;
3115 if (preg_match(
"/<[^>]*?>/", $a_text))
3133 include_once
"./Services/Utilities/classes/class.ilUtil.php";
3147 for ($i = 0; $i < $a_material->getMaterialCount(); $i++)
3149 $material = $a_material->getMaterial($i);
3150 if (strcmp($material[
"type"],
"mattext") == 0)
3152 $result .= $material[
"material"]->getContent();
3154 if (strcmp($material[
"type"],
"matimage") == 0)
3156 $matimage = $material[
"material"];
3157 if (preg_match(
"/(il_([0-9]+)_mob_([0-9]+))/", $matimage->getLabel(), $matches))
3160 if (!is_array(
$_SESSION[
"import_mob_xhtml"]))
$_SESSION[
"import_mob_xhtml"] = array();
3161 array_push(
$_SESSION[
"import_mob_xhtml"], array(
"mob" => $matimage->getLabel(),
"uri" => $matimage->getUri()));
3176 function addQTIMaterial(&$a_xml_writer, $a_material, $close_material_tag = TRUE, $add_mobs = TRUE)
3178 include_once
"./Services/RTE/classes/class.ilRTE.php";
3179 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
3181 $a_xml_writer->xmlStartTag(
"material");
3183 "texttype" =>
"text/plain"
3185 if ($this->
isHTML($a_material))
3187 $attrs[
"texttype"] =
"text/xhtml";
3193 foreach (
$mobs as $mob)
3195 $moblabel =
"il_" . IL_INST_ID .
"_mob_" . $mob;
3196 if (strpos($a_material,
"mm_$mob") !== FALSE)
3202 "label" => $moblabel,
3203 "uri" =>
"objects/" .
"il_" . IL_INST_ID .
"_mob_" . $mob .
"/" . $mob_obj->getTitle()
3206 $a_xml_writer->xmlElement(
"matimage", $imgattrs, NULL);
3210 if ($close_material_tag) $a_xml_writer->xmlEndTag(
"material");
3216 if (preg_match(
"/.*\.(png|jpg|gif|jpeg)$/i", $image_filename, $matches))
3218 $extension =
"." . $matches[1];
3220 $image_filename = md5($image_filename) . $extension;
3221 return $image_filename;
3247 $result = $ilDB->queryF(
"SELECT points FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3248 array(
'integer',
'integer',
'integer'),
3249 array($active_id, $question_id, $pass)
3251 $manual = ($manualscoring) ? 1 : 0;
3252 $rowsnum =
$result->numRows();
3255 $row = $ilDB->fetchAssoc(
$result);
3256 $old_points = $row[
"points"];
3259 $affectedRows = $ilDB->manipulateF(
"UPDATE tst_test_result SET points = %s, manual = %s, tstamp = %s WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3260 array(
'float',
'integer',
'integer',
'integer',
'integer',
'integer'),
3261 array(
$points, $manual, time(), $active_id, $question_id, $pass)
3267 $next_id = $ilDB->nextId(
'tst_test_result');
3268 $affectedRows = $ilDB->manipulateF(
"INSERT INTO tst_test_result (test_result_id, active_fi, question_fi, points, pass, manual, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
3269 array(
'integer',
'integer',
'integer',
'float',
'integer',
'integer',
'integer'),
3270 array($next_id, $active_id, $question_id,
$points, $pass, $manual, time())
3274 if($old_points !=
$points || !$rowsnum)
3276 assQuestion::_updateTestPassResults($active_id, $pass, $obligationsEnabled);
3278 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3279 include_once
'./Modules/Course/classes/class.ilCourseObjectiveResult.php';
3282 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
3286 include_once
"./Modules/Test/classes/class.ilObjTestAccess.php";
3348 $result = $ilDB->queryF(
"SELECT question_type_id FROM qpl_qst_type WHERE type_tag = %s",
3354 $row = $ilDB->fetchAssoc(
$result);
3355 return $row[
"question_type_id"];
3360 public function syncHints()
3365 $ilDB->manipulateF(
"DELETE FROM qpl_hints WHERE qht_question_fi = %s",
3367 array($this->original_id)
3371 $result = $ilDB->queryF(
"SELECT * FROM qpl_hints WHERE qht_question_fi = %s",
3373 array($this->
getId())
3379 while ($row = $ilDB->fetchAssoc(
$result))
3381 $next_id = $ilDB->nextId(
'qpl_hints');
3383 $ilDB->insert(
'qpl_hints', array(
3384 'qht_hint_id' => array(
'integer', $next_id),
3385 'qht_question_fi' => array(
'integer', $this->original_id),
3386 'qht_hint_index' => array(
'integer', $row[
"qht_hint_index"]),
3387 'qht_hint_points' => array(
'integer', $row[
"qht_hint_points"]),
3388 'qht_hint_text' => array(
'text', $row[
"qht_hint_text"]),
3404 $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(),
false);
3405 $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(),
true);
3408 $collected .= $this->feedbackOBJ->getSpecificAnswerFeedbackContent($this->
getId(), $i);
3410 foreach ($this->suggested_solutions as $solution_array)
3412 $collected .= $solution_array[
"value"];
3424 include_once(
"./Services/RTE/classes/class.ilRTE.php");
3437 $result = $ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE original_id = %s",
3439 array($this->
getId())
3441 $instances = array();
3443 while ($row = $ilDB->fetchAssoc(
$result))
3445 array_push($ids, $row[
"question_id"]);
3447 foreach ($ids as $question_id)
3450 $result = $ilDB->queryF(
"SELECT tst_tests.obj_fi FROM tst_tests, tst_test_question WHERE tst_test_question.question_fi = %s AND tst_test_question.test_fi = tst_tests.test_id",
3454 while ($row = $ilDB->fetchAssoc(
$result))
3459 $result = $ilDB->queryF(
"SELECT tst_tests.obj_fi FROM tst_tests, tst_test_rnd_qst, tst_active WHERE tst_test_rnd_qst.active_fi = tst_active.active_id AND tst_test_rnd_qst.question_fi = %s AND tst_tests.test_id = tst_active.test_fi",
3463 while ($row = $ilDB->fetchAssoc(
$result))
3468 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3469 foreach ($instances as $key => $value)
3478 include_once
"./Modules/Test/classes/class.ilObjAssessmentFolder.php";
3481 if (in_array($questiontype, $scoring))
3501 $result = $ilDB->queryF(
"SELECT * FROM tst_active WHERE active_id = %s",
3507 $row = $ilDB->fetchAssoc(
$result);
3508 return array(
"user_id" => $row[
"user_fi"],
"test_id" => $row[
"test_fi"]);
3525 if( self::isCoreQuestionType($question_type) )
3537 return $questionType.
'GUI';
3542 return $questionType;
3547 return str_replace(
'ass',
'ilAss', $questionType).
'Feedback';
3553 return file_exists(
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php");
3561 require_once
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php";
3568 require_once
"Modules/TestQuestionPool/classes/class.{$objectClassName}.php";
3572 require_once
"Modules/TestQuestionPool/classes/feedback/class.{$feedbackClassName}.php";
3577 global $ilPluginAdmin;
3580 self::getObjectClassNameByQuestionType($questionType),
3581 self::getFeedbackClassNameByQuestionType($questionType)
3589 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
"TestQuestionPool",
"qst");
3590 foreach ($pl_names as $pl_name)
3593 if (strcmp($pl->getQuestionType(), $questionType) == 0)
3595 foreach($classes as $class)
3597 $pl->includeClass(
"class.{$class}.php");
3613 if (file_exists(
"./Modules/TestQuestionPool/classes/class.".$type_tag.
".php"))
3616 return $lng->txt($type_tag);
3620 global $ilPluginAdmin;
3621 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
"TestQuestionPool",
"qst");
3622 foreach ($pl_names as $pl_name)
3625 if (strcmp($pl->getQuestionType(), $type_tag) == 0)
3627 return $pl->getQuestionTypeTranslation();
3659 if (strcmp($a_question_id,
"") != 0)
3666 $question_gui =
new $question_type_gui();
3667 $question_gui->object->loadFromDb($a_question_id);
3670 $question_gui->object->feedbackOBJ =
new $feedbackObjectClassname($question_gui->object, $ilCtrl, $ilDB, $lng);
3672 $assSettings =
new ilSetting(
'assessment');
3673 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionProcessLockerFactory.php';
3675 $processLockerFactory->setQuestionId($question_gui->object->getId());
3676 $processLockerFactory->setUserId($ilUser->getId());
3677 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
3679 $question_gui->object->setProcessLocker($processLockerFactory->getLocker());
3684 $ilLog->write(
'Instantiate question called without question id. (instantiateQuestionGUI@assQuestion)', $ilLog->WARNING);
3687 return $question_gui;
3715 return $this->
getId();
3735 case "est_working_time":
3759 case "suggested_solutions":
3766 if (array_key_exists($value, $this->arrData))
3768 return $this->arrData[$value];
3786 $this->
setId($value);
3806 case "est_working_time":
3807 if (is_array($value))
3828 $this->page =& $value;
3831 $this->arrData[$key] = $value;
3843 $this->nr_of_tries = $a_nr_of_tries;
3848 $this->export_image_path = (string)$a_path;
3855 if ($question_id < 1)
3860 $result = $ilDB->queryF(
"SELECT question_fi FROM tst_test_question WHERE question_fi = %s AND test_fi = %s",
3861 array(
'integer',
'integer'),
3882 include_once(
"./Services/RTE/classes/class.ilRTE.php");
3884 $a_q = str_replace(
"</li><br />",
"</li>", $a_q);
3885 $a_q = str_replace(
"</li><br>",
"</li>", $a_q);
3890 $a_q = str_replace(
'{',
'{', $a_q);
3891 $a_q = str_replace(
'}',
'}', $a_q);
3905 $this->prevent_rte_usage = $a_val;
3925 $this->selfassessmenteditingmode = $a_selfassessmenteditingmode;
3945 $this->defaultnroftries = $a_defaultnroftries;
3969 $query =
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s";
3971 $res = $ilDB->queryF(
$query, array(
'integer'), array((
int)$questionId));
3972 $row = $ilDB->fetchAssoc(
$res);
3974 return $row[
'obj_fi'];
3994 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
3999 require_once
'Modules/TestQuestionPool/classes/class.ilAssHintPage.php';
4001 foreach($hintIds as $originalHintId => $duplicateHintId)
4004 $originalXML = $originalPageObject->getXMLContent();
4007 $duplicatePageObject->setId($duplicateHintId);
4008 $duplicatePageObject->setParentId($this->
getId());
4009 $duplicatePageObject->setXMLContent($originalXML);
4010 $duplicatePageObject->createFromXML();
4093 SELECT count(active_fi) cnt
4097 WHERE active_fi = %s
4098 AND question_fi = %s
4102 $res = $ilDB->queryF(
4103 $query, array(
'integer',
'integer',
'integer'),
4104 array($activeId, $questionId, $pass)
4107 $row = $ilDB->fetchAssoc(
$res);
4109 $solutionRecordsExist = (
4110 0 < (int)$row[
'cnt'] ?
true :
false
4113 return $solutionRecordsExist;
4137 require_once
'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
4181 self::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT,
4182 self::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
4191 $this->questionChangeListeners[] = $listener;
4206 $listener->notifyQuestionCreated($this);
4214 $listener->notifyQuestionEdited($this);
4222 $listener->notifyQuestionDeleted($this);
4231 require_once
'Services/Html/classes/class.ilHtmlPurifierFactory.php';