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);
180 $output = str_replace(
'GAPMASKEDDOLLAR',
'$', $output);
194 $ilDB = $DIC[
'ilDB'];
202 $this->
setId($question_id);
224 include_once(
"./Services/RTE/classes/class.ilRTE.php");
228 $this->
setEstimatedWorkingTime(substr($data[
"working_time"], 0, 2), substr($data[
"working_time"], 3, 2), substr($data[
"working_time"], 6, 2));
236 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
237 include_once
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
239 "SELECT * FROM qpl_a_cloze WHERE question_fi = %s ORDER BY gap_id, aorder ASC",
244 $this->gaps = array();
246 switch ($data[
"cloze_type"]) {
248 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
256 $this->gaps[$data[
"gap_id"]]->setGapSize($data[
'gap_size']);
258 $this->gaps[$data[
"gap_id"]]->addItem($answer);
261 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
263 $this->gaps[$data[
"gap_id"]]->setShuffle($data[
"shuffle"]);
270 $this->gaps[$data[
"gap_id"]]->addItem($answer);
273 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
281 $this->gaps[$data[
"gap_id"]]->setGapSize($data[
'gap_size']);
282 $answer->setLowerBound($data[
"lowerlimit"]);
283 $answer->setUpperBound($data[
"upperlimit"]);
284 $this->gaps[$data[
"gap_id"]]->addItem($answer);
291 $check_for_gap_combinations = $assClozeGapCombinationObj->loadFromDb($question_id);
292 if (count($check_for_gap_combinations) != 0) {
296 parent::loadFromDb($question_id);
299 #region Save question to db 325 $ilDB = $DIC[
'ilDB'];
328 "DELETE FROM qpl_a_cloze WHERE question_fi = %s",
330 array( $this->
getId() )
333 foreach ($this->gaps as $key => $gap) {
348 $DIC->database()->manipulateF(
351 array( $this->
getId() )
355 'question_fi' => array(
'integer', $this->
getId()),
373 $ilDB = $DIC[
'ilDB'];
374 foreach ($gap->getItems($this->getShuffler()) as $item) {
376 $next_id =
$ilDB->nextId(
'qpl_a_cloze');
377 switch ($gap->getType()) {
402 $ilDB = $DIC[
'ilDB'];
404 "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)",
419 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
423 (int) $gap->getGapSize()
439 $ilDB = $DIC[
'ilDB'];
441 "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)",
456 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
460 ($gap->getShuffle()) ?
"1" :
"0" 476 $ilDB = $DIC[
'ilDB'];
478 include_once
"./Services/Math/classes/class.EvalMath.php";
480 $eval->suppress_errors =
true;
482 "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)",
499 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
503 ($eval->e($item->getLowerBound() !==
false) && strlen(
504 $item->getLowerBound()
505 ) > 0) ? $item->getLowerBound() : $item->getAnswertext(),
506 ($eval->e($item->getUpperBound() !==
false) && strlen(
507 $item->getUpperBound()
508 ) > 0) ? $item->getUpperBound() : $item->getAnswertext(),
509 (int) $gap->getGapSize()
516 #endregion Save question to db 538 $this->gaps = array();
552 $this->gaps = array();
647 include_once
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
648 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
649 $search_pattern =
"|\[gap\](.*?)\[/gap\]|i";
650 preg_match_all($search_pattern, $this->
getClozeText(), $found);
651 $this->gaps = array();
652 if (count($found[0])) {
653 foreach ($found[1] as $gap_index => $answers) {
656 $textparams = preg_split(
"/(?<!\\\\),/", $answers);
657 foreach ($textparams as $key => $value) {
659 $gap->addItem($answer);
661 $this->gaps[$gap_index] = $gap;
673 if (array_key_exists($gap_index, $this->gaps)) {
674 $this->gaps[$gap_index]->setType($gap_type);
689 if (array_key_exists($gap_index, $this->gaps)) {
690 $this->gaps[$gap_index]->setShuffle(
$shuffle);
702 foreach ($this->gaps as $gap_index => $gap) {
703 $this->gaps[$gap_index]->clearItems();
716 if (is_array($this->gaps)) {
717 return count($this->gaps);
735 if (array_key_exists($gap_index, $this->gaps)) {
738 $answer = str_replace(
",",
".", $answer);
740 $this->gaps[$gap_index]->addItem(
new assAnswerCloze($answer, 0, $order));
754 if (array_key_exists($gap_index, $this->gaps)) {
755 return $this->gaps[$gap_index];
763 if (array_key_exists($gap_index, $this->gaps)) {
764 $this->gaps[$gap_index]->setGapSize(
$size);
780 if (array_key_exists($gap_index, $this->gaps)) {
781 $this->gaps[$gap_index]->setItemPoints($order,
$points);
795 if (array_key_exists($gap_index, $this->gaps)) {
796 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
800 $this->gaps[$gap_index]->getItemCount()
802 $this->gaps[$gap_index]->addItem($answer);
816 $this->gaps[
$index] = $gap;
831 if (array_key_exists($gap_index, $this->gaps)) {
832 $this->gaps[$gap_index]->setItemLowerBound($order, $bound);
848 if (array_key_exists($gap_index, $this->gaps)) {
849 $this->gaps[$gap_index]->setItemUpperBound($order, $bound);
863 $gaps_used_in_combination = array();
864 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
865 $points = $assClozeGapCombinationObj->getMaxPointsForCombination($this->
getId());
866 $gaps_used_in_combination = $assClozeGapCombinationObj->getGapsWhichAreUsedInCombination($this->
getId());
868 foreach ($this->gaps as $gap_index => $gap) {
869 if (!array_key_exists($gap_index, $gaps_used_in_combination)) {
872 foreach ($gap->getItems($this->getShuffler()) as $item) {
873 if ($item->getPoints() > $gap_max_points) {
874 $gap_max_points = $item->getPoints();
880 foreach ($gap->getItems($this->getShuffler()) as $item) {
881 if ($item->getPoints() > $srpoints) {
882 $srpoints = $item->getPoints();
888 foreach ($gap->getItems($this->getShuffler()) as $item) {
889 if ($item->getPoints() > $numpoints) {
890 $numpoints = $item->getPoints();
908 if ($this->
id <= 0) {
913 $this_id = $this->
getId();
917 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
921 if ((
int) $testObjId > 0) {
922 $clone->setObjId($testObjId);
939 if ($this->gap_combinations_exists) {
948 $clone->copyPageOfQuestion($this_id);
950 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
952 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
954 return $clone->getId();
964 if ($this->
getId() <= 0) {
969 $thisId = $this->
getId();
973 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
976 $clone->setObjId($target_questionpool_id);
983 if ($this->gap_combinations_exists) {
993 $clone->onCopy($thisObjId, $thisId, $clone->getObjId(), $clone->getId());
995 return $clone->getId();
1000 if ($this->
id <= 0) {
1005 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
1008 $sourceParentId = $this->
getObjId();
1014 $clone->setObjId($targetParentId);
1016 if ($targetQuestionTitle) {
1017 $clone->setTitle($targetQuestionTitle);
1022 if ($this->gap_combinations_exists) {
1027 $clone->copyPageOfQuestion($sourceQuestionId);
1029 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
1031 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
1039 $array = $assClozeGapCombinationObj->loadFromDb($orgID);
1040 $assClozeGapCombinationObj->importGapCombinationToDb($newID, $array);
1051 foreach ($this->
getGaps() as $gap_index => $gap) {
1053 foreach ($gap->getItemsRaw() as $item) {
1054 array_push($answers, str_replace(
",",
"\\,", $item->getAnswerText()));
1060 $output = str_replace(
"_gap]",
"gap]", $output);
1061 $this->cloze_text = $output;
1075 if (array_key_exists($gap_index, $this->gaps)) {
1076 if ($this->gaps[$gap_index]->getItemCount() == 1) {
1081 $this->gaps[$gap_index]->deleteItem($answer_index);
1097 if (array_key_exists($gap_index, $this->gaps)) {
1099 foreach ($this->
getGaps() as $replace_gap_index => $gap) {
1101 foreach ($gap->getItemsRaw() as $item) {
1102 array_push($answers, str_replace(
",",
"\\,", $item->getAnswerText()));
1104 if ($replace_gap_index == $gap_index) {
1110 $output = $this->
replaceFirstGap($output,
"[_gap]" . join(
",", $answers) .
"[/_gap]");
1114 $output = str_replace(
"_gap]",
"gap]", $output);
1115 $this->cloze_text = $output;
1116 unset($this->gaps[$gap_index]);
1117 $this->gaps = array_values($this->gaps);
1132 include_once
"./Services/Utilities/classes/class.ilStr.php";
1135 switch ($gaprating) {
1142 if (strcmp($a_original, $a_entered) == 0) {
1147 if (levenshtein($a_original, $a_entered) <= 1) {
1152 if (levenshtein($a_original, $a_entered) <= 2) {
1157 if (levenshtein($a_original, $a_entered) <= 3) {
1162 if (levenshtein($a_original, $a_entered) <= 4) {
1167 if (levenshtein($a_original, $a_entered) <= 5) {
1192 include_once
"./Services/Math/classes/class.EvalMath.php";
1194 $eval->suppress_errors =
true;
1197 if ($eval->e($a_entered) ===
false) {
1199 } elseif (($eval->e($lowerBound) !==
false) && ($eval->e($upperBound) !==
false)) {
1201 if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($upperBound))) {
1204 } elseif ($eval->e($lowerBound) !==
false) {
1205 if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($a_original))) {
1208 } elseif ($eval->e($upperBound) !==
false) {
1209 if (($eval->e($a_entered) >= $eval->e($a_original)) && ($eval->e($a_entered) <= $eval->e($upperBound))) {
1213 if ($eval->e($a_entered) == $eval->e($a_original)) {
1226 return preg_match(
"/^-?(\\d*)(,|\\.|\\/){0,1}(\\d*)$/", $value, $matches);
1241 $ilDB = $DIC[
'ilDB'];
1243 if (is_null(
$pass)) {
1248 $user_result = array();
1250 if (strcmp(
$data[
"value2"],
"") != 0) {
1251 $user_result[
$data[
"value1"]] = array(
1252 "gap_id" => $data[
"value1"],
1253 "value" => $data[
"value2"]
1258 ksort($user_result);
1260 if ($returndetails) {
1261 $detailed = array();
1271 if (is_numeric($submittedValue)) {
1275 if (preg_match(
'/^[-+]{0,1}\d+\/\d+$/', $submittedValue)) {
1285 $gap = $this->
getGap($gapIndex);
1302 $solutionSubmit = array();
1304 foreach ($submit as $key => $value) {
1305 if (preg_match(
"/^gap_(\d+)/", $key, $matches)) {
1307 if (strlen($value)) {
1308 $gap = $this->
getGap($matches[1]);
1309 if (is_object($gap)) {
1310 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1))) {
1311 if ($gap->getType() ==
CLOZE_NUMERIC && !is_numeric(str_replace(
",",
".", $value))) {
1314 $value = str_replace(
",",
".", $value);
1316 $solutionSubmit[trim($matches[1])] = $value;
1323 return $solutionSubmit;
1329 $solutionSubmit = array();
1331 foreach ($submit as $key => $value) {
1332 if (preg_match(
"/^gap_(\d+)/", $key, $matches)) {
1334 if (strlen($value)) {
1335 $gap = $this->
getGap($matches[1]);
1336 if (is_object($gap)) {
1337 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1))) {
1339 $value = str_replace(
",",
".", $value);
1341 $solutionSubmit[trim($matches[1])] = $value;
1348 return $solutionSubmit;
1367 $ilDB = $DIC[
'ilDB'];
1369 if (is_null(
$pass)) {
1370 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1374 $entered_values = 0;
1376 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use (&$entered_values, $active_id,
$pass, $authorized) {
1381 if (strlen($value)) {
1383 if (is_object($gap)) {
1384 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1))) {
1393 if ($entered_values) {
1394 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1399 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1416 return "assClozeTest";
1440 switch ($a_textgap_rating) {
1448 $this->textgap_rating = $a_textgap_rating;
1465 return ($this->identical_scoring) ? 1 : 0;
1477 $this->identical_scoring = ($a_identical_scoring) ? 1 : 0;
1488 return "qpl_qst_cloze";
1499 return array(
"qpl_a_cloze",
'qpl_a_cloze_combi_res');
1510 $this->fixedTextLength = $a_text_len;
1535 $gap_max_points = 0;
1536 if (array_key_exists($gap_index, $this->gaps)) {
1537 $gap = &$this->gaps[$gap_index];
1538 foreach ($gap->getItems($this->getShuffler()) as $answer) {
1539 if ($answer->getPoints() > $gap_max_points) {
1540 $gap_max_points = $answer->getPoints();
1554 return parent::getRTETextWithMediaObjects() . $this->
getClozeText();
1568 $this->gap_combinations_exists = $value;
1573 $this->gap_combinations = $value;
1581 parent::setExportDetailsXLS($worksheet, $startrow, $active_id,
$pass);
1585 foreach ($this->
getGaps() as $gap_index => $gap) {
1586 $worksheet->setCell($startrow +
$i, 0, $this->lng->txt(
"gap") .
" $i");
1587 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow +
$i));
1589 foreach ($solution as $solutionvalue) {
1590 if ($gap_index == $solutionvalue[
"value1"]) {
1591 $string_escaping_org_value = $worksheet->getStringEscaping();
1593 $worksheet->setStringEscaping(
false);
1595 switch ($gap->getType()) {
1597 $worksheet->setCell($startrow +
$i, 1, $gap->getItem($solutionvalue[
"value2"])->getAnswertext());
1601 $worksheet->setCell($startrow +
$i, 1, $solutionvalue[
"value2"]);
1605 $worksheet->setStringEscaping($string_escaping_org_value);
1612 return $startrow +
$i + 1;
1631 include_once(
"./Services/RTE/classes/class.ilRTE.php");
1641 'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
false)),
1642 'allcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
true))
1646 foreach ($this->
getGaps() as $key => $gap) {
1648 foreach ($gap->getItems($this->getShuffler()) as $item) {
1650 $jitem[
'points'] = $item->getPoints();
1652 $jitem[
'order'] = $item->getOrder();
1654 $jitem[
'lowerbound'] = $item->getLowerBound();
1655 $jitem[
'upperbound'] = $item->getUpperBound();
1657 $jitem[
'value'] = trim($jitem[
'value']);
1659 array_push($items, $jitem);
1663 $jgap[
'size'] = $gap->getGapSize();
1666 $jgap[
'shuffle'] = $gap->getShuffle();
1667 $jgap[
'type'] = $gap->getType();
1668 $jgap[
'item'] = $items;
1670 array_push($gaps, $jgap);
1688 require_once
"./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1719 $ilDB = $DIC[
'ilDB'];
1722 $maxStep = $this->lookupMaxStep($active_id,
$pass);
1724 if ($maxStep !== null) {
1727 SELECT sol.value1+1 as val, sol.value2, cloze.cloze_type 1728 FROM tst_solutions sol 1729 INNER JOIN qpl_a_cloze cloze ON cloze.gap_id = value1 AND cloze.question_fi = sol.question_fi 1730 WHERE sol.active_fi = %s AND sol.pass = %s AND sol.question_fi = %s AND sol.step = %s 1731 GROUP BY sol.solution_id, sol.value1+1, sol.value2, cloze.cloze_type 1733 array(
"integer",
"integer",
"integer",
"integer"),
1734 array($active_id,
$pass, $this->
getId(), $maxStep)
1739 SELECT sol.value1+1 as val, sol.value2, cloze.cloze_type 1740 FROM tst_solutions sol 1741 INNER JOIN qpl_a_cloze cloze ON cloze.gap_id = value1 AND cloze.question_fi = sol.question_fi 1742 WHERE sol.active_fi = %s AND sol.pass = %s AND sol.question_fi = %s 1743 GROUP BY sol.solution_id, sol.value1+1, sol.value2, cloze.cloze_type 1745 array(
"integer",
"integer",
"integer"),
1751 if ($row[
"cloze_type"] == 1) {
1754 $result->addKeyValue($row[
"val"], $row[
"value2"]);
1788 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
1789 $combinations_for_question = $assClozeGapCombinationObj->getCleanCombinationArray($this->
getId());
1790 $gap_answers = array();
1791 $gap_used_in_combination = array();
1792 foreach ($user_result as $user_result_build_list) {
1793 if (is_array($user_result_build_list)) {
1794 $gap_answers[$user_result_build_list[
'gap_id']] = $user_result_build_list[
'value'];
1798 foreach ($combinations_for_question as $combination) {
1799 foreach ($combination as $row_key => $row_answers) {
1800 $combination_fulfilled =
true;
1801 $points_for_combination = $row_answers[
'points'];
1802 foreach ($row_answers as $gap_key => $combination_gap_answer) {
1803 if ($gap_key !==
'points') {
1804 $gap_used_in_combination[$gap_key] = $gap_key;
1806 if ($combination_fulfilled && array_key_exists($gap_key, $gap_answers)) {
1807 switch ($combination_gap_answer[
'type']) {
1809 $is_text_gap_correct = $this->
getTextgapPoints($gap_answers[$gap_key], $combination_gap_answer[
'answer'], 1);
1810 if ($is_text_gap_correct != 1) {
1811 $combination_fulfilled =
false;
1815 $answer = $this->gaps[$gap_key]->getItem($gap_answers[$gap_key]);
1816 $answertext = $answer->getAnswertext();
1817 if ($answertext != $combination_gap_answer[
'answer']) {
1818 $combination_fulfilled =
false;
1822 $answer = $this->gaps[$gap_key]->getItem(0);
1823 if ($combination_gap_answer[
'answer'] !=
'out_of_bound') {
1824 $is_numeric_gap_correct = $this->
getNumericgapPoints($answer->getAnswertext(), $gap_answers[$gap_key], 1, $answer->getLowerBound(), $answer->getUpperBound());
1825 if ($is_numeric_gap_correct != 1) {
1826 $combination_fulfilled =
false;
1829 $wrong_is_the_new_right = $this->
getNumericgapPoints($answer->getAnswertext(), $gap_answers[$gap_key], 1, $answer->getLowerBound(), $answer->getUpperBound());
1830 if ($wrong_is_the_new_right == 1) {
1831 $combination_fulfilled =
false;
1837 if ($gap_key !==
'points') {
1838 $combination_fulfilled =
false;
1842 if ($combination_fulfilled) {
1843 $points += $points_for_combination;
1848 return array(
$points, $gap_used_in_combination);
1857 if ($detailed === null) {
1858 $detailed = array();
1862 $combinations[1] = array();
1863 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
1868 $solution_values_text = array();
1869 $solution_values_select = array();
1870 $solution_values_numeric = array();
1871 foreach ($user_result as $gap_id => $value) {
1872 if (is_string($value)) {
1873 $value = array(
"value" => $value);
1876 if (array_key_exists($gap_id, $this->gaps) && !array_key_exists($gap_id, $combinations[1])) {
1877 switch ($this->gaps[$gap_id]->getType()) {
1880 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1881 $answer = $this->gaps[$gap_id]->getItem($order);
1882 $gotpoints = $this->
getTextgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints());
1883 if ($gotpoints > $gappoints) {
1884 $gappoints = $gotpoints;
1889 if ((in_array($value[
"value"], $solution_values_text)) && ($gappoints > 0)) {
1894 $detailed[$gap_id] = array(
"points" => $gappoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ?
true :
false,
"positive" => ($gappoints > 0) ?
true :
false);
1895 array_push($solution_values_text, $value[
"value"]);
1899 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1900 $answer = $this->gaps[$gap_id]->getItem($order);
1901 $gotpoints = $this->
getNumericgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints(), $answer->getLowerBound(), $answer->getUpperBound());
1902 if ($gotpoints > $gappoints) {
1903 $gappoints = $gotpoints;
1908 include_once
"./Services/Math/classes/class.EvalMath.php";
1910 $eval->suppress_errors =
true;
1911 $found_value =
false;
1912 foreach ($solution_values_numeric as $solval) {
1913 if ($eval->e($solval) == $eval->e($value[
"value"])) {
1914 $found_value =
true;
1917 if ($found_value && ($gappoints > 0)) {
1922 $detailed[$gap_id] = array(
"points" => $gappoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ?
true :
false,
"positive" => ($gappoints > 0) ?
true :
false);
1923 array_push($solution_values_numeric, $value[
"value"]);
1926 if ($value[
"value"] >= 0) {
1927 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1928 $answer = $this->gaps[$gap_id]->getItem($order);
1929 if ($value[
"value"] == $answer->getOrder()) {
1930 $answerpoints = $answer->getPoints();
1933 if ((in_array($answer->getAnswertext(), $solution_values_select)) && ($answerpoints > 0)) {
1938 $detailed[$gap_id] = array(
"points" => $answerpoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $answerpoints) ?
true :
false,
"positive" => ($answerpoints > 0) ?
true :
false);
1939 array_push($solution_values_select, $answer->getAnswertext());
1953 $userSolution = array();
1956 $userSolution[$key] = array(
'gap_id' => $key,
'value' => $val);
1969 foreach ($userSolution as $value1 => $value2) {
1970 if ($value1 == $gapIndex) {
1971 $answerValue = $value2;
1976 return $answerValue;
1981 $gap = $this->
getGap($qIndex);
1988 if ($item->getAnswertext() == $answerOptionValue) {
1998 $gap = $this->
getGap($qIndex);
2001 $item->setOrder($gap->getItemCount());
2003 $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.
static getInstance($identifier)
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.
__construct(Container $dic, ilPlugin $plugin)
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...
setLifecycle(ilAssQuestionLifecycle $lifecycle)
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)
static getDraftInstance()
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