21 require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
134 $this->start_tag =
"[gap]";
135 $this->end_tag =
"[/gap]";
138 $this->fixedTextLength =
"";
139 $this->identical_scoring = 1;
140 $this->gap_combinations_exists =
false;
141 $this->gap_combinations = [];
142 $this->randomGroup = $DIC->refinery()->random();
172 $text = str_replace(
'$',
'GAPMASKEDDOLLAR', $text);
173 $text = preg_replace(
"/\[gap[^\]]*?\]/",
"[gap]", $text);
174 $text = preg_replace(
"/<gap([^>]*?)>/",
"[gap]", $text);
175 $text = str_replace(
"</gap>",
"[/gap]", $text);
176 $text = str_replace(
'GAPMASKEDDOLLAR',
'$', $text);
190 $content = str_replace(
'$',
'GAPMASKEDDOLLAR', $content);
191 $output = preg_replace(
"/\[gap\].*?\[\/gap\]/", $content, $gaptext, 1);
192 $output = str_replace(
'GAPMASKEDDOLLAR',
'$', $output);
206 $ilDB = $DIC[
'ilDB'];
207 $result =
$ilDB->queryF(
212 if ($result->numRows() == 1) {
214 $this->
setId($question_id);
218 $this->
setComment((
string) $data[
"description"]);
236 include_once(
"./Services/RTE/classes/class.ilRTE.php");
247 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
248 include_once
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
249 $result =
$ilDB->queryF(
250 "SELECT * FROM qpl_a_cloze WHERE question_fi = %s ORDER BY gap_id, aorder ASC",
254 if ($result->numRows() > 0) {
256 while ($data =
$ilDB->fetchAssoc($result)) {
257 switch ($data[
"cloze_type"]) {
259 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
267 $this->gaps[$data[
"gap_id"]]->setGapSize((
int) $data[
'gap_size']);
269 $this->gaps[$data[
"gap_id"]]->addItem($answer);
272 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
274 $this->gaps[$data[
"gap_id"]]->setShuffle($data[
"shuffle"]);
281 $this->gaps[$data[
"gap_id"]]->addItem($answer);
284 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
292 $this->gaps[$data[
"gap_id"]]->setGapSize((
int) $data[
'gap_size']);
293 $answer->setLowerBound($data[
"lowerlimit"]);
294 $answer->setUpperBound($data[
"upperlimit"]);
295 $this->gaps[$data[
"gap_id"]]->addItem($answer);
302 $check_for_gap_combinations = $assClozeGapCombinationObj->loadFromDb($question_id);
303 if (count($check_for_gap_combinations) != 0) {
307 parent::loadFromDb($question_id);
310 #region Save question to db 340 $ilDB = $DIC[
'ilDB'];
343 "DELETE FROM qpl_a_cloze WHERE question_fi = %s",
345 array( $this->
getId() )
348 foreach ($this->gaps as
$key => $gap) {
363 $DIC->database()->manipulateF(
366 array( $this->
getId() )
370 'question_fi' => array(
'integer', $this->
getId()),
388 $ilDB = $DIC[
'ilDB'];
389 foreach ($gap->getItems($this->getShuffler()) as $item) {
391 $next_id =
$ilDB->nextId(
'qpl_a_cloze');
392 switch ($gap->getType()) {
417 $ilDB = $DIC[
'ilDB'];
419 "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)",
434 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
438 (
int) $gap->getGapSize()
454 $ilDB = $DIC[
'ilDB'];
456 "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)",
471 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
475 ($gap->getShuffle()) ?
"1" :
"0" 491 $ilDB = $DIC[
'ilDB'];
493 include_once
"./Services/Math/classes/class.EvalMath.php";
495 $eval->suppress_errors =
true;
497 "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)",
514 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
518 ($eval->e($item->getLowerBound() !==
false) && strlen(
519 $item->getLowerBound()
520 ) > 0) ? $item->getLowerBound() : $item->getAnswertext(),
521 ($eval->e($item->getUpperBound() !==
false) && strlen(
522 $item->getUpperBound()
523 ) > 0) ? $item->getUpperBound() : $item->getAnswertext(),
524 (
int) $gap->getGapSize()
531 #endregion Save question to db 596 preg_match_all(
'/\[gap\].*?\[\/gap\]/', $this->
getClozeText(), $gaps);
597 $string_with_replaced_gaps = str_replace($gaps[0],
'######GAP######', $this->
getClozeText());
599 $string_with_replaced_gaps
601 $cleaned_text_with_gaps = preg_replace_callback(
'/######GAP######/',
function ($match) use (&$gaps) {
602 return array_shift($gaps[0]);
606 || !(
new ilSetting(
'advanced_editing'))->
get(
'advanced_editing_javascript_editor') ===
'tinymce') {
607 $cleaned_text_with_gaps = nl2br($cleaned_text_with_gaps);
685 include_once
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
686 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
687 $search_pattern =
"|\[gap\](.*?)\[/gap\]|i";
688 preg_match_all($search_pattern, $this->
getClozeText(), $found);
690 if (count($found[0])) {
691 foreach ($found[1] as $gap_index => $answers) {
694 $textparams = preg_split(
"/(?<!\\\\),/", $answers);
695 foreach ($textparams as
$key => $value) {
697 $gap->addItem($answer);
699 $this->gaps[$gap_index] = $gap;
711 if (array_key_exists($gap_index, $this->gaps)) {
712 $this->gaps[$gap_index]->setType($gap_type);
727 if (array_key_exists($gap_index, $this->gaps)) {
728 $this->gaps[$gap_index]->setShuffle(
$shuffle);
740 foreach ($this->gaps as $gap_index => $gap) {
741 $this->gaps[$gap_index]->clearItems();
754 if (is_array($this->gaps)) {
755 return count($this->gaps);
773 if (array_key_exists($gap_index, $this->gaps)) {
776 $answer = str_replace(
",",
".", $answer);
778 $this->gaps[$gap_index]->addItem(
new assAnswerCloze(trim($answer), 0, $order));
790 if (array_key_exists($gap_index, $this->gaps)) {
791 return $this->gaps[$gap_index];
799 if (array_key_exists($gap_index, $this->gaps)) {
800 $this->gaps[$gap_index]->setGapSize((
int) $size);
816 if (array_key_exists($gap_index, $this->gaps)) {
817 $this->gaps[$gap_index]->setItemPoints($order,
$points);
831 if (array_key_exists($gap_index, $this->gaps)) {
832 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
836 $this->gaps[$gap_index]->getItemCount()
838 $this->gaps[$gap_index]->addItem($answer);
852 $this->gaps[
$index] = $gap;
867 if (array_key_exists($gap_index, $this->gaps)) {
868 $this->gaps[$gap_index]->setItemLowerBound($order, $bound);
884 if (array_key_exists($gap_index, $this->gaps)) {
885 $this->gaps[$gap_index]->setItemUpperBound($order, $bound);
899 $gaps_used_in_combination = [];
900 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
901 $points = $assClozeGapCombinationObj->getMaxPointsForCombination($this->
getId());
902 $gaps_used_in_combination = $assClozeGapCombinationObj->getGapsWhichAreUsedInCombination($this->
getId());
904 foreach ($this->gaps as $gap_index => $gap) {
905 if (!array_key_exists($gap_index, $gaps_used_in_combination)) {
908 foreach ($gap->getItems($this->getShuffler()) as $item) {
909 if ($item->getPoints() > $gap_max_points) {
910 $gap_max_points = $item->getPoints();
916 foreach ($gap->getItems($this->getShuffler()) as $item) {
917 if ($item->getPoints() > $srpoints) {
918 $srpoints = $item->getPoints();
924 foreach ($gap->getItems($this->getShuffler()) as $item) {
925 if ($item->getPoints() > $numpoints) {
926 $numpoints = $item->getPoints();
944 if ($this->
id <= 0) {
949 $this_id = $this->
getId();
953 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
957 if ((
int) $testObjId > 0) {
958 $clone->setObjId($testObjId);
975 if ($this->gap_combinations_exists) {
984 $clone->copyPageOfQuestion($this_id);
986 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
988 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
990 return $clone->getId();
1000 if ($this->
getId() <= 0) {
1001 throw new RuntimeException(
'The question has not been saved. It cannot be duplicated');
1004 $thisId = $this->
getId();
1008 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
1011 $clone->setObjId($target_questionpool_id);
1013 $clone->setTitle(
$title);
1018 if ($this->gap_combinations_exists) {
1028 $clone->onCopy($thisObjId, $thisId, $clone->getObjId(), $clone->getId());
1030 return $clone->getId();
1035 if ($this->
getId() <= 0) {
1036 throw new RuntimeException(
'The question has not been saved. It cannot be duplicated');
1039 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
1042 $sourceParentId = $this->
getObjId();
1048 $clone->setObjId($targetParentId);
1050 if ($targetQuestionTitle) {
1051 $clone->setTitle($targetQuestionTitle);
1056 if ($this->gap_combinations_exists) {
1061 $clone->copyPageOfQuestion($sourceQuestionId);
1063 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
1065 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
1073 $array = $assClozeGapCombinationObj->loadFromDb($orgID);
1074 $assClozeGapCombinationObj->importGapCombinationToDb($newID, $array);
1085 foreach ($this->
getGaps() as $gap_index => $gap) {
1087 foreach ($gap->getItemsRaw() as $item) {
1088 array_push($answers, str_replace([
',',
'['], [
"\\,",
'[ '], $item->getAnswerText()));
1094 $output = str_replace(
"_gap]",
"gap]", $output);
1095 $this->cloze_text = $output;
1109 if (array_key_exists($gap_index, $this->gaps)) {
1110 if ($this->gaps[$gap_index]->getItemCount() == 1) {
1115 $this->gaps[$gap_index]->deleteItem($answer_index);
1131 if (array_key_exists($gap_index, $this->gaps)) {
1133 foreach ($this->
getGaps() as $replace_gap_index => $gap) {
1135 foreach ($gap->getItemsRaw() as $item) {
1136 array_push($answers, str_replace(
",",
"\\,", $item->getAnswerText()));
1138 if ($replace_gap_index == $gap_index) {
1144 $output = $this->
replaceFirstGap($output,
"[_gap]" . join(
",", $answers) .
"[/_gap]");
1148 $output = str_replace(
"_gap]",
"gap]", $output);
1149 $this->cloze_text = $output;
1150 unset($this->gaps[$gap_index]);
1151 $this->gaps = array_values($this->gaps);
1166 include_once
"./Services/Utilities/classes/class.ilStr.php";
1172 switch ($gaprating) {
1175 $result = $max_points;
1179 if (strcmp($a_original, $a_entered) == 0) {
1180 $result = $max_points;
1184 $transformation =
$refinery->string()->levenshtein()->standard($a_original, 1);
1187 $transformation =
$refinery->string()->levenshtein()->standard($a_original, 2);
1190 $transformation =
$refinery->string()->levenshtein()->standard($a_original, 3);
1193 $transformation =
$refinery->string()->levenshtein()->standard($a_original, 4);
1196 $transformation =
$refinery->string()->levenshtein()->standard($a_original, 5);
1201 if (isset($transformation) && $transformation->transform($a_entered) >= 0) {
1202 $result = $max_points;
1219 include_once
"./Services/Math/classes/class.EvalMath.php";
1221 $eval->suppress_errors =
true;
1224 if ($eval->e($a_entered) ===
false) {
1226 } elseif (($eval->e($lowerBound) !==
false) && ($eval->e($upperBound) !==
false)) {
1227 if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($upperBound))) {
1228 $result = $max_points;
1230 } elseif ($eval->e($lowerBound) !==
false) {
1231 if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($a_original))) {
1232 $result = $max_points;
1234 } elseif ($eval->e($upperBound) !==
false) {
1235 if (($eval->e($a_entered) >= $eval->e($a_original)) && ($eval->e($a_entered) <= $eval->e($upperBound))) {
1236 $result = $max_points;
1238 } elseif ($eval->e($a_entered) == $eval->e($a_original)) {
1239 $result = $max_points;
1250 return preg_match(
"/^-?(\\d*)(,|\\.|\\/){0,1}(\\d*)$/", $value, $matches);
1265 if (is_null($pass)) {
1272 if (strcmp(
$data[
"value2"],
"") != 0) {
1273 $user_result[
$data[
"value1"]] = array(
1274 "gap_id" => $data[
"value1"],
1275 "value" => $data[
"value2"]
1280 ksort($user_result);
1282 if ($returndetails) {
1293 if (is_numeric($submittedValue)) {
1297 if (preg_match(
'/^[-+]{0,1}\d+\/\d+$/', $submittedValue)) {
1307 $gap = $this->
getGap($gapIndex);
1314 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
"err_no_numeric_value"),
true);
1324 $solutionSubmit = [];
1325 $post_wrapper = $this->dic->http()->wrapper()->post();
1327 if (!$post_wrapper->has(
"gap_$index")) {
1330 $value = trim($post_wrapper->retrieve(
1332 $this->dic->refinery()->kindlyTo()->string()
1334 if ($value ===
'') {
1341 && !is_numeric(str_replace(
",",
".", $value))
1345 $value = str_replace(
",",
".", $value);
1347 $solutionSubmit[
$index] = $value;
1351 return $solutionSubmit;
1357 $solutionSubmit = [];
1359 foreach ($submit as
$key => $value) {
1360 if (preg_match(
"/^gap_(\d+)/",
$key, $matches)) {
1361 if ($value !== null && $value !==
'') {
1362 $gap = $this->
getGap($matches[1]);
1363 if (is_object($gap)) {
1364 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1))) {
1366 $value = str_replace(
",",
".", $value);
1368 $solutionSubmit[trim($matches[1])] = $value;
1375 return $solutionSubmit;
1393 if (is_null($pass)) {
1394 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1398 $entered_values = 0;
1400 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use (&$entered_values, $active_id, $pass, $authorized) {
1404 if ($value !== null && $value !==
'') {
1406 if (is_object($gap)) {
1407 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1))) {
1416 if ($entered_values) {
1417 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1421 "log_user_entered_values",
1423 ), $active_id, $this->
getId());
1426 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1430 "log_user_not_entered_values",
1432 ), $active_id, $this->
getId());
1447 return "assClozeTest";
1471 switch ($a_textgap_rating) {
1479 $this->textgap_rating = $a_textgap_rating;
1496 return ($this->identical_scoring) ? 1 : 0;
1508 $this->identical_scoring = ($a_identical_scoring) ? 1 : 0;
1519 return "qpl_qst_cloze";
1524 return array(
"qpl_a_cloze",
'qpl_a_cloze_combi_res');
1535 $this->fixedTextLength = $a_text_len;
1560 $gap_max_points = 0;
1561 if (array_key_exists($gap_index, $this->gaps)) {
1562 $gap = &$this->gaps[$gap_index];
1563 foreach ($gap->getItems($this->getShuffler()) as $answer) {
1564 if ($answer->getPoints() > $gap_max_points) {
1565 $gap_max_points = $answer->getPoints();
1579 return parent::getRTETextWithMediaObjects() . $this->
getClozeText();
1593 $this->gap_combinations_exists = $value;
1598 $this->gap_combinations = $value;
1606 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1610 foreach ($this->
getGaps() as $gap_index => $gap) {
1611 $worksheet->
setCell($startrow +
$i, 0, $this->
lng->txt(
"gap") .
" $i");
1614 foreach ($solution as $solutionvalue) {
1615 if ($gap_index == $solutionvalue[
"value1"]) {
1620 switch ($gap->getType()) {
1622 $worksheet->
setCell($startrow +
$i, 2, $gap->getItem($solutionvalue[
"value2"])->getAnswertext());
1626 $worksheet->
setCell($startrow +
$i, 2, $solutionvalue[
"value2"]);
1637 return $startrow +
$i + 1;
1656 include_once(
"./Services/RTE/classes/class.ilRTE.php");
1658 $result[
'id'] = $this->
getId();
1665 $result[
'feedback'] = array(
1666 'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
false)),
1667 'allcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
true))
1673 foreach ($gap->getItems($this->getShuffler()) as $item) {
1675 $jitem[
'points'] = $item->getPoints();
1677 $jitem[
'order'] = $item->getOrder();
1679 $jitem[
'lowerbound'] = $item->getLowerBound();
1680 $jitem[
'upperbound'] = $item->getUpperBound();
1682 $jitem[
'value'] = trim($jitem[
'value']);
1684 array_push($items, $jitem);
1688 $jgap[
'size'] = $gap->getGapSize();
1691 $jgap[
'shuffle'] = $gap->getShuffle();
1692 $jgap[
'type'] = $gap->getType();
1693 $jgap[
'item'] = $items;
1695 array_push($gaps, $jgap);
1697 $result[
'gaps'] =
$gaps;
1699 $result[
'mobs'] =
$mobs;
1700 return json_encode($result);
1743 $ilDB = $DIC[
'ilDB'];
1748 if ($maxStep !== null) {
1751 SELECT sol.value1+1 as val, sol.value2, cloze.cloze_type 1752 FROM tst_solutions sol 1753 INNER JOIN qpl_a_cloze cloze ON cloze.gap_id = value1 AND cloze.question_fi = sol.question_fi 1754 WHERE sol.active_fi = %s AND sol.pass = %s AND sol.question_fi = %s AND sol.step = %s 1755 GROUP BY sol.solution_id, sol.value1+1, sol.value2, cloze.cloze_type 1757 array(
"integer",
"integer",
"integer",
"integer"),
1758 array($active_id, $pass, $this->
getId(), $maxStep)
1763 SELECT sol.value1+1 as val, sol.value2, cloze.cloze_type 1764 FROM tst_solutions sol 1765 INNER JOIN qpl_a_cloze cloze ON cloze.gap_id = value1 AND cloze.question_fi = sol.question_fi 1766 WHERE sol.active_fi = %s AND sol.pass = %s AND sol.question_fi = %s 1767 GROUP BY sol.solution_id, sol.value1+1, sol.value2, cloze.cloze_type 1769 array(
"integer",
"integer",
"integer"),
1770 array($active_id, $pass, $this->
getId())
1775 if ($row[
"cloze_type"] == 1) {
1778 $result->addKeyValue($row[
"val"], $row[
"value2"]);
1784 $result->setReachedPercentage((
$points / $max_points) * 100);
1811 $gap_used_in_combination = [];
1812 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
1813 $combinations_for_question = $assClozeGapCombinationObj->getCleanCombinationArray($this->
getId());
1816 foreach ($user_result as $user_result_build_list) {
1817 if (is_array($user_result_build_list)) {
1818 $gap_answers[$user_result_build_list[
'gap_id']] = $user_result_build_list[
'value'];
1822 foreach ($combinations_for_question as $combination) {
1823 foreach ($combination as $row_key => $row_answers) {
1824 $combination_fulfilled =
true;
1825 $points_for_combination = $row_answers[
'points'];
1826 foreach ($row_answers as $gap_key => $combination_gap_answer) {
1827 if ($gap_key !==
'points') {
1828 $gap_used_in_combination[$gap_key] = $gap_key;
1830 if ($combination_fulfilled && array_key_exists($gap_key, $gap_answers)) {
1831 switch ($combination_gap_answer[
'type']) {
1833 $is_text_gap_correct = $this->
getTextgapPoints($gap_answers[$gap_key], $combination_gap_answer[
'answer'], 1);
1834 if ($is_text_gap_correct != 1) {
1835 $combination_fulfilled =
false;
1839 $answer = $this->gaps[$gap_key]->getItem($gap_answers[$gap_key]);
1841 if ($answer !== null) {
1842 $answertext = $answer->getAnswertext();
1845 if ($answertext != $combination_gap_answer[
'answer']) {
1846 $combination_fulfilled =
false;
1850 $answer = $this->gaps[$gap_key]->getItem(0);
1851 if ($combination_gap_answer[
'answer'] !=
'out_of_bound') {
1852 $is_numeric_gap_correct = $this->
getNumericgapPoints($answer->getAnswertext(), $gap_answers[$gap_key], 1, $answer->getLowerBound(), $answer->getUpperBound());
1853 if ($is_numeric_gap_correct != 1) {
1854 $combination_fulfilled =
false;
1857 $wrong_is_the_new_right = $this->
getNumericgapPoints($answer->getAnswertext(), $gap_answers[$gap_key], 1, $answer->getLowerBound(), $answer->getUpperBound());
1858 if ($wrong_is_the_new_right == 1) {
1859 $combination_fulfilled =
false;
1865 if ($gap_key !==
'points') {
1866 $combination_fulfilled =
false;
1870 if ($combination_fulfilled) {
1871 $points += $points_for_combination;
1876 return array(
$points, $gap_used_in_combination);
1884 if ($detailed === null) {
1891 $combinations[1] = [];
1892 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
1897 $solution_values_text = [];
1898 $solution_values_select = [];
1899 $solution_values_numeric = [];
1900 foreach ($user_result as $gap_id => $value) {
1901 if (is_string($value)) {
1902 $value = array(
"value" => $value);
1905 if (array_key_exists($gap_id, $this->gaps) && !array_key_exists($gap_id, $combinations[1])) {
1906 switch ($this->gaps[$gap_id]->getType()) {
1909 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1910 $answer = $this->gaps[$gap_id]->getItem($order);
1911 $gotpoints = $this->
getTextgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints());
1912 if ($gotpoints > $gappoints) {
1913 $gappoints = $gotpoints;
1918 if ((in_array($value[
"value"], $solution_values_text)) && ($gappoints > 0)) {
1923 $detailed[$gap_id] = array(
"points" => $gappoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ?
true :
false,
"positive" => ($gappoints > 0) ?
true :
false);
1924 array_push($solution_values_text, $value[
"value"]);
1928 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1929 $answer = $this->gaps[$gap_id]->getItem($order);
1930 $gotpoints = $this->
getNumericgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints(), $answer->getLowerBound(), $answer->getUpperBound());
1931 if ($gotpoints > $gappoints) {
1932 $gappoints = $gotpoints;
1937 include_once
"./Services/Math/classes/class.EvalMath.php";
1939 $eval->suppress_errors =
true;
1940 $found_value =
false;
1941 foreach ($solution_values_numeric as $solval) {
1942 if ($eval->e($solval) == $eval->e($value[
"value"])) {
1943 $found_value =
true;
1946 if ($found_value && ($gappoints > 0)) {
1951 $detailed[$gap_id] = array(
"points" => $gappoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ?
true :
false,
"positive" => ($gappoints > 0) ?
true :
false);
1952 array_push($solution_values_numeric, $value[
"value"]);
1955 if ($value[
"value"] >= 0) {
1956 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1957 $answer = $this->gaps[$gap_id]->getItem($order);
1958 if ($value[
"value"] == $answer->getOrder()) {
1959 $answerpoints = $answer->getPoints();
1962 if ((in_array($answer->getAnswertext(), $solution_values_select)) && ($answerpoints > 0)) {
1967 $detailed[$gap_id] = array(
"points" => $answerpoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $answerpoints) ?
true :
false,
"positive" => ($answerpoints > 0) ?
true :
false);
1968 array_push($solution_values_select, $answer->getAnswertext());
1984 if (!is_array($participant_session)) {
1988 $user_solution = [];
1990 foreach ($participant_session as
$key => $val) {
1991 $user_solution[
$key] = array(
'gap_id' =>
$key,
'value' => $val);
2004 foreach ($userSolution as $value1 => $value2) {
2005 if ($value1 == $gapIndex) {
2006 $answerValue = $value2;
2011 return $answerValue;
2016 $gap = $this->
getGap($qIndex);
2022 foreach ($gap->getItems($this->randomGroup->dontShuffle()) as $item) {
2023 if ($item->getAnswertext() === $answerOptionValue) {
2033 $gap = $this->
getGap($qIndex);
2036 $item->setOrder($gap->getItemCount());
2038 $gap->addItem($item);
static _replaceMediaObjectImageSrc(string $a_text, int $a_direction=0, string $nic='')
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
getSolutionValues($active_id, $pass=null, bool $authorized=true)
Loads solutions of a given user from the database an returns it.
setNrOfTries(int $a_nr_of_tries)
setGapCombinations($value)
fetchSolutionSubmit($submit)
toJSON()
Returns a JSON representation of the question.
static getInstance($identifier)
getGapCount()
Returns the number of gaps.
duplicate(bool $for_test=true, string $title="", string $author="", string $owner="", $testObjId=null)
Duplicates an assClozeTest.
const TEXTGAP_RATING_LEVENSHTEIN5
const PercentageResultExpression
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getMaximumGapPoints($gap_index)
Returns the maximum points for a gap.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
getQuestionType()
Returns the question type of the question.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
getClozeTextForHTMLOutput()
Returns the cloze text as HTML (with optional nl2br) Fix for Mantis 29987: We assume Tiny embeds any ...
setEndTag($end_tag="[/gap]")
Sets the end tag of a cloze gap.
clearGapAnswers()
Removes all answers from the gaps.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getAdditionalTableName()
Returns the name of the additional question data table in the database.
const NumberOfResultExpression
saveAnswerSpecificDataToDb()
Save all gaps to the database.
setGapSize($gap_index, $size)
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()
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
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.
getColumnCoord(int $a_col)
Get column "name" from number.
ensureNonNegativePoints($points)
bool $shuffle
Indicates whether the answers will be shuffled or not.
addAnswerOptionValue(int $qIndex, string $answerOptionValue, float $points)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getOriginalId(int $question_id)
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.
getParticipantsSolution()
setClozeTextValue($cloze_text="")
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
checkForValidFormula($value)
const StringResultExpression
setComment(string $comment="")
createGapsFromQuestiontext()
Create gap entries by parsing the question text.
float $points
The maximum available points for the question.
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
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...
ilAssQuestionFeedback $feedbackOBJ
getStartTag()
Returns the start tag of a cloze gap.
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)
getGaps()
Returns the array of gaps.
saveCurrentSolution(int $active_id, int $pass, $value1, $value2, bool $authorized=true, $tstamp=0)
setBold(string $a_coords)
Set cell(s) to bold.
static _enabledAssessmentLogging()
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.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static logAction(string $logtext, int $active_id, int $question_id)
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
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addGapAtIndex($gap, $index)
Adds a ClozeGap object at a given index.
string $question
The question text.
getGapCombinationsExists()
setGapAnswerUpperBound($gap_index, $order, $bound)
Sets the upper bound of a gap with a given index and an answer with a given order.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $preview_session)
saveClozeTextGapRecordToDb($next_id, $key, $item, $gap)
Saves a gap-item record.
setExportDetailsXLS(ilAssExcelFormatHelper $worksheet, int $startrow, int $active_id, int $pass)
{}
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.
isAdditionalContentEditingModePageObject()
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
saveClozeNumericGapRecordToDb($next_id, $key, $item, $gap)
Saves a gap-item record.
saveQuestionDataToDb(int $original_id=-1)
deleteGap($gap_index)
Deletes a gap with a given index.
getSolutionMaxPass(int $active_id)
replaceFirstGap($gaptext, $content)
Replace the first gap in a string without treating backreferences.
removeCurrentSolution(int $active_id, int $pass, bool $authorized=true)
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.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getEndTag()
Returns the end tag of a cloze gap.
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.
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.
setOriginalId(?int $original_id)
const TEXTGAP_RATING_LEVENSHTEIN4
setTitle(string $title="")
static strToLower(string $a_string)
setLifecycle(ilAssQuestionLifecycle $lifecycle)
prepareTextareaOutput(string $txt_output, bool $prepare_for_latex_output=false, bool $omitNl2BrWhenTextArea=false)
saveClozeSelectGapRecordToDb($next_id, $key, $item, $gap)
Saves a gap-item record.
getClozeText()
Returns the cloze text.
getCurrentSolutionResultSet(int $active_id, int $pass, bool $authorized=true)
__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.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getHtmlQuestionContentPurifier()
lookupMaxStep(int $active_id, int $pass)
getIdenticalScoring()
Returns the identical scoring status of the question.
setAuthor(string $author="")
setIdenticalScoring($a_identical_scoring)
Sets the identical scoring option for cloze questions.
setAdditionalContentEditingMode(?string $additionalContentEditingMode)
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
isAddableAnswerOptionValue(int $qIndex, string $answerOptionValue)
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)
ILIAS Refinery Factory $refinery
const TEXTGAP_RATING_CASEINSENSITIVE
setQuestion(string $question="")
const EmptyAnswerExpression