4 require_once
'./Modules/TestQuestionPool/classes/class.assQuestion.php';
5 require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
6 require_once
'./Modules/TestQuestionPool/classes/class.assClozeGapCombination.php';
7 require_once
'./Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
8 require_once
'./Modules/TestQuestionPool/interfaces/interface.ilObjAnswerScoringAdjustable.php';
9 require_once
'./Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
10 require_once
'./Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
11 require_once
'Modules/TestQuestionPool/classes/feedback/class.ilAssClozeTestFeedback.php';
125 $this->start_tag =
"[gap]";
126 $this->end_tag =
"[/gap]";
127 $this->gaps = array();
129 $this->fixedTextLength =
"";
130 $this->identical_scoring = 1;
131 $this->gap_combinations_exists =
false;
132 $this->gap_combinations = array();
162 $text = str_replace(
'$',
'GAPMASKEDDOLLAR',
$text);
$text = preg_replace(
"/\[gap[^\]]*?\]/",
"[gap]",
$text);
163 $text = preg_replace(
"/<gap([^>]*?)>/",
"[gap]",
$text);
164 $text = str_replace(
"</gap>",
"[/gap]",
$text);
$text = str_replace(
'GAPMASKEDDOLLAR',
'$',
$text);
178 $content = str_replace(
'$',
'GAPMASKEDDOLLAR', $content);
179 $output = preg_replace(
"/\[gap\].*?\[\/gap\]/", $content, $gaptext, 1);
194 $ilDB = $DIC[
'ilDB'];
202 $this->
setId($question_id);
217 include_once(
"./Services/RTE/classes/class.ilRTE.php");
221 $this->
setEstimatedWorkingTime(substr($data[
"working_time"], 0, 2), substr($data[
"working_time"], 3, 2), substr($data[
"working_time"], 6, 2));
229 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
230 include_once
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
232 "SELECT * FROM qpl_a_cloze WHERE question_fi = %s ORDER BY gap_id, aorder ASC",
237 $this->gaps = array();
239 switch ($data[
"cloze_type"]) {
241 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
249 $this->gaps[$data[
"gap_id"]]->setGapSize($data[
'gap_size']);
251 $this->gaps[$data[
"gap_id"]]->addItem($answer);
254 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
256 $this->gaps[$data[
"gap_id"]]->setShuffle($data[
"shuffle"]);
263 $this->gaps[$data[
"gap_id"]]->addItem($answer);
266 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
274 $this->gaps[$data[
"gap_id"]]->setGapSize($data[
'gap_size']);
275 $answer->setLowerBound($data[
"lowerlimit"]);
276 $answer->setUpperBound($data[
"upperlimit"]);
277 $this->gaps[$data[
"gap_id"]]->addItem($answer);
284 $check_for_gap_combinations = $assClozeGapCombinationObj->loadFromDb($question_id);
285 if (count($check_for_gap_combinations) != 0) {
289 parent::loadFromDb($question_id);
292 #region Save question to db 318 $ilDB = $DIC[
'ilDB'];
321 "DELETE FROM qpl_a_cloze WHERE question_fi = %s",
323 array( $this->
getId() )
326 foreach ($this->gaps as
$key => $gap) {
341 $DIC->database()->manipulateF(
344 array( $this->
getId() )
348 'question_fi' => array(
'integer', $this->
getId()),
366 $ilDB = $DIC[
'ilDB'];
367 foreach ($gap->getItems($this->getShuffler()) as $item) {
369 $next_id =
$ilDB->nextId(
'qpl_a_cloze');
370 switch ($gap->getType()) {
395 $ilDB = $DIC[
'ilDB'];
397 "INSERT INTO qpl_a_cloze (answer_id, question_fi, gap_id, answertext, points, aorder, cloze_type, gap_size) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
412 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
416 (int) $gap->getGapSize()
432 $ilDB = $DIC[
'ilDB'];
434 "INSERT INTO qpl_a_cloze (answer_id, question_fi, gap_id, answertext, points, aorder, cloze_type, shuffle) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
449 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
453 ($gap->getShuffle()) ?
"1" :
"0" 469 $ilDB = $DIC[
'ilDB'];
471 include_once
"./Services/Math/classes/class.EvalMath.php";
473 $eval->suppress_errors =
true;
475 "INSERT INTO qpl_a_cloze (answer_id, question_fi, gap_id, answertext, points, aorder, cloze_type, lowerlimit, upperlimit, gap_size) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
492 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
496 ($eval->e($item->getLowerBound() !==
false) && strlen(
497 $item->getLowerBound()
498 ) > 0) ? $item->getLowerBound() : $item->getAnswertext(),
499 ($eval->e($item->getUpperBound() !==
false) && strlen(
500 $item->getUpperBound()
501 ) > 0) ? $item->getUpperBound() : $item->getAnswertext(),
502 (int) $gap->getGapSize()
509 #endregion Save question to db 531 $this->gaps = array();
545 $this->gaps = array();
640 include_once
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
641 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
642 $search_pattern =
"|\[gap\](.*?)\[/gap\]|i";
643 preg_match_all($search_pattern, $this->
getClozeText(), $found);
644 $this->gaps = array();
645 if (count($found[0])) {
646 foreach ($found[1] as $gap_index => $answers) {
649 $textparams = preg_split(
"/(?<!\\\\),/", $answers);
650 foreach ($textparams as
$key => $value) {
652 $gap->addItem($answer);
654 $this->gaps[$gap_index] = $gap;
666 if (array_key_exists($gap_index, $this->gaps)) {
667 $this->gaps[$gap_index]->setType($gap_type);
682 if (array_key_exists($gap_index, $this->gaps)) {
683 $this->gaps[$gap_index]->setShuffle(
$shuffle);
695 foreach ($this->gaps as $gap_index => $gap) {
696 $this->gaps[$gap_index]->clearItems();
709 if (is_array($this->gaps)) {
710 return count($this->gaps);
728 if (array_key_exists($gap_index, $this->gaps)) {
731 $answer = str_replace(
",",
".", $answer);
733 $this->gaps[$gap_index]->addItem(
new assAnswerCloze($answer, 0, $order));
747 if (array_key_exists($gap_index, $this->gaps)) {
748 return $this->gaps[$gap_index];
756 if (array_key_exists($gap_index, $this->gaps)) {
757 $this->gaps[$gap_index]->setGapSize(
$size);
773 if (array_key_exists($gap_index, $this->gaps)) {
774 $this->gaps[$gap_index]->setItemPoints($order,
$points);
788 if (array_key_exists($gap_index, $this->gaps)) {
789 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
793 $this->gaps[$gap_index]->getItemCount()
795 $this->gaps[$gap_index]->addItem($answer);
809 $this->gaps[
$index] = $gap;
824 if (array_key_exists($gap_index, $this->gaps)) {
825 $this->gaps[$gap_index]->setItemLowerBound($order, $bound);
841 if (array_key_exists($gap_index, $this->gaps)) {
842 $this->gaps[$gap_index]->setItemUpperBound($order, $bound);
856 $gaps_used_in_combination = array();
857 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
858 $points = $assClozeGapCombinationObj->getMaxPointsForCombination($this->
getId());
859 $gaps_used_in_combination = $assClozeGapCombinationObj->getGapsWhichAreUsedInCombination($this->
getId());
861 foreach ($this->gaps as $gap_index => $gap) {
862 if (!array_key_exists($gap_index, $gaps_used_in_combination)) {
865 foreach ($gap->getItems($this->getShuffler()) as $item) {
866 if ($item->getPoints() > $gap_max_points) {
867 $gap_max_points = $item->getPoints();
873 foreach ($gap->getItems($this->getShuffler()) as $item) {
874 if ($item->getPoints() > $srpoints) {
875 $srpoints = $item->getPoints();
881 foreach ($gap->getItems($this->getShuffler()) as $item) {
882 if ($item->getPoints() > $numpoints) {
883 $numpoints = $item->getPoints();
901 if ($this->
id <= 0) {
906 $this_id = $this->
getId();
910 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
914 if ((
int) $testObjId > 0) {
915 $clone->setObjId($testObjId);
932 if ($this->gap_combinations_exists) {
941 $clone->copyPageOfQuestion($this_id);
943 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
945 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
947 return $clone->getId();
957 if ($this->
getId() <= 0) {
962 $thisId = $this->
getId();
966 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
969 $clone->setObjId($target_questionpool_id);
976 if ($this->gap_combinations_exists) {
986 $clone->onCopy($thisObjId, $thisId, $clone->getObjId(), $clone->getId());
988 return $clone->getId();
993 if ($this->
id <= 0) {
998 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
1001 $sourceParentId = $this->
getObjId();
1007 $clone->setObjId($targetParentId);
1009 if ($targetQuestionTitle) {
1010 $clone->setTitle($targetQuestionTitle);
1015 if ($this->gap_combinations_exists) {
1020 $clone->copyPageOfQuestion($sourceQuestionId);
1022 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
1024 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
1032 $array = $assClozeGapCombinationObj->loadFromDb($orgID);
1033 $assClozeGapCombinationObj->importGapCombinationToDb($newID, $array);
1044 foreach ($this->
getGaps() as $gap_index => $gap) {
1046 foreach ($gap->getItemsRaw() as $item) {
1047 array_push($answers, str_replace(
",",
"\\,", $item->getAnswerText()));
1068 if (array_key_exists($gap_index, $this->gaps)) {
1069 if ($this->gaps[$gap_index]->getItemCount() == 1) {
1074 $this->gaps[$gap_index]->deleteItem($answer_index);
1090 if (array_key_exists($gap_index, $this->gaps)) {
1092 foreach ($this->
getGaps() as $replace_gap_index => $gap) {
1094 foreach ($gap->getItemsRaw() as $item) {
1095 array_push($answers, str_replace(
",",
"\\,", $item->getAnswerText()));
1097 if ($replace_gap_index == $gap_index) {
1109 unset($this->gaps[$gap_index]);
1110 $this->gaps = array_values($this->gaps);
1125 include_once
"./Services/Utilities/classes/class.ilStr.php";
1128 switch ($gaprating) {
1135 if (strcmp($a_original, $a_entered) == 0) {
1140 if (levenshtein($a_original, $a_entered) <= 1) {
1145 if (levenshtein($a_original, $a_entered) <= 2) {
1150 if (levenshtein($a_original, $a_entered) <= 3) {
1155 if (levenshtein($a_original, $a_entered) <= 4) {
1160 if (levenshtein($a_original, $a_entered) <= 5) {
1185 include_once
"./Services/Math/classes/class.EvalMath.php";
1187 $eval->suppress_errors =
true;
1190 if ($eval->e($a_entered) ===
false) {
1192 } elseif (($eval->e($lowerBound) !==
false) && ($eval->e($upperBound) !==
false)) {
1194 if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($upperBound))) {
1197 } elseif ($eval->e($lowerBound) !==
false) {
1198 if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($a_original))) {
1201 } elseif ($eval->e($upperBound) !==
false) {
1202 if (($eval->e($a_entered) >= $eval->e($a_original)) && ($eval->e($a_entered) <= $eval->e($upperBound))) {
1206 if ($eval->e($a_entered) == $eval->e($a_original)) {
1219 return preg_match(
"/^-?(\\d*)(,|\\.|\\/){0,1}(\\d*)$/", $value, $matches);
1234 $ilDB = $DIC[
'ilDB'];
1236 if (is_null(
$pass)) {
1241 $user_result = array();
1243 if (strcmp(
$data[
"value2"],
"") != 0) {
1244 $user_result[
$data[
"value1"]] = array(
1245 "gap_id" => $data[
"value1"],
1246 "value" => $data[
"value2"]
1251 ksort($user_result);
1253 if ($returndetails) {
1254 $detailed = array();
1264 if (is_numeric($submittedValue)) {
1268 if (preg_match(
'/^[-+]{0,1}\d+\/\d+$/', $submittedValue)) {
1278 $gap = $this->
getGap($gapIndex);
1295 $solutionSubmit = array();
1297 foreach ($submit as
$key => $value) {
1298 if (preg_match(
"/^gap_(\d+)/",
$key, $matches)) {
1300 if (strlen($value)) {
1301 $gap = $this->
getGap($matches[1]);
1302 if (is_object($gap)) {
1303 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1))) {
1304 if ($gap->getType() ==
CLOZE_NUMERIC && !is_numeric(str_replace(
",",
".", $value))) {
1307 $value = str_replace(
",",
".", $value);
1309 $solutionSubmit[trim($matches[1])] = $value;
1316 return $solutionSubmit;
1322 $solutionSubmit = array();
1324 foreach ($submit as
$key => $value) {
1325 if (preg_match(
"/^gap_(\d+)/",
$key, $matches)) {
1327 if (strlen($value)) {
1328 $gap = $this->
getGap($matches[1]);
1329 if (is_object($gap)) {
1330 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1))) {
1332 $value = str_replace(
",",
".", $value);
1334 $solutionSubmit[trim($matches[1])] = $value;
1341 return $solutionSubmit;
1360 $ilDB = $DIC[
'ilDB'];
1362 if (is_null(
$pass)) {
1363 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1367 $entered_values = 0;
1369 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use (&$entered_values, $active_id,
$pass, $authorized) {
1374 if (strlen($value)) {
1376 if (is_object($gap)) {
1377 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1))) {
1386 if ($entered_values) {
1387 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1392 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1409 return "assClozeTest";
1433 switch ($a_textgap_rating) {
1441 $this->textgap_rating = $a_textgap_rating;
1458 return ($this->identical_scoring) ? 1 : 0;
1470 $this->identical_scoring = ($a_identical_scoring) ? 1 : 0;
1481 return "qpl_qst_cloze";
1492 return array(
"qpl_a_cloze",
'qpl_a_cloze_combi_res');
1503 $this->fixedTextLength = $a_text_len;
1528 $gap_max_points = 0;
1529 if (array_key_exists($gap_index, $this->gaps)) {
1530 $gap = &$this->gaps[$gap_index];
1531 foreach ($gap->getItems($this->getShuffler()) as $answer) {
1532 if ($answer->getPoints() > $gap_max_points) {
1533 $gap_max_points = $answer->getPoints();
1547 return parent::getRTETextWithMediaObjects() . $this->
getClozeText();
1561 $this->gap_combinations_exists = $value;
1566 $this->gap_combinations = $value;
1574 parent::setExportDetailsXLS($worksheet, $startrow, $active_id,
$pass);
1578 foreach ($this->
getGaps() as $gap_index => $gap) {
1579 $worksheet->setCell($startrow +
$i, 0, $this->lng->txt(
"gap") .
" $i");
1580 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow +
$i));
1582 foreach ($solution as $solutionvalue) {
1583 if ($gap_index == $solutionvalue[
"value1"]) {
1584 $string_escaping_org_value = $worksheet->getStringEscaping();
1586 $worksheet->setStringEscaping(
false);
1588 switch ($gap->getType()) {
1590 $worksheet->setCell($startrow +
$i, 1, $gap->getItem($solutionvalue[
"value2"])->getAnswertext());
1594 $worksheet->setCell($startrow +
$i, 1, $solutionvalue[
"value2"]);
1598 $worksheet->setStringEscaping($string_escaping_org_value);
1605 return $startrow +
$i + 1;
1624 include_once(
"./Services/RTE/classes/class.ilRTE.php");
1634 'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
false)),
1635 'allcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
true))
1641 foreach ($gap->getItems($this->getShuffler()) as $item) {
1643 $jitem[
'points'] = $item->getPoints();
1645 $jitem[
'order'] = $item->getOrder();
1647 $jitem[
'lowerbound'] = $item->getLowerBound();
1648 $jitem[
'upperbound'] = $item->getUpperBound();
1650 $jitem[
'value'] = trim($jitem[
'value']);
1652 array_push($items, $jitem);
1656 $jgap[
'size'] = $gap->getGapSize();
1659 $jgap[
'shuffle'] = $gap->getShuffle();
1660 $jgap[
'type'] = $gap->getType();
1661 $jgap[
'item'] = $items;
1663 array_push($gaps, $jgap);
1681 require_once
"./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1712 $ilDB = $DIC[
'ilDB'];
1715 $maxStep = $this->lookupMaxStep($active_id,
$pass);
1717 if ($maxStep !== null) {
1720 SELECT sol.value1+1 as val, sol.value2, cloze.cloze_type 1721 FROM tst_solutions sol 1722 INNER JOIN qpl_a_cloze cloze ON cloze.gap_id = value1 AND cloze.question_fi = sol.question_fi 1723 WHERE sol.active_fi = %s AND sol.pass = %s AND sol.question_fi = %s AND sol.step = %s 1724 GROUP BY sol.solution_id, sol.value1+1, sol.value2, cloze.cloze_type 1726 array(
"integer",
"integer",
"integer",
"integer"),
1727 array($active_id,
$pass, $this->
getId(), $maxStep)
1732 SELECT sol.value1+1 as val, sol.value2, cloze.cloze_type 1733 FROM tst_solutions sol 1734 INNER JOIN qpl_a_cloze cloze ON cloze.gap_id = value1 AND cloze.question_fi = sol.question_fi 1735 WHERE sol.active_fi = %s AND sol.pass = %s AND sol.question_fi = %s 1736 GROUP BY sol.solution_id, sol.value1+1, sol.value2, cloze.cloze_type 1738 array(
"integer",
"integer",
"integer"),
1744 if (
$row[
"cloze_type"] == 1) {
1781 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
1782 $combinations_for_question = $assClozeGapCombinationObj->getCleanCombinationArray($this->
getId());
1783 $gap_answers = array();
1784 $gap_used_in_combination = array();
1785 foreach ($user_result as $user_result_build_list) {
1786 if (is_array($user_result_build_list)) {
1787 $gap_answers[$user_result_build_list[
'gap_id']] = $user_result_build_list[
'value'];
1791 foreach ($combinations_for_question as $combination) {
1792 foreach ($combination as $row_key => $row_answers) {
1793 $combination_fulfilled =
true;
1794 $points_for_combination = $row_answers[
'points'];
1795 foreach ($row_answers as $gap_key => $combination_gap_answer) {
1796 if ($gap_key !==
'points') {
1797 $gap_used_in_combination[$gap_key] = $gap_key;
1799 if ($combination_fulfilled && array_key_exists($gap_key, $gap_answers)) {
1800 switch ($combination_gap_answer[
'type']) {
1802 $is_text_gap_correct = $this->
getTextgapPoints($gap_answers[$gap_key], $combination_gap_answer[
'answer'], 1);
1803 if ($is_text_gap_correct != 1) {
1804 $combination_fulfilled =
false;
1808 $answer = $this->gaps[$gap_key]->getItem($gap_answers[$gap_key]);
1809 $answertext = $answer->getAnswertext();
1810 if ($answertext != $combination_gap_answer[
'answer']) {
1811 $combination_fulfilled =
false;
1815 $answer = $this->gaps[$gap_key]->getItem(0);
1816 if ($combination_gap_answer[
'answer'] !=
'out_of_bound') {
1817 $is_numeric_gap_correct = $this->
getNumericgapPoints($answer->getAnswertext(), $gap_answers[$gap_key], 1, $answer->getLowerBound(), $answer->getUpperBound());
1818 if ($is_numeric_gap_correct != 1) {
1819 $combination_fulfilled =
false;
1822 $wrong_is_the_new_right = $this->
getNumericgapPoints($answer->getAnswertext(), $gap_answers[$gap_key], 1, $answer->getLowerBound(), $answer->getUpperBound());
1823 if ($wrong_is_the_new_right == 1) {
1824 $combination_fulfilled =
false;
1830 if ($gap_key !==
'points') {
1831 $combination_fulfilled =
false;
1835 if ($combination_fulfilled) {
1836 $points += $points_for_combination;
1841 return array(
$points, $gap_used_in_combination);
1850 if ($detailed === null) {
1851 $detailed = array();
1855 $combinations[1] = array();
1856 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
1861 $solution_values_text = array();
1862 $solution_values_select = array();
1863 $solution_values_numeric = array();
1864 foreach ($user_result as $gap_id => $value) {
1865 if (is_string($value)) {
1866 $value = array(
"value" => $value);
1869 if (array_key_exists($gap_id, $this->gaps) && !array_key_exists($gap_id, $combinations[1])) {
1870 switch ($this->gaps[$gap_id]->getType()) {
1873 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1874 $answer = $this->gaps[$gap_id]->getItem($order);
1875 $gotpoints = $this->
getTextgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints());
1876 if ($gotpoints > $gappoints) {
1877 $gappoints = $gotpoints;
1882 if ((in_array($value[
"value"], $solution_values_text)) && ($gappoints > 0)) {
1887 $detailed[$gap_id] = array(
"points" => $gappoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ?
true :
false,
"positive" => ($gappoints > 0) ?
true :
false);
1888 array_push($solution_values_text, $value[
"value"]);
1892 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1893 $answer = $this->gaps[$gap_id]->getItem($order);
1894 $gotpoints = $this->
getNumericgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints(), $answer->getLowerBound(), $answer->getUpperBound());
1895 if ($gotpoints > $gappoints) {
1896 $gappoints = $gotpoints;
1901 include_once
"./Services/Math/classes/class.EvalMath.php";
1903 $eval->suppress_errors =
true;
1904 $found_value =
false;
1905 foreach ($solution_values_numeric as $solval) {
1906 if ($eval->e($solval) == $eval->e($value[
"value"])) {
1907 $found_value =
true;
1910 if ($found_value && ($gappoints > 0)) {
1915 $detailed[$gap_id] = array(
"points" => $gappoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ?
true :
false,
"positive" => ($gappoints > 0) ?
true :
false);
1916 array_push($solution_values_numeric, $value[
"value"]);
1919 if ($value[
"value"] >= 0) {
1920 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1921 $answer = $this->gaps[$gap_id]->getItem($order);
1922 if ($value[
"value"] == $answer->getOrder()) {
1923 $answerpoints = $answer->getPoints();
1926 if ((in_array($answer->getAnswertext(), $solution_values_select)) && ($answerpoints > 0)) {
1931 $detailed[$gap_id] = array(
"points" => $answerpoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $answerpoints) ?
true :
false,
"positive" => ($answerpoints > 0) ?
true :
false);
1932 array_push($solution_values_select, $answer->getAnswertext());
1946 $userSolution = array();
1950 $userSolution[
$key] = array(
'gap_id' => $key,
'value' => $val);
1964 foreach ($userSolution as $value1 => $value2) {
1965 if ($value1 == $gapIndex) {
1966 $answerValue = $value2;
1971 return $answerValue;
1976 $gap = $this->
getGap($qIndex);
1983 if ($item->getAnswertext() == $answerOptionValue) {
1993 $gap = $this->
getGap($qIndex);
1996 $item->setOrder($gap->getItemCount());
1998 $gap->addItem($item);
setGapCombinations($value)
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getId()
Gets the id of the assQuestion object.
fetchSolutionSubmit($submit)
toJSON()
Returns a JSON representation of the question.
getGapCount()
Returns the number of gaps.
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
const TEXTGAP_RATING_LEVENSHTEIN5
const PercentageResultExpression
Class for cloze question numeric answers.
getMaximumGapPoints($gap_index)
Returns the maximum points for a gap.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
getQuestionType()
Returns the question type of the question.
Class iQuestionCondition.
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
setEndTag($end_tag="[/gap]")
Sets the end tag of a cloze gap.
clearGapAnswers()
Removes all answers from the gaps.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
const NumberOfResultExpression
saveAnswerSpecificDataToDb()
Save all gaps to the database.
getAnswerTableName()
Returns the name of the answer table in the database.
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
const TEXTGAP_RATING_LEVENSHTEIN2
const TEXTGAP_RATING_LEVENSHTEIN1
Abstract basic class which is to be extended by the concrete assessment question type classes...
const CLOZE_TEXT
Cloze question constants.
getSolutionSubmitValidation()
setGapSize($gap_index, $order, $size)
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
calculateCombinationResult($user_result)
getOperators($expression)
Get all available operations for a specific question.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
ensureNonNegativePoints($points)
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
setId($id=-1)
Sets the id of the assQuestion object.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
migrateToLmContent($content)
copyGapCombination($orgID, $newID)
getGap($gap_index=0)
Returns the gap at a given index.
setGapAnswerPoints($gap_index, $order, $points)
Sets the points of a gap with a given index and an answer with a given order.
getTextgapRating()
Returns the rating option for text gaps.
Class for cloze question gaps.
saveToDb($original_id="")
Saves a assClozeTest object to a database.
static strToLower($a_string)
getParticipantsSolution()
setClozeTextValue($cloze_text="")
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
checkForValidFormula($value)
setNrOfTries($a_nr_of_tries)
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{}
const StringResultExpression
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
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...
createGapsFromQuestiontext()
Create gap entries by parsing the question text.
getObjId()
Get the object id of the container object.
getShuffle()
Gets the shuffle flag.
getNumericgapPoints($a_original, $a_entered, $max_points, $lowerBound, $upperBound)
Returns the points for a text gap and compares the given solution with the entered solution using the...
addAnswerOptionValue($qIndex, $answerOptionValue, $points)
getStartTag()
Returns the start tag of a cloze gap.
isAddableAnswerOptionValue($qIndex, $answerOptionValue)
getTextgapPoints($a_original, $a_entered, $max_points)
Returns the points for a text gap and compares the given solution with the entered solution using the...
setGapType($gap_index, $gap_type)
Set the type of a gap with a given index.
setGapCombinationsExists($value)
static _getLogLanguage()
retrieve the log language for assessment logging
getGaps()
Returns the array of gaps.
setAuthor($author="")
Sets the authors name of the assQuestion object.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assClozeTest.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
getAuthor()
Gets the authors name of the assQuestion object.
const TEXTGAP_RATING_LEVENSHTEIN3
setGapAnswerLowerBound($gap_index, $order, $bound)
Sets the lower bound of a gap with a given index and an answer with a given order.
Class ilUserQuestionResult.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
setFixedTextLength($a_text_len)
Sets a fixed text length for all text fields in the cloze question.
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
const NumericResultExpression
isValidNumericSubmitValue($submittedValue)
copyObject($target_questionpool_id, $title="")
Copies an assClozeTest object.
const TEXTGAP_RATING_CASESENSITIVE
Interface ilObjAnswerScoringAdjustable.
getQuestion()
Gets the question string of the question object.
calculateReachedPoints($active_id, $pass=null, $authorized=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
addGapAtIndex($gap, $index)
Adds a ClozeGap object at a given index.
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
getGapCombinationsExists()
setGapAnswerUpperBound($gap_index, $order, $bound)
Sets the upper bound of a gap with a given index and an answer with a given order.
saveClozeTextGapRecordToDb($next_id, $key, $item, $gap)
Saves a gap-item record.
saveAdditionalQuestionDataToDb()
Saves the data for the additional data table.
addGapAnswer($gap_index, $order, $answer)
Sets the answer text of a gap with a given index.
setGapShuffle($gap_index=0, $shuffle=1)
Sets the shuffle state of a gap with a given index.
setClozeText($cloze_text="")
Evaluates the text gap solutions from the cloze text.
cleanQuestiontext($text)
Cleans cloze question text to remove attributes or tags from older ILIAS versions.
getExpressionTypes()
Get all available expression types for a specific question.
fetchAnswerValueForGap($userSolution, $gapIndex)
static getOperatorsByExpression($expression)
flushGaps()
Deletes all gaps without changing the cloze text.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
saveClozeNumericGapRecordToDb($next_id, $key, $item, $gap)
Saves a gap-item record.
deleteGap($gap_index)
Deletes a gap with a given index.
replaceFirstGap($gaptext, $content)
Replace the first gap in a string without treating backreferences.
updateClozeTextFromGaps()
Updates the gap parameters in the cloze text from the form input.
setFeedbackMode($feedbackMode)
setTextgapRating($a_textgap_rating)
Sets the rating option for text gaps.
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
getEndTag()
Returns the end tag of a cloze gap.
removeCurrentSolution($active_id, $pass, $authorized=true)
setStartTag($start_tag="[gap]")
Sets the start tag of a cloze gap.
addGapText($gap_index)
Adds a new answer text value to a text gap with a given index.
prepareTextareaOutput($txt_output, $prepare_for_latex_output=false, $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output in tests.
deleteAnswerText($gap_index, $answer_index)
Deletes the answer text of a gap with a given index and an answer with a given order.
getFixedTextLength()
Gets the fixed text length for all text fields in the cloze question.
const TEXTGAP_RATING_LEVENSHTEIN4
setOriginalId($original_id)
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass...
saveClozeSelectGapRecordToDb($next_id, $key, $item, $gap)
Saves a gap-item record.
getClozeText()
Returns the cloze text.
getTitle()
Gets the title string of the assQuestion object.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assClozeTest constructor
loadFromDb($question_id)
Loads a assClozeTest object from a database.
isComplete()
Returns TRUE, if a cloze test is complete for use.
getIdenticalScoring()
Returns the identical scoring status of the question.
setTitle($title="")
Sets the title string of the assQuestion object.
setObjId($obj_id=0)
Set the object id of the container object.
setIdenticalScoring($a_identical_scoring)
Sets the identical scoring option for cloze questions.
setComment($comment="")
Sets the comment string of the assQuestion object.
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
const FB_MODE_GAP_QUESTION
constants for different feedback modes (per gap or per gap-answers/options)
saveClozeGapItemsToDb($gap, $key)
Save all items belonging to one cloze gap to the db.
calculateReachedPointsForSolution($user_result, &$detailed=null)
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
const TEXTGAP_RATING_CASEINSENSITIVE
const EmptyAnswerExpression