4require_once
'./Modules/TestQuestionPool/classes/class.assQuestion.php';
5require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
6require_once
'./Modules/TestQuestionPool/classes/class.assClozeGapCombination.php';
7require_once
'./Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
8require_once
'./Modules/TestQuestionPool/interfaces/interface.ilObjAnswerScoringAdjustable.php';
9require_once
'./Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
10require_once
'./Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
11require_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);
202 $this->
setId($question_id);
224 include_once(
"./Services/RTE/classes/class.ilRTE.php");
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
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()),
374 foreach ($gap->getItems($this->getShuffler()) as $item) {
376 $next_id =
$ilDB->nextId(
'qpl_a_cloze');
377 switch ($gap->getType()) {
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()
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"
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);
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;
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";
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);
An exception for terminatinating execution or to throw for unit testing.
Class for cloze question numeric answers.
Class for cloze question gaps.
clearGapAnswers()
Removes all answers from the gaps.
getEndTag()
Returns the end tag of a cloze gap.
addGapAnswer($gap_index, $order, $answer)
Sets the answer text of a gap with a given index.
isComplete()
Returns TRUE, if a cloze test is complete for use.
setGapShuffle($gap_index=0, $shuffle=1)
Sets the shuffle state of a gap with a given index.
getClozeText()
Returns the cloze text.
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...
isValidNumericSubmitValue($submittedValue)
setGapAnswerPoints($gap_index, $order, $points)
Sets the points of a gap with a given index and an answer with a given order.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
addAnswerOptionValue($qIndex, $answerOptionValue, $points)
setFeedbackMode($feedbackMode)
copyObject($target_questionpool_id, $title="")
Copies an assClozeTest object.
setClozeTextValue($cloze_text="")
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
addGapAtIndex($gap, $index)
Adds a ClozeGap object at a given index.
setTextgapRating($a_textgap_rating)
Sets the rating option for text gaps.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
getSolutionSubmitValidation()
setGapSize($gap_index, $order, $size)
setGapAnswerUpperBound($gap_index, $order, $bound)
Sets the upper bound of a gap with a given index and an answer with a given order.
createGapsFromQuestiontext()
Create gap entries by parsing the question text.
getAnswerTableName()
Returns the name of the answer table in the database.
setGapCombinations($value)
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
updateClozeTextFromGaps()
Updates the gap parameters in the cloze text from the form input.
flushGaps()
Deletes all gaps without changing the cloze text.
getStartTag()
Returns the start tag of a cloze gap.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
saveAnswerSpecificDataToDb()
Save all gaps to the database.
getFixedTextLength()
Gets the fixed text length for all text fields in the cloze question.
addGapText($gap_index)
Adds a new answer text value to a text gap with a given index.
setIdenticalScoring($a_identical_scoring)
Sets the identical scoring option for cloze questions.
saveToDb($original_id="")
Saves a assClozeTest object to a database.
getGaps()
Returns the array of gaps.
getOperators($expression)
Get all available operations for a specific question.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assClozeTest constructor
getQuestionType()
Returns the question type of the question.
checkForValidFormula($value)
getTextgapRating()
Returns the rating option for text gaps.
deleteGap($gap_index)
Deletes a gap with a given index.
getGap($gap_index=0)
Returns the gap at a given index.
setGapType($gap_index, $gap_type)
Set the type of a gap with a given index.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{Creates an Excel worksheet for the detailed cumulated results of this question.object}
calculateReachedPoints($active_id, $pass=null, $authorized=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
copyGapCombination($orgID, $newID)
calculateReachedPointsForSolution($user_result, &$detailed=null)
getGapCombinationsExists()
getExpressionTypes()
Get all available expression types for a specific question.
isAddableAnswerOptionValue($qIndex, $answerOptionValue)
saveClozeTextGapRecordToDb($next_id, $key, $item, $gap)
Saves a gap-item record.
getGapCount()
Returns the number of gaps.
setGapCombinationsExists($value)
saveClozeGapItemsToDb($gap, $key)
Save all items belonging to one cloze gap to the db.
setGapAnswerLowerBound($gap_index, $order, $bound)
Sets the lower bound of a gap with a given index and an answer with a given order.
setEndTag($end_tag="[/gap]")
Sets the end tag of a cloze gap.
fetchAnswerValueForGap($userSolution, $gapIndex)
getMaximumGapPoints($gap_index)
Returns the maximum points for a gap.
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
saveAdditionalQuestionDataToDb()
Saves the data for the additional data table.
deleteAnswerText($gap_index, $answer_index)
Deletes the answer text of a gap with a given index and an answer with a given order.
saveClozeSelectGapRecordToDb($next_id, $key, $item, $gap)
Saves a gap-item record.
fetchSolutionSubmit($submit)
toJSON()
Returns a JSON representation of the question.
loadFromDb($question_id)
Loads a assClozeTest object from a database.
setFixedTextLength($a_text_len)
Sets a fixed text length for all text fields in the cloze question.
calculateCombinationResult($user_result)
setClozeText($cloze_text="")
Evaluates the text gap solutions from the cloze text.
saveClozeNumericGapRecordToDb($next_id, $key, $item, $gap)
Saves a gap-item record.
replaceFirstGap($gaptext, $content)
Replace the first gap in a string without treating backreferences.
setStartTag($start_tag="[gap]")
Sets the start tag of a cloze gap.
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...
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assClozeTest.
cleanQuestiontext($text)
Cleans cloze question text to remove attributes or tags from older ILIAS versions.
getIdenticalScoring()
Returns the identical scoring status of the question.
Abstract basic class which is to be extended by the concrete assessment question type classes.
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass.
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
setId($id=-1)
Sets the id of the assQuestion object.
setOriginalId($original_id)
setObjId($obj_id=0)
Set the object id of the container object.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
saveQuestionDataToDb($original_id="")
getId()
Gets the id of the assQuestion object.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
getObjId()
Get the object id of the container object.
setTitle($title="")
Sets the title string of the assQuestion object.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second.
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
removeCurrentSolution($active_id, $pass, $authorized=true)
setAuthor($author="")
Sets the authors name of the assQuestion object.
prepareTextareaOutput($txt_output, $prepare_for_latex_output=false, $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output in tests.
getShuffle()
Gets the shuffle flag.
setLifecycle(ilAssQuestionLifecycle $lifecycle)
getTitle()
Gets the title string of the assQuestion object.
setPoints($a_points)
Sets the maximum available points for the question.
setComment($comment="")
Sets the comment string of the assQuestion object.
getAuthor()
Gets the authors name of the assQuestion object.
setNrOfTries($a_nr_of_tries)
getQuestion()
Gets the question string of the question object.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
setQuestion($question="")
Sets the question string of the question object.
ensureNonNegativePoints($points)
const FB_MODE_GAP_QUESTION
constants for different feedback modes (per gap or per gap-answers/options)
static getDraftInstance()
static getInstance($identifier)
getParticipantsSolution()
static _getLogLanguage()
retrieve the log language for assessment logging
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static getOperatorsByExpression($expression)
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...
static strToLower($a_string)
Class ilUserQuestionResult.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
const TEXTGAP_RATING_LEVENSHTEIN5
const TEXTGAP_RATING_LEVENSHTEIN4
const TEXTGAP_RATING_LEVENSHTEIN3
const TEXTGAP_RATING_CASESENSITIVE
const TEXTGAP_RATING_LEVENSHTEIN2
const TEXTGAP_RATING_CASEINSENSITIVE
const TEXTGAP_RATING_LEVENSHTEIN1
const CLOZE_TEXT
Cloze question constants.
Class iQuestionCondition.
const PercentageResultExpression
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
const StringResultExpression
const NumericResultExpression
const EmptyAnswerExpression
const NumberOfResultExpression
migrateToLmContent($content)
Interface ilObjAnswerScoringAdjustable.
Interface ilObjQuestionScoringAdjustable.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc