24 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
25 include_once
"./Modules/Test/classes/inc.AssessmentConstants.php";
114 $this->start_tag =
"[gap]";
115 $this->end_tag =
"[/gap]";
116 $this->gaps = array();
118 $this->fixedTextLength =
"";
119 $this->identical_scoring = 1;
149 $text = preg_replace(
"/\[gap[^\]]*?\]/",
"[gap]", $text);
150 $text = preg_replace(
"/<gap([^>]*?)>/",
"[gap]", $text);
151 $text = str_replace(
"</gap>",
"[/gap]", $text);
172 $this->
setId($question_id);
185 include_once(
"./Services/RTE/classes/class.ilRTE.php");
191 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
192 include_once
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
193 $result = $ilDB->queryF(
"SELECT * FROM qpl_a_cloze WHERE question_fi = %s ORDER BY gap_id, aorder ASC",
199 $this->gaps = array();
202 switch (
$data[
"cloze_type"])
205 if (!array_key_exists(
$data[
"gap_id"], $this->gaps))
214 $this->gaps[
$data[
"gap_id"]]->addItem($answer);
217 if (!array_key_exists(
$data[
"gap_id"], $this->gaps))
220 $this->gaps[$data[
"gap_id"]]->setShuffle($data[
"shuffle"]);
227 $this->gaps[
$data[
"gap_id"]]->addItem($answer);
230 if (!array_key_exists(
$data[
"gap_id"], $this->gaps))
239 $answer->setLowerBound(
$data[
"lowerlimit"]);
240 $answer->setUpperBound(
$data[
"upperlimit"]);
241 $this->gaps[
$data[
"gap_id"]]->addItem($answer);
262 include_once
"./Services/Math/classes/class.EvalMath.php";
264 $eval->suppress_errors = TRUE;
267 $affectedRows = $ilDB->manipulateF(
"DELETE FROM " . $this->
getAdditionalTableName() .
" WHERE question_fi = %s",
269 array($this->
getId())
273 $affectedRows = $ilDB->manipulateF(
"INSERT INTO " . $this->
getAdditionalTableName() .
" (question_fi, textgap_rating, identical_scoring, fixed_textlen) VALUES (%s, %s, %s, %s)",
288 $affectedRows = $ilDB->manipulateF(
"DELETE FROM qpl_a_cloze WHERE question_fi = %s",
290 array($this->
getId())
293 foreach ($this->gaps as
$key => $gap)
295 foreach ($gap->getItems() as $item)
298 switch ($gap->getType())
301 $next_id = $ilDB->nextId(
'qpl_a_cloze');
302 $affectedRows = $ilDB->manipulateF(
"INSERT INTO qpl_a_cloze (answer_id, question_fi, gap_id, answertext, points, aorder, cloze_type) VALUES (%s, %s, %s, %s, %s, %s, %s)",
316 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
324 $next_id = $ilDB->nextId(
'qpl_a_cloze');
325 $affectedRows = $ilDB->manipulateF(
"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)",
340 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
344 ($gap->getShuffle()) ?
"1" :
"0"
349 $next_id = $ilDB->nextId(
'qpl_a_cloze');
350 $affectedRows = $ilDB->manipulateF(
"INSERT INTO qpl_a_cloze (answer_id, question_fi, gap_id, answertext, points, aorder, cloze_type, lowerlimit, upperlimit) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)",
366 strlen($item->getAnswertext()) ? $item->getAnswertext() :
"",
370 ($eval->e($item->getLowerBound() !== FALSE) && strlen($item->getLowerBound()) > 0) ? $item->getLowerBound() : $item->getAnswertext(),
371 ($eval->e($item->getUpperBound() !== FALSE) && strlen($item->getUpperBound()) > 0) ? $item->getUpperBound() : $item->getAnswertext()
401 $this->gaps = array();
415 $this->gaps = array();
417 $this->question = $cloze_text;
489 include_once
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
490 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
491 $search_pattern =
"|\[gap\](.*?)\[/gap\]|i";
492 preg_match_all($search_pattern, $this->
getClozeText(), $found);
493 $this->gaps = array();
494 if (count($found[0]))
496 foreach ($found[1] as $gap_index => $answers)
500 $textparams = preg_split(
"/(?<!\\\\),/", $answers);
501 foreach ($textparams as
$key => $value)
504 $gap->addItem($answer);
506 $this->gaps[$gap_index] = $gap;
518 if (array_key_exists($gap_index, $this->gaps))
520 $this->gaps[$gap_index]->setType($gap_type);
535 if (array_key_exists($gap_index, $this->gaps))
537 $this->gaps[$gap_index]->setShuffle(
$shuffle);
549 foreach ($this->gaps as $gap_index => $gap)
551 $this->gaps[$gap_index]->clearItems();
564 if (is_array($this->gaps))
566 return count($this->gaps);
586 if (array_key_exists($gap_index, $this->gaps))
591 $answer = str_replace(
",",
".", $answer);
593 $this->gaps[$gap_index]->addItem(
new assAnswerCloze($answer, 0, $order));
607 if (array_key_exists($gap_index, $this->gaps))
609 return $this->gaps[$gap_index];
629 if (array_key_exists($gap_index, $this->gaps))
631 $this->gaps[$gap_index]->setItemPoints($order,
$points);
645 if (array_key_exists($gap_index, $this->gaps))
647 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
651 $this->gaps[$gap_index]->getItemCount()
653 $this->gaps[$gap_index]->addItem($answer);
667 $this->gaps[$index] = $gap;
682 if (array_key_exists($gap_index, $this->gaps))
684 $this->gaps[$gap_index]->setItemLowerBound($order, $bound);
700 if (array_key_exists($gap_index, $this->gaps))
702 $this->gaps[$gap_index]->setItemUpperBound($order, $bound);
715 foreach ($this->gaps as $gap_index => $gap)
720 foreach ($gap->getItems() as $item)
722 if ($item->getPoints() > $gap_max_points)
724 $gap_max_points = $item->getPoints();
732 foreach ($gap->getItems() as $item)
734 if ($item->getPoints() > $srpoints)
736 $srpoints = $item->getPoints();
744 foreach ($gap->getItems() as $item)
746 if ($item->getPoints() > $numpoints)
748 $numpoints = $item->getPoints();
770 $this_id = $this->
getId();
772 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
797 $clone->copyPageOfQuestion($this_id);
799 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
801 $clone->duplicateFeedbackGeneric($this_id);
803 $clone->onDuplicate($this_id);
805 return $clone->getId();
815 if ($this->
getId() <= 0)
821 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
824 $source_questionpool = $this->
getObjId();
825 $clone->setObjId($target_questionpool);
840 return $clone->getId();
851 foreach ($this->
getGaps() as $gap_index => $gap)
854 foreach ($gap->getItemsRaw() as $item)
856 array_push($answers, str_replace(
",",
"\\,", $item->getAnswerText()));
858 $output = preg_replace(
"/\[gap\].*?\[\/gap\]/",
"[_gap]" . $this->
prepareTextareaOutput(join(
",", $answers),
true) .
"[/_gap]", $output, 1);
860 $output = str_replace(
"_gap]",
"gap]", $output);
861 $this->question = $output;
875 if (array_key_exists($gap_index, $this->gaps))
877 if ($this->gaps[$gap_index]->getItemCount() == 1)
885 $this->gaps[$gap_index]->deleteItem($answer_index);
901 if (array_key_exists($gap_index, $this->gaps))
904 foreach ($this->
getGaps() as $replace_gap_index => $gap)
907 foreach ($gap->getItemsRaw() as $item)
909 array_push($answers, str_replace(
",",
"\\,", $item->getAnswerText()));
911 if ($replace_gap_index == $gap_index)
913 $output = preg_replace(
"/\[gap\].*?\[\/gap\]/",
"", $output, 1);
917 $output = preg_replace(
"/\[gap\].*?\[\/gap\]/",
"[_gap]" . join(
",", $answers) .
"[/_gap]", $output, 1);
920 $output = str_replace(
"_gap]",
"gap]", $output);
921 $this->question = $output;
922 unset($this->gaps[$gap_index]);
923 $this->gaps = array_values($this->gaps);
938 include_once
"./Services/Utilities/classes/class.ilStr.php";
947 if (strcmp($a_original, $a_entered) == 0)
$result = $max_points;
950 if (levenshtein($a_original, $a_entered) <= 1)
$result = $max_points;
953 if (levenshtein($a_original, $a_entered) <= 2)
$result = $max_points;
956 if (levenshtein($a_original, $a_entered) <= 3)
$result = $max_points;
959 if (levenshtein($a_original, $a_entered) <= 4)
$result = $max_points;
962 if (levenshtein($a_original, $a_entered) <= 5)
$result = $max_points;
979 include_once
"./Services/Math/classes/class.EvalMath.php";
981 $eval->suppress_errors = TRUE;
983 if (($eval->e($lowerBound) !== FALSE) && ($eval->e($upperBound) !== FALSE))
985 if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($upperBound)))
$result = $max_points;
987 else if ($eval->e($lowerBound) !== FALSE)
989 if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($a_original)))
$result = $max_points;
991 else if ($eval->e($upperBound) !== FALSE)
993 if (($eval->e($a_entered) >= $eval->e($a_original)) && ($eval->e($a_entered) <= $eval->e($upperBound)))
$result = $max_points;
997 if ($eval->e($a_entered) == $eval->e($a_original))
$result = $max_points;
1015 $found_value1 = array();
1016 $found_value2 = array();
1017 $detailed = array();
1022 $result = $ilDB->queryF(
"SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
1034 $user_result = array();
1037 if (strcmp(
$data[
"value2"],
"") != 0)
1039 $user_result[
$data[
"value1"]] = array(
1040 "gap_id" => $data[
"value1"],
1041 "value" => $data[
"value2"]
1047 $solution_values_text = array();
1048 $solution_values_select = array();
1049 $solution_values_numeric = array();
1050 foreach ($user_result as $gap_id => $value)
1052 if (array_key_exists($gap_id, $this->gaps))
1054 switch ($this->gaps[$gap_id]->getType())
1058 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++)
1060 $answer = $this->gaps[$gap_id]->getItem($order);
1061 $gotpoints = $this->
getTextgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints());
1062 if ($gotpoints > $gappoints) $gappoints = $gotpoints;
1067 if ((in_array($value[
"value"], $solution_values_text)) && ($gappoints > 0))
1073 $detailed[$gap_id] = array(
"points" =>$gappoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ? TRUE : FALSE,
"positive" => ($gappoints > 0) ? TRUE : FALSE);
1074 array_push($solution_values_text, $value[
"value"]);
1078 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++)
1080 $answer = $this->gaps[$gap_id]->getItem($order);
1081 $gotpoints = $this->
getNumericgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints(), $answer->getLowerBound(), $answer->getUpperBound());
1082 if ($gotpoints > $gappoints) $gappoints = $gotpoints;
1087 include_once
"./Services/Math/classes/class.EvalMath.php";
1089 $eval->suppress_errors = TRUE;
1090 $found_value = FALSE;
1091 foreach ($solution_values_numeric as $solval)
1093 if ($eval->e($solval) == $eval->e($value[
"value"]))
1095 $found_value = TRUE;
1098 if ($found_value && ($gappoints > 0))
1104 $detailed[$gap_id] = array(
"points" =>$gappoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ? TRUE : FALSE,
"positive" => ($gappoints > 0) ? TRUE : FALSE);
1105 array_push($solution_values_numeric, $value[
"value"]);
1108 if ($value[
"value"] >= 0)
1110 for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++)
1112 $answer = $this->gaps[$gap_id]->getItem($order);
1113 if ($value[
"value"] == $answer->getOrder())
1115 $answerpoints = $answer->getPoints();
1119 if ((in_array($answer->getAnswertext(), $solution_values_select)) && ($answerpoints > 0))
1125 $detailed[$gap_id] = array(
"points" =>$answerpoints,
"best" => ($this->
getMaximumGapPoints($gap_id) == $answerpoints) ? TRUE : FALSE,
"positive" => ($answerpoints > 0) ? TRUE : FALSE);
1126 array_push($solution_values_select, $answer->getAnswertext());
1159 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1163 $affectedRows = $ilDB->manipulateF(
"DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
1176 $entered_values = 0;
1179 if (preg_match(
"/^gap_(\d+)/",
$key, $matches))
1184 $gap = $this->
getGap($matches[1]);
1185 if (is_object($gap))
1187 if (!(($gap->getType() ==
CLOZE_SELECT) && ($value == -1)))
1191 $value = str_replace(
",",
".", $value);
1193 $next_id = $ilDB->nextId(
"tst_solutions");
1194 $affectedRows = $ilDB->insert(
"tst_solutions", array(
1195 "solution_id" => array(
"integer", $next_id),
1196 "active_fi" => array(
"integer", $active_id),
1197 "question_fi" => array(
"integer", $this->
getId()),
1198 "value1" => array(
"clob", trim($matches[1])),
1199 "value2" => array(
"clob", trim($value)),
1200 "pass" => array(
"integer",
$pass),
1201 "tstamp" => array(
"integer", time())
1209 if ($entered_values)
1211 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1219 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1237 return "assClozeTest";
1261 switch ($a_textgap_rating)
1270 $this->textgap_rating = $a_textgap_rating;
1287 return ($this->identical_scoring) ? 1 : 0;
1299 $this->identical_scoring = ($a_identical_scoring) ? 1 : 0;
1310 return "qpl_qst_cloze";
1321 return "qpl_a_cloze";
1332 $this->fixedTextLength = $a_text_len;
1357 if (array_key_exists($gap_index, $this->gaps))
1359 $gap =& $this->gaps[$gap_index];
1360 foreach ($gap->getItems() as $answer)
1362 if ($answer->getPoints() > $gap_max_points)
1364 $gap_max_points = $answer->getPoints();
1395 include_once (
"./Services/Excel/classes/class.ilExcelUtils.php");
1400 foreach ($this->
getGaps() as $gap_index => $gap)
1404 foreach ($solution as $solutionvalue)
1406 if ($gap_index == $solutionvalue[
"value1"])
1408 switch ($gap->getType())
1411 $worksheet->writeString($startrow + $i, 1, $gap->getItem($solutionvalue[
"value2"])->getAnswertext());
1415 $worksheet->writeString($startrow + $i, 1, $solutionvalue[
"value2"]);
1422 return $startrow + $i + 1;
1430 include_once(
"./Services/RTE/classes/class.ilRTE.php");
1446 foreach ($gap->getItems() as $item)
1449 $jitem[
'points'] = $item->getPoints();
1450 $jitem[
'value'] = $item->getAnswertext();
1453 $jitem[
'lowerbound'] = $item->getLowerBound();
1454 $jitem[
'upperbound'] = $item->getUpperBound();
1456 array_push($items, $jitem);
1458 $jgap[
'shuffle'] = $gap->getShuffle();
1459 $jgap[
'type'] = $gap->getType();
1460 $jgap[
'item'] = $items;
1461 array_push(
$gaps, $jgap);