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);
163 $text = preg_replace(
"/\[gap[^\]]*?\]/",
"[gap]", $text);
164 $text = preg_replace(
"/<gap([^>]*?)>/",
"[gap]", $text);
165 $text = str_replace(
"</gap>",
"[/gap]", $text);
166 $text = str_replace(
'GAPMASKEDDOLLAR',
'$', $text);
180 $content = str_replace(
'$',
'GAPMASKEDDOLLAR', $content);
181 $output = preg_replace(
"/\[gap\].*?\[\/gap\]/", $content, $gaptext, 1);
182 $output = str_replace(
'GAPMASKEDDOLLAR',
'$', $output);
196 $ilDB = $DIC[
'ilDB'];
204 $this->
setId($question_id);
226 include_once(
"./Services/RTE/classes/class.ilRTE.php");
230 $this->
setEstimatedWorkingTime(substr($data[
"working_time"], 0, 2), substr($data[
"working_time"], 3, 2), substr($data[
"working_time"], 6, 2));
238 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
239 include_once
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
241 "SELECT * FROM qpl_a_cloze WHERE question_fi = %s ORDER BY gap_id, aorder ASC",
246 $this->gaps = array();
248 switch ($data[
"cloze_type"]) {
250 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
258 $this->gaps[$data[
"gap_id"]]->setGapSize($data[
'gap_size']);
260 $this->gaps[$data[
"gap_id"]]->addItem($answer);
263 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
265 $this->gaps[$data[
"gap_id"]]->setShuffle($data[
"shuffle"]);
272 $this->gaps[$data[
"gap_id"]]->addItem($answer);
275 if (!array_key_exists($data[
"gap_id"], $this->gaps)) {
283 $this->gaps[$data[
"gap_id"]]->setGapSize($data[
'gap_size']);
284 $answer->setLowerBound($data[
"lowerlimit"]);
285 $answer->setUpperBound($data[
"upperlimit"]);
286 $this->gaps[$data[
"gap_id"]]->addItem($answer);
293 $check_for_gap_combinations = $assClozeGapCombinationObj->loadFromDb($question_id);
294 if (count($check_for_gap_combinations) != 0) {
298 parent::loadFromDb($question_id);
301 #region Save question to db 327 $ilDB = $DIC[
'ilDB'];
330 "DELETE FROM qpl_a_cloze WHERE question_fi = %s",
332 array( $this->
getId() )
335 foreach ($this->gaps as $key => $gap) {
350 $DIC->database()->manipulateF(
353 array( $this->
getId() )
357 'question_fi' => array(
'integer', $this->
getId()),
375 $ilDB = $DIC[
'ilDB'];
376 foreach ($gap->getItems($this->getShuffler()) as $item) {
378 $next_id =
$ilDB->nextId(
'qpl_a_cloze');
379 switch ($gap->getType()) {
404 $ilDB = $DIC[
'ilDB'];
406 "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)",
421 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
425 (int) $gap->getGapSize()
441 $ilDB = $DIC[
'ilDB'];
443 "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)",
458 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
462 ($gap->getShuffle()) ?
"1" :
"0" 478 $ilDB = $DIC[
'ilDB'];
480 include_once
"./Services/Math/classes/class.EvalMath.php";
482 $eval->suppress_errors =
true;
484 "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)",
501 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
505 ($eval->e($item->getLowerBound() !==
false) && strlen(
506 $item->getLowerBound()
507 ) > 0) ? $item->getLowerBound() : $item->getAnswertext(),
508 ($eval->e($item->getUpperBound() !==
false) && strlen(
509 $item->getUpperBound()
510 ) > 0) ? $item->getUpperBound() : $item->getAnswertext(),
511 (int) $gap->getGapSize()
518 #endregion Save question to db 540 $this->gaps = array();
588 $string_with_replaced_gaps = str_replace(
$gaps[0],
'######GAP######', $this->
getClozeText());
590 $string_with_replaced_gaps
592 $cleaned_text_with_gaps = preg_replace_callback(
'/######GAP######/',
function ($match) use (&
$gaps) {
593 return array_shift(
$gaps[0]);
597 || !(
new ilSetting(
'advanced_editing'))->
get(
'advanced_editing_javascript_editor') ===
'tinymce') {
598 $cleaned_text_with_gaps = nl2br($cleaned_text_with_gaps);
676 include_once
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
677 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
678 $search_pattern =
"|\[gap\](.*?)\[/gap\]|i";
679 preg_match_all($search_pattern, $this->
getClozeText(), $found);
680 $this->gaps = array();
681 if (count($found[0])) {
682 foreach ($found[1] as $gap_index => $answers) {
685 $textparams = preg_split(
"/(?<!\\\\),/", $answers);
686 foreach ($textparams as $key => $value) {
688 $gap->addItem($answer);
690 $this->gaps[$gap_index] = $gap;
702 if (array_key_exists($gap_index, $this->gaps)) {
703 $this->gaps[$gap_index]->setType($gap_type);
718 if (array_key_exists($gap_index, $this->gaps)) {
719 $this->gaps[$gap_index]->setShuffle(
$shuffle);
731 foreach ($this->gaps as $gap_index => $gap) {
732 $this->gaps[$gap_index]->clearItems();
745 if (is_array($this->gaps)) {
746 return count($this->gaps);
764 if (array_key_exists($gap_index, $this->gaps)) {
767 $answer = str_replace(
",",
".", $answer);
769 $this->gaps[$gap_index]->addItem(
new assAnswerCloze(trim($answer), 0, $order));
783 if (array_key_exists($gap_index, $this->gaps)) {
784 return $this->gaps[$gap_index];
792 if (array_key_exists($gap_index, $this->gaps)) {
793 $this->gaps[$gap_index]->setGapSize(
$size);
809 if (array_key_exists($gap_index, $this->gaps)) {
810 $this->gaps[$gap_index]->setItemPoints($order,
$points);
824 if (array_key_exists($gap_index, $this->gaps)) {
825 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
829 $this->gaps[$gap_index]->getItemCount()
831 $this->gaps[$gap_index]->addItem($answer);
845 $this->gaps[
$index] = $gap;
860 if (array_key_exists($gap_index, $this->gaps)) {
861 $this->gaps[$gap_index]->setItemLowerBound($order, $bound);
877 if (array_key_exists($gap_index, $this->gaps)) {
878 $this->gaps[$gap_index]->setItemUpperBound($order, $bound);
892 $gaps_used_in_combination = array();
893 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
894 $points = $assClozeGapCombinationObj->getMaxPointsForCombination($this->
getId());
895 $gaps_used_in_combination = $assClozeGapCombinationObj->getGapsWhichAreUsedInCombination($this->
getId());
897 foreach ($this->gaps as $gap_index => $gap) {
898 if (!array_key_exists($gap_index, $gaps_used_in_combination)) {
901 foreach ($gap->getItems($this->getShuffler()) as $item) {
902 if ($item->getPoints() > $gap_max_points) {
903 $gap_max_points = $item->getPoints();
909 foreach ($gap->getItems($this->getShuffler()) as $item) {
910 if ($item->getPoints() > $srpoints) {
911 $srpoints = $item->getPoints();
917 foreach ($gap->getItems($this->getShuffler()) as $item) {
918 if ($item->getPoints() > $numpoints) {
919 $numpoints = $item->getPoints();
937 if ($this->
id <= 0) {
942 $this_id = $this->
getId();
946 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
950 if ((
int) $testObjId > 0) {
951 $clone->setObjId($testObjId);
968 if ($this->gap_combinations_exists) {
977 $clone->copyPageOfQuestion($this_id);
979 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
981 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
983 return $clone->getId();
993 if ($this->
getId() <= 0) {
998 $thisId = $this->
getId();
1002 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
1005 $clone->setObjId($target_questionpool_id);
1007 $clone->setTitle(
$title);
1012 if ($this->gap_combinations_exists) {
1022 $clone->onCopy($thisObjId, $thisId, $clone->getObjId(), $clone->getId());
1024 return $clone->getId();
1029 if ($this->
id <= 0) {
1034 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
1037 $sourceParentId = $this->
getObjId();
1043 $clone->setObjId($targetParentId);
1045 if ($targetQuestionTitle) {
1046 $clone->setTitle($targetQuestionTitle);
1051 if ($this->gap_combinations_exists) {
1056 $clone->copyPageOfQuestion($sourceQuestionId);
1058 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
1060 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
1068 $array = $assClozeGapCombinationObj->loadFromDb($orgID);
1069 $assClozeGapCombinationObj->importGapCombinationToDb($newID, $array);
1080 foreach ($this->
getGaps() as $gap_index => $gap) {
1082 foreach ($gap->getItemsRaw() as $item) {
1083 array_push($answers, str_replace([
',',
'['], [
"\\,",
'[ '], $item->getAnswerText()));
1089 $output = str_replace(
"_gap]",
"gap]", $output);
1090 $this->cloze_text = $output;
1104 if (array_key_exists($gap_index, $this->gaps)) {
1105 if ($this->gaps[$gap_index]->getItemCount() == 1) {
1110 $this->gaps[$gap_index]->deleteItem($answer_index);
1126 if (array_key_exists($gap_index, $this->gaps)) {
1128 foreach ($this->
getGaps() as $replace_gap_index => $gap) {
1130 foreach ($gap->getItemsRaw() as $item) {
1131 array_push($answers, str_replace(
",",
"\\,", $item->getAnswerText()));
1133 if ($replace_gap_index == $gap_index) {
1139 $output = $this->
replaceFirstGap($output,
"[_gap]" . join(
",", $answers) .
"[/_gap]");
1143 $output = str_replace(
"_gap]",
"gap]", $output);
1144 $this->cloze_text = $output;
1145 unset($this->gaps[$gap_index]);
1146 $this->gaps = array_values($this->gaps);
1161 include_once
"./Services/Utilities/classes/class.ilStr.php";
1167 switch ($gaprating) {
1174 if (strcmp($a_original, $a_entered) == 0) {
1179 $transformation =
$refinery->string()->levenshtein()->standard($a_original, 1);
1182 $transformation =
$refinery->string()->levenshtein()->standard($a_original, 2);
1185 $transformation =
$refinery->string()->levenshtein()->standard($a_original, 3);
1188 $transformation =
$refinery->string()->levenshtein()->standard($a_original, 4);
1191 $transformation =
$refinery->string()->levenshtein()->standard($a_original, 5);
1196 if (isset($transformation) && $transformation->transform($a_entered) >= 0) {
1220 include_once
"./Services/Math/classes/class.EvalMath.php";
1222 $eval->suppress_errors =
true;
1225 if ($eval->e($a_entered) ===
false) {
1227 } elseif (($eval->e($lowerBound) !==
false) && ($eval->e($upperBound) !==
false)) {
1229 if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($upperBound))) {
1232 } elseif ($eval->e($lowerBound) !==
false) {
1233 if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($a_original))) {
1236 } elseif ($eval->e($upperBound) !==
false) {
1237 if (($eval->e($a_entered) >= $eval->e($a_original)) && ($eval->e($a_entered) <= $eval->e($upperBound))) {
1241 if ($eval->e($a_entered) == $eval->e($a_original)) {
1254 return preg_match(
"/^-?(\\d*)(,|\\.|\\/){0,1}(\\d*)$/", $value, $matches);
1269 $ilDB = $DIC[
'ilDB'];
1271 if (is_null(
$pass)) {
1276 $user_result = array();
1278 if (strcmp(
$data[
"value2"],
"") != 0) {
1279 $user_result[
$data[
"value1"]] = array(
1280 "gap_id" => $data[
"value1"],
1281 "value" => $data[
"value2"]
1286 ksort($user_result);
1288 if ($returndetails) {
1289 $detailed = array();
1299 if (is_numeric($submittedValue)) {
1303 if (preg_match(
'/^[-+]{0,1}\d+\/\d+$/', $submittedValue)) {
1313 $gap = $this->
getGap($gapIndex);
1330 $solutionSubmit = array();
1331 foreach ($submit as $key => $value) {
1332 if ($value === null || is_array($value)) {
1336 $trimmed_value = trim($value);
1337 if ($trimmed_value ===
'') {
1341 if (preg_match(
"/^gap_(\d+)/", $key, $matches)) {
1342 $gap = $this->
getGap($matches[1]);
1343 if (!is_object($gap)
1344 || $gap->getType() ==
CLOZE_SELECT && $trimmed_value == -1) {
1348 if ($gap->getType() ==
CLOZE_NUMERIC && !is_numeric(str_replace(
",",
".", $trimmed_value))) {
1349 $trimmed_value = null;
1351 $trimmed_value = str_replace(
",",
".", $trimmed_value);
1353 $solutionSubmit[trim($matches[1])] = $trimmed_value;
1357 return $solutionSubmit;
1363 $solutionSubmit = array();
1365 foreach ($submit as $key => $value) {
1366 if (preg_match(
"/^gap_(\d+)/", $key, $matches)) {
1367 if ($value !== null && $value !==
'') {
1368 $gap = $this->
getGap($matches[1]);
1369 if (is_object($gap)) {
1370 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1))) {
1372 $value = str_replace(
",",
".", $value);
1374 $solutionSubmit[trim($matches[1])] = $value;
1381 return $solutionSubmit;
1400 $ilDB = $DIC[
'ilDB'];
1402 if (is_null(
$pass)) {
1403 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1407 $entered_values = 0;
1409 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use (&$entered_values, $active_id,
$pass, $authorized) {
1413 if ($value !== null && $value !==
'') {
1414 $gap = $this->
getGap($key);
1415 if (is_object($gap)) {
1416 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1))) {
1425 if ($entered_values) {
1426 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1431 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1448 return "assClozeTest";
1472 switch ($a_textgap_rating) {
1480 $this->textgap_rating = $a_textgap_rating;
1497 return ($this->identical_scoring) ? 1 : 0;
1509 $this->identical_scoring = ($a_identical_scoring) ? 1 : 0;
1520 return "qpl_qst_cloze";
1531 return array(
"qpl_a_cloze",
'qpl_a_cloze_combi_res');
1542 $this->fixedTextLength = $a_text_len;
1567 $gap_max_points = 0;
1568 if (array_key_exists($gap_index, $this->gaps)) {
1569 $gap = &$this->gaps[$gap_index];
1570 foreach ($gap->getItems($this->getShuffler()) as $answer) {
1571 if ($answer->getPoints() > $gap_max_points) {
1572 $gap_max_points = $answer->getPoints();
1586 return parent::getRTETextWithMediaObjects() . $this->
getClozeText();
1600 $this->gap_combinations_exists = $value;
1605 $this->gap_combinations = $value;
1613 parent::setExportDetailsXLS($worksheet, $startrow, $active_id,
$pass);
1617 foreach ($this->
getGaps() as $gap_index => $gap) {
1618 $worksheet->setCell($startrow +
$i, 0, $this->lng->txt(
"gap") .
" $i");
1619 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow +
$i));
1621 foreach ($solution as $solutionvalue) {
1622 if ($gap_index == $solutionvalue[
"value1"]) {
1623 $string_escaping_org_value = $worksheet->getStringEscaping();
1625 $worksheet->setStringEscaping(
false);
1627 switch ($gap->getType()) {
1629 $worksheet->setCell($startrow +
$i, 2, $gap->getItem($solutionvalue[
"value2"])->getAnswertext());
1633 $worksheet->setCell($startrow +
$i, 2, $solutionvalue[
"value2"]);
1637 $worksheet->setStringEscaping($string_escaping_org_value);
1644 return $startrow +
$i + 1;
1663 include_once(
"./Services/RTE/classes/class.ilRTE.php");
1673 'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
false)),
1674 'allcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
true))
1678 foreach ($this->
getGaps() as $key => $gap) {
1680 foreach ($gap->getItems($this->getShuffler()) as $item) {
1682 $jitem[
'points'] = $item->getPoints();
1684 $jitem[
'order'] = $item->getOrder();
1686 $jitem[
'lowerbound'] = $item->getLowerBound();
1687 $jitem[
'upperbound'] = $item->getUpperBound();
1689 $jitem[
'value'] = trim($jitem[
'value']);
1691 array_push($items, $jitem);
1695 $jgap[
'size'] = $gap->getGapSize();
1698 $jgap[
'shuffle'] = $gap->getShuffle();
1699 $jgap[
'type'] = $gap->getType();
1700 $jgap[
'item'] = $items;
1702 array_push($gaps, $jgap);
1720 require_once
"./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1751 $ilDB = $DIC[
'ilDB'];
1754 $maxStep = $this->lookupMaxStep($active_id,
$pass);
1756 if ($maxStep !== null) {
1759 SELECT sol.value1+1 as val, sol.value2, cloze.cloze_type 1760 FROM tst_solutions sol 1761 INNER JOIN qpl_a_cloze cloze ON cloze.gap_id = value1 AND cloze.question_fi = sol.question_fi 1762 WHERE sol.active_fi = %s AND sol.pass = %s AND sol.question_fi = %s AND sol.step = %s 1763 GROUP BY sol.solution_id, sol.value1+1, sol.value2, cloze.cloze_type 1765 array(
"integer",
"integer",
"integer",
"integer"),
1766 array($active_id,
$pass, $this->
getId(), $maxStep)
1771 SELECT sol.value1+1 as val, sol.value2, cloze.cloze_type 1772 FROM tst_solutions sol 1773 INNER JOIN qpl_a_cloze cloze ON cloze.gap_id = value1 AND cloze.question_fi = sol.question_fi 1774 WHERE sol.active_fi = %s AND sol.pass = %s AND sol.question_fi = %s 1775 GROUP BY sol.solution_id, sol.value1+1, sol.value2, cloze.cloze_type 1777 array(
"integer",
"integer",
"integer"),
1783 if ($row[
"cloze_type"] == 1) {
1786 $result->addKeyValue($row[
"val"], $row[
"value2"]);
1820 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
1821 $combinations_for_question = $assClozeGapCombinationObj->getCleanCombinationArray($this->
getId());
1822 $gap_answers = array();
1823 $gap_used_in_combination = array();
1824 foreach ($user_result as $user_result_build_list) {
1825 if (is_array($user_result_build_list)) {
1826 $gap_answers[$user_result_build_list[
'gap_id']] = $user_result_build_list[
'value'];
1830 foreach ($combinations_for_question as $combination) {
1831 foreach ($combination as $row_key => $row_answers) {
1832 $combination_fulfilled =
true;
1833 $points_for_combination = $row_answers[
'points'];
1834 foreach ($row_answers as $gap_key => $combination_gap_answer) {
1835 if ($gap_key !==
'points') {
1836 $gap_used_in_combination[$gap_key] = $gap_key;
1838 if ($combination_fulfilled && array_key_exists($gap_key, $gap_answers)) {
1839 switch ($combination_gap_answer[
'type']) {
1841 $is_text_gap_correct = $this->
getTextgapPoints($gap_answers[$gap_key], $combination_gap_answer[
'answer'], 1);
1842 if ($is_text_gap_correct != 1) {
1843 $combination_fulfilled =
false;
1847 $answer = $this->gaps[$gap_key]->getItem($gap_answers[$gap_key]);
1848 $answertext = $answer->getAnswertext();
1849 if ($answertext != $combination_gap_answer[
'answer']) {
1850 $combination_fulfilled =
false;
1854 $answer = $this->gaps[$gap_key]->getItem(0);
1855 if ($combination_gap_answer[
'answer'] !=
'out_of_bound') {
1856 $is_numeric_gap_correct = $this->
getNumericgapPoints($answer->getAnswertext(), $gap_answers[$gap_key], 1, $answer->getLowerBound(), $answer->getUpperBound());
1857 if ($is_numeric_gap_correct != 1) {
1858 $combination_fulfilled =
false;
1861 $wrong_is_the_new_right = $this->
getNumericgapPoints($answer->getAnswertext(), $gap_answers[$gap_key], 1, $answer->getLowerBound(), $answer->getUpperBound());
1862 if ($wrong_is_the_new_right == 1) {
1863 $combination_fulfilled =
false;
1869 if ($gap_key !==
'points') {
1870 $combination_fulfilled =
false;
1874 if ($combination_fulfilled) {
1875 $points += $points_for_combination;
1880 return array(
$points, $gap_used_in_combination);
1889 if ($detailed === null) {
1890 $detailed = array();
1894 $combinations[1] = array();
1895 if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
1900 $solution_values_text = array();
1901 $solution_values_select = array();
1902 $solution_values_numeric = array();
1903 foreach ($user_result as $gap_id => $value) {
1904 if (is_string($value)) {
1905 $value = array(
"value" => $value);
1908 if (array_key_exists($gap_id, $this->gaps) && !array_key_exists($gap_id, $combinations[1])) {
1909 switch ($this->gaps[$gap_id]->getType()) {
1912 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1913 $answer = $this->gaps[$gap_id]->getItem($order);
1914 $gotpoints = $this->
getTextgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints());
1915 if ($gotpoints > $gappoints) {
1916 $gappoints = $gotpoints;
1921 if ((in_array($value[
"value"], $solution_values_text)) && ($gappoints > 0)) {
1926 $detailed[$gap_id] = array(
"points" => $gappoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ?
true :
false,
"positive" => ($gappoints > 0) ?
true :
false);
1927 array_push($solution_values_text, $value[
"value"]);
1931 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1932 $answer = $this->gaps[$gap_id]->getItem($order);
1933 $gotpoints = $this->
getNumericgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints(), $answer->getLowerBound(), $answer->getUpperBound());
1934 if ($gotpoints > $gappoints) {
1935 $gappoints = $gotpoints;
1940 include_once
"./Services/Math/classes/class.EvalMath.php";
1942 $eval->suppress_errors =
true;
1943 $found_value =
false;
1944 foreach ($solution_values_numeric as $solval) {
1945 if ($eval->e($solval) == $eval->e($value[
"value"])) {
1946 $found_value =
true;
1949 if ($found_value && ($gappoints > 0)) {
1954 $detailed[$gap_id] = array(
"points" => $gappoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ?
true :
false,
"positive" => ($gappoints > 0) ?
true :
false);
1955 array_push($solution_values_numeric, $value[
"value"]);
1958 if ($value[
"value"] >= 0) {
1959 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
1960 $answer = $this->gaps[$gap_id]->getItem($order);
1961 if ($value[
"value"] == $answer->getOrder()) {
1962 $answerpoints = $answer->getPoints();
1965 if ((in_array($answer->getAnswertext(), $solution_values_select)) && ($answerpoints > 0)) {
1970 $detailed[$gap_id] = array(
"points" => $answerpoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $answerpoints) ?
true :
false,
"positive" => ($answerpoints > 0) ?
true :
false);
1971 array_push($solution_values_select, $answer->getAnswertext());
1985 $userSolution = array();
1988 $userSolution[$key] = array(
'gap_id' => $key,
'value' => $val);
2001 foreach ($userSolution as $value1 => $value2) {
2002 if ($value1 == $gapIndex) {
2003 $answerValue = $value2;
2008 return $answerValue;
2013 $gap = $this->
getGap($qIndex);
2020 if ($item->getAnswertext() === $answerOptionValue) {
2030 $gap = $this->
getGap($qIndex);
2033 $item->setOrder($gap->getItemCount());
2035 $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.
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.
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.
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.
isAdditionalContentEditingModePageObject()
isser for additional "pageobject" content editing mode
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.
getHtmlQuestionContentPurifier()
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