00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 include_once "./assessment/classes/class.assQuestion.php";
00025 include_once "./assessment/classes/inc.AssessmentConstants.php";
00026
00037 class ASS_ClozeTest extends ASS_Question
00038 {
00047 var $cloze_text;
00048
00056 var $gaps;
00057
00065 var $start_tag;
00066
00074 var $end_tag;
00075
00086 var $textgap_rating;
00087
00100 function ASS_ClozeTest(
00101 $title = "",
00102 $comment = "",
00103 $author = "",
00104 $owner = -1,
00105 $cloze_text = ""
00106 )
00107 {
00108 $this->start_tag = "<gap>";
00109 $this->end_tag = "</gap>";
00110 $this->ASS_Question($title, $comment, $author, $owner);
00111 $this->gaps = array();
00112 $this->set_cloze_text($cloze_text);
00113 }
00114
00123 function isComplete()
00124 {
00125 if (($this->title) and ($this->author) and ($this->cloze_text) and (count($this->gaps)) and ($this->getMaximumPoints() > 0))
00126 {
00127 return true;
00128 }
00129 else
00130 {
00131 return false;
00132 }
00133 }
00134
00143 function &createCloseTextArray()
00144 {
00145 $result = array();
00146 $search_pattern = "|<gap([^>]*?)>(.*?)</gap>|i";
00147 preg_match_all($search_pattern, $this->cloze_text, $gaps);
00148 if (count($gaps[0]))
00149 {
00150
00151 $delimiters = preg_split($search_pattern, $this->cloze_text, -1, PREG_SPLIT_OFFSET_CAPTURE);
00152 $result["gaps"] = array();
00153 foreach ($gaps[0] as $index => $gap)
00154 {
00155 $result["gaps"][$index] = array();
00156 $result["gaps"][$index]["gap"] = $gap;
00157 $result["gaps"][$index]["params"] = array();
00158 $result["gaps"][$index]["params"]["text"] = $gaps[1][$index];
00159
00160 if (preg_match("/name\=\"([^\"]*?)\"/", $gaps[1][$index], $params))
00161 {
00162 $result["gaps"][$index]["params"]["name"] = $params[1];
00163 }
00164 else
00165 {
00166 $result["gaps"][$index]["params"]["name"] = $this->lng->txt("gap") . " " . ($index+1);
00167 }
00168 if (preg_match("/type\=\"([^\"]*?)\"/", $gaps[1][$index], $params))
00169 {
00170 $result["gaps"][$index]["params"]["type"] = $params[1];
00171 }
00172 else
00173 {
00174 $result["gaps"][$index]["params"]["type"] = "text";
00175 }
00176 if (preg_match("/shuffle\=\"([^\"]*?)\"/", $gaps[1][$index], $params))
00177 {
00178 $result["gaps"][$index]["params"]["shuffle"] = $params[1];
00179 }
00180 else
00181 {
00182 if (strcmp(strtolower($result["gaps"][$index]["params"]["type"]), "select") == 0)
00183 {
00184 $result["gaps"][$index]["params"]["shuffle"] = "yes";
00185 }
00186 }
00187 $result["gaps"][$index]["text"] = array();
00188 $result["gaps"][$index]["text"]["text"] = $gaps[2][$index];
00189 $textparams = preg_split("/(?<!\\\\),/", $gaps[2][$index]);
00190 foreach ($textparams as $key => $value)
00191 {
00192 $result["gaps"][$index]["text"][$key] = $value;
00193 }
00194 }
00195 $result["delimiters"] = $delimiters;
00196 }
00197 else
00198 {
00199 $result["gaps"] = array();
00200 $result["delimiters"] =
00201 array(
00202 array(0 => $this->cloze_text, 1 => "0")
00203 );
00204 }
00205
00206 return $result;
00207 }
00208
00217 function createCloseTextFromArray($assoc_array)
00218 {
00219 $this->cloze_text = "";
00220 if (count($assoc_array))
00221 {
00222 $gap = 0;
00223 foreach ($assoc_array["delimiters"] as $key => $value)
00224 {
00225 if (($key > 0) && ($key < count($assoc_array["delimiters"])))
00226 {
00227 if (strcmp($assoc_array["gaps"][$gap]["params"]["shuffle"], "") == 0)
00228 {
00229 $shuffle = "";
00230 }
00231 else
00232 {
00233 $shuffle = " shuffle=\"" . $assoc_array["gaps"][$gap]["params"]["shuffle"] . "\"";
00234 }
00235 $textarray = array();
00236 if (is_array($assoc_array["gaps"][$gap]["text"]))
00237 {
00238 foreach ($assoc_array["gaps"][$gap]["text"] as $textindex => $textvalue)
00239 {
00240 if (preg_match("/\d+/", $textindex))
00241 {
00242 array_push($textarray, $textvalue);
00243 }
00244 }
00245 }
00246 if (count($textarray))
00247 {
00248 $this->cloze_text .= sprintf("<gap name=\"%s\" type=\"%s\"%s>%s</gap>",
00249 $assoc_array["gaps"][$gap]["params"]["name"],
00250 $assoc_array["gaps"][$gap]["params"]["type"],
00251 $shuffle,
00252 join(",", $textarray)
00253 );
00254 }
00255 $gap++;
00256 }
00257 $this->cloze_text .= $value[0];
00258 }
00259 }
00260 }
00261
00270 function saveToDb($original_id = "")
00271 {
00272 global $ilias;
00273
00274 $db =& $ilias->db;
00275 $complete = 0;
00276 if ($this->isComplete())
00277 {
00278 $complete = 1;
00279 }
00280
00281 $estw_time = $this->getEstimatedWorkingTime();
00282 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00283 $shuffle = 1;
00284
00285 if (!$this->shuffle)
00286 {
00287 $shuffle = 0;
00288 }
00289
00290 if ($original_id)
00291 {
00292 $original_id = $db->quote($original_id);
00293 }
00294 else
00295 {
00296 $original_id = "NULL";
00297 }
00298
00299 if ($this->id == -1)
00300 {
00301
00302 $now = getdate();
00303 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00304 $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, points, author, owner, question_text, working_time, shuffle, complete, created, original_id, textgap_rating, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00305 $db->quote($this->getQuestionType()),
00306 $db->quote($this->obj_id),
00307 $db->quote($this->title),
00308 $db->quote($this->comment),
00309 $db->quote($this->getMaximumPoints() . ""),
00310 $db->quote($this->author),
00311 $db->quote($this->owner),
00312 $db->quote($this->cloze_text),
00313 $db->quote($estw_time),
00314 $db->quote("$this->shuffle"),
00315 $db->quote("$complete"),
00316 $db->quote($created),
00317 $original_id,
00318 $db->quote($this->textgap_rating)
00319 );
00320 $result = $db->query($query);
00321 if ($result == DB_OK)
00322 {
00323 $this->id = $this->ilias->db->getLastInsertId();
00324
00325
00326 $this->createPageObject();
00327
00328
00329 if ($this->getTestId() > 0)
00330 {
00331 $this->insertIntoTest($this->getTestId());
00332 }
00333 }
00334 }
00335 else
00336 {
00337
00338 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, points = %s, author = %s, question_text = %s, working_time = %s, shuffle = %s, complete = %s, textgap_rating = %s WHERE question_id = %s",
00339 $db->quote($this->obj_id. ""),
00340 $db->quote($this->title),
00341 $db->quote($this->comment),
00342 $db->quote($this->getMaximumPoints() . ""),
00343 $db->quote($this->author),
00344 $db->quote($this->cloze_text),
00345 $db->quote($estw_time),
00346 $db->quote("$this->shuffle"),
00347 $db->quote("$complete"),
00348 $db->quote($this->textgap_rating),
00349 $db->quote($this->id)
00350 );
00351 $result = $db->query($query);
00352 }
00353
00354 if ($result == DB_OK)
00355 {
00356
00357
00358
00359 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00360 $db->quote($this->id)
00361 );
00362 $result = $db->query($query);
00363
00364 foreach ($this->gaps as $key => $value)
00365 {
00366 foreach ($value as $answer_id => $answer_obj)
00367 {
00368 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, gap_id, answertext, points, aorder, cloze_type, name, shuffle, correctness, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00369 $db->quote($this->id),
00370 $db->quote($key),
00371 $db->quote($answer_obj->get_answertext() . ""),
00372 $db->quote($answer_obj->get_points() . ""),
00373 $db->quote($answer_obj->get_order() . ""),
00374 $db->quote($answer_obj->get_cloze_type() . ""),
00375 $db->quote($answer_obj->get_name() . ""),
00376 $db->quote($answer_obj->get_shuffle() . ""),
00377 $db->quote($answer_obj->getState() . "")
00378 );
00379 $answer_result = $db->query($query);
00380 }
00381 }
00382 }
00383 parent::saveToDb($original_id);
00384 }
00385
00395 function loadFromDb($question_id)
00396 {
00397 global $ilias;
00398 $db =& $ilias->db;
00399
00400 include_once "./assessment/classes/class.assAnswerCloze.php";
00401 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00402 $db->quote($question_id)
00403 );
00404 $result = $db->query($query);
00405 if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00406 if ($result->numRows() == 1) {
00407 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00408 $this->id = $question_id;
00409 $this->obj_id = $data->obj_fi;
00410 $this->title = $data->title;
00411 $this->comment = $data->comment;
00412 $this->solution_hint = $data->solution_hint;
00413 $this->original_id = $data->original_id;
00414 $this->author = $data->author;
00415 $this->points = $data->points;
00416 $this->owner = $data->owner;
00417 $this->cloze_text = $data->question_text;
00418 $this->setTextgapRating($data->textgap_rating);
00419 $this->shuffle = $data->shuffle;
00420 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00421 }
00422
00423 $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY gap_id, aorder ASC",
00424 $db->quote($question_id)
00425 );
00426 $result = $db->query($query);
00427 if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00428 $counter = -1;
00429 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
00430 if ($data->gap_id != $counter) {
00431 $answer_array = array();
00432 array_push($this->gaps, $answer_array);
00433 $counter = $data->gap_id;
00434 }
00435 if ($data->cloze_type == CLOZE_SELECT)
00436 {
00437 if ($data->correctness == 0)
00438 {
00439
00440 $data->correctness = 1;
00441 $data->points = 0;
00442 }
00443 }
00444 array_push($this->gaps[$counter], new ASS_AnswerCloze($data->answertext, $data->points, $data->aorder, $data->correctness, $data->cloze_type, $data->name, $data->shuffle, $data->answer_id));
00445 }
00446 }
00447 }
00448 parent::loadFromDb($question_id);
00449 }
00450
00458 function addAnswer($gap, $answertext, $points, $answerorder, $correctness, $clozetype, $name, $shuffle, $answer_id = -1)
00459 {
00460 include_once "./assessment/classes/class.assAnswerCloze.php";
00461 if (!is_array($this->gaps[$gap]))
00462 {
00463 $this->gaps[$gap] = array();
00464 }
00465 array_push($this->gaps[$gap], new ASS_AnswerCloze($answertext, $points, $answerorder, $correctness, $clozetype, $name, $shuffle, $answer_id));
00466 }
00467
00475 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00476 {
00477 if ($this->id <= 0)
00478 {
00479
00480 return;
00481 }
00482
00483 $this_id = $this->getId();
00484 $clone = $this;
00485 include_once ("./assessment/classes/class.assQuestion.php");
00486 $original_id = ASS_Question::_getOriginalId($this->id);
00487 $clone->id = -1;
00488 if ($title)
00489 {
00490 $clone->setTitle($title);
00491 }
00492 if ($author)
00493 {
00494 $clone->setAuthor($author);
00495 }
00496 if ($owner)
00497 {
00498 $clone->setOwner($owner);
00499 }
00500 if ($for_test)
00501 {
00502 $clone->saveToDb($original_id);
00503 }
00504 else
00505 {
00506 $clone->saveToDb();
00507 }
00508
00509
00510 $clone->copyPageOfQuestion($this_id);
00511
00512 return $clone->id;
00513 }
00514
00522 function copyObject($target_questionpool, $title = "")
00523 {
00524 if ($this->id <= 0)
00525 {
00526
00527 return;
00528 }
00529
00530 $clone = $this;
00531 include_once ("./assessment/classes/class.assQuestion.php");
00532 $original_id = ASS_Question::_getOriginalId($this->id);
00533 $clone->id = -1;
00534 $source_questionpool = $this->getObjId();
00535 $clone->setObjId($target_questionpool);
00536 if ($title)
00537 {
00538 $clone->setTitle($title);
00539 }
00540 $clone->saveToDb();
00541
00542
00543 $clone->copyPageOfQuestion($original_id);
00544
00545 return $clone->id;
00546 }
00547
00557 function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
00558 {
00559 include_once("./classes/class.ilXmlWriter.php");
00560 $a_xml_writer = new ilXmlWriter;
00561
00562 $a_xml_writer->xmlHeader();
00563 $a_xml_writer->xmlStartTag("questestinterop");
00564 $attrs = array(
00565 "ident" => "il_".IL_INST_ID."_qst_".$this->getId(),
00566 "title" => $this->getTitle()
00567 );
00568 $a_xml_writer->xmlStartTag("item", $attrs);
00569
00570 $a_xml_writer->xmlElement("qticomment", NULL, $this->getComment());
00571
00572 $workingtime = $this->getEstimatedWorkingTime();
00573 $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]);
00574 $a_xml_writer->xmlElement("duration", NULL, $duration);
00575
00576 $a_xml_writer->xmlStartTag("itemmetadata");
00577 $a_xml_writer->xmlStartTag("qtimetadata");
00578 $a_xml_writer->xmlStartTag("qtimetadatafield");
00579 $a_xml_writer->xmlElement("fieldlabel", NULL, "ILIAS_VERSION");
00580 $a_xml_writer->xmlElement("fieldentry", NULL, $this->ilias->getSetting("ilias_version"));
00581 $a_xml_writer->xmlEndTag("qtimetadatafield");
00582 $a_xml_writer->xmlStartTag("qtimetadatafield");
00583 $a_xml_writer->xmlElement("fieldlabel", NULL, "QUESTIONTYPE");
00584 $a_xml_writer->xmlElement("fieldentry", NULL, CLOZE_TEST_IDENTIFIER);
00585 $a_xml_writer->xmlEndTag("qtimetadatafield");
00586 $a_xml_writer->xmlStartTag("qtimetadatafield");
00587 $a_xml_writer->xmlElement("fieldlabel", NULL, "AUTHOR");
00588 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getAuthor());
00589 $a_xml_writer->xmlEndTag("qtimetadatafield");
00590 $a_xml_writer->xmlStartTag("qtimetadatafield");
00591 $a_xml_writer->xmlElement("fieldlabel", NULL, "textgaprating");
00592 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getTextgapRating());
00593 $a_xml_writer->xmlEndTag("qtimetadatafield");
00594 $a_xml_writer->xmlEndTag("qtimetadata");
00595 $a_xml_writer->xmlEndTag("itemmetadata");
00596
00597
00598 $attrs = array(
00599 "label" => $this->getTitle()
00600 );
00601 $a_xml_writer->xmlStartTag("presentation", $attrs);
00602
00603 $a_xml_writer->xmlStartTag("flow");
00604 $text_parts = preg_split("/<gap.*?<\/gap>/", $this->get_cloze_text());
00605
00606 for ($i = 0; $i <= $this->get_gap_count(); $i++)
00607 {
00608
00609 $a_xml_writer->xmlStartTag("material");
00610 $a_xml_writer->xmlElement("mattext", NULL, $text_parts[$i]);
00611 $a_xml_writer->xmlEndTag("material");
00612
00613 if ($i < $this->get_gap_count())
00614 {
00615
00616 $gap = $this->get_gap($i);
00617 if ($gap[0]->get_cloze_type() == CLOZE_SELECT)
00618 {
00619
00620 $attrs = array(
00621 "ident" => "gap_$i",
00622 "rcardinality" => "Single"
00623 );
00624 $a_xml_writer->xmlStartTag("response_str", $attrs);
00625 $solution = $this->getSuggestedSolution($i);
00626 if (count($solution))
00627 {
00628 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00629 {
00630 $attrs = array(
00631 "label" => "suggested_solution"
00632 );
00633 $a_xml_writer->xmlStartTag("material", $attrs);
00634 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00635 if (strcmp($matches[1], "") != 0)
00636 {
00637 $intlink = $solution["internal_link"];
00638 }
00639 $a_xml_writer->xmlElement("mattext", NULL, $intlink);
00640 $a_xml_writer->xmlEndTag("material");
00641 }
00642 }
00643
00644 $attrs = array();
00645 if ($gap[0]->get_shuffle())
00646 {
00647 $attrs = array("shuffle" => "Yes");
00648 }
00649 else
00650 {
00651 $attrs = array("shuffle" => "No");
00652 }
00653 $a_xml_writer->xmlStartTag("render_choice", $attrs);
00654
00655
00656 $gkeys = array_keys($gap);
00657 if ($gap[0]->get_shuffle() && $a_shuffle)
00658 {
00659 $gkeys = $this->pcArrayShuffle($gkeys);
00660 }
00661
00662
00663 foreach ($gkeys as $key)
00664 {
00665 $value = $gap[$key];
00666 $attrs = array(
00667 "ident" => $key
00668 );
00669 $a_xml_writer->xmlStartTag("response_label", $attrs);
00670 $a_xml_writer->xmlStartTag("material");
00671 $a_xml_writer->xmlElement("mattext", NULL, $value->get_answertext());
00672 $a_xml_writer->xmlEndTag("material");
00673 $a_xml_writer->xmlEndTag("response_label");
00674 }
00675 $a_xml_writer->xmlEndTag("render_choice");
00676 $a_xml_writer->xmlEndTag("response_str");
00677 }
00678 else
00679 {
00680
00681 $attrs = array(
00682 "ident" => "gap_$i",
00683 "rcardinality" => "Single"
00684 );
00685 $a_xml_writer->xmlStartTag("response_str", $attrs);
00686 $solution = $this->getSuggestedSolution($i);
00687 if (count($solution))
00688 {
00689 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00690 {
00691 $attrs = array(
00692 "label" => "suggested_solution"
00693 );
00694 $a_xml_writer->xmlStartTag("material", $attrs);
00695 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00696 if (strcmp($matches[1], "") != 0)
00697 {
00698 $intlink = $solution["internal_link"];
00699 }
00700 $a_xml_writer->xmlElement("mattext", NULL, $intlink);
00701 $a_xml_writer->xmlEndTag("material");
00702 }
00703 }
00704 $attrs = array(
00705 "fibtype" => "String",
00706 "prompt" => "Box",
00707 "columns" => $this->getColumnSize($gap)
00708 );
00709 $a_xml_writer->xmlStartTag("render_fib", $attrs);
00710 $a_xml_writer->xmlEndTag("render_fib");
00711 $a_xml_writer->xmlEndTag("response_str");
00712 }
00713 }
00714 }
00715 $a_xml_writer->xmlEndTag("flow");
00716 $a_xml_writer->xmlEndTag("presentation");
00717
00718
00719 $a_xml_writer->xmlStartTag("resprocessing");
00720 $a_xml_writer->xmlStartTag("outcomes");
00721 $a_xml_writer->xmlStartTag("decvar");
00722 $a_xml_writer->xmlEndTag("decvar");
00723 $a_xml_writer->xmlEndTag("outcomes");
00724
00725
00726 for ($i = 0; $i < $this->get_gap_count(); $i++)
00727 {
00728 $gap = $this->get_gap($i);
00729 if ($gap[0]->get_cloze_type() == CLOZE_SELECT)
00730 {
00731 foreach ($gap as $index => $answer)
00732 {
00733 $attrs = array(
00734 "continue" => "Yes"
00735 );
00736 $a_xml_writer->xmlStartTag("respcondition", $attrs);
00737
00738 $a_xml_writer->xmlStartTag("conditionvar");
00739
00740 if (!$answer->isStateSet())
00741 {
00742 $a_xml_writer->xmlStartTag("not");
00743 }
00744
00745 $attrs = array(
00746 "respident" => "gap_$i"
00747 );
00748 $a_xml_writer->xmlElement("varequal", $attrs, $answer->get_answertext());
00749 if (!$answer->isStateSet())
00750 {
00751 $a_xml_writer->xmlEndTag("not");
00752 }
00753 $a_xml_writer->xmlEndTag("conditionvar");
00754
00755 $attrs = array(
00756 "action" => "Add"
00757 );
00758 $a_xml_writer->xmlElement("setvar", $attrs, $answer->get_points());
00759
00760 $linkrefid = "";
00761 if ($answer->get_points() > 0)
00762 {
00763 $linkrefid = "$i" . "_True";
00764 }
00765 else
00766 {
00767 $linkrefid = "$i" . "_False_$index";
00768 }
00769 $attrs = array(
00770 "feedbacktype" => "Response",
00771 "linkrefid" => $linkrefid
00772 );
00773 $a_xml_writer->xmlElement("displayfeedback", $attrs);
00774 $a_xml_writer->xmlEndTag("respcondition");
00775 }
00776 }
00777 else
00778 {
00779 foreach ($gap as $index => $answer)
00780 {
00781 $attrs = array(
00782 "continue" => "Yes"
00783 );
00784 $a_xml_writer->xmlStartTag("respcondition", $attrs);
00785
00786 $a_xml_writer->xmlStartTag("conditionvar");
00787 $attrs = array(
00788 "respident" => "gap_$i"
00789 );
00790 $a_xml_writer->xmlElement("varequal", $attrs, $answer->get_answertext());
00791 $a_xml_writer->xmlEndTag("conditionvar");
00792
00793 $attrs = array(
00794 "action" => "Add"
00795 );
00796 $a_xml_writer->xmlElement("setvar", $attrs, $answer->get_points());
00797
00798 $attrs = array(
00799 "feedbacktype" => "Response",
00800 "linkrefid" => "$i" . "_True_$index"
00801 );
00802 $a_xml_writer->xmlElement("displayfeedback", $attrs);
00803 $a_xml_writer->xmlEndTag("respcondition");
00804 }
00805 }
00806 }
00807 $a_xml_writer->xmlEndTag("resprocessing");
00808
00809
00810 for ($i = 0; $i < $this->get_gap_count(); $i++)
00811 {
00812 $gap = $this->get_gap($i);
00813 if ($gap[0]->get_cloze_type() == CLOZE_SELECT)
00814 {
00815 foreach ($gap as $index => $answer)
00816 {
00817 $linkrefid = "";
00818 if ($answer->isStateSet())
00819 {
00820 $linkrefid = "$i" . "_True";
00821 }
00822 else
00823 {
00824 $linkrefid = "$i" . "_False_$index";
00825 }
00826 $attrs = array(
00827 "ident" => $linkrefid,
00828 "view" => "All"
00829 );
00830 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
00831
00832 $a_xml_writer->xmlStartTag("flow_mat");
00833 $a_xml_writer->xmlStartTag("material");
00834 $a_xml_writer->xmlElement("mattext");
00835 $a_xml_writer->xmlEndTag("material");
00836 $a_xml_writer->xmlEndTag("flow_mat");
00837 $a_xml_writer->xmlEndTag("itemfeedback");
00838 }
00839 }
00840 else
00841 {
00842 foreach ($gap as $index => $answer)
00843 {
00844 $linkrefid = "";
00845 if ($answer->isStateSet())
00846 {
00847 $linkrefid = "$i" . "_True_$index";
00848 }
00849 else
00850 {
00851 $linkrefid = "$i" . "_False_$index";
00852 }
00853 $attrs = array(
00854 "ident" => $linkrefid,
00855 "view" => "All"
00856 );
00857 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
00858
00859 $a_xml_writer->xmlStartTag("flow_mat");
00860 $a_xml_writer->xmlStartTag("material");
00861 $a_xml_writer->xmlElement("mattext");
00862 $a_xml_writer->xmlEndTag("material");
00863 $a_xml_writer->xmlEndTag("flow_mat");
00864 $a_xml_writer->xmlEndTag("itemfeedback");
00865 }
00866 }
00867 }
00868
00869 $a_xml_writer->xmlEndTag("item");
00870 $a_xml_writer->xmlEndTag("questestinterop");
00871
00872 $xml = $a_xml_writer->xmlDumpMem(FALSE);
00873 if (!$a_include_header)
00874 {
00875 $pos = strpos($xml, "?>");
00876 $xml = substr($xml, $pos + 2);
00877 }
00878 return $xml;
00879 }
00880
00892 function set_cloze_text($cloze_text = "")
00893 {
00894 $this->gaps = array();
00895 $this->cloze_text =& $cloze_text;
00896 $close = $this->createCloseTextArray();
00897 if (count($close))
00898 {
00899 foreach ($close["gaps"] as $key => $value)
00900 {
00901 if (strcmp(strtolower($value["params"]["type"]), "select") == 0)
00902 {
00903 $type = CLOZE_SELECT;
00904 }
00905 else
00906 {
00907 $type = CLOZE_TEXT;
00908 }
00909 if ($type == CLOZE_TEXT)
00910 {
00911 $default_state = 1;
00912 }
00913 else
00914 {
00915 $default_state = 0;
00916 }
00917 $name = $value["params"]["name"];
00918 if (strcmp(strtolower($value["params"]["shuffle"]), "no") == 0)
00919 {
00920 $shuffle = 0;
00921 }
00922 else
00923 {
00924 $shuffle = 1;
00925 }
00926 $answer_array = array();
00927 include_once "./assessment/classes/class.assAnswerCloze.php";
00928 foreach ($value["text"] as $index => $textvalue)
00929 {
00930 if (preg_match("/\d+/", $index))
00931 {
00932 $textvalue = str_replace("\,", ",", $textvalue);
00933 array_push($answer_array, new ASS_AnswerCloze($textvalue, 0, $index, $default_state, $type, $name, $shuffle));
00934 }
00935 }
00936 array_push($this->gaps, $answer_array);
00937 }
00938 }
00939 }
00940
00950 function get_cloze_text() {
00951 return $this->cloze_text;
00952 }
00953
00963 function get_start_tag() {
00964 return $this->start_tag;
00965 }
00966
00976 function get_end_tag() {
00977 return $this->end_tag;
00978 }
00979
00989 function set_start_tag($start_tag = "<gap>") {
00990 $this->start_tag = $start_tag;
00991 }
00992
00993
01003 function set_end_tag($end_tag = "</gap>") {
01004 $this->end_tag = $end_tag;
01005 }
01006
01015 function rebuild_cloze_text()
01016 {
01017 $close =& $this->createCloseTextArray();
01018 if (count($close))
01019 {
01020 for ($i = 0; $i < count($this->gaps); $i++)
01021 {
01022 $gaptext = $this->get_gap_text_list($i);
01023 $textparams = preg_split("/(?<!\\\\),/", $gaptext);
01024 $close["gaps"][$i]["text"] = array();
01025 $close["gaps"][$i]["text"]["text"] = $gaptext;
01026 foreach ($textparams as $key => $value)
01027 {
01028 $close["gaps"][$i]["text"][$key] = $value;
01029 }
01030 }
01031 }
01032 $this->createCloseTextFromArray($close);
01033 }
01034
01046 function get_gap($index = 0) {
01047 if ($index < 0) return array();
01048 if (count($this->gaps) < 1) return array();
01049 if ($index >= count($this->gaps)) return array();
01050 return $this->gaps[$index];
01051 }
01052
01062 function get_gap_count() {
01063 return count($this->gaps);
01064 }
01065
01078 function get_gap_text_list($index = 0, $separator = ",") {
01079 if ($index < 0) return "";
01080 if (count($this->gaps) < 1) return "";
01081 if ($index >= count($this->gaps)) return "";
01082 $result = array();
01083 foreach ($this->gaps[$index] as $key => $value) {
01084 array_push($result, str_replace(",", "\,", $value->get_answertext()));
01085 }
01086 return join($separator, $result);
01087 }
01097 function get_gap_text_count($index = 0) {
01098 if ($index < 0) return 0;
01099 if (count($this->gaps) < 1) return 0;
01100 if ($index >= count($this->gaps)) return 0;
01101 return count($this->gaps[$index]);
01102 }
01113 function delete_gap($index = 0) {
01114 if ($index < 0) return;
01115 if (count($this->gaps) < 1) return;
01116 if ($index >= count($this->gaps)) return;
01117 $close = $this->createCloseTextArray();
01118 unset($close["gaps"][$index]);
01119 $this->createCloseTextFromArray($close);
01120 unset($this->gaps[$index]);
01121 $this->gaps = array_values($this->gaps);
01122 }
01123
01132 function flush_gaps() {
01133 $this->gaps = array();
01134 }
01135
01147 function delete_answertext_by_index($gap_index = 0, $answertext_index = 0) {
01148 if ($gap_index < 0) return;
01149 if (count($this->gaps) < 1) return;
01150 if ($gap_index >= count($this->gaps)) return;
01151 $old_text = $this->get_gap_text_list($gap_index);
01152 if (count($this->gaps[$gap_index]) == 1) {
01153 $this->delete_gap($gap_index);
01154 } else {
01155 $close = $this->createCloseTextArray();
01156 unset($this->gaps[$gap_index][$answertext_index]);
01157 $this->gaps[$gap_index] = array_values($this->gaps[$gap_index]);
01158 unset($close["gaps"][$gap_index]["text"][$answertext_index]);
01159 $this->createCloseTextFromArray($close);
01160 }
01161 }
01162
01175 function set_answertext($index = 0, $answertext_index = 0, $answertext = "", $add_gaptext=0)
01176 {
01177 $answertext = str_replace("\,", ",", $answertext);
01178 if ($add_gaptext == 1)
01179 {
01180 $arr = $this->gaps[$index][0];
01181 if (strlen($this->gaps[$index][count($this->gaps[$index])-1]->get_answertext()) != 0)
01182 {
01183 $default_state = 0;
01184 $default_points = 0;
01185 if ($arr->get_cloze_type() == CLOZE_TEXT)
01186 {
01187 $default_state = 1;
01188 if ($answertext_index > 0) $default_points = $this->gaps[$index][0]->get_points();
01189 }
01190 include_once "./assessment/classes/class.assAnswerCloze.php";
01191 array_push($this->gaps[$index], new ASS_AnswerCloze($answertext, $default_points, count($this->gaps[$index]),
01192 $default_state, $arr->get_cloze_type(),
01193 $arr->get_name(), $arr->get_shuffle()));
01194 $this->rebuild_cloze_text();
01195 }
01196 return;
01197 }
01198 if ($index < 0) return;
01199 if (count($this->gaps) < 1) return;
01200 if ($index >= count($this->gaps)) return;
01201 if ($answertext_index < 0) return;
01202 if (count($this->gaps[$index]) < 1) return;
01203 if ($answertext_index >= count($this->gaps[$index])) return;
01204
01205
01206 if (strlen($answertext) == 0)
01207 {
01208
01209 $this->delete_answertext($index, $this->gaps[$index][$answertext_index]->get_answertext());
01210 }
01211 else
01212 {
01213 $this->gaps[$index][$answertext_index]->set_answertext($answertext);
01214 $this->rebuild_cloze_text();
01215 }
01216 }
01217
01226 function update_all_gap_params() {
01227 global $lng;
01228 $close = $this->createCloseTextArray();
01229 for ($i = 0; $i < $this->get_gap_count(); $i++)
01230 {
01231 $gaptext = $this->get_gap_text_list($i);
01232 if ($this->gaps[$i][0]->get_cloze_type() == CLOZE_TEXT)
01233 {
01234 $close["gaps"][$i]["params"]["type"] = "text";
01235 if (array_key_exists("shuffle", $close["gaps"][$i]["params"]))
01236 {
01237 unset($close["gaps"][$i]["params"]["shuffle"]);
01238 }
01239 }
01240 else
01241 {
01242 $close["gaps"][$i]["params"]["type"] = "select";
01243 if ($this->gaps[$i][0]->get_shuffle() == 0)
01244 {
01245 $close["gaps"][$i]["params"]["shuffle"] = "no";
01246 }
01247 else
01248 {
01249 $close["gaps"][$i]["params"]["shuffle"] = "yes";
01250 }
01251 }
01252 $name = $this->gaps[$i][0]->get_name();
01253 if (!$name)
01254 {
01255 $name = $this->lng->txt("gap") . " " . ($i+1);
01256 }
01257 $close["gaps"][$i]["params"]["name"] = $name;
01258 }
01259 $this->createCloseTextFromArray($close);
01260 }
01261
01272 function set_cloze_type($index, $cloze_type = CLOZE_TEXT) {
01273 if ($index < 0) return;
01274 if (count($this->gaps) < 1) return;
01275 if ($index >= count($this->gaps)) return;
01276 $close = $this->createCloseTextArray();
01277 foreach ($this->gaps[$index] as $key => $value) {
01278 $this->gaps[$index][$key]->set_cloze_type($cloze_type);
01279 $this->gaps[$index][$key]->setState(1);
01280 }
01281 if ($cloze_type == CLOZE_TEXT)
01282 {
01283 $type = "text";
01284 }
01285 else
01286 {
01287 $type = "select";
01288 }
01289 $close["gaps"][$index]["type"] = $type;
01290 $this->createCloseTextFromArray($close);
01291 }
01292
01304 function set_gap_points($index = 0, $points = 0.0) {
01305 if ($index < 0) return;
01306 if (count($this->gaps) < 1) return;
01307 if ($index >= count($this->gaps)) return;
01308 foreach ($this->gaps[$index] as $key => $value) {
01309 $this->gaps[$index][$key]->set_points($points);
01310 }
01311 }
01312
01324 function set_gap_shuffle($index = 0, $shuffle = 1) {
01325 if ($index < 0) return;
01326 if (count($this->gaps) < 1) return;
01327 if ($index >= count($this->gaps)) return;
01328 foreach ($this->gaps[$index] as $key => $value) {
01329 $this->gaps[$index][$key]->set_shuffle($shuffle);
01330 }
01331 }
01332
01333
01346 function set_single_answer_points($index_gaps = 0, $index_answerobject = 0, $points = 0.0) {
01347 if ($index_gaps < 0) return;
01348 if (count($this->gaps) < 1) return;
01349 if ($index_gaps >= count($this->gaps)) return;
01350 if ($index_answerobject < 0) return;
01351 if (count($this->gaps[$index_gaps]) < 1) return;
01352 if ($index_answerobject >= count($this->gaps[$index_gaps])) return;
01353 $this->gaps[$index_gaps][$index_answerobject]->set_points($points);
01354 }
01355
01368 function set_single_answer_state($index_gaps = 0, $index_answerobject = 0, $state = 0) {
01369 if ($index_gaps < 0) return;
01370 if (count($this->gaps) < 1) return;
01371 if ($index_gaps >= count($this->gaps)) return;
01372 if ($index_answerobject < 0) return;
01373 if (count($this->gaps[$index_gaps]) < 1) return;
01374 if ($index_answerobject >= count($this->gaps[$index_gaps])) return;
01375 $this->gaps[$index_gaps][$index_answerobject]->setState($state);
01376 }
01377
01389 function getTextgapPoints($a_original, $a_entered, $max_points)
01390 {
01391 $result = 0;
01392 $gaprating = $this->getTextgapRating();
01393 switch ($gaprating)
01394 {
01395 case TEXTGAP_RATING_CASEINSENSITIVE:
01396 if (strcmp(strtolower(utf8_decode($a_original)), strtolower(utf8_decode($a_entered))) == 0) $result = $max_points;
01397 break;
01398 case TEXTGAP_RATING_CASESENSITIVE:
01399 if (strcmp(utf8_decode($a_original), utf8_decode($a_entered)) == 0) $result = $max_points;
01400 break;
01401 case TEXTGAP_RATING_LEVENSHTEIN1:
01402 if (levenshtein(utf8_decode($a_original), utf8_decode($a_entered)) <= 1) $result = $max_points;
01403 break;
01404 case TEXTGAP_RATING_LEVENSHTEIN2:
01405 if (levenshtein(utf8_decode($a_original), utf8_decode($a_entered)) <= 2) $result = $max_points;
01406 break;
01407 case TEXTGAP_RATING_LEVENSHTEIN3:
01408 if (levenshtein(utf8_decode($a_original), utf8_decode($a_entered)) <= 3) $result = $max_points;
01409 break;
01410 case TEXTGAP_RATING_LEVENSHTEIN4:
01411 if (levenshtein(utf8_decode($a_original), utf8_decode($a_entered)) <= 4) $result = $max_points;
01412 break;
01413 case TEXTGAP_RATING_LEVENSHTEIN5:
01414 if (levenshtein(utf8_decode($a_original), utf8_decode($a_entered)) <= 5) $result = $max_points;
01415 break;
01416 }
01417 return $result;
01418 }
01419
01431 function calculateReachedPoints($user_id, $test_id, $pass = NULL)
01432 {
01433 global $ilDB;
01434
01435 $found_value1 = array();
01436 $found_value2 = array();
01437 if (is_null($pass))
01438 {
01439 $pass = $this->getSolutionMaxPass($user_id, $test_id);
01440 }
01441 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
01442 $ilDB->quote($user_id . ""),
01443 $ilDB->quote($test_id . ""),
01444 $ilDB->quote($this->getId() . ""),
01445 $ilDB->quote($pass . "")
01446 );
01447 $result = $ilDB->query($query);
01448 $user_result = array();
01449 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01450 {
01451 if (strcmp($data->value2, "") != 0)
01452 {
01453 $user_result[$data->value1] = array(
01454 "gap_id" => $data->value1,
01455 "value" => $data->value2
01456 );
01457 }
01458 }
01459 $points = 0;
01460 $counter = 0;
01461 foreach ($user_result as $gap_id => $value)
01462 {
01463 if ($this->gaps[$gap_id][0]->get_cloze_type() == CLOZE_TEXT)
01464 {
01465 $gappoints = 0;
01466 foreach ($this->gaps[$gap_id] as $k => $v)
01467 {
01468 $gotpoints = $this->getTextgapPoints($v->get_answertext(), $value["value"], $v->get_points());
01469 if ($gotpoints > $gappoints) $gappoints = $gotpoints;
01470 }
01471 $points += $gappoints;
01472 }
01473 else
01474 {
01475 if ($value["value"] >= 0)
01476 {
01477 foreach ($this->gaps[$gap_id] as $answerkey => $answer)
01478 {
01479 if ($value["value"] == $answerkey)
01480 {
01481 $points += $answer->get_points();
01482 }
01483 }
01484 }
01485 }
01486 }
01487
01488
01489 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
01490 $ilDB->quote($test_id)
01491 );
01492 $result = $ilDB->query($query);
01493 if ($result->numRows() == 1)
01494 {
01495 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01496 if ($row["count_system"] == 1)
01497 {
01498 if ($points != $this->getMaximumPoints())
01499 {
01500 $points = 0;
01501 }
01502 }
01503 }
01504 else
01505 {
01506 $points = 0;
01507 }
01508 return $points;
01509 }
01510
01520 function getReachedInformation($user_id, $test_id, $pass = NULL)
01521 {
01522 $found_value1 = array();
01523 $found_value2 = array();
01524 $pass = array();
01525 if (is_null($pass))
01526 {
01527 $pass = $this->getSolutionMaxPass($user_id, $test_id);
01528 }
01529 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
01530 $this->ilias->db->quote($user_id . ""),
01531 $this->ilias->db->quote($test_id . ""),
01532 $this->ilias->db->quote($this->getId() . ""),
01533 $this->ilias->db->quote($pass . "")
01534 );
01535 $result = $this->ilias->db->query($query);
01536 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01537 {
01538 array_push($found_value1, $data->value1);
01539 array_push($found_value2, $data->value2);
01540 }
01541 $counter = 1;
01542 $user_result = array();
01543 foreach ($found_value1 as $key => $value)
01544 {
01545 if ($this->gaps[$value][0]->get_cloze_type() == CLOZE_TEXT)
01546 {
01547 $solution = array(
01548 "gap" => "$counter",
01549 "points" => 0,
01550 "true" => 0,
01551 "value" => $found_value2[$key]
01552 );
01553 foreach ($this->gaps[$value] as $k => $v)
01554 {
01555 if (strcmp(strtolower($v->get_answertext()), strtolower($found_value2[$key])) == 0)
01556 {
01557 $solution = array(
01558 "gap" => "$counter",
01559 "points" => $v->get_points(),
01560 "true" => 1,
01561 "value" => $found_value2[$key]
01562 );
01563 }
01564 }
01565 }
01566 else
01567 {
01568 $solution = array(
01569 "gap" => "$counter",
01570 "points" => 0,
01571 "true" => 0,
01572 "value" => $found_value2[$key]
01573 );
01574 if ($this->gaps[$value][$found_value1[$key]]->isStateSet())
01575 {
01576 $solution["points"] = $this->gaps[$value][$found_value1[$key]]->get_points();
01577 $solution["true"] = 1;
01578 }
01579 }
01580 $counter++;
01581 $user_result[$value] = $solution;
01582 }
01583 return $user_result;
01584 }
01585
01594 function getMaximumPoints() {
01595 $points = 0;
01596 foreach ($this->gaps as $key => $value) {
01597 if ($value[0]->get_cloze_type() == CLOZE_TEXT)
01598 {
01599 $gap_max_points = 0;
01600 foreach ($value as $key2 => $value2)
01601 {
01602 if ($value2->get_points() > $gap_max_points)
01603 {
01604 $gap_max_points = $value2->get_points();
01605 }
01606 }
01607 $points += $gap_max_points;
01608 } else
01609 {
01610 $points_arr = array("set" => 0, "unset" => 0);
01611 foreach ($value as $key2 => $value2)
01612 {
01613 if ($value2->get_points() > $points_arr["set"])
01614 {
01615 $points_arr["set"] = $value2->get_points();
01616 }
01617 }
01618 $points += $points_arr["set"];
01619 }
01620 }
01621 return $points;
01622 }
01623
01634 function saveWorkingData($test_id, $pass = NULL)
01635 {
01636 global $ilDB;
01637 global $ilUser;
01638 $db =& $ilDB->db;
01639
01640 include_once "./assessment/classes/class.ilObjTest.php";
01641 $activepass = ilObjTest::_getPass($ilUser->id, $test_id);
01642
01643 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
01644 $db->quote($ilUser->id),
01645 $db->quote($test_id),
01646 $db->quote($this->getId()),
01647 $db->quote($activepass . "")
01648 );
01649 $result = $db->query($query);
01650
01651 $entered_values = 0;
01652 foreach ($_POST as $key => $value) {
01653 if (preg_match("/^gap_(\d+)/", $key, $matches))
01654 {
01655 $value = ilUtil::stripSlashes($value);
01656 if (strlen($value))
01657 {
01658 $gap = $this->get_gap($matches[1]);
01659 if (!(($gap[0]->get_cloze_type() == CLOZE_SELECT) && ($value == -1)))
01660 {
01661 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
01662 $db->quote($ilUser->id),
01663 $db->quote($test_id),
01664 $db->quote($this->getId()),
01665 $db->quote($matches[1]),
01666 $db->quote($value),
01667 $db->quote($activepass . "")
01668 );
01669 $result = $db->query($query);
01670 $entered_values++;
01671 }
01672 }
01673 }
01674 }
01675 if ($entered_values)
01676 {
01677 include_once ("./classes/class.ilObjAssessmentFolder.php");
01678 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01679 {
01680 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $test_id, $this->getId());
01681 }
01682 }
01683 else
01684 {
01685 include_once ("./classes/class.ilObjAssessmentFolder.php");
01686 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01687 {
01688 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $test_id, $this->getId());
01689 }
01690 }
01691 parent::saveWorkingData($test_id, $pass);
01692 return true;
01693 }
01694
01695 function syncWithOriginal()
01696 {
01697 global $ilias;
01698 if ($this->original_id)
01699 {
01700 $complete = 0;
01701 if ($this->isComplete())
01702 {
01703 $complete = 1;
01704 }
01705 $db = & $ilias->db;
01706
01707 $estw_time = $this->getEstimatedWorkingTime();
01708 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01709
01710 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, points = %s, author = %s, question_text = %s, working_time = %s, shuffle = %s, textgap_rating = %s, complete = %s WHERE question_id = %s",
01711 $db->quote($this->obj_id. ""),
01712 $db->quote($this->title . ""),
01713 $db->quote($this->comment . ""),
01714 $db->quote($this->getMaximumPoints() . ""),
01715 $db->quote($this->author . ""),
01716 $db->quote($this->cloze_text . ""),
01717 $db->quote($estw_time . ""),
01718 $db->quote($this->shuffle . ""),
01719 $db->quote($this->textgap_rating . ""),
01720 $db->quote($complete . ""),
01721 $db->quote($this->original_id . "")
01722 );
01723 $result = $db->query($query);
01724
01725 if ($result == DB_OK)
01726 {
01727
01728
01729 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01730 $db->quote($this->original_id)
01731 );
01732 $result = $db->query($query);
01733
01734 foreach ($this->gaps as $key => $value)
01735 {
01736 foreach ($value as $answer_id => $answer_obj)
01737 {
01738 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, gap_id, answertext, points, aorder, cloze_type, name, shuffle, correctness, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
01739 $db->quote($this->original_id . ""),
01740 $db->quote($key . ""),
01741 $db->quote($answer_obj->get_answertext() . ""),
01742 $db->quote($answer_obj->get_points() . ""),
01743 $db->quote($answer_obj->get_order() . ""),
01744 $db->quote($answer_obj->get_cloze_type() . ""),
01745 $db->quote($answer_obj->get_name() . ""),
01746 $db->quote($answer_obj->get_shuffle() . ""),
01747 $db->quote($answer_obj->getState() . "")
01748 );
01749 $answer_result = $db->query($query);
01750 }
01751 }
01752 }
01753 parent::syncWithOriginal();
01754 }
01755 }
01756
01765 function getQuestionType()
01766 {
01767 return 3;
01768 }
01769
01778 function getColumnSize($gap)
01779 {
01780 $size = 0;
01781 foreach ($gap as $answer)
01782 {
01783 $answertextsize = strlen($answer->get_answertext());
01784 if ($answertextsize > $size) $size = $answertextsize;
01785 }
01786 return $size;
01787 }
01788
01798 function getTextgapRating()
01799 {
01800 return $this->textgap_rating;
01801 }
01802
01812 function setTextgapRating($a_textgap_rating)
01813 {
01814 switch ($a_textgap_rating)
01815 {
01816 case TEXTGAP_RATING_CASEINSENSITIVE:
01817 case TEXTGAP_RATING_CASESENSITIVE:
01818 case TEXTGAP_RATING_LEVENSHTEIN1:
01819 case TEXTGAP_RATING_LEVENSHTEIN2:
01820 case TEXTGAP_RATING_LEVENSHTEIN3:
01821 case TEXTGAP_RATING_LEVENSHTEIN4:
01822 case TEXTGAP_RATING_LEVENSHTEIN5:
01823 $this->textgap_rating = $a_textgap_rating;
01824 break;
01825 default:
01826 $this->textgap_rating = TEXTGAP_RATING_CASEINSENSITIVE;
01827 break;
01828 }
01829 }
01830 }
01831
01832 ?>