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';
 
  117        $this->start_tag = 
"[gap]";
 
  118        $this->end_tag = 
"[/gap]";
 
  119        $this->gaps = array();
 
  121        $this->fixedTextLength = 
"";
 
  122        $this->identical_scoring = 1;
 
  123        $this->gap_combinations_exists = 
false;
 
  124        $this->gap_combinations = array();
 
  153        $text = preg_replace(
"/\[gap[^\]]*?\]/", 
"[gap]", 
$text);
 
  154        $text = preg_replace(
"/<gap([^>]*?)>/", 
"[gap]", 
$text);
 
  155        $text = str_replace(
"</gap>", 
"[/gap]", 
$text);
 
  175            $this->
setId($question_id);
 
  189            include_once(
"./Services/RTE/classes/class.ilRTE.php");
 
  201            include_once 
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
 
  202            include_once 
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
 
  204                "SELECT * FROM qpl_a_cloze WHERE question_fi = %s ORDER BY gap_id, aorder ASC",
 
  209                $this->gaps = array();
 
  211                    switch (
$data[
"cloze_type"]) {
 
  213                            if (!array_key_exists(
$data[
"gap_id"], $this->gaps)) {
 
  221                            $this->gaps[
$data[
"gap_id"]]->setGapSize(
$data[
'gap_size']);
 
  223                            $this->gaps[
$data[
"gap_id"]]->addItem($answer);
 
  226                            if (!array_key_exists(
$data[
"gap_id"], $this->gaps)) {
 
  228                                $this->gaps[
$data[
"gap_id"]]->setShuffle(
$data[
"shuffle"]);
 
  235                            $this->gaps[
$data[
"gap_id"]]->addItem($answer);
 
  238                            if (!array_key_exists(
$data[
"gap_id"], $this->gaps)) {
 
  246                            $this->gaps[
$data[
"gap_id"]]->setGapSize(
$data[
'gap_size']);
 
  247                            $answer->setLowerBound(
$data[
"lowerlimit"]);
 
  248                            $answer->setUpperBound(
$data[
"upperlimit"]);
 
  249                            $this->gaps[
$data[
"gap_id"]]->addItem($answer);
 
  256        $check_for_gap_combinations = $assClozeGapCombinationObj->loadFromDb($question_id);
 
  257        if (count($check_for_gap_combinations) != 0) {
 
  261        parent::loadFromDb($question_id);
 
  264    #region Save question to db 
  292            "DELETE FROM qpl_a_cloze WHERE question_fi = %s",
 
  294            array( $this->
getId() )
 
  297        foreach ($this->gaps as 
$key => $gap) {
 
  314            array( $this->
getId() )
 
  319                                . 
" (question_fi, textgap_rating, identical_scoring, fixed_textlen, cloze_text) VALUES (%s, %s, %s, %s, %s)",
 
  346        foreach ($gap->getItems($this->getShuffler()) as $item) {
 
  348            $next_id = 
$ilDB->nextId(
'qpl_a_cloze');
 
  349            switch ($gap->getType()) {
 
  375            "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)",
 
  390                                strlen($item->getAnswertext()) ? $item->getAnswertext() : 
"",
 
  394                                (
int) $gap->getGapSize()
 
  411            "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)",
 
  426                                strlen($item->getAnswertext()) ? $item->getAnswertext() : 
"",
 
  430                                ($gap->getShuffle()) ? 
"1" : 
"0" 
  447        include_once 
"./Services/Math/classes/class.EvalMath.php";
 
  449        $eval->suppress_errors = 
true;
 
  451            "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)",
 
  468                                strlen($item->getAnswertext()) ? $item->getAnswertext() : 
"",
 
  472                                ($eval->e($item->getLowerBound() !== 
false) && strlen(
 
  473                                    $item->getLowerBound()
 
  474                                ) > 0) ? $item->getLowerBound() : $item->getAnswertext(),
 
  475                                ($eval->e($item->getUpperBound() !== 
false) && strlen(
 
  476                                    $item->getUpperBound()
 
  477                                ) > 0) ? $item->getUpperBound() : $item->getAnswertext(),
 
  478                                (
int) $gap->getGapSize()
 
  485    #endregion Save question to db 
  507        $this->gaps = array();
 
  521        $this->gaps = array();
 
  600        include_once 
"./Modules/TestQuestionPool/classes/class.assClozeGap.php";
 
  601        include_once 
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
 
  602        $search_pattern = 
"|\[gap\](.*?)\[/gap\]|i";
 
  603        preg_match_all($search_pattern, $this->
getClozeText(), $found);
 
  604        $this->gaps = array();
 
  605        if (count($found[0])) {
 
  606            foreach ($found[1] as $gap_index => $answers) {
 
  609                $textparams = preg_split(
"/(?<!\\\\),/", $answers);
 
  610                foreach ($textparams as 
$key => $value) {
 
  612                    $gap->addItem($answer);
 
  614                $this->gaps[$gap_index] = $gap;
 
  626        if (array_key_exists($gap_index, $this->gaps)) {
 
  627            $this->gaps[$gap_index]->setType($gap_type);
 
  642        if (array_key_exists($gap_index, $this->gaps)) {
 
  643            $this->gaps[$gap_index]->setShuffle(
$shuffle);
 
  655        foreach ($this->gaps as $gap_index => $gap) {
 
  656            $this->gaps[$gap_index]->clearItems();
 
  669        if (is_array($this->gaps)) {
 
  670            return count($this->gaps);
 
  688        if (array_key_exists($gap_index, $this->gaps)) {
 
  691                $answer = str_replace(
",", 
".", $answer);
 
  693            $this->gaps[$gap_index]->addItem(
new assAnswerCloze($answer, 0, $order));
 
  707        if (array_key_exists($gap_index, $this->gaps)) {
 
  708            return $this->gaps[$gap_index];
 
  716        if (array_key_exists($gap_index, $this->gaps)) {
 
  717            $this->gaps[$gap_index]->setGapSize(
$size);
 
  733        if (array_key_exists($gap_index, $this->gaps)) {
 
  734            $this->gaps[$gap_index]->setItemPoints($order, 
$points);
 
  748        if (array_key_exists($gap_index, $this->gaps)) {
 
  749            include_once 
"./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
 
  753                $this->gaps[$gap_index]->getItemCount()
 
  755            $this->gaps[$gap_index]->addItem($answer);
 
  769        $this->gaps[
$index] = $gap;
 
  784        if (array_key_exists($gap_index, $this->gaps)) {
 
  785            $this->gaps[$gap_index]->setItemLowerBound($order, $bound);
 
  801        if (array_key_exists($gap_index, $this->gaps)) {
 
  802            $this->gaps[$gap_index]->setItemUpperBound($order, $bound);
 
  816        $gaps_used_in_combination = array();
 
  817        if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
 
  818            $points =  $assClozeGapCombinationObj->getMaxPointsForCombination($this->
getId());
 
  819            $gaps_used_in_combination = $assClozeGapCombinationObj->getGapsWhichAreUsedInCombination($this->
getId());
 
  821        foreach ($this->gaps as $gap_index => $gap) {
 
  822            if (!array_key_exists($gap_index, $gaps_used_in_combination)) {
 
  825                    foreach ($gap->getItems($this->getShuffler()) as $item) {
 
  826                        if ($item->getPoints() > $gap_max_points) {
 
  827                            $gap_max_points = $item->getPoints();
 
  833                    foreach ($gap->getItems($this->getShuffler()) as $item) {
 
  834                        if ($item->getPoints() > $srpoints) {
 
  835                            $srpoints = $item->getPoints();
 
  841                    foreach ($gap->getItems($this->getShuffler()) as $item) {
 
  842                        if ($item->getPoints() > $numpoints) {
 
  843                            $numpoints = $item->getPoints();
 
  861        if ($this->
id <= 0) {
 
  866        $this_id = $this->
getId();
 
  870        include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
 
  874        if ((
int) $testObjId > 0) {
 
  875            $clone->setObjId($testObjId);
 
  892        if ($this->gap_combinations_exists) {
 
  901        $clone->copyPageOfQuestion($this_id);
 
  903        $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
 
  905        $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
 
  907        return $clone->getId();
 
  917        if ($this->
getId() <= 0) {
 
  922        $thisId = $this->
getId();
 
  926        include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
 
  929        $clone->setObjId($target_questionpool_id);
 
  936        if ($this->gap_combinations_exists) {
 
  946        $clone->onCopy($thisObjId, $thisId, $clone->getObjId(), $clone->getId());
 
  948        return $clone->getId();
 
  953        if ($this->
id <= 0) {
 
  958        include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
 
  961        $sourceParentId = $this->
getObjId();
 
  967        $clone->setObjId($targetParentId);
 
  969        if ($targetQuestionTitle) {
 
  970            $clone->setTitle($targetQuestionTitle);
 
  975        if ($this->gap_combinations_exists) {
 
  980        $clone->copyPageOfQuestion($sourceQuestionId);
 
  982        $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
 
  984        $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
 
  992        $array = $assClozeGapCombinationObj->loadFromDb($orgID);
 
  993        $assClozeGapCombinationObj->importGapCombinationToDb($newID, $array);
 
 1004        foreach ($this->
getGaps() as $gap_index => $gap) {
 
 1006            foreach ($gap->getItemsRaw() as $item) {
 
 1007                array_push($answers, str_replace(
",", 
"\\,", $item->getAnswerText()));
 
 1026        if (array_key_exists($gap_index, $this->gaps)) {
 
 1027            if ($this->gaps[$gap_index]->getItemCount() == 1) {
 
 1032                $this->gaps[$gap_index]->deleteItem($answer_index);
 
 1048        if (array_key_exists($gap_index, $this->gaps)) {
 
 1050            foreach ($this->
getGaps() as $replace_gap_index => $gap) {
 
 1052                foreach ($gap->getItemsRaw() as $item) {
 
 1053                    array_push($answers, str_replace(
",", 
"\\,", $item->getAnswerText()));
 
 1055                if ($replace_gap_index == $gap_index) {
 
 1058                    $output = preg_replace(
"/\[gap\].*?\[\/gap\]/", 
"[_gap]" . join(
",", $answers) . 
"[/_gap]", 
$output, 1);
 
 1063            unset($this->gaps[$gap_index]);
 
 1064            $this->gaps = array_values($this->gaps);
 
 1079        include_once 
"./Services/Utilities/classes/class.ilStr.php";
 
 1082        switch ($gaprating) {
 
 1089                if (strcmp($a_original, $a_entered) == 0) {
 
 1094                if (levenshtein($a_original, $a_entered) <= 1) {
 
 1099                if (levenshtein($a_original, $a_entered) <= 2) {
 
 1104                if (levenshtein($a_original, $a_entered) <= 3) {
 
 1109                if (levenshtein($a_original, $a_entered) <= 4) {
 
 1114                if (levenshtein($a_original, $a_entered) <= 5) {
 
 1139        include_once 
"./Services/Math/classes/class.EvalMath.php";
 
 1141        $eval->suppress_errors = 
true;
 
 1144        if ($eval->e($a_entered) === 
false) {
 
 1146        } elseif (($eval->e($lowerBound) !== 
false) && ($eval->e($upperBound) !== 
false)) {
 
 1148            if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($upperBound))) {
 
 1151        } elseif ($eval->e($lowerBound) !== 
false) {
 
 1152            if (($eval->e($a_entered) >= $eval->e($lowerBound)) && ($eval->e($a_entered) <= $eval->e($a_original))) {
 
 1155        } elseif ($eval->e($upperBound) !== 
false) {
 
 1156            if (($eval->e($a_entered) >= $eval->e($a_original)) && ($eval->e($a_entered) <= $eval->e($upperBound))) {
 
 1160            if ($eval->e($a_entered) == $eval->e($a_original)) {
 
 1173        return preg_match(
"/^-?(\\d*)(,|\\.|\\/){0,1}(\\d*)$/", $value, $matches);
 
 1189        if (is_null(
$pass)) {
 
 1194        $user_result = array();
 
 1196            if (strcmp(
$data[
"value2"], 
"") != 0) {
 
 1197                $user_result[
$data[
"value1"]] = array(
 
 1198                    "gap_id" => 
$data[
"value1"],
 
 1199                    "value" => 
$data[
"value2"]
 
 1204        ksort($user_result); 
 
 1206        if ($returndetails) {
 
 1207            $detailed = array();
 
 1217        if (is_numeric($submittedValue)) {
 
 1221        if (preg_match(
'/^[-+]{0,1}\d+\/\d+$/', $submittedValue)) {
 
 1231            $gap = $this->
getGap($gapIndex);
 
 1248        $solutionSubmit = array();
 
 1250        foreach ($submit as 
$key => $value) {
 
 1251            if (preg_match(
"/^gap_(\d+)/", 
$key, $matches)) {
 
 1253                if (strlen($value)) {
 
 1254                    $gap = $this->
getGap($matches[1]);
 
 1255                    if (is_object($gap)) {
 
 1256                        if (!(($gap->getType() == 
CLOZE_SELECT) && ($value == -1))) {
 
 1258                                $value = str_replace(
",", 
".", $value);
 
 1260                            $solutionSubmit[trim($matches[1])] = $value;
 
 1267        return $solutionSubmit;
 
 1287        if (is_null(
$pass)) {
 
 1288            include_once 
"./Modules/Test/classes/class.ilObjTest.php";
 
 1292        $entered_values = 0;
 
 1294        $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use (&$entered_values, $active_id, 
$pass, $authorized) {
 
 1299                if (strlen($value)) {
 
 1301                    if (is_object($gap)) {
 
 1302                        if (!(($gap->getType() == 
CLOZE_SELECT) && ($value == -1))) {
 
 1311        if ($entered_values) {
 
 1312            include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
 
 1317            include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
 
 1342        return "assClozeTest";
 
 1366        switch ($a_textgap_rating) {
 
 1374                $this->textgap_rating = $a_textgap_rating;
 
 1391        return ($this->identical_scoring) ? 1 : 0;
 
 1403        $this->identical_scoring = ($a_identical_scoring) ? 1 : 0;
 
 1414        return "qpl_qst_cloze";
 
 1425        return array(
"qpl_a_cloze",
'qpl_a_cloze_combi_res');
 
 1436        $this->fixedTextLength = $a_text_len;
 
 1461        $gap_max_points = 0;
 
 1462        if (array_key_exists($gap_index, $this->gaps)) {
 
 1463            $gap =&$this->gaps[$gap_index];
 
 1464            foreach ($gap->getItems($this->getShuffler()) as $answer) {
 
 1465                if ($answer->getPoints() > $gap_max_points) {
 
 1466                    $gap_max_points = $answer->getPoints();
 
 1480        return parent::getRTETextWithMediaObjects() . $this->
getClozeText();
 
 1494        $this->gap_combinations_exists = $value;
 
 1499        $this->gap_combinations = $value;
 
 1507        parent::setExportDetailsXLS(
$worksheet, $startrow, $active_id, 
$pass);
 
 1511        foreach ($this->
getGaps() as $gap_index => $gap) {
 
 1512            $worksheet->setCell($startrow + 
$i, 0, $this->lng->txt(
"gap") . 
" $i");
 
 1515            foreach ($solution as $solutionvalue) {
 
 1516                if ($gap_index == $solutionvalue[
"value1"]) {
 
 1517                    $string_escaping_org_value = 
$worksheet->getStringEscaping();
 
 1521                        switch ($gap->getType()) {
 
 1523                                $worksheet->setCell($startrow + 
$i, 1, $gap->getItem($solutionvalue[
"value2"])->getAnswertext());
 
 1527                                $worksheet->setCell($startrow + 
$i, 1, $solutionvalue[
"value2"]);
 
 1531                        $worksheet->setStringEscaping($string_escaping_org_value);
 
 1538        return $startrow + 
$i + 1;
 
 1557        include_once(
"./Services/RTE/classes/class.ilRTE.php");
 
 1567            'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), 
false)),
 
 1568            'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), 
true))
 
 1574            foreach ($gap->getItems($this->getShuffler()) as $item) {
 
 1576                $jitem[
'points'] = $item->getPoints();
 
 1578                $jitem[
'order'] = $item->getOrder();
 
 1580                    $jitem[
'lowerbound'] = $item->getLowerBound();
 
 1581                    $jitem[
'upperbound'] = $item->getUpperBound();
 
 1583                    $jitem[
'value'] = trim($jitem[
'value']);
 
 1585                array_push($items, $jitem);
 
 1589                $jgap[
'size'] = $gap->getGapSize();
 
 1592            $jgap[
'shuffle'] = $gap->getShuffle();
 
 1593            $jgap[
'type'] = $gap->getType();
 
 1594            $jgap[
'item'] = $items;
 
 1596            array_push(
$gaps, $jgap);
 
 1614        require_once 
"./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
 
 1647        $maxStep = $this->lookupMaxStep($active_id, 
$pass);
 
 1649        if ($maxStep !== 
null) {
 
 1652                                SELECT sol.value1+1 as val, sol.value2, cloze.cloze_type 
 1653                                FROM tst_solutions sol 
 1654                                INNER JOIN qpl_a_cloze cloze ON cloze.gap_id = value1 AND cloze.question_fi = sol.question_fi 
 1655                                WHERE sol.active_fi = %s AND sol.pass = %s AND sol.question_fi = %s AND sol.step = %s 
 1656                                GROUP BY sol.solution_id, sol.value1+1, sol.value2, cloze.cloze_type 
 1658                array(
"integer", 
"integer", 
"integer",
"integer"),
 
 1659                array($active_id, 
$pass, $this->
getId(), $maxStep)
 
 1664                                SELECT sol.value1+1 as val, sol.value2, cloze.cloze_type 
 1665                                FROM tst_solutions sol 
 1666                                INNER JOIN qpl_a_cloze cloze ON cloze.gap_id = value1 AND cloze.question_fi = sol.question_fi 
 1667                                WHERE sol.active_fi = %s AND sol.pass = %s AND sol.question_fi = %s 
 1668                                GROUP BY sol.solution_id, sol.value1+1, sol.value2, cloze.cloze_type 
 1670                array(
"integer", 
"integer", 
"integer"),
 
 1675        while (
$row = $ilDB->fetchAssoc(
$data)) {
 
 1676            if (
$row[
"cloze_type"] == 1) {
 
 1713        if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
 
 1714            $combinations_for_question  = $assClozeGapCombinationObj->getCleanCombinationArray($this->
getId());
 
 1715            $gap_answers                = array();
 
 1716            $gap_used_in_combination    = array();
 
 1717            foreach ($user_result as $user_result_build_list) {
 
 1718                if (is_array($user_result_build_list)) {
 
 1719                    $gap_answers[$user_result_build_list[
'gap_id']] = $user_result_build_list[
'value'];
 
 1723            foreach ($combinations_for_question as $combination) {
 
 1724                foreach ($combination as $row_key => $row_answers) {
 
 1725                    $combination_fulfilled = 
true;
 
 1726                    $points_for_combination = $row_answers[
'points'];
 
 1727                    foreach ($row_answers as $gap_key => $combination_gap_answer) {
 
 1728                        if ($gap_key !== 
'points') {
 
 1729                            $gap_used_in_combination[$gap_key]= $gap_key;
 
 1731                        if ($combination_fulfilled && array_key_exists($gap_key, $gap_answers)) {
 
 1732                            switch ($combination_gap_answer[
'type']) {
 
 1734                                    $is_text_gap_correct = $this->
getTextgapPoints($gap_answers[$gap_key], $combination_gap_answer[
'answer'], 1);
 
 1735                                    if ($is_text_gap_correct != 1) {
 
 1736                                        $combination_fulfilled = 
false;
 
 1740                                    $answer     = $this->gaps[$gap_key]->getItem($gap_answers[$gap_key]);
 
 1741                                    $answertext = $answer->getAnswertext();
 
 1742                                    if ($answertext != $combination_gap_answer[
'answer']) {
 
 1743                                        $combination_fulfilled = 
false;
 
 1747                                    $answer = $this->gaps[$gap_key]->getItem(0);
 
 1748                                    if ($combination_gap_answer[
'answer'] != 
'out_of_bound') {
 
 1749                                        $is_numeric_gap_correct = $this->
getNumericgapPoints($answer->getAnswertext(), $gap_answers[$gap_key], 1, $answer->getLowerBound(), $answer->getUpperBound());
 
 1750                                        if ($is_numeric_gap_correct != 1) {
 
 1751                                            $combination_fulfilled = 
false;
 
 1754                                        $wrong_is_the_new_right = $this->
getNumericgapPoints($answer->getAnswertext(), $gap_answers[$gap_key], 1, $answer->getLowerBound(), $answer->getUpperBound());
 
 1755                                        if ($wrong_is_the_new_right == 1) {
 
 1756                                            $combination_fulfilled = 
false;
 
 1762                            if ($gap_key !== 
'points') {
 
 1763                                $combination_fulfilled = 
false;
 
 1767                    if ($combination_fulfilled) {
 
 1768                        $points += $points_for_combination;
 
 1773        return array(
$points, $gap_used_in_combination);
 
 1782        if ($detailed === 
null) {
 
 1783            $detailed = array();
 
 1787        $combinations[1] = array();
 
 1788        if ($assClozeGapCombinationObj->combinationExistsForQid($this->getId())) {
 
 1793        $solution_values_text = array(); 
 
 1794        $solution_values_select = array(); 
 
 1795        $solution_values_numeric = array(); 
 
 1796        foreach ($user_result as $gap_id => $value) {
 
 1797            if (is_string($value)) {
 
 1798                $value = array(
"value" => $value);
 
 1801            if (array_key_exists($gap_id, $this->gaps) && !array_key_exists($gap_id, $combinations[1])) {
 
 1802                switch ($this->gaps[$gap_id]->getType()) {
 
 1805                        for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
 
 1806                            $answer = $this->gaps[$gap_id]->getItem($order);
 
 1807                            $gotpoints = $this->
getTextgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints());
 
 1808                            if ($gotpoints > $gappoints) {
 
 1809                                $gappoints = $gotpoints;
 
 1814                            if ((in_array($value[
"value"], $solution_values_text)) && ($gappoints > 0)) {
 
 1819                        $detailed[$gap_id] = array(
"points" => $gappoints, 
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ? 
true : 
false, 
"positive" => ($gappoints > 0) ? 
true : 
false);
 
 1820                        array_push($solution_values_text, $value[
"value"]);
 
 1824                        for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
 
 1825                            $answer = $this->gaps[$gap_id]->getItem($order);
 
 1826                            $gotpoints = $this->
getNumericgapPoints($answer->getAnswertext(), $value[
"value"], $answer->getPoints(), $answer->getLowerBound(), $answer->getUpperBound());
 
 1827                            if ($gotpoints > $gappoints) {
 
 1828                                $gappoints = $gotpoints;
 
 1833                            include_once 
"./Services/Math/classes/class.EvalMath.php";
 
 1835                            $eval->suppress_errors = 
true;
 
 1836                            $found_value = 
false;
 
 1837                            foreach ($solution_values_numeric as $solval) {
 
 1838                                if ($eval->e($solval) == $eval->e($value[
"value"])) {
 
 1839                                    $found_value = 
true;
 
 1842                            if ($found_value && ($gappoints > 0)) {
 
 1847                        $detailed[$gap_id] = array(
"points" => $gappoints, 
"best" => ($this->
getMaximumGapPoints($gap_id) == $gappoints) ? 
true : 
false, 
"positive" => ($gappoints > 0) ? 
true : 
false);
 
 1848                        array_push($solution_values_numeric, $value[
"value"]);
 
 1851                        if ($value[
"value"] >= 0) {
 
 1852                            for ($order = 0; $order < $this->gaps[$gap_id]->getItemCount(); $order++) {
 
 1853                                $answer = $this->gaps[$gap_id]->getItem($order);
 
 1854                                if ($value[
"value"] == $answer->getOrder()) {
 
 1855                                    $answerpoints = $answer->getPoints();
 
 1858                                        if ((in_array($answer->getAnswertext(), $solution_values_select)) && ($answerpoints > 0)) {
 
 1863                                    $detailed[$gap_id] = array(
"points" => $answerpoints, 
"best" => ($this->
getMaximumGapPoints($gap_id) == $answerpoints) ? 
true : 
false, 
"positive" => ($answerpoints > 0) ? 
true : 
false);
 
 1864                                    array_push($solution_values_select, $answer->getAnswertext());
 
 1878        $userSolution = array();
 
 1882            $userSolution[
$key] = array(
'gap_id' => 
$key, 
'value' => $val);
 
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.
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.
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.
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
{Reworks the allready saved working data if neccessary.}
copyGapCombination($orgID, $newID)
calculateReachedPointsForSolution($user_result, &$detailed=null)
getGapCombinationsExists()
getExpressionTypes()
Get all available expression types for a specific question.
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.
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.
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.
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)
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
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
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.