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 require_once "./assessment/classes/class.assQuestion.php";
00025 require_once "./assessment/classes/class.assAnswerCloze.php";
00026 require_once "./assessment/classes/class.ilQTIUtils.php";
00027
00028 define("CLOZE_TEXT", "0");
00029 define("CLOZE_SELECT", "1");
00030 define("CLOZE_TEST_IDENTIFIER", "CLOZE QUESTION");
00031
00042 class ASS_ClozeTest extends ASS_Question
00043 {
00052 var $cloze_text;
00053
00061 var $gaps;
00062
00070 var $start_tag;
00071
00079 var $end_tag;
00092 function ASS_ClozeTest(
00093 $title = "",
00094 $comment = "",
00095 $author = "",
00096 $owner = -1,
00097 $cloze_text = ""
00098 )
00099 {
00100 $this->start_tag = "<gap>";
00101 $this->end_tag = "</gap>";
00102 $this->ASS_Question($title, $comment, $author, $owner);
00103 $this->gaps = array();
00104 $this->set_cloze_text($cloze_text);
00105 }
00106
00115 function isComplete()
00116 {
00117 if (($this->title) and ($this->author) and ($this->cloze_text) and (count($this->gaps)))
00118 {
00119 return true;
00120 }
00121 else
00122 {
00123 return false;
00124 }
00125 }
00126
00135 function &createCloseTextArray()
00136 {
00137 $result = array();
00138 $search_pattern = "|<gap([^>]*?)>(.*?)</gap>|i";
00139 preg_match_all($search_pattern, $this->cloze_text, $gaps);
00140 if (count($gaps[0]))
00141 {
00142
00143 $delimiters = preg_split($search_pattern, $this->cloze_text, -1, PREG_SPLIT_OFFSET_CAPTURE);
00144 $result["gaps"] = array();
00145 foreach ($gaps[0] as $index => $gap)
00146 {
00147 $result["gaps"][$index] = array();
00148 $result["gaps"][$index]["gap"] = $gap;
00149 $result["gaps"][$index]["params"] = array();
00150 $result["gaps"][$index]["params"]["text"] = $gaps[1][$index];
00151
00152 if (preg_match("/name\=\"([^\"]*?)\"/", $gaps[1][$index], $params))
00153 {
00154 $result["gaps"][$index]["params"]["name"] = $params[1];
00155 }
00156 else
00157 {
00158 $result["gaps"][$index]["params"]["name"] = $this->lng->txt("gap") . " " . ($index+1);
00159 }
00160 if (preg_match("/type\=\"([^\"]*?)\"/", $gaps[1][$index], $params))
00161 {
00162 $result["gaps"][$index]["params"]["type"] = $params[1];
00163 }
00164 else
00165 {
00166 $result["gaps"][$index]["params"]["type"] = "text";
00167 }
00168 if (preg_match("/shuffle\=\"([^\"]*?)\"/", $gaps[1][$index], $params))
00169 {
00170 $result["gaps"][$index]["params"]["shuffle"] = $params[1];
00171 }
00172 else
00173 {
00174 if (strcmp(strtolower($result["gaps"][$index]["params"]["type"]), "select") == 0)
00175 {
00176 $result["gaps"][$index]["params"]["shuffle"] = "yes";
00177 }
00178 }
00179 $result["gaps"][$index]["text"] = array();
00180 $result["gaps"][$index]["text"]["text"] = $gaps[2][$index];
00181 $textparams = preg_split("/(?<!\\\\),/", $gaps[2][$index]);
00182 foreach ($textparams as $key => $value)
00183 {
00184 $result["gaps"][$index]["text"][$key] = $value;
00185 }
00186 }
00187 $result["delimiters"] = $delimiters;
00188 }
00189
00190 return $result;
00191 }
00192
00201 function createCloseTextFromArray($assoc_array)
00202 {
00203 $this->cloze_text = "";
00204 if (count($assoc_array))
00205 {
00206 $gap = 0;
00207 foreach ($assoc_array["delimiters"] as $key => $value)
00208 {
00209 if (($key > 0) && ($key < count($assoc_array["delimiters"])))
00210 {
00211 if (strcmp($assoc_array["gaps"][$gap]["params"]["shuffle"], "") == 0)
00212 {
00213 $shuffle = "";
00214 }
00215 else
00216 {
00217 $shuffle = " shuffle=\"" . $assoc_array["gaps"][$gap]["params"]["shuffle"] . "\"";
00218 }
00219 if (strlen($assoc_array["gaps"][$gap]["text"]["text"]))
00220 {
00221 $textarray = array();
00222 foreach ($assoc_array["gaps"][$gap]["text"] as $textindex => $textvalue)
00223 {
00224 if (preg_match("/\d+/", $textindex))
00225 {
00226 array_push($textarray, $textvalue);
00227 }
00228 }
00229 $this->cloze_text .= sprintf("<gap name=\"%s\" type=\"%s\"%s>%s</gap>",
00230 $assoc_array["gaps"][$gap]["params"]["name"],
00231 $assoc_array["gaps"][$gap]["params"]["type"],
00232 $shuffle,
00233 join(",", $textarray)
00234 );
00235 }
00236 $gap++;
00237 }
00238 $this->cloze_text .= $value[0];
00239 }
00240 }
00241 }
00242
00251 function saveToDb($original_id = "")
00252 {
00253 global $ilias;
00254
00255 $db =& $ilias->db;
00256 $complete = 0;
00257 if ($this->isComplete())
00258 {
00259 $complete = 1;
00260 }
00261
00262 $estw_time = $this->getEstimatedWorkingTime();
00263 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00264 $shuffle = 1;
00265
00266 if (!$this->shuffle)
00267 {
00268 $shuffle = 0;
00269 }
00270
00271 if ($original_id)
00272 {
00273 $original_id = $db->quote($original_id);
00274 }
00275 else
00276 {
00277 $original_id = "NULL";
00278 }
00279
00280 if ($this->id == -1)
00281 {
00282
00283 $now = getdate();
00284 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00285 $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, shuffle, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00286 $db->quote($this->getQuestionType()),
00287 $db->quote($this->obj_id),
00288 $db->quote($this->title),
00289 $db->quote($this->comment),
00290 $db->quote($this->author),
00291 $db->quote($this->owner),
00292 $db->quote($this->cloze_text),
00293 $db->quote($estw_time),
00294 $db->quote("$this->shuffle"),
00295 $db->quote("$complete"),
00296 $db->quote($created),
00297 $original_id
00298 );
00299 $result = $db->query($query);
00300 if ($result == DB_OK)
00301 {
00302 $this->id = $this->ilias->db->getLastInsertId();
00303
00304
00305 $this->createPageObject();
00306
00307
00308 if ($this->getTestId() > 0)
00309 {
00310 $this->insertIntoTest($this->getTestId());
00311 }
00312 }
00313 }
00314 else
00315 {
00316
00317 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, shuffle = %s, complete = %s WHERE question_id = %s",
00318 $db->quote($this->obj_id. ""),
00319 $db->quote($this->title),
00320 $db->quote($this->comment),
00321 $db->quote($this->author),
00322 $db->quote($this->cloze_text),
00323 $db->quote($estw_time),
00324 $db->quote("$this->shuffle"),
00325 $db->quote("$complete"),
00326 $db->quote($this->id)
00327 );
00328 $result = $db->query($query);
00329 }
00330
00331 if ($result == DB_OK)
00332 {
00333
00334
00335
00336 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00337 $db->quote($this->id)
00338 );
00339 $result = $db->query($query);
00340
00341 foreach ($this->gaps as $key => $value)
00342 {
00343 foreach ($value as $answer_id => $answer_obj)
00344 {
00345 $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)",
00346 $db->quote($this->id),
00347 $db->quote($key),
00348 $db->quote($answer_obj->get_answertext() . ""),
00349 $db->quote($answer_obj->get_points() . ""),
00350 $db->quote($answer_obj->get_order() . ""),
00351 $db->quote($answer_obj->get_cloze_type() . ""),
00352 $db->quote($answer_obj->get_name() . ""),
00353 $db->quote($answer_obj->get_shuffle() . ""),
00354 $db->quote($answer_obj->getState() . "")
00355 );
00356 $answer_result = $db->query($query);
00357 }
00358 }
00359 }
00360 parent::saveToDb($original_id);
00361 }
00362
00372 function loadFromDb($question_id)
00373 {
00374 global $ilias;
00375 $db =& $ilias->db;
00376
00377 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00378 $db->quote($question_id)
00379 );
00380 $result = $db->query($query);
00381 if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00382 if ($result->numRows() == 1) {
00383 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00384 $this->id = $question_id;
00385 $this->obj_id = $data->obj_fi;
00386 $this->title = $data->title;
00387 $this->comment = $data->comment;
00388 $this->solution_hint = $data->solution_hint;
00389 $this->original_id = $data->original_id;
00390 $this->author = $data->author;
00391 $this->owner = $data->owner;
00392 $this->cloze_text = $data->question_text;
00393 $this->shuffle = $data->shuffle;
00394 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00395 }
00396
00397 $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY gap_id, aorder ASC",
00398 $db->quote($question_id)
00399 );
00400 $result = $db->query($query);
00401 if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00402 $counter = -1;
00403 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
00404 if ($data->gap_id != $counter) {
00405 $answer_array = array();
00406 array_push($this->gaps, $answer_array);
00407 $counter = $data->gap_id;
00408 }
00409 if ($data->cloze_type == CLOZE_SELECT)
00410 {
00411 if ($data->correctness == 0)
00412 {
00413
00414 $data->correctness = 1;
00415 $data->points = 0;
00416 }
00417 }
00418 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));
00419 }
00420 }
00421 }
00422 parent::loadFromDb($question_id);
00423 }
00424
00432 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00433 {
00434 if ($this->id <= 0)
00435 {
00436
00437 return;
00438 }
00439
00440 $clone = $this;
00441 $original_id = $this->id;
00442 if ($original_id <= 0)
00443 {
00444 $original_id = "";
00445 }
00446 $clone->id = -1;
00447 if ($title)
00448 {
00449 $clone->setTitle($title);
00450 }
00451 if ($author)
00452 {
00453 $clone->setAuthor($author);
00454 }
00455 if ($owner)
00456 {
00457 $clone->setOwner($owner);
00458 }
00459 if ($for_test)
00460 {
00461 $clone->saveToDb($original_id);
00462 }
00463 else
00464 {
00465 $clone->saveToDb();
00466 }
00467
00468
00469 $clone->copyPageOfQuestion($original_id);
00470
00471 return $clone->id;
00472 }
00473
00483 function from_xml($xml_text)
00484 {
00485 $result = false;
00486 if (!empty($this->domxml))
00487 {
00488 $this->domxml->free();
00489 }
00490 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
00491 $this->domxml = domxml_open_mem($xml_text);
00492 if (!empty($this->domxml))
00493 {
00494 $root = $this->domxml->document_element();
00495 $item = $root->first_child();
00496 $this->setTitle($item->get_attribute("title"));
00497 $this->gaps = array();
00498 $itemnodes = $item->child_nodes();
00499 $materials = array();
00500 $gapcounter = 0;
00501 foreach ($itemnodes as $index => $node)
00502 {
00503 switch ($node->node_name())
00504 {
00505 case "qticomment":
00506 $comment = $node->get_content();
00507 if (strpos($comment, "ILIAS Version=") !== false)
00508 {
00509 }
00510 elseif (strpos($comment, "Questiontype=") !== false)
00511 {
00512 }
00513 elseif (strpos($comment, "Author=") !== false)
00514 {
00515 $comment = str_replace("Author=", "", $comment);
00516 $this->setAuthor($comment);
00517 }
00518 else
00519 {
00520 $this->setComment($comment);
00521 }
00522 break;
00523 case "duration":
00524 $iso8601period = $node->get_content();
00525 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
00526 {
00527 $this->setEstimatedWorkingTime($matches[4], $matches[5], $matches[6]);
00528 }
00529 break;
00530 case "presentation":
00531 $flow = $node->first_child();
00532 $flownodes = $flow->child_nodes();
00533 foreach ($flownodes as $idx => $flownode)
00534 {
00535 if (strcmp($flownode->node_name(), "material") == 0)
00536 {
00537 $mattext = $flownode->first_child();
00538 array_push($materials, $mattext->get_content());
00539 }
00540 elseif (strcmp($flownode->node_name(), "response_str") == 0)
00541 {
00542 $ident = $flownode->get_attribute("ident");
00543 $this->gaps["$ident"] = array();
00544 $shuffle = "";
00545 $subnodes = $flownode->child_nodes();
00546 foreach ($subnodes as $node_type)
00547 {
00548 switch ($node_type->node_name())
00549 {
00550 case "render_choice":
00551 $render_type = $node_type;
00552 if (strcmp($render_type->node_name(), "render_choice") == 0)
00553 {
00554
00555 $shuffle = $render_type->get_attribute("shuffle");
00556 $labels = $render_type->child_nodes();
00557 foreach ($labels as $lidx => $response_label)
00558 {
00559 $material = $response_label->first_child();
00560 $mattext = $material->first_child();
00561 $shuf = 0;
00562 if (strcmp(strtolower($shuffle), "yes") == 0)
00563 {
00564 $shuf = 1;
00565 }
00566 array_push($this->gaps["$ident"], new ASS_AnswerCloze($mattext->get_content(), 0, count($this->gaps["$ident"]), 0, CLOZE_SELECT, $ident, $shuf));
00567 }
00568 }
00569 break;
00570 case "render_fib":
00571 break;
00572 case "material":
00573 $matlabel = $node_type->get_attribute("label");
00574 if (strcmp($matlabel, "suggested_solution") == 0)
00575 {
00576 $mattype = $node_type->first_child();
00577 if (strcmp($mattype->node_name(), "mattext") == 0)
00578 {
00579 $suggested_solution = $mattype->get_content();
00580 if ($suggested_solution)
00581 {
00582 if ($this->getId() < 1)
00583 {
00584 $this->saveToDb();
00585 }
00586 if (preg_match("/gap_(\d+)/", $ident, $matches))
00587 {
00588 $this->setSuggestedSolution($suggested_solution, $matches[1], true);
00589 }
00590 }
00591 }
00592 }
00593 break;
00594 }
00595 }
00596 }
00597 }
00598 break;
00599 case "resprocessing":
00600 $resproc_nodes = $node->child_nodes();
00601 foreach ($resproc_nodes as $index => $respcondition)
00602 {
00603 if (strcmp($respcondition->node_name(), "respcondition") == 0)
00604 {
00605 $respcondition_array =& ilQTIUtils::_getRespcondition($respcondition);
00606 $found_answer = 0;
00607 foreach ($this->gaps[$respcondition_array["conditionvar"]["respident"]] as $key => $value)
00608 {
00609 if (strcmp($value->get_answertext(), $respcondition_array["conditionvar"]["value"]) == 0)
00610 {
00611 $found_answer = 1;
00612 $this->gaps[$respcondition_array["conditionvar"]["respident"]][$key]->set_points($respcondition_array["setvar"]["points"]);
00613 if ($respcondition_array["conditionvar"]["selected"])
00614 {
00615 $this->gaps[$respcondition_array["conditionvar"]["respident"]][$key]->setChecked();
00616 }
00617 }
00618 }
00619 if (!$found_answer)
00620 {
00621
00622 array_push($this->gaps[$respcondition_array["conditionvar"]["respident"]], new ASS_AnswerCloze($respcondition_array["conditionvar"]["value"], $respcondition_array["setvar"]["points"], count($this->gaps[$respcondition_array["conditionvar"]["respident"]]), 1, CLOZE_TEXT, $respcondition_array["conditionvar"]["respident"], 0));
00623 }
00624 }
00625 }
00626 break;
00627 }
00628 }
00629 $this->gaps = array_values($this->gaps);
00630 $i = 0;
00631 foreach ($materials as $key => $value)
00632 {
00633 $this->cloze_text .= $value;
00634 $gaptext = $this->get_gap_text_list($i);
00635 if ($gaptext)
00636 {
00637 $type = " type=\"select\"";
00638 if ($this->gaps[$i][0]->get_cloze_type() == CLOZE_TEXT)
00639 {
00640 $type = " type=\"text\"";
00641 }
00642 $shuffle = " shuffle=\"yes\"";
00643 if (!$this->gaps[$i][0]->get_shuffle())
00644 {
00645 $shuffle = " shuffle=\"no\"";
00646 }
00647 $this->cloze_text .= "<gap$type$shuffle>$gaptext</gap>";
00648 }
00649 $i++;
00650 }
00651 $result = true;
00652 }
00653 return $result;
00654 }
00655
00665 function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false)
00666 {
00667 if (!empty($this->domxml))
00668 {
00669 $this->domxml->free();
00670 }
00671 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<questestinterop></questestinterop>\n";
00672 $this->domxml = domxml_open_mem($xml_header);
00673 $root = $this->domxml->document_element();
00674
00675 $qtiIdent = $this->domxml->create_element("item");
00676 $qtiIdent->set_attribute("ident", "il_".IL_INST_ID."_qst_".$this->getId());
00677 $qtiIdent->set_attribute("title", $this->getTitle());
00678 $root->append_child($qtiIdent);
00679
00680 $qtiComment = $this->domxml->create_element("qticomment");
00681 $qtiCommentText = $this->domxml->create_text_node($this->getComment());
00682 $qtiComment->append_child($qtiCommentText);
00683 $qtiIdent->append_child($qtiComment);
00684 $qtiComment = $this->domxml->create_element("qticomment");
00685 $qtiCommentText = $this->domxml->create_text_node("ILIAS Version=".$this->ilias->getSetting("ilias_version"));
00686 $qtiComment->append_child($qtiCommentText);
00687 $qtiIdent->append_child($qtiComment);
00688 $qtiComment = $this->domxml->create_element("qticomment");
00689 $qtiCommentText = $this->domxml->create_text_node("Questiontype=".CLOZE_TEST_IDENTIFIER);
00690 $qtiComment->append_child($qtiCommentText);
00691 $qtiIdent->append_child($qtiComment);
00692 $qtiComment = $this->domxml->create_element("qticomment");
00693 $qtiCommentText = $this->domxml->create_text_node("Author=".$this->getAuthor());
00694 $qtiComment->append_child($qtiCommentText);
00695 $qtiIdent->append_child($qtiComment);
00696
00697 $qtiDuration = $this->domxml->create_element("duration");
00698 $workingtime = $this->getEstimatedWorkingTime();
00699 $qtiDurationText = $this->domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]));
00700 $qtiDuration->append_child($qtiDurationText);
00701 $qtiIdent->append_child($qtiDuration);
00702
00703 $qtiPresentation = $this->domxml->create_element("presentation");
00704 $qtiPresentation->set_attribute("label", $this->getTitle());
00705
00706 $qtiFlow = $this->domxml->create_element("flow");
00707
00708 $text_parts = preg_split("/<gap.*?<\/gap>/", $this->get_cloze_text());
00709
00710 for ($i = 0; $i <= $this->get_gap_count(); $i++)
00711 {
00712
00713 $qtiMaterial = $this->domxml->create_element("material");
00714 $qtiMatText = $this->domxml->create_element("mattext");
00715 $qtiMatTextText = $this->domxml->create_text_node($text_parts[$i]);
00716 $qtiMatText->append_child($qtiMatTextText);
00717 $qtiMaterial->append_child($qtiMatText);
00718 $qtiFlow->append_child($qtiMaterial);
00719
00720 if ($i < $this->get_gap_count())
00721 {
00722
00723 $gap = $this->get_gap($i);
00724 if ($gap[0]->get_cloze_type() == CLOZE_SELECT)
00725 {
00726
00727 $qtiResponseStr = $this->domxml->create_element("response_str");
00728 $qtiResponseStr->set_attribute("ident", "gap_$i");
00729 $qtiResponseStr->set_attribute("rcardinality", "Single");
00730 $solution = $this->getSuggestedSolution($i);
00731 if (count($solution))
00732 {
00733 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00734 {
00735 $qtiMaterial = $this->domxml->create_element("material");
00736 $qtiMaterial->set_attribute("label", "suggested_solution");
00737 $qtiMatText = $this->domxml->create_element("mattext");
00738 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00739 if (strcmp($matches[1], "") != 0)
00740 {
00741 $intlink = $solution["internal_link"];
00742 }
00743 $qtiMatTextText = $this->domxml->create_text_node($intlink);
00744 $qtiMatText->append_child($qtiMatTextText);
00745 $qtiMaterial->append_child($qtiMatText);
00746 $qtiResponseStr->append_child($qtiMaterial);
00747 }
00748 }
00749
00750 $qtiRenderChoice = $this->domxml->create_element("render_choice");
00751
00752 if ($gap[0]->get_shuffle())
00753 {
00754 $qtiRenderChoice->set_attribute("shuffle", "Yes");
00755 }
00756 else
00757 {
00758 $qtiRenderChoice->set_attribute("shuffle", "No");
00759 }
00760
00761 $gkeys = array_keys($gap);
00762 if ($this->getshuffle() && $a_shuffle)
00763 {
00764 $gkeys = $this->pcArrayShuffle($gkeys);
00765 }
00766
00767
00768 foreach ($gkeys as $key)
00769 {
00770 $value = $gap[$key];
00771 $qtiResponseLabel = $this->domxml->create_element("response_label");
00772 $qtiResponseLabel->set_attribute("ident", $key);
00773 $qtiMaterial = $this->domxml->create_element("material");
00774 $qtiMatText = $this->domxml->create_element("mattext");
00775 $tmpvalue = $value->get_answertext();
00776 $qtiMatTextText = $this->domxml->create_text_node($tmpvalue);
00777 $qtiMatText->append_child($qtiMatTextText);
00778 $qtiMaterial->append_child($qtiMatText);
00779 $qtiResponseLabel->append_child($qtiMaterial);
00780 $qtiRenderChoice->append_child($qtiResponseLabel);
00781 }
00782 $qtiResponseStr->append_child($qtiRenderChoice);
00783 $qtiFlow->append_child($qtiResponseStr);
00784 }
00785 else
00786 {
00787
00788 $qtiResponseStr = $this->domxml->create_element("response_str");
00789 $qtiResponseStr->set_attribute("ident", "gap_$i");
00790 $qtiResponseStr->set_attribute("rcardinality", "Single");
00791 $solution = $this->getSuggestedSolution($i);
00792 if (count($solution))
00793 {
00794 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00795 {
00796 $qtiMaterial = $this->domxml->create_element("material");
00797 $qtiMaterial->set_attribute("label", "suggested_solution");
00798 $qtiMatText = $this->domxml->create_element("mattext");
00799 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00800 if (strcmp($matches[1], "") != 0)
00801 {
00802 $intlink = $solution["internal_link"];
00803 }
00804 $qtiMatTextText = $this->domxml->create_text_node($intlink);
00805 $qtiMatText->append_child($qtiMatTextText);
00806 $qtiMaterial->append_child($qtiMatText);
00807 $qtiResponseStr->append_child($qtiMaterial);
00808 }
00809 }
00810 $qtiRenderFib = $this->domxml->create_element("render_fib");
00811 $qtiRenderFib->set_attribute("fibtype", "String");
00812 $qtiRenderFib->set_attribute("prompt", "Box");
00813 $qtiResponseLabel = $this->domxml->create_element("response_label");
00814 $qtiResponseLabel->set_attribute("ident", $i);
00815 $qtiRenderFib->append_child($qtiResponseLabel);
00816 $qtiResponseStr->append_child($qtiRenderFib);
00817 $qtiFlow->append_child($qtiResponseStr);
00818 }
00819 }
00820 }
00821 $qtiPresentation->append_child($qtiFlow);
00822 $qtiIdent->append_child($qtiPresentation);
00823
00824
00825 $qtiResprocessing = $this->domxml->create_element("resprocessing");
00826 $qtiOutcomes = $this->domxml->create_element("outcomes");
00827 $qtiDecvar = $this->domxml->create_element("decvar");
00828 $qtiOutcomes->append_child($qtiDecvar);
00829 $qtiResprocessing->append_child($qtiOutcomes);
00830
00831 for ($i = 0; $i < $this->get_gap_count(); $i++)
00832 {
00833 $gap = $this->get_gap($i);
00834 if ($gap[0]->get_cloze_type() == CLOZE_SELECT)
00835 {
00836 foreach ($gap as $index => $answer)
00837 {
00838 $qtiRespcondition = $this->domxml->create_element("respcondition");
00839 $qtiRespcondition->set_attribute("continue", "Yes");
00840
00841 $qtiConditionvar = $this->domxml->create_element("conditionvar");
00842
00843 if (!$answer->isStateSet())
00844 {
00845 $qtinot = $this->domxml->create_element("not");
00846 }
00847
00848 $qtiVarequal = $this->domxml->create_element("varequal");
00849 $qtiVarequal->set_attribute("respident", "gap_$i");
00850 $qtiVarequalText = $this->domxml->create_text_node($answer->get_answertext());
00851 $qtiVarequal->append_child($qtiVarequalText);
00852 if (!$answer->isStateSet())
00853 {
00854 $qtiConditionvar->append_child($qtinot);
00855 $qtinot->append_child($qtiVarequal);
00856 }
00857 else
00858 {
00859 $qtiConditionvar->append_child($qtiVarequal);
00860 }
00861
00862 $qtiSetvar = $this->domxml->create_element("setvar");
00863 $qtiSetvar->set_attribute("action", "Add");
00864 $qtiSetvarText = $this->domxml->create_text_node($answer->get_points());
00865 $qtiSetvar->append_child($qtiSetvarText);
00866
00867 $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00868 $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00869 $linkrefid = "";
00870 if ($answer->isStateSet())
00871 {
00872 $linkrefid = "$i" . "_True";
00873 }
00874 else
00875 {
00876 $linkrefid = "$i" . "_False_$index";
00877 }
00878 $qtiDisplayfeedback->set_attribute("linkrefid", $linkrefid);
00879 $qtiRespcondition->append_child($qtiConditionvar);
00880 $qtiRespcondition->append_child($qtiSetvar);
00881 $qtiRespcondition->append_child($qtiDisplayfeedback);
00882 $qtiResprocessing->append_child($qtiRespcondition);
00883 }
00884 }
00885 else
00886 {
00887 foreach ($gap as $index => $answer)
00888 {
00889 $qtiRespcondition = $this->domxml->create_element("respcondition");
00890 $qtiRespcondition->set_attribute("continue", "Yes");
00891
00892 $qtiConditionvar = $this->domxml->create_element("conditionvar");
00893 $qtiVarequal = $this->domxml->create_element("varequal");
00894 $qtiVarequal->set_attribute("respident", "gap_$i");
00895 $qtiVarequalText = $this->domxml->create_text_node($answer->get_answertext());
00896 $qtiVarequal->append_child($qtiVarequalText);
00897 $qtiConditionvar->append_child($qtiVarequal);
00898
00899 $qtiSetvar = $this->domxml->create_element("setvar");
00900 $qtiSetvar->set_attribute("action", "Add");
00901 $qtiSetvarText = $this->domxml->create_text_node($answer->get_points());
00902 $qtiSetvar->append_child($qtiSetvarText);
00903
00904 $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00905 $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00906 $qtiDisplayfeedback->set_attribute("linkrefid", "$i" . "_True_$index");
00907 $qtiRespcondition->append_child($qtiConditionvar);
00908 $qtiRespcondition->append_child($qtiSetvar);
00909 $qtiRespcondition->append_child($qtiDisplayfeedback);
00910 $qtiResprocessing->append_child($qtiRespcondition);
00911 }
00912 }
00913 }
00914 $qtiIdent->append_child($qtiResprocessing);
00915
00916
00917 for ($i = 0; $i < $this->get_gap_count(); $i++)
00918 {
00919 $gap = $this->get_gap($i);
00920 if ($gap[0]->get_cloze_type() == CLOZE_SELECT)
00921 {
00922 foreach ($gap as $index => $answer)
00923 {
00924 $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00925 $linkrefid = "";
00926 if ($answer->isStateSet())
00927 {
00928 $linkrefid = "$i" . "_True";
00929 }
00930 else
00931 {
00932 $linkrefid = "$i" . "_False_$index";
00933 }
00934 $qtiItemfeedback->set_attribute("ident", $linkrefid);
00935 $qtiItemfeedback->set_attribute("view", "All");
00936
00937 $qtiFlowmat = $this->domxml->create_element("flow_mat");
00938 $qtiMaterial = $this->domxml->create_element("material");
00939 $qtiMattext = $this->domxml->create_element("mattext");
00940
00941 $qtiMattextText = $this->domxml->create_text_node("");
00942 $qtiMattext->append_child($qtiMattextText);
00943 $qtiMaterial->append_child($qtiMattext);
00944 $qtiFlowmat->append_child($qtiMaterial);
00945 $qtiItemfeedback->append_child($qtiFlowmat);
00946 $qtiIdent->append_child($qtiItemfeedback);
00947 }
00948 }
00949 else
00950 {
00951 foreach ($gap as $index => $answer)
00952 {
00953 $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00954 $linkrefid = "";
00955 if ($answer->isStateSet())
00956 {
00957 $linkrefid = "$i" . "_True_$index";
00958 }
00959 else
00960 {
00961 $linkrefid = "$i" . "_False_$index";
00962 }
00963 $qtiItemfeedback->set_attribute("ident", $linkrefid);
00964 $qtiItemfeedback->set_attribute("view", "All");
00965
00966 $qtiFlowmat = $this->domxml->create_element("flow_mat");
00967 $qtiMaterial = $this->domxml->create_element("material");
00968 $qtiMattext = $this->domxml->create_element("mattext");
00969
00970 $qtiMattextText = $this->domxml->create_text_node("");
00971 $qtiMattext->append_child($qtiMattextText);
00972 $qtiMaterial->append_child($qtiMattext);
00973 $qtiFlowmat->append_child($qtiMaterial);
00974 $qtiItemfeedback->append_child($qtiFlowmat);
00975 $qtiIdent->append_child($qtiItemfeedback);
00976 }
00977 }
00978 }
00979
00980 $xml = $this->domxml->dump_mem(true);
00981 if (!$a_include_header)
00982 {
00983 $pos = strpos($xml, "?>");
00984 $xml = substr($xml, $pos + 2);
00985 }
00986
00987 return $xml;
00988
00989 }
00990
01002 function set_cloze_text($cloze_text = "")
01003 {
01004 $this->gaps = array();
01005 $this->cloze_text =& $cloze_text;
01006 $close = $this->createCloseTextArray();
01007 if (count($close))
01008 {
01009 foreach ($close["gaps"] as $key => $value)
01010 {
01011 if (strcmp(strtolower($value["params"]["type"]), "select") == 0)
01012 {
01013 $type = CLOZE_SELECT;
01014 }
01015 else
01016 {
01017 $type = CLOZE_TEXT;
01018 }
01019 if ($type == CLOZE_TEXT)
01020 {
01021 $default_state = 1;
01022 }
01023 else
01024 {
01025 $default_state = 0;
01026 }
01027 $name = $value["params"]["name"];
01028 if (strcmp(strtolower($value["params"]["shuffle"]), "no") == 0)
01029 {
01030 $shuffle = 0;
01031 }
01032 else
01033 {
01034 $shuffle = 1;
01035 }
01036 $answer_array = array();
01037 foreach ($value["text"] as $index => $textvalue)
01038 {
01039 if (preg_match("/\d+/", $index))
01040 {
01041 $textvalue = str_replace("\,", ",", $textvalue);
01042 array_push($answer_array, new ASS_AnswerCloze($textvalue, 0, $index, $default_state, $type, $name, $shuffle));
01043 }
01044 }
01045 array_push($this->gaps, $answer_array);
01046 }
01047 }
01048 }
01049
01059 function get_cloze_text() {
01060 return $this->cloze_text;
01061 }
01062
01072 function get_start_tag() {
01073 return $this->start_tag;
01074 }
01075
01085 function get_end_tag() {
01086 return $this->end_tag;
01087 }
01088
01098 function set_start_tag($start_tag = "<gap>") {
01099 $this->start_tag = $start_tag;
01100 }
01101
01102
01112 function set_end_tag($end_tag = "</gap>") {
01113 $this->end_tag = $end_tag;
01114 }
01115
01124 function rebuild_cloze_text()
01125 {
01126 $close =& $this->createCloseTextArray();
01127 if (count($close))
01128 {
01129 for ($i = 0; $i < count($this->gaps); $i++)
01130 {
01131 $gaptext = $this->get_gap_text_list($i);
01132 $textparams = preg_split("/(?<!\\\\),/", $gaptext);
01133 $close["gaps"][$i]["text"] = array();
01134 $close["gaps"][$i]["text"]["text"] = $gaptext;
01135 foreach ($textparams as $key => $value)
01136 {
01137 $close["gaps"][$i]["text"][$key] = $value;
01138 }
01139 }
01140 }
01141 $this->createCloseTextFromArray($close);
01142 }
01143
01155 function get_gap($index = 0) {
01156 if ($index < 0) return array();
01157 if (count($this->gaps) < 1) return array();
01158 if ($index >= count($this->gaps)) return array();
01159 return $this->gaps[$index];
01160 }
01161
01171 function get_gap_count() {
01172 return count($this->gaps);
01173 }
01174
01187 function get_gap_text_list($index = 0, $separator = ",") {
01188 if ($index < 0) return "";
01189 if (count($this->gaps) < 1) return "";
01190 if ($index >= count($this->gaps)) return "";
01191 $result = array();
01192 foreach ($this->gaps[$index] as $key => $value) {
01193 array_push($result, str_replace(",", "\,", $value->get_answertext()));
01194 }
01195 return join($separator, $result);
01196 }
01206 function get_gap_text_count($index = 0) {
01207 if ($index < 0) return 0;
01208 if (count($this->gaps) < 1) return 0;
01209 if ($index >= count($this->gaps)) return 0;
01210 return count($this->gaps[$index]);
01211 }
01222 function delete_gap($index = 0) {
01223 if ($index < 0) return;
01224 if (count($this->gaps) < 1) return;
01225 if ($index >= count($this->gaps)) return;
01226 $close = $this->createCloseTextArray();
01227 unset($close["gaps"][$index]);
01228 $this->createCloseTextFromArray($close);
01229 unset($this->gaps[$index]);
01230 $this->gaps = array_values($this->gaps);
01231 }
01232
01241 function flush_gaps() {
01242 $this->gaps = array();
01243 }
01244
01256 function delete_answertext_by_index($gap_index = 0, $answertext_index = 0) {
01257 if ($gap_index < 0) return;
01258 if (count($this->gaps) < 1) return;
01259 if ($gap_index >= count($this->gaps)) return;
01260 $old_text = $this->get_gap_text_list($gap_index);
01261 if (count($this->gaps[$gap_index]) == 1) {
01262 $this->delete_gap($gap_index);
01263 } else {
01264 $close = $this->createCloseTextArray();
01265 unset($this->gaps[$gap_index][$answertext_index]);
01266 $this->gaps[$gap_index] = array_values($this->gaps[$gap_index]);
01267 unset($close["gaps"][$gap_index]["text"][$answertext_index]);
01268 $this->createCloseTextFromArray($close);
01269 }
01270 }
01271
01284 function set_answertext($index = 0, $answertext_index = 0, $answertext = "", $add_gaptext=0) {
01285 $answertext = str_replace("\,", ",", $answertext);
01286 if ($add_gaptext == 1) {
01287 $arr = $this->gaps[$index][0];
01288 if (strlen($this->gaps[$index][count($this->gaps[$index])-1]->get_answertext()) != 0) {
01289 $default_state = 0;
01290 if ($arr->get_cloze_type() == CLOZE_TEXT)
01291 {
01292 $default_state = 1;
01293 }
01294 array_push($this->gaps[$index], new ASS_AnswerCloze($answertext, 0, count($this->gaps[$index]),
01295 $default_state, $arr->get_cloze_type(),
01296 $arr->get_name(), $arr->get_shuffle()));
01297 $this->rebuild_cloze_text();
01298 }
01299 return;
01300 }
01301 if ($index < 0) return;
01302 if (count($this->gaps) < 1) return;
01303 if ($index >= count($this->gaps)) return;
01304 if ($answertext_index < 0) return;
01305 if (count($this->gaps[$index]) < 1) return;
01306 if ($answertext_index >= count($this->gaps[$index])) return;
01307
01308
01309 if (strlen($answertext) == 0) {
01310
01311 $this->delete_answertext($index, $this->gaps[$index][$answertext_index]->get_answertext());
01312 } else {
01313 $this->gaps[$index][$answertext_index]->set_answertext($answertext);
01314 $this->rebuild_cloze_text();
01315 }
01316 }
01317
01326 function update_all_gap_params() {
01327 global $lng;
01328 $close = $this->createCloseTextArray();
01329 for ($i = 0; $i < $this->get_gap_count(); $i++)
01330 {
01331 $gaptext = $this->get_gap_text_list($i);
01332 if ($this->gaps[$i][0]->get_cloze_type() == CLOZE_TEXT)
01333 {
01334 $close["gaps"][$i]["params"]["type"] = "text";
01335 if (array_key_exists("shuffle", $close["gaps"][$i]["params"]))
01336 {
01337 unset($close["gaps"][$i]["params"]["shuffle"]);
01338 }
01339 }
01340 else
01341 {
01342 $close["gaps"][$i]["params"]["type"] = "select";
01343 if ($this->gaps[$i][0]->get_shuffle() == 0)
01344 {
01345 $close["gaps"][$i]["params"]["shuffle"] = "no";
01346 }
01347 else
01348 {
01349 $close["gaps"][$i]["params"]["shuffle"] = "yes";
01350 }
01351 }
01352 $name = $this->gaps[$i][0]->get_name();
01353 if (!$name)
01354 {
01355 $name = $this->lng->txt("gap") . " " . ($i+1);
01356 }
01357 $close["gaps"][$i]["params"]["name"] = $name;
01358 }
01359 $this->createCloseTextFromArray($close);
01360 }
01361
01372 function set_cloze_type($index, $cloze_type = CLOZE_TEXT) {
01373 if ($index < 0) return;
01374 if (count($this->gaps) < 1) return;
01375 if ($index >= count($this->gaps)) return;
01376 $close = $this->createCloseTextArray();
01377 foreach ($this->gaps[$index] as $key => $value) {
01378 $this->gaps[$index][$key]->set_cloze_type($cloze_type);
01379 $this->gaps[$index][$key]->setState(1);
01380 }
01381 if ($cloze_type == CLOZE_TEXT)
01382 {
01383 $type = "text";
01384 }
01385 else
01386 {
01387 $type = "select";
01388 }
01389 $close["gaps"][$index]["type"] = $type;
01390 $this->createCloseTextFromArray($close);
01391 }
01392
01404 function set_gap_points($index = 0, $points = 0.0) {
01405 if ($index < 0) return;
01406 if (count($this->gaps) < 1) return;
01407 if ($index >= count($this->gaps)) return;
01408 foreach ($this->gaps[$index] as $key => $value) {
01409 $this->gaps[$index][$key]->set_points($points);
01410 }
01411 }
01412
01424 function set_gap_shuffle($index = 0, $shuffle = 1) {
01425 if ($index < 0) return;
01426 if (count($this->gaps) < 1) return;
01427 if ($index >= count($this->gaps)) return;
01428 foreach ($this->gaps[$index] as $key => $value) {
01429 $this->gaps[$index][$key]->set_shuffle($shuffle);
01430 }
01431 }
01432
01433
01446 function set_single_answer_points($index_gaps = 0, $index_answerobject = 0, $points = 0.0) {
01447 if ($index_gaps < 0) return;
01448 if (count($this->gaps) < 1) return;
01449 if ($index_gaps >= count($this->gaps)) return;
01450 if ($index_answerobject < 0) return;
01451 if (count($this->gaps[$index_gaps]) < 1) return;
01452 if ($index_answerobject >= count($this->gaps[$index_gaps])) return;
01453 $this->gaps[$index_gaps][$index_answerobject]->set_points($points);
01454 }
01455
01468 function set_single_answer_state($index_gaps = 0, $index_answerobject = 0, $state = 0) {
01469 if ($index_gaps < 0) return;
01470 if (count($this->gaps) < 1) return;
01471 if ($index_gaps >= count($this->gaps)) return;
01472 if ($index_answerobject < 0) return;
01473 if (count($this->gaps[$index_gaps]) < 1) return;
01474 if ($index_answerobject >= count($this->gaps[$index_gaps])) return;
01475 $this->gaps[$index_gaps][$index_answerobject]->setState($state);
01476 }
01477
01487 function getReachedPoints($user_id, $test_id) {
01488 $found_value1 = array();
01489 $found_value2 = array();
01490 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01491 $this->ilias->db->quote($user_id),
01492 $this->ilias->db->quote($test_id),
01493 $this->ilias->db->quote($this->getId())
01494 );
01495 $result = $this->ilias->db->query($query);
01496 $user_result = array();
01497 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
01498 if (strcmp($data->value2, "") != 0)
01499 {
01500 $user_result[$data->value1] = array(
01501 "gap_id" => $data->value1,
01502 "value" => $data->value2
01503 );
01504 }
01505 }
01506 $points = 0;
01507 $counter = 0;
01508 foreach ($user_result as $gap_id => $value) {
01509 if ($this->gaps[$gap_id][0]->get_cloze_type() == CLOZE_TEXT)
01510 {
01511 $foundsolution = 0;
01512 foreach ($this->gaps[$gap_id] as $k => $v) {
01513 if ((strcmp(strtolower($v->get_answertext()), strtolower($value["value"])) == 0) && (!$foundsolution)) {
01514 $points += $v->get_points();
01515 $foundsolution = 1;
01516 }
01517 }
01518 }
01519 else
01520 {
01521 if ($value["value"] >= 0)
01522 {
01523 foreach ($this->gaps[$gap_id] as $answerkey => $answer)
01524 {
01525 if ($value["value"] == $answerkey)
01526 {
01527 $points += $answer->get_points();
01528 }
01529 }
01530 }
01531 }
01532 }
01533 return $points;
01534 }
01535
01545 function getReachedInformation($user_id, $test_id) {
01546 $found_value1 = array();
01547 $found_value2 = array();
01548 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01549 $this->ilias->db->quote($user_id),
01550 $this->ilias->db->quote($test_id),
01551 $this->ilias->db->quote($this->getId())
01552 );
01553 $result = $this->ilias->db->query($query);
01554 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
01555 array_push($found_value1, $data->value1);
01556 array_push($found_value2, $data->value2);
01557 }
01558 $counter = 1;
01559 $user_result = array();
01560 foreach ($found_value1 as $key => $value) {
01561 if ($this->gaps[$value][0]->get_cloze_type() == CLOZE_TEXT)
01562 {
01563 $solution = array(
01564 "gap" => "$counter",
01565 "points" => 0,
01566 "true" => 0,
01567 "value" => $found_value2[$key]
01568 );
01569 foreach ($this->gaps[$value] as $k => $v) {
01570 if (strcmp(strtolower($v->get_answertext()), strtolower($found_value2[$key])) == 0) {
01571 $solution = array(
01572 "gap" => "$counter",
01573 "points" => $v->get_points(),
01574 "true" => 1,
01575 "value" => $found_value2[$key]
01576 );
01577 }
01578 }
01579 }
01580 else
01581 {
01582 $solution = array(
01583 "gap" => "$counter",
01584 "points" => 0,
01585 "true" => 0,
01586 "value" => $found_value2[$key]
01587 );
01588 if ($this->gaps[$value][$found_value1[$key]]->isStateSet()) {
01589 $solution["points"] = $this->gaps[$value][$found_value1[$key]]->get_points();
01590 $solution["true"] = 1;
01591 }
01592 }
01593 $counter++;
01594 $user_result[$value] = $solution;
01595 }
01596 return $user_result;
01597 }
01598
01607 function getMaximumPoints() {
01608 $points = 0;
01609 foreach ($this->gaps as $key => $value) {
01610 if ($value[0]->get_cloze_type() == CLOZE_TEXT) {
01611 $points += $value[0]->get_points();
01612 } else {
01613 $points_arr = array("set" => 0, "unset" => 0);
01614 foreach ($value as $key2 => $value2) {
01615 if ($value2->get_points() > $points_arr["set"])
01616 {
01617 $points_arr["set"] = $value2->get_points();
01618 }
01619 }
01620 $points += $points_arr["set"];
01621 }
01622 }
01623 return $points;
01624 }
01625
01636 function saveWorkingData($test_id, $limit_to = LIMIT_NO_LIMIT) {
01637 global $ilDB;
01638 global $ilUser;
01639 $db =& $ilDB->db;
01640
01641 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01642 $db->quote($ilUser->id),
01643 $db->quote($test_id),
01644 $db->quote($this->getId())
01645 );
01646 $result = $db->query($query);
01647
01648 foreach ($_POST as $key => $value) {
01649 if (preg_match("/^gap_(\d+)/", $key, $matches)) {
01650 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01651 $db->quote($ilUser->id),
01652 $db->quote($test_id),
01653 $db->quote($this->getId()),
01654 $db->quote($matches[1]),
01655 $db->quote(ilUtil::stripSlashes($value))
01656 );
01657 $result = $db->query($query);
01658 }
01659 }
01660
01661 return true;
01662 }
01663
01664 function syncWithOriginal()
01665 {
01666 global $ilias;
01667 if ($this->original_id)
01668 {
01669 $complete = 0;
01670 if ($this->isComplete())
01671 {
01672 $complete = 1;
01673 }
01674 $db = & $ilias->db;
01675
01676 $estw_time = $this->getEstimatedWorkingTime();
01677 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01678
01679 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, shuffle = %s, complete = %s WHERE question_id = %s",
01680 $db->quote($this->obj_id. ""),
01681 $db->quote($this->title . ""),
01682 $db->quote($this->comment . ""),
01683 $db->quote($this->author . ""),
01684 $db->quote($this->cloze_text . ""),
01685 $db->quote($estw_time . ""),
01686 $db->quote($this->shuffle . ""),
01687 $db->quote($complete . ""),
01688 $db->quote($this->original_id . "")
01689 );
01690 $result = $db->query($query);
01691
01692 if ($result == DB_OK)
01693 {
01694
01695
01696 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01697 $db->quote($this->original_id)
01698 );
01699 $result = $db->query($query);
01700
01701 foreach ($this->gaps as $key => $value)
01702 {
01703 foreach ($value as $answer_id => $answer_obj)
01704 {
01705 $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)",
01706 $db->quote($this->original_id . ""),
01707 $db->quote($key . ""),
01708 $db->quote($answer_obj->get_answertext() . ""),
01709 $db->quote($answer_obj->get_points() . ""),
01710 $db->quote($answer_obj->get_order() . ""),
01711 $db->quote($answer_obj->get_cloze_type() . ""),
01712 $db->quote($answer_obj->get_name() . ""),
01713 $db->quote($answer_obj->get_shuffle() . ""),
01714 $db->quote($answer_obj->getState() . "")
01715 );
01716 $answer_result = $db->query($query);
01717 }
01718 }
01719 }
01720 parent::syncWithOriginal();
01721 }
01722 }
01723
01732 function getQuestionType()
01733 {
01734 return 3;
01735 }
01736 }
01737
01738 ?>