4include_once
"./Modules/Test/classes/inc.AssessmentConstants.php";
27 self::IMG_MIME_TYPE_JPG => array(
'jpg',
'jpeg'),
28 self::IMG_MIME_TYPE_PNG => array(
'png'),
29 self::IMG_MIME_TYPE_GIF => array(
'gif')
33 self::IMG_MIME_TYPE_JPG => array(
'binary'),
34 self::IMG_MIME_TYPE_PNG => array(
'binary'),
35 self::IMG_MIME_TYPE_GIF => array(
'binary')
288 $this->original_id =
null;
296 $this->author = $this->
ilias->account->fullname;
299 if ($this->owner <= 0)
301 $this->owner = $this->
ilias->account->id;
305 $this->suggested_solutions = array();
307 $this->nr_of_tries = 0;
310 $this->arrData = array();
313 $this->questionActionCmd =
'handleQuestionAction';
315 $this->lastChange =
null;
320 return (
bool)count(self::getAllowedFileExtensionsForMimeType($mimeType));
325 return current(explode(
';', $contentTypeString));
330 foreach(self::$allowedFileExtensionsByMimeType as $allowedMimeType => $extensions)
332 $rexCharsets = implode(
'|', self::$allowedCharsetsByMimeType[$allowedMimeType]);
333 $rexMimeType = preg_quote($allowedMimeType,
'/');
335 $rex =
'/^'.$rexMimeType.
'(;(\s)*charset=('.$rexCharsets.
'))*$/';
337 if( !preg_match($rex, $mimeType) )
351 strtolower($fileExtension), self::getAllowedFileExtensionsForMimeType($mimeType)
357 $allowedExtensions = array();
359 foreach(self::$allowedFileExtensionsByMimeType as $mimeType => $fileExtensions)
361 $allowedExtensions = array_merge($allowedExtensions, $fileExtensions);
364 return $allowedExtensions;
395 function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
397 include_once
"./Modules/TestQuestionPool/classes/import/qti12/class." . $this->
getQuestionType() .
"Import.php";
399 $import =
new $classname($this);
400 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
409 function toXML($a_include_header =
true, $a_include_binary =
true, $a_shuffle =
false, $test_output =
false, $force_image_references =
false)
411 include_once
"./Modules/TestQuestionPool/classes/export/qti12/class." . $this->
getQuestionType() .
"Export.php";
413 $export =
new $classname($this);
414 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
439 $result =
$ilDB->queryF(
"SELECT * FROM qpl_questions WHERE obj_fi = %s AND title = %s",
440 array(
'integer',
'text'),
441 array($questionpool_id,
$title)
443 return (
$result->numRows() > 0) ? TRUE : FALSE;
479 $this->test_id =
$id;
538 $this->est_working_time = array(
"h" => (
int)$hour,
"m" => (
int)$min,
"s" => (
int)$sec);
549 $this->est_working_time = array(
550 'h' => (
int)substr($durationString, 0, 2),
551 'm' => (
int)substr($durationString, 3, 2),
552 's' => (
int)substr($durationString, 6, 2)
567 foreach ($array as $key => $value)
569 if (strcmp($key, $searchkey)==0)
708 if (!$this->est_working_time)
710 $this->est_working_time = array(
"h" => 0,
"m" => 0,
"s" => 0);
776 if(!strlen($this->external_id))
778 if($this->
getId() > 0)
780 return 'il_' . IL_INST_ID .
'_qst_' . $this->
getId();
784 return uniqid(
'',
true);
804 $result =
$ilDB->queryF(
"SELECT points FROM qpl_questions WHERE question_id = %s",
826 $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",
847 $result =
$ilDB->queryF(
"SELECT suggested_solution_id FROM qpl_sol_sug WHERE question_fi = %s",
864 return $question->getSuggestedSolutionOutput();
870 foreach ($this->suggested_solutions as $solution)
872 switch ($solution[
"type"])
881 $possible_texts = array_values(array_filter(array(
884 $this->lng->txt(
'tst_show_solution_suggested')
886 array_push($output,
'<a href="' . $this->
getSuggestedSolutionPathWeb() . $solution[
"value"][
"name"] .
'">' . $possible_texts[0] .
'</a>');
889 $solutionValue = $solution[
"value"];
890 $solutionValue = $this->
fixSvgToPng($solutionValue);
896 return join($output,
"<br />");
911 $result =
$ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
912 array(
'integer',
'integer'),
913 array($question_id, $subquestion_index)
919 "internal_link" =>
$row[
"internal_link"],
920 "import_id" =>
$row[
"import_id"]
953 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
956 $result =
$ilDB->queryF(
"SELECT * FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
957 array(
'integer',
'integer',
'integer'),
958 array($active_id, $question_id,
$pass)
1007 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1017 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
1019 $requestsStatisticData = $hintTracking->getRequestStatisticDataByQuestionAndTestpass();
1020 $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
1025 return $reached_points;
1041 if( is_null(
$pass) )
1043 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1051 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
1053 $requestsStatisticData = $questionHintTracking->getRequestStatisticDataByQuestionAndTestpass();
1054 $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
1068 if( is_null($reached_points) ) $reached_points = 0;
1073 DELETE FROM tst_test_result
1075 WHERE active_fi = %s
1076 AND question_fi = %s
1080 $types = array(
'integer',
'integer',
'integer');
1081 $values = array($active_id, $this->
getId(),
$pass);
1083 if( $this->
getStep() !== NULL )
1089 $types[] =
'integer';
1093 $affectedRows =
$ilDB->manipulateF(
$query, $types, $values);
1095 $next_id =
$ilDB->nextId(
"tst_test_result");
1098 'test_result_id' => array(
'integer', $next_id),
1099 'active_fi' => array(
'integer', $active_id),
1100 'question_fi' => array(
'integer', $this->
getId()),
1101 'pass' => array(
'integer',
$pass),
1102 'points' => array(
'float', $reached_points),
1103 'tstamp' => array(
'integer', time()),
1104 'hint_count' => array(
'integer', $requestsStatisticData->getRequestsCount()),
1105 'hint_points' => array(
'float', $requestsStatisticData->getRequestsPoints()),
1106 'answered' => array(
'integer', $isAnswered)
1109 if( $this->
getStep() !== NULL )
1111 $fieldData[
'step'] = array(
'integer', $this->
getStep());
1114 $ilDB->insert(
'tst_test_result', $fieldData);
1118 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1138 include_once
'Modules/Course/classes/class.ilCourseObjectiveResult.php';
1152 if(
$pass ===
null )
1154 require_once
'Modules/Test/classes/class.ilObjTest.php';
1211 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1212 include_once
"./Modules/Test/classes/class.assMarkSchema.php";
1217 SELECT tst_pass_result.*
1218 FROM tst_pass_result
1219 WHERE active_fi = %s
1224 $query, array(
'integer',
'integer'), array($active_id,
$pass)
1229 $max =
$row[
'maxpoints'];
1230 $reached =
$row[
'points'];
1232 $obligationsAnswered = (int)
$row[
'obligations_answered'];
1234 include_once
"./Modules/Test/classes/class.assMarkSchema.php";
1236 $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
1238 $mark = ASS_MarkSchema::_getMatchingMarkFromActiveId($active_id, $percentage);
1240 $isPassed = ( $mark[
"passed"] ? 1 : 0 );
1241 $isFailed = ( !$mark[
"passed"] ? 1 : 0 );
1249 DELETE FROM tst_result_cache
1250 WHERE active_fi = %s
1253 $affectedRows =
$ilDB->manipulateF(
1254 $query, array(
'integer'), array($active_id)
1257 $ilDB->insert(
'tst_result_cache', array(
1258 'active_fi'=> array(
'integer', $active_id),
1259 'pass'=> array(
'integer', strlen(
$pass) ?
$pass : 0),
1260 'max_points'=> array(
'float', strlen($max) ? $max : 0),
1261 'reached_points'=> array(
'float', strlen($reached) ? $reached : 0),
1262 'mark_short'=> array(
'text', strlen($mark[
"short_name"]) ? $mark[
"short_name"] :
" "),
1263 'mark_official'=> array(
'text', strlen($mark[
"official_name"]) ? $mark[
"official_name"] :
" "),
1264 'passed'=> array(
'integer', $isPassed),
1265 'failed'=> array(
'integer', $isFailed),
1266 'tstamp'=> array(
'integer', time()),
1267 'hint_count'=> array(
'integer',
$row[
'hint_count']),
1268 'hint_points'=> array(
'float',
$row[
'hint_points']),
1269 'obligations_answered' => array(
'integer', $obligationsAnswered)
1283 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1285 if( self::getResultGateway() !==
null )
1300 SELECT SUM(points) reachedpoints,
1301 SUM(hint_count) hint_count,
1302 SUM(hint_points) hint_points,
1303 COUNT(DISTINCT(question_fi)) answeredquestions
1304 FROM tst_test_result
1305 WHERE active_fi = %s
1308 array(
'integer',
'integer'),
1309 array($active_id,
$pass)
1314 if( $obligationsEnabled )
1317 SELECT count(*) cnt,
1318 min( answered ) answ
1319 FROM tst_test_question
1320 INNER JOIN tst_active
1322 AND tst_test_question.test_fi = tst_active.test_fi
1323 LEFT JOIN tst_test_result
1324 ON tst_test_result.active_fi = %s
1325 AND tst_test_result.pass = %s
1326 AND tst_test_question.question_fi = tst_test_result.question_fi
1327 WHERE obligatory = 1';
1329 $result_obligatory =
$ilDB->queryF(
1330 $query, array(
'integer',
'integer',
'integer'), array($active_id, $active_id,
$pass)
1333 $row_obligatory =
$ilDB->fetchAssoc($result_obligatory);
1335 if ($row_obligatory[
'cnt'] == 0)
1337 $obligations_answered = 1;
1341 $obligations_answered = (int) $row_obligatory[
'answ'];
1346 $obligations_answered = 1;
1351 if(
$row[
'hint_count'] ===
null )
$row[
'hint_count'] = 0;
1352 if(
$row[
'hint_points'] ===
null )
$row[
'hint_points'] = 0;
1374 $ilDB->replace(
'tst_pass_result',
1376 'active_fi' => array(
'integer', $active_id),
1377 'pass' => array(
'integer', strlen(
$pass) ?
$pass : 0)),
1379 'points' => array(
'float',
$row[
'reachedpoints'] ?
$row[
'reachedpoints'] : 0),
1380 'maxpoints' => array(
'float',
$data[
'points']),
1381 'questioncount' => array(
'integer',
$data[
'count']),
1382 'answeredquestions' => array(
'integer',
$row[
'answeredquestions']),
1383 'workingtime' => array(
'integer', $time),
1384 'tstamp' => array(
'integer', time()),
1385 'hint_count' => array(
'integer',
$row[
'hint_count']),
1386 'hint_points' => array(
'float',
$row[
'hint_points']),
1387 'obligations_answered' => array(
'integer', $obligations_answered),
1388 'exam_id' => array(
'text', $exam_identifier)
1418 'active_fi' => $active_id,
1420 'points' => (
$row[
"reachedpoints"]) ?
$row[
"reachedpoints"] : 0,
1421 'maxpoints' =>
$data[
"points"],
1422 'questioncount' =>
$data[
"count"],
1423 'answeredquestions' =>
$row[
"answeredquestions"],
1424 'workingtime' => $time,
1426 'hint_count' =>
$row[
'hint_count'],
1427 'hint_points' =>
$row[
'hint_points'],
1428 'obligations_answered' => $obligations_answered,
1429 'exam_id' => $exam_identifier
1440 function logAction($logtext =
"", $active_id =
"", $question_id =
"")
1445 if (strcmp($question_id,
"") != 0)
1447 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
1450 include_once
"./Modules/Test/classes/class.ilObjAssessmentFolder.php";
1451 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1462 function _logAction($logtext =
"", $active_id =
"", $question_id =
"")
1467 if (strcmp($question_id,
"") != 0)
1469 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
1472 include_once
"./Modules/Test/classes/class.ilObjAssessmentFolder.php";
1473 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1486 $mediatempdir = CLIENT_WEB_DIR .
"/assessment/temp";
1488 $temp_name = tempnam($mediatempdir, $name .
"_____");
1489 $temp_name = str_replace(
"\\",
"/", $temp_name);
1490 @unlink($temp_name);
1507 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/solution/";
1517 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/java/";
1528 if( $question_id ===
null)
1533 if( $object_id ===
null)
1543 return CLIENT_WEB_DIR .
"/assessment/{$parentObjectId}/{$questionId}/images/";
1554 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/flash/";
1565 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1577 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1590 if(!$this->export_image_path)
1592 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1610 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1634 if( $this->
getStep() !== NULL )
1636 $result =
$ilDB->queryF(
"SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s AND step = %s ORDER BY solution_id",
1637 array(
'integer',
'integer',
'integer',
'integer'),
1638 array($active_id, $this->
getId(), $pass, $this->
getStep())
1643 $result = $ilDB->queryF(
"SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s ORDER BY solution_id",
1644 array(
'integer',
'integer',
'integer'),
1645 array($active_id, $this->
getId(), $pass)
1651 array_push($values,
$row);
1667 if ($question_id < 1) $question_id = $this->
getId();
1668 $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",
1673 $count =
$row[
"question_count"];
1675 $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",
1694 if ($question_id < 1) $question_id =
$this->id;
1695 $result =
$ilDB->queryF(
"SELECT original_id FROM qpl_questions WHERE question_id = %s",
1700 return (
$row[
"original_id"] > 0) ? TRUE : FALSE;
1711 $keys = array_keys($array);
1714 foreach ($keys as $key)
1730 $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",
1735 return $data[
"type_tag"];
1771 if( !is_array($answer_table_name) )
1773 $answer_table_name = array($answer_table_name);
1776 foreach ($answer_table_name as $table)
1780 $affectedRows =
$ilDB->manipulateF(
"DELETE FROM $table WHERE question_fi = %s",
1800 if( !is_array($additional_table_name) )
1802 $additional_table_name = array($additional_table_name);
1805 foreach ($additional_table_name as $table)
1809 $affectedRows =
$ilDB->manipulateF(
"DELETE FROM $table WHERE question_fi = %s",
1825 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
1837 public function delete($question_id)
1841 if ($question_id < 1)
return true;
1843 $result =
$ilDB->queryF(
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
1862 $ilLog->write(
"EXCEPTION: Could not delete page of question $question_id: $e");
1866 $affectedRows =
$ilDB->manipulateF(
"DELETE FROM qpl_questions WHERE question_id = %s",
1870 if ($affectedRows == 0)
return false;
1881 $ilLog->write(
"EXCEPTION: Could not delete additional table data of question $question_id: $e");
1888 $affectedRows =
$ilDB->manipulateF(
"DELETE FROM tst_test_question WHERE question_fi = %s",
1895 $ilLog->write(
"EXCEPTION: Could not delete delete question $question_id from a test: $e");
1902 $affectedRows =
$ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s",
1909 $ilLog->write(
"EXCEPTION: Could not delete suggested solutions of question $question_id: $e");
1915 $directory = CLIENT_WEB_DIR .
"/assessment/" .
$obj_id .
"/$question_id";
1916 if (preg_match(
"/\d+/",
$obj_id) and preg_match(
"/\d+/", $question_id) and is_dir($directory))
1918 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1924 $ilLog->write(
"EXCEPTION: Could not delete question file directory $directory of question $question_id: $e");
1930 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1936 foreach(
$mobs as $mob)
1948 $ilLog->write(
"EXCEPTION: Error deleting the media objects of question $question_id: $e");
1952 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
1955 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
1963 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
1968 $ilLog->write(
"EXCEPTION: Error updating the question pool question count of question pool " . $this->
getObjId() .
" when deleting question $question_id: $e");
1979 require_once
'Services/Taxonomy/classes/class.ilObjTaxonomy.php';
1980 require_once
'Services/Taxonomy/classes/class.ilTaxNodeAssignment.php';
1983 foreach($taxIds as $taxId)
1986 $taxNodeAssignment->deleteAssignmentsOfItem($this->
getId());
2009 $result =
$ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
2010 array(
'integer',
'integer'),
2011 array($a_q_id, $a_q_id)
2017 $found_id = array();
2020 array_push($found_id,
$row[
"question_id"]);
2023 $result =
$ilDB->query(
"SELECT * FROM tst_test_result WHERE " .
$ilDB->in(
'question_fi', $found_id,
false,
'integer'));
2038 $result =
$ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
2039 array(
'integer',
'integer'),
2040 array($a_q_id, $a_q_id)
2046 $found_id = array();
2049 array_push($found_id,
$row[
"question_id"]);
2051 $result =
$ilDB->query(
"SELECT * FROM tst_test_result WHERE " .
$ilDB->in(
'question_fi', $found_id,
false,
'integer'));
2055 $reached =
$row[
"points"];
2056 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
2058 array_push($answers, array(
"reached" => $reached,
"max" => $max));
2062 foreach ($answers as $key => $value)
2064 $max += $value[
"max"];
2065 $reached += $value[
"reached"];
2069 return $reached / $max;
2085 $result =
$ilDB->queryF(
"SELECT title FROM qpl_questions WHERE question_id = %s",
2092 return $row[
"title"];
2108 $result =
$ilDB->queryF(
"SELECT question_text FROM qpl_questions WHERE question_id = %s",
2115 return $row[
"question_text"];
2125 if( !file_exists(
$file) )
2130 if( !is_file(
$file) )
2135 if( !is_readable(
$file) )
2145 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2147 foreach (
$mobs as $mob)
2155 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2157 foreach (
$mobs as $mob)
2170 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2172 $this->page->setId($this->
getId());
2173 $this->page->setParentId($qpl_id);
2174 $this->page->setXMLContent(
"<PageObject><PageContent>".
2175 "<Question QRef=\"il__qst_".$this->
getId().
"\"/>".
2176 "</PageContent></PageObject>");
2177 $this->page->create();
2184 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2187 $xml = str_replace(
"il__qst_".$a_q_id,
"il__qst_".$this->
id,
$page->getXMLContent());
2188 $this->page->setXMLContent($xml);
2189 $this->page->updateFromXML();
2195 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2197 return $page->getXMLContent();
2211 if ($question_id < 1)
return "";
2212 $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",
2219 return $data[
"type_tag"];
2238 if ($question_id < 1)
return "";
2240 $result =
$ilDB->queryF(
"SELECT title FROM qpl_questions WHERE qpl_questions.question_id = %s",
2247 return $data[
"title"];
2266 'ok.svg' =>
'ok.png',
'not_ok.svg' =>
'not_ok.png',
2267 'checkbox_checked.svg' =>
'checkbox_checked.png',
2268 'checkbox_unchecked.svg' =>
'checkbox_unchecked.png',
2269 'radiobutton_checked.svg' =>
'radiobutton_checked.png',
2270 'radiobutton_unchecked.svg' =>
'radiobutton_unchecked.png'
2275 $needles = array_keys(self::$imageSourceFixReplaceMap);
2276 $replacements = array_values(self::$imageSourceFixReplaceMap);
2277 return str_replace($needles, $replacements, $imageFilenameContainingString);
2284 if( preg_match_all(
'/src="(.*?)"/m', $html, $matches) )
2286 $sources = $matches[1];
2288 $needleReplacementMap = array();
2290 foreach($sources as $src)
2294 if( file_exists(
$file) )
2299 $levels = explode(DIRECTORY_SEPARATOR, $src);
2300 if( count($levels) < 5 || $levels[0] !=
'Customizing' || $levels[2] !=
'skin' )
2307 if( $levels[4] ==
'Modules' || $levels[4] ==
'Services' )
2309 $component = $levels[4] . DIRECTORY_SEPARATOR . $levels[5];
2315 if( count($needleReplacementMap) )
2317 $html = str_replace(array_keys($needleReplacementMap), array_values($needleReplacementMap), $html);
2335 "SELECT external_id FROM qpl_questions WHERE question_id = %s",
2342 $this->external_id =
$data[
'external_id'];
2345 $result =
$ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
2347 array($this->
getId())
2349 $this->suggested_solutions = array();
2352 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2356 $this->suggested_solutions[
$row[
"subquestion_index"]] = array(
2357 "type" =>
$row[
"type"],
2359 "internal_link" =>
$row[
"internal_link"],
2360 "import_id" =>
$row[
"import_id"]
2378 $estw_time = sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
2392 $next_id =
$ilDB->nextId(
'qpl_questions');
2393 $affectedRows =
$ilDB->insert(
"qpl_questions", array(
2394 "question_id" => array(
"integer", $next_id),
2396 "obj_fi" => array(
"integer",
$obj_id),
2397 "title" => array(
"text", NULL),
2398 "description" => array(
"text", NULL),
2399 "author" => array(
"text", $this->
getAuthor()),
2400 "owner" => array(
"integer",
$ilUser->getId()),
2401 "question_text" => array(
"clob", NULL),
2402 "points" => array(
"float", 0),
2404 "working_time" => array(
"text", $estw_time),
2405 "complete" => array(
"text", $complete),
2406 "created" => array(
"integer", time()),
2407 "original_id" => array(
"integer", NULL),
2408 "tstamp" => array(
"integer", $tstamp),
2412 $this->
setId($next_id);
2423 return $this->
getId();
2431 $estw_time = sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
2434 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2435 if ($this->
getId() == -1)
2438 $next_id =
$ilDB->nextId(
'qpl_questions');
2439 $affectedRows =
$ilDB->insert(
"qpl_questions", array(
2440 "question_id" => array(
"integer", $next_id),
2442 "obj_fi" => array(
"integer", $this->
getObjId()),
2443 "title" => array(
"text", $this->
getTitle()),
2444 "description" => array(
"text", $this->
getComment()),
2445 "author" => array(
"text", $this->
getAuthor()),
2446 "owner" => array(
"integer", $this->
getOwner()),
2449 "working_time" => array(
"text", $estw_time),
2450 "nr_of_tries" => array(
"integer", $this->
getNrOfTries()),
2451 "created" => array(
"integer", time()),
2453 "tstamp" => array(
"integer", time()),
2457 $this->
setId($next_id);
2464 $affectedRows =
$ilDB->update(
"qpl_questions", array(
2465 "obj_fi" => array(
"integer", $this->
getObjId()),
2466 "title" => array(
"text", $this->
getTitle()),
2467 "description" => array(
"text", $this->
getComment()),
2468 "author" => array(
"text", $this->
getAuthor()),
2471 "nr_of_tries" => array(
"integer", $this->
getNrOfTries()),
2472 "working_time" => array(
"text", $estw_time),
2473 "tstamp" => array(
"integer", time()),
2474 'complete' => array(
'integer', $this->
isComplete()),
2477 "question_id" => array(
"integer", $this->
getId())
2492 $this->updateSuggestedSolutions();
2504 $affectedRows =
$ilDB->manipulateF(
"UPDATE qpl_questions SET tstamp = %s, owner = %s, complete = %s WHERE question_id = %s",
2505 array(
'integer',
'integer',
'integer',
'text'),
2506 array(time(), ($this->
getOwner() <= 0) ? $this->
ilias->account->id : $this->getOwner(), $complete, $this->getId())
2510 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
2518 $ilDB->manipulateF(
"UPDATE qpl_questions SET tstamp = %s, original_id = %s WHERE question_id = %s",
2519 array(
'integer',
'integer',
'text'),
2520 array(time(), $newId, $this->
getId())
2527 protected function onDuplicate($originalParentId, $originalQuestionId, $duplicateParentId, $duplicateQuestionId)
2532 $this->feedbackOBJ->duplicateFeedback($originalQuestionId, $duplicateQuestionId);
2546 $this->feedbackOBJ->syncFeedback($origQuestionId, $dupQuestionId);
2552 protected function onCopy($sourceParentId, $sourceQuestionId, $targetParentId, $targetQuestionId)
2557 $this->feedbackOBJ->duplicateFeedback($sourceQuestionId, $targetQuestionId);
2570 $affectedRows =
$ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2572 array($this->
getId())
2575 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2577 $this->suggested_solutions = array();
2590 if (array_key_exists($subquestion_index, $this->suggested_solutions))
2592 return $this->suggested_solutions[$subquestion_index];
2610 if (array_key_exists($subquestion_index, $this->suggested_solutions))
2612 $title = $this->suggested_solutions[$subquestion_index][
"internal_link"];
2633 if (strcmp($solution_id,
"") != 0)
2638 $import_id = $solution_id;
2641 $this->suggested_solutions[$subquestion_index] = array(
2642 "internal_link" => $solution_id,
2643 "import_id" => $import_id
2655 foreach ($this->suggested_solutions as $index => $solution)
2657 if (strcmp($solution[
"type"],
"file") == 0)
2660 $filepath_original = str_replace(
2661 "/{$this->obj_id}/{$this->id}/solution",
2662 "/$parent_id/$question_id/solution",
2665 if (!file_exists($filepath))
2674 $ilLog->write(
"File could not be duplicated!!!!",
$ilLog->ERROR);
2675 $ilLog->write(
"object: " . print_r($this, TRUE),
$ilLog->ERROR);
2690 $filepath_original = str_replace(
"/$this->id/solution",
"/$original_id/solution", $filepath);
2692 foreach ($this->suggested_solutions as $index => $solution)
2694 if (strcmp($solution[
"type"],
"file") == 0)
2696 if (!file_exists($filepath_original))
2705 $ilLog->write(
"File could not be duplicated!!!!",
$ilLog->ERROR);
2706 $ilLog->write(
"object: " . print_r($this, TRUE),
$ilLog->ERROR);
2717 foreach ($this->suggested_solutions as $index => $solution)
2719 if (strcmp($solution[
"type"],
"file") == 0)
2722 $filepath_original = str_replace(
"/$this->obj_id/$this->id/solution",
"/$source_questionpool_id/$source_question_id/solution", $filepath);
2723 if (!file_exists($filepath))
2732 $ilLog->write(
"File could not be copied!!!!",
$ilLog->ERROR);
2733 $ilLog->write(
"object: " . print_r($this, TRUE),
$ilLog->ERROR);
2743 public function updateSuggestedSolutions(
$original_id =
"")
2748 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2749 $affectedRows =
$ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2754 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2755 foreach ($this->suggested_solutions as $index => $solution)
2757 $next_id =
$ilDB->nextId(
'qpl_sol_sug');
2759 $ilDB->insert(
'qpl_sol_sug', array(
2760 'suggested_solution_id' => array(
'integer', $next_id ),
2761 'question_fi' => array(
'integer',
$id ),
2762 'type' => array(
'text', $solution[
'type'] ),
2764 'internal_link' => array(
'text', $solution[
'internal_link'] ),
2765 'import_id' => array(
'text',
null ),
2766 'subquestion_index' => array(
'integer', $index ),
2767 'tstamp' => array(
'integer', time() ),
2770 if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/", $solution[
"internal_link"], $matches))
2788 function saveSuggestedSolution($type, $solution_id =
"", $subquestion_index = 0, $value =
"")
2792 $affectedRows =
$ilDB->manipulateF(
"DELETE FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
2793 array(
"integer",
"integer"),
2800 $next_id =
$ilDB->nextId(
'qpl_sol_sug');
2801 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2803 $affectedRows =
$ilDB->insert(
'qpl_sol_sug', array(
2804 'suggested_solution_id' => array(
'integer', $next_id ),
2805 'question_fi' => array(
'integer', $this->
getId() ),
2806 'type' => array(
'text', $type ),
2808 'internal_link' => array(
'text', $solution_id ),
2809 'import_id' => array(
'text',
null ),
2810 'subquestion_index' => array(
'integer', $subquestion_index ),
2811 'tstamp' => array(
'integer', time() ),
2814 if ($affectedRows == 1)
2816 $this->suggested_solutions[$subquestion_index] = array(
2819 "internal_link" => $solution_id,
2828 if (preg_match(
"/il_(\d+)_(\w+)_(\d+)/", $internal_link, $matches))
2830 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2831 include_once
"./Modules/LearningModule/classes/class.ilLMObject.php";
2832 include_once
"./Modules/Glossary/classes/class.ilGlossaryTerm.php";
2833 switch ($matches[2])
2851 if (strcmp($resolved_link,
"") == 0)
2853 $resolved_link = $internal_link;
2858 $resolved_link = $internal_link;
2860 return $resolved_link;
2867 $result =
$ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
2875 $internal_link =
$row[
"internal_link"];
2876 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
2878 if (strcmp($internal_link, $resolved_link) != 0)
2881 $affectedRows =
$ilDB->manipulateF(
"UPDATE qpl_sol_sug SET internal_link = %s WHERE suggested_solution_id = %s",
2882 array(
'text',
'integer'),
2883 array($resolved_link,
$row[
"suggested_solution_id"])
2894 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2897 $result =
$ilDB->queryF(
"SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
2905 if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/",
$row[
"internal_link"], $matches))
2918 "lm" =>
"LearningModule",
2919 "pg" =>
"PageObject",
2920 "st" =>
"StructureObject",
2921 "git" =>
"GlossaryItem",
2922 "mob" =>
"MediaObject"
2925 if (preg_match(
"/il__(\w+)_(\d+)/", $target, $matches))
2927 $type = $matches[1];
2929 include_once
"./Services/Utilities/classes/class.ilUtil.php";
2930 switch($linktypes[$matches[1]])
2932 case "LearningModule":
2933 $href =
"./goto.php?target=" . $type .
"_" .
$target_id;
2936 case "StructureObject":
2937 $href =
"./goto.php?target=" . $type .
"_" .
$target_id;
2939 case "GlossaryItem":
2940 $href =
"./goto.php?target=" . $type .
"_" .
$target_id;
2943 $href =
"./ilias.php?baseClass=ilLMPresentationGUI&obj_type=" . $linktypes[$type] .
"&cmd=media&ref_id=".$_GET[
"ref_id"].
"&mob_id=".
$target_id;
2960 $result =
$ilDB->queryF(
"SELECT * FROM qpl_questions WHERE question_id = %s",
2967 if (
$row[
"original_id"] > 0)
2969 return $row[
"original_id"];
2973 return $row[
"question_id"];
2987 SELECT COUNT(dupl.question_id) cnt
2988 FROM qpl_questions dupl
2989 INNER JOIN qpl_questions orig
2990 ON orig.question_id = dupl.original_id
2991 WHERE dupl.question_id = %s
2997 return $row[
'cnt'] > 0;
3011 if ( !$originalObjId )
3032 $this->updateSuggestedSolutions($original);
3054 if ($question_id < 1)
3059 $result =
$ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE question_id = %s",
3084 if ($question_id < 1)
3089 $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'",
3119 if (strcmp($question_id,
"") != 0)
3122 if (!strlen($question_type))
return null;
3143 if (strcmp($this->points,
"") == 0)
3162 $this->points = $a_points;
3193 $result =
$ilDB->queryF(
"SELECT MAX(pass) maxpass FROM tst_test_result WHERE active_fi = %s AND question_fi = %s",
3194 array(
'integer',
'integer'),
3195 array($active_id, $question_id)
3200 return $row[
"maxpass"];
3220 if (($question_id < 1) || ($user_id < 1))
3225 $result =
$ilDB->queryF(
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
3232 $qpl_object_id =
$row[
"obj_fi"];
3233 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
3252 if ($question_id < 1)
return 0;
3253 $result =
$ilDB->queryF(
"SELECT test_random_question_id FROM tst_test_rnd_qst WHERE question_fi = %s",
3303 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3305 if ($count_system == 1)
3313 if ($score_cutting == 0)
3338 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
3341 $result =
$ilDB->queryF(
"SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3342 array(
'integer',
'integer',
'integer'),
3343 array($active_id, $question_id,
$pass)
3366 $res =
$ilDB->queryF(
"SELECT DISTINCT(question_fi) FROM tst_test_result JOIN tst_active ".
3367 "ON (active_id = active_fi) ".
3368 "WHERE " .
$ilDB->in(
'question_fi', $a_question_ids,
false,
'integer') .
3369 " AND user_fi = %s",
3373 return (
$res->numRows() == count($a_question_ids)) ? true :
false;
3386 if (preg_match(
"/<[^>]*?>/", $a_text))
3404 include_once
"./Services/Utilities/classes/class.ilUtil.php";
3418 for ($i = 0; $i < $a_material->getMaterialCount(); $i++)
3420 $material = $a_material->getMaterial($i);
3421 if (strcmp($material[
"type"],
"mattext") == 0)
3423 $result .= $material[
"material"]->getContent();
3425 if (strcmp($material[
"type"],
"matimage") == 0)
3427 $matimage = $material[
"material"];
3428 if (preg_match(
"/(il_([0-9]+)_mob_([0-9]+))/", $matimage->getLabel(), $matches))
3431 if (!is_array(
$_SESSION[
"import_mob_xhtml"]))
$_SESSION[
"import_mob_xhtml"] = array();
3432 array_push(
$_SESSION[
"import_mob_xhtml"], array(
"mob" => $matimage->getLabel(),
"uri" => $matimage->getUri()));
3447 function addQTIMaterial(&$a_xml_writer, $a_material, $close_material_tag = TRUE, $add_mobs = TRUE)
3449 include_once
"./Services/RTE/classes/class.ilRTE.php";
3450 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
3452 $a_xml_writer->xmlStartTag(
"material");
3454 "texttype" =>
"text/plain"
3456 if ($this->
isHTML($a_material))
3458 $attrs[
"texttype"] =
"text/xhtml";
3464 foreach (
$mobs as $mob)
3466 $moblabel =
"il_" . IL_INST_ID .
"_mob_" . $mob;
3467 if (strpos($a_material,
"mm_$mob") !== FALSE)
3473 "label" => $moblabel,
3474 "uri" =>
"objects/" .
"il_" . IL_INST_ID .
"_mob_" . $mob .
"/" . $mob_obj->getTitle()
3477 $a_xml_writer->xmlElement(
"matimage", $imgattrs, NULL);
3481 if ($close_material_tag) $a_xml_writer->xmlEndTag(
"material");
3488 if (preg_match(
"/.*\.(png|jpg|gif|jpeg)$/i", $image_filename, $matches))
3490 $extension =
"." . $matches[1];
3495 $image_filename = uniqid($image_filename.microtime(
true));
3498 $image_filename = md5($image_filename) . $extension;
3500 return $image_filename;
3526 $result =
$ilDB->queryF(
"SELECT points FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3527 array(
'integer',
'integer',
'integer'),
3528 array($active_id, $question_id,
$pass)
3530 $manual = ($manualscoring) ? 1 : 0;
3531 $rowsnum =
$result->numRows();
3535 $old_points =
$row[
"points"];
3538 $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",
3539 array(
'float',
'integer',
'integer',
'integer',
'integer',
'integer'),
3540 array(
$points, $manual, time(), $active_id, $question_id,
$pass)
3546 $next_id =
$ilDB->nextId(
'tst_test_result');
3547 $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)",
3548 array(
'integer',
'integer',
'integer',
'float',
'integer',
'integer',
'integer'),
3549 array($next_id, $active_id, $question_id,
$points,
$pass, $manual, time())
3553 if($old_points !=
$points || !$rowsnum)
3555 assQuestion::_updateTestPassResults($active_id,
$pass, $obligationsEnabled);
3557 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3558 include_once
'./Modules/Course/classes/class.ilCourseObjectiveResult.php';
3561 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
3565 include_once
"./Modules/Test/classes/class.ilObjTestAccess.php";
3622 $result =
$ilDB->queryF(
"SELECT question_type_id FROM qpl_qst_type WHERE type_tag = %s",
3629 return $row[
"question_type_id"];
3634 public function syncHints()
3639 $ilDB->manipulateF(
"DELETE FROM qpl_hints WHERE qht_question_fi = %s",
3641 array($this->original_id)
3645 $result =
$ilDB->queryF(
"SELECT * FROM qpl_hints WHERE qht_question_fi = %s",
3647 array($this->
getId())
3655 $next_id =
$ilDB->nextId(
'qpl_hints');
3657 $ilDB->insert(
'qpl_hints', array(
3658 'qht_hint_id' => array(
'integer', $next_id),
3659 'qht_question_fi' => array(
'integer', $this->original_id),
3660 'qht_hint_index' => array(
'integer',
$row[
"qht_hint_index"]),
3661 'qht_hint_points' => array(
'integer',
$row[
"qht_hint_points"]),
3662 'qht_hint_text' => array(
'text',
$row[
"qht_hint_text"]),
3678 $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(),
false);
3679 $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(),
true);
3680 $collected .= $this->feedbackOBJ->getAllSpecificAnswerFeedbackContents($this->
getId());
3682 foreach ($this->suggested_solutions as $solution_array)
3684 $collected .= $solution_array[
"value"];
3687 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
3689 foreach($questionHintList as $questionHint)
3692 $collected .= $questionHint->getText();
3705 include_once(
"./Services/RTE/classes/class.ilRTE.php");
3718 $result =
$ilDB->queryF(
"SELECT question_id FROM qpl_questions WHERE original_id = %s",
3720 array($this->
getId())
3722 $instances = array();
3726 array_push($ids,
$row[
"question_id"]);
3728 foreach ($ids as $question_id)
3731 $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",
3740 $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",
3749 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3750 foreach ($instances as $key => $value)
3759 include_once
"./Modules/Test/classes/class.ilObjAssessmentFolder.php";
3762 if (in_array($questiontype, $scoring))
3782 $result =
$ilDB->queryF(
"SELECT * FROM tst_active WHERE active_id = %s",
3789 return array(
"user_id" =>
$row[
"user_fi"],
"test_id" =>
$row[
"test_fi"]);
3806 if( self::isCoreQuestionType($question_type) )
3818 return $questionType.
'GUI';
3823 return $questionType;
3828 return str_replace(
'ass',
'ilAss', $questionType).
'Feedback';
3834 return file_exists(
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php");
3842 require_once
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php";
3849 require_once
"Modules/TestQuestionPool/classes/class.{$objectClassName}.php";
3853 require_once
"Modules/TestQuestionPool/classes/feedback/class.{$feedbackClassName}.php";
3858 global $ilPluginAdmin;
3861 self::getObjectClassNameByQuestionType($questionType),
3862 self::getFeedbackClassNameByQuestionType($questionType)
3870 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
"TestQuestionPool",
"qst");
3871 foreach ($pl_names as $pl_name)
3874 if (strcmp($pl->getQuestionType(), $questionType) == 0)
3876 foreach($classes as $class)
3878 $pl->includeClass(
"class.{$class}.php");
3894 if (file_exists(
"./Modules/TestQuestionPool/classes/class.".$type_tag.
".php"))
3897 return $lng->txt($type_tag);
3901 global $ilPluginAdmin;
3902 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
"TestQuestionPool",
"qst");
3903 foreach ($pl_names as $pl_name)
3906 if (strcmp($pl->getQuestionType(), $type_tag) == 0)
3908 return $pl->getQuestionTypeTranslation();
3940 if (strcmp($a_question_id,
"") != 0)
3947 $question_gui =
new $question_type_gui();
3948 $question_gui->object->loadFromDb($a_question_id);
3951 $question_gui->object->feedbackOBJ =
new $feedbackObjectClassname($question_gui->object,
$ilCtrl,
$ilDB,
$lng);
3953 $assSettings =
new ilSetting(
'assessment');
3954 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionProcessLockerFactory.php';
3956 $processLockerFactory->setQuestionId($question_gui->object->getId());
3957 $processLockerFactory->setUserId(
$ilUser->getId());
3958 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
3960 $question_gui->object->setProcessLocker($processLockerFactory->getLocker());
3965 $ilLog->write(
'Instantiate question called without question id. (instantiateQuestionGUI@assQuestion)',
$ilLog->WARNING);
3968 return $question_gui;
3996 return $this->
getId();
4016 case "est_working_time":
4040 case "suggested_solutions":
4047 if (array_key_exists($value, $this->arrData))
4049 return $this->arrData[$value];
4067 $this->
setId($value);
4087 case "est_working_time":
4088 if (is_array($value))
4109 $this->page =& $value;
4112 $this->arrData[$key] = $value;
4124 $this->nr_of_tries = $a_nr_of_tries;
4129 $this->export_image_path = (string)$a_path;
4136 if ($question_id < 1)
4141 $result =
$ilDB->queryF(
"SELECT question_fi FROM tst_test_question WHERE question_fi = %s AND test_fi = %s",
4142 array(
'integer',
'integer'),
4175 $this->prevent_rte_usage = $a_val;
4195 $this->selfassessmenteditingmode = $a_selfassessmenteditingmode;
4215 $this->defaultnroftries = $a_defaultnroftries;
4239 $query =
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s";
4241 $res =
$ilDB->queryF(
$query, array(
'integer'), array((
int)$questionId));
4244 return $row[
'obj_fi'];
4264 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
4269 require_once
'Modules/TestQuestionPool/classes/class.ilAssHintPage.php';
4271 foreach($hintIds as $originalHintId => $duplicateHintId)
4274 $originalXML = $originalPageObject->getXMLContent();
4277 $duplicatePageObject->setId($duplicateHintId);
4278 $duplicatePageObject->setParentId($this->
getId());
4279 $duplicatePageObject->setXMLContent($originalXML);
4280 $duplicatePageObject->createFromXML();
4361 SELECT count(active_fi) cnt
4365 WHERE active_fi = %s
4366 AND question_fi = %s
4371 $query, array(
'integer',
'integer',
'integer'),
4372 array($activeId, $questionId,
$pass)
4377 return (
int)
$row[
'cnt'];
4401 require_once
'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
4445 self::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT,
4446 self::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
4455 $this->questionChangeListeners[] = $listener;
4470 $listener->notifyQuestionCreated($this);
4478 $listener->notifyQuestionEdited($this);
4486 $listener->notifyQuestionDeleted($this);
4495 require_once
'Services/Html/classes/class.ilHtmlPurifierFactory.php';
4504 require_once
'Services/Html/classes/class.ilHtmlPurifierFactory.php';
4511 SELECT qpl_questions.*,
4512 {$this->getAdditionalTableName()}.*
4514 LEFT JOIN {$this->getAdditionalTableName()}
4515 ON {$this->getAdditionalTableName()}.question_fi = qpl_questions.question_id
4516 WHERE qpl_questions.question_id = %s
4538 protected function getCurrentSolutionResultSet($active_id,
$pass)
4545 return $ilDB->queryF(
"SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s AND step = %s",
4546 array(
'integer',
'integer',
'integer',
'integer'),
4547 array($active_id, $this->
getId(), $pass, $this->
getStep())
4552 return $ilDB->queryF(
"SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
4553 array(
'integer',
'integer',
'integer'),
4554 array($active_id, $this->
getId(), $pass)
4566 protected function removeCurrentSolution($active_id,
$pass)
4575 return $ilDB->manipulateF(
"DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s AND step = %s",
4576 array(
'integer',
'integer',
'integer',
'integer'),
4577 array($active_id, $this->
getId(), $pass, $this->
getStep())
4582 return $ilDB->manipulateF(
"DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
4583 array(
'integer',
'integer',
'integer'),
4584 array($active_id, $this->
getId(), $pass)
4598 public function saveCurrentSolution($active_id,
$pass, $value1, $value2)
4603 $next_id =
$ilDB->nextId(
"tst_solutions");
4606 "solution_id" => array(
"integer", $next_id),
4607 "active_fi" => array(
"integer", $active_id),
4608 "question_fi" => array(
"integer", $this->
getId()),
4609 "value1" => array(
"clob", $value1),
4610 "value2" => array(
"clob", $value2),
4611 "pass" => array(
"integer",
$pass),
4612 "tstamp" => array(
"integer", time())
4615 if( $this->
getStep() !==
null )
4617 $fieldData[
'step'] = array(
"integer", $this->
getStep());
4620 $aff =
$ilDB->insert(
"tst_solutions", $fieldData);
4647 $this->step =
$step;
4667 return gmdate(
'H:i:s', $time);
4677 $time_array = explode(
':',$time);
4678 if(
sizeof($time_array) == 3)
4680 $sec += $time_array[0] * 3600;
4681 $sec += $time_array[1] * 60;
4682 $sec += $time_array[2];
4692 require_once
'Modules/TestQuestionPool/classes/questions/class.ilAssSelfAssessmentQuestionFormatter.php';
4693 return new \ilAssSelfAssessmentQuestionFormatter();
4698 return json_encode(array());
Abstract basic class which is to be extended by the concrete assessment question type classes.
getTotalAnswers()
get total number of answers
_getQuestionTitle($question_id)
Returns the question title of a question with a given id.
$export_image_path
(Web) Path to images
moveUploadedMediaFile($file, $name)
Move an uploaded media file to an public accessible temp dir to present it.
static includePluginClass($questionType, $withGuiClass)
static getFeedbackClassNameByQuestionType($questionType)
setPreventRteUsage($a_val)
Set prevent rte usage.
& getSolutionValues($active_id, $pass=NULL)
Loads solutions of a given user from the database an returns it.
static _getOriginalId($question_id)
Returns the original id of a question.
$additinalContentEditingMode
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
setProcessLocker($processLocker)
formatSAQuestion($a_q)
Format self assessment question.
setShuffle($shuffle=true)
Sets the shuffle flag.
setId($id=-1)
Sets the id of the assQuestion object.
keyInArray($searchkey, $array)
returns TRUE if the key occurs in an array
setOriginalId($original_id)
static _instantiateQuestion($question_id)
getQuestionTypeID()
Returns the question type of the question.
setObjId($obj_id=0)
Set the object id of the container object.
static sumTimesInISO8601FormatH_i_s_Extended($time1, $time2)
static instantiateQuestionGUI($a_question_id)
Creates an instance of a question gui with a given question id.
static isAllowedImageFileExtension($mimeType, $fileExtension)
copySuggestedSolutionFiles($source_questionpool_id, $source_question_id)
static originalQuestionExists($questionId)
beforeSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
setSuggestedSolution($solution_id="", $subquestion_index=0, $is_import=false)
Sets a suggested solution for the question.
_getSolutionMaxPass($question_id, $active_id)
Returns the maximum pass a users question solution.
saveQuestionDataToDb($original_id="")
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
Receives parameters from a QTI parser and creates a valid ILIAS question object.
QTIMaterialToString($a_material)
Reads an QTI material tag an creates a text string.
syncSuggestedSolutionFiles($original_id)
Syncs the files of a suggested solution if the question is synced.
isClone($question_id="")
Checks whether the question is a clone of another question or not.
static fetchMimeTypeIdentifier($contentTypeString)
fixUnavailableSkinImageSources($html)
adjustReachedPointsByScoringOptions($points, $active_id, $pass=NULL)
Adjust the given reached points by checks for all special scoring options in the test container.
deletePageOfQuestion($question_id)
Deletes the page object of a question with a given ID.
_getMaximumPoints($question_id)
Returns the maximum points, a learner can reach answering the question.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
isComplete()
Returns true, if a question is complete for use.
getHtmlQuestionContentPurifier()
const ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT
constant for additional content editing mode "default"
static _getSuggestedSolutionCount($question_id)
Returns the number of suggested solutions associated with a question.
getAdjustedReachedPoints($active_id, $pass=NULL)
returns the reached points ...
isInUse($question_id="")
Checks whether the question is in use or not.
static _areAnswered($a_user_id, $a_question_ids)
Checks if an array of question ids is answered by an user or not.
isPreviewSolutionCorrect(ilAssQuestionPreviewSession $previewSession)
cleanupMediaObjectUsage()
synchronises appearances of media objects in the question with media object usage table
persistWorkingState($active_id, $pass=NULL, $obligationsEnabled=false)
persists the working state for current testactive and testpass
createNewImageFileName($image_filename, $unique=false)
_questionExistsInTest($question_id, $test_id)
saveWorkingData($active_id, $pass=NULL)
Saves the learners input of the question to the database.
setObligationsToBeConsidered($obligationsToBeConsidered=true)
sets the flag wether obligations are to be considered or not
_getReachedPoints($active_id, $question_id, $pass=NULL)
Returns the points, a learner has reached answering the question.
getId()
Gets the id of the assQuestion object.
_getQuestionText($a_q_id)
Returns question text.
_updateTestResultCache($active_id, ilAssQuestionProcessLocker $processLocker=null)
@TODO Move this to a proper place.
getObjId()
Get the object id of the container object.
questionTitleExists($questionpool_id, $title)
Returns TRUE if the question title exists in the database.
supportsJavascriptOutput()
Returns true if the question type supports JavaScript output.
static _getQuestionTypeName($type_tag)
Return the translation for a given question type tag.
_getInternalLinkHref($target="")
getSuggestedSolutionPath()
Returns the path for a suggested solution.
areObligationsToBeConsidered()
gets the flag wether obligations are to be considered or not
setTitle($title="")
Sets the title string of the assQuestion object.
getOwner()
Gets the creator/owner ID of the assQuestion object.
prepareTextareaOutput($txt_output, $prepare_for_latex_output=FALSE)
Prepares a string for a text area output in tests.
getAdditionalContentEditingMode()
getter for additional content editing mode for this question
isHTML($a_text)
Checks if a given string contains HTML or not.
persistPreviewState(ilAssQuestionPreviewSession $previewSession)
persists the preview state for current user and question
addQuestionChangeListener(ilQuestionChangeListener $listener)
syncXHTMLMediaObjectsOfQuestion()
onCopy($sourceParentId, $sourceQuestionId, $targetParentId, $targetQuestionId)
Will be called when a question is copied (into another question pool)
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
getJavaPath()
Returns the image path for web accessable images of a question.
createNewQuestion($a_create_page=true)
Creates a new question without an owner when a new question is created This assures that an ID is giv...
getAdditionalTableName()
Returns the name of the additional question data table in the database.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second.
getHtmlUserSolutionPurifier()
getSuggestedSolutionTitle($subquestion_index=0)
Returns the title of a suggested solution at a given subquestion_index.
static getObjectClassNameByQuestionType($questionType)
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
setExportImagePath($a_path)
isValidAdditionalContentEditingMode($additionalContentEditingMode)
returns the fact wether the passed additional content mode is valid or not
toXML($a_include_header=true, $a_include_binary=true, $a_shuffle=false, $test_output=false, $force_image_references=false)
Returns a QTI xml representation of the question.
setEstimatedWorkingTimeFromDurationString($durationString)
Sets the estimated working time of a question from a given datetime string.
getSuggestedSolutionPathWeb()
Returns the web path for a suggested solution.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
buildImagePath($questionId, $parentObjectId)
addQTIMaterial(&$a_xml_writer, $a_material, $close_material_tag=TRUE, $add_mobs=TRUE)
Creates a QTI material tag from a plain text or xhtml text.
getFlashPath()
Returns the image path for web accessable flash files of a question.
__get($value)
Object getter.
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
getSuggestedSolution($subquestion_index=0)
Returns a suggested solution for a given subquestion index.
$obligationsToBeConsidered
_isUsedInRandomTest($question_id="")
Checks whether the question is used in a random test or not.
static getNumExistingSolutionRecords($activeId, $pass, $questionId)
returns the number of existing solution records for the given test active / pass and given question i...
static convertISO8601FormatH_i_s_ExtendedToSeconds($time)
duplicateSuggestedSolutionFiles($parent_id, $question_id)
Duplicates the files of a suggested solution if the question is duplicated.
setAuthor($author="")
Sets the authors name of the assQuestion object.
$arrData
Associative array to store properties.
static isFileAvailable($file)
getQuestionType()
Returns the question type of the question.
deleteSuggestedSolutions()
Deletes all suggestes solutions in the database.
getPoints()
Returns the maximum available points for the question.
getOutputType()
Gets the output type.
static isCoreQuestionType($questionType)
_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...
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
getActiveUserData($active_id)
Returns the user id and the test id for a given active id.
setExternalId($external_id)
getValidAdditionalContentEditingModes()
getter for valid additional content editing modes
deleteTaxonomyAssignments()
static _getSuggestedSolutionOutput($question_id)
Returns the output of the suggested solution.
getQuestionChangeListeners()
_getTotalAnswers($a_q_id)
get number of answers for question id (static) note: do not use $this inside this method
getJavaPathWeb()
Returns the web image path for web accessable java applets of a question.
onDuplicate($originalParentId, $originalQuestionId, $duplicateParentId, $duplicateQuestionId)
Will be called when a question is duplicated (inside a question pool or for insertion in a test)
getTestId()
Gets the test id of the assQuestion object.
__set($key, $value)
Object setter.
calculateResultsFromSolution($active_id, $pass=NULL, $obligationsEnabled=false)
Calculates the question results from a previously saved question solution.
_resolveIntLinks($question_id)
getSelfAssessmentEditingMode()
Get Self-Assessment Editing Mode.
static $allowedCharsetsByMimeType
copyPageOfQuestion($a_q_id)
static lookupOriginalParentObjId($originalQuestionId)
returns the parent object id for given original question id (should be a qpl id, but theoretically it...
_resolveInternalLink($internal_link)
static & _instanciateQuestionGUI($question_id)
Creates an instance of a question gui with a given question id.
_questionExistsInPool($question_id)
Returns true if the question already exists in the database and is assigned to a question pool.
setOutputType($outputType=OUTPUT_HTML)
Sets the output type.
static lookupParentObjId($questionId)
@global ilDB $ilDB
static _getTotalRightAnswers($a_q_id)
get number of answers for question id (static) note: do not use $this inside this method
getSelfAssessmentFormatter()
static $imageSourceFixReplaceMap
static getGuiClassNameByQuestionType($questionType)
& _getQuestionInfo($question_id)
Returns question information from the database.
_isWriteable($question_id, $user_id)
Returns true if the question is writeable by a certain user.
static getAllowedImageFileExtensions()
getDefaultNrOfTries()
Get Default Nr of Tries.
setSelfAssessmentEditingMode($a_selfassessmenteditingmode)
Set Self-Assessment Editing Mode.
static $allowedFileExtensionsByMimeType
static setResultGateway($resultGateway)
getShuffle()
Gets the shuffle flag.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
getFlashPathWeb()
Returns the web image path for web accessable flash applications of a question.
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
static includeCoreClass($questionType, $withGuiClass)
_needsManualScoring($question_id)
createPageObject()
create page object of question
copyXHTMLMediaObjectsOfQuestion($a_q_id)
const ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
constant for additional content editing mode "pageobject"
static _isWorkedThrough($active_id, $question_id, $pass=NULL)
Returns true if the question was worked through in the given pass Worked through means that the user ...
getSuggestedSolutions()
Return the suggested solutions.
_logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
& _getSuggestedSolution($question_id, $subquestion_index=0)
Returns a suggested solution for a given subquestion index.
getAnswerTableName()
Returns the name of the answer table in the database.
fixSvgToPng($imageFilenameContainingString)
calculateReachedPoints($active_id, $pass=NULL, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
_getTitle($a_q_id)
Returns the title of a question.
deleteAdditionalTableData($question_id)
Deletes datasets from the additional question table in the database.
static _includeClass($question_type, $gui=0)
Include the php class file for a given question type.
$selfassessmenteditingmode
getTitle()
Gets the title string of the assQuestion object.
setPoints($a_points)
Sets the maximum available points for the question.
afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
isAdditionalContentEditingModePageObject()
isser for additional "pageobject" content editing mode
duplicateQuestionHints($originalQuestionId, $duplicateQuestionId)
setComment($comment="")
Sets the comment string of the assQuestion object.
getSuggestedSolutionOutput()
getComment()
Gets the comment string of the assQuestion object.
setTestId($id=-1)
Sets the test id of the assQuestion object.
getAuthor()
Gets the authors name of the assQuestion object.
_getQuestionType($question_id)
Returns the question type of a question with a given id.
setNrOfTries($a_nr_of_tries)
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assQuestion constructor
getReachedPoints($active_id, $pass=NULL)
Returns the points, a learner has reached answering the question This is the fast way to get the poin...
$nr_of_tries
Number of tries.
getQuestion()
Gets the question string of the question object.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
static isAllowedImageMimeType($mimeType)
isAnswered($active_id, $pass=null)
returns boolean wether the question is answered during test pass or not
saveToDb($original_id="")
Saves the question to the database.
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
_questionExists($question_id)
Returns true if the question already exists in the database.
pcArrayShuffle($array)
Shuffles the values of a given array.
setQuestion($question="")
Sets the question string of the question object.
getImagePathWeb()
Returns the web image path for web accessable images of a question.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
loadFromDb($question_id)
Loads the question from the database.
static getAllowedFileExtensionsForMimeType($mimeType)
setLastChange($lastChange)
static getResultGateway()
& getInstances()
Gets all instances of the question.
createRandomSolution($test_id, $user_id)
getEstimatedWorkingTime()
Gets the estimated working time of a question.
getQuestionTypeFromDb($question_id)
get question type for question id
getPreventRteUsage()
Get prevent rte usage.
deleteAnswers($question_id)
Deletes datasets from answers tables.
setDefaultNrOfTries($a_defaultnroftries)
Set Default Nr of Tries.
Assessment hint page object.
static deleteHintsByQuestionIds($questionIds)
Deletes all question hints relating to questions included in given question ids.
static duplicateListForQuestion($originalQuestionId, $duplicateQuestionId)
duplicates a hint list from given original question id to given duplicate question id and returns an ...
static getListByQuestionId($questionId)
instantiates a question hint list for the passed question id
deleteRequestsByQuestionIds($questionIds)
Deletes all hint requests relating to a question included in given question ids.
getParticipantsSolution()
setParticipantsSolution($participantSolution)
_updateObjectiveResult($a_user_id, $a_active_id, $a_question_id)
static _getInstanceByType($a_type)
Factory method for creating purifier instances.
_saveLink($a_source_type, $a_source_id, $a_target_type, $a_target_id, $a_target_inst=0, $a_source_lang="-")
save internal link information
_deleteAllLinksOfSource($a_source_type, $a_source_id, $a_lang="-")
Delete all links of a given source.
_getIdForImportId($a_type, $a_target)
Get current id for an import id.
_getIdForImportId($a_import_id)
get current object id for import id (static)
_addLog($user_id, $object_id, $logtext, $question_id="", $original_id="", $test_only=FALSE, $test_ref_id=NULL)
Add an assessment log entry.
_getLogLanguage()
retrieve the log language for assessment logging
_getManualScoringTypes()
Retrieve the manual scoring settings as type strings.
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
_isWriteable($object_id, $user_id)
Returns true, if the question pool is writeable by a given user.
static _updateQuestionCount($object_id)
Updates the number of available questions for a question pool in the database.
static getUsageOfObject($a_obj_id, $a_include_titles=false)
Get usage of object.
_getParticipantData($active_id)
Retrieves a participant name from active id.
_getCountSystem($active_id)
Gets the count system for the calculation of points.
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
_getQuestionCountAndPointsForPassOfParticipant($active_id, $pass)
_lookupAuthor($obj_id)
Gets the authors name of the ilObjTest object.
static buildExamId($active_id, $pass, $test_obj_id=null)
_getObjectIDFromActiveID($active_id)
Returns the ILIAS test object id for a given active id.
static _getUserIdFromActiveId($active_id)
_getResultPass($active_id)
Retrieves the pass number that should be counted for a given user.
_getScoreCutting($active_id)
Determines if the score of a question should be cut at 0 points or the score of the whole test.
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
_getWorkingTimeOfParticipantForPass($active_id, $pass)
Returns the complete working time in seconds for a test participant.
static _lookupObjId($a_id)
static _lookupTitle($a_id)
lookup object title
static _getAllReferences($a_id)
get all reference ids of object
static getPluginObject($a_ctype, $a_cname, $a_slot_id, $a_pname)
Get plugin object.
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
_cleanupMediaObjectUsage($a_text, $a_usage_type, $a_usage_id)
synchronises appearances of media objects in $a_text with media object usage table
Taxonomy node <-> item assignment.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static 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 makeDirParents($a_dir)
Create a new directory and all parent directories.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static removeTrailingPathSeparators($path)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
static createDirectory($a_dir, $a_mod=0755)
create directory
redirection script todo: (a better solution should control the processing via a xml file)
const ILIAS_ABSOLUTE_PATH