00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 require_once "./assessment/classes/class.assQuestion.php";
00024 require_once "./assessment/classes/class.assAnswerBinaryState.php";
00025 require_once "./assessment/classes/class.ilQTIUtils.php";
00026
00027 define("RESPONSE_SINGLE", "0");
00028 define("RESPONSE_MULTIPLE", "1");
00029
00030 define("OUTPUT_ORDER", "0");
00031 define("OUTPUT_RANDOM", "1");
00032
00033 define("MULTIPLE_CHOICE_QUESTION_IDENTIFIER", "MULTIPLE CHOICE QUESTION");
00034
00046 class ASS_MultipleChoice extends ASS_Question
00047 {
00055 var $question;
00056
00064 var $answers;
00065
00074 var $response;
00075
00084 var $output_type;
00085
00101 function ASS_MultipleChoice(
00102 $title = "",
00103 $comment = "",
00104 $author = "",
00105 $owner = -1,
00106 $question = "",
00107 $response = RESPONSE_SINGLE,
00108 $output_type = OUTPUT_ORDER
00109 )
00110 {
00111 $this->ASS_Question($title, $comment, $author, $owner);
00112 $this->question = $question;
00113 $this->response = $response;
00114 $this->output_type = $output_type;
00115 $this->answers = array();
00116 }
00117
00126 function isComplete()
00127 {
00128 if (($this->title) and ($this->author) and ($this->question) and (count($this->answers)))
00129 {
00130 return true;
00131 }
00132 else
00133 {
00134 return false;
00135 }
00136 }
00137
00147 function from_xml($xml_text)
00148 {
00149 $result = false;
00150 if (!empty($this->domxml))
00151 {
00152 $this->domxml->free();
00153 }
00154 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
00155 $this->domxml = domxml_open_mem($xml_text);
00156 if (!empty($this->domxml))
00157 {
00158 $root = $this->domxml->document_element();
00159 $item = $root->first_child();
00160 $this->setTitle($item->get_attribute("title"));
00161 $this->gaps = array();
00162 $itemnodes = $item->child_nodes();
00163 foreach ($itemnodes as $index => $node)
00164 {
00165 switch ($node->node_name())
00166 {
00167 case "qticomment":
00168 $comment = $node->get_content();
00169 if (strpos($comment, "ILIAS Version=") !== false)
00170 {
00171 }
00172 elseif (strpos($comment, "Questiontype=") !== false)
00173 {
00174 }
00175 elseif (strpos($comment, "Author=") !== false)
00176 {
00177 $comment = str_replace("Author=", "", $comment);
00178 $this->setAuthor($comment);
00179 }
00180 else
00181 {
00182 $this->setComment($comment);
00183 }
00184 break;
00185 case "itemmetadata":
00186 $md_array = array();
00187 $metanodes = $node->child_nodes();
00188 foreach ($metanodes as $metanode)
00189 {
00190 switch ($metanode->node_name())
00191 {
00192 case "qtimetadata":
00193 $metafields = $metanode->child_nodes();
00194 foreach ($metafields as $metafield)
00195 {
00196 switch ($metafield->node_name())
00197 {
00198 case "qtimetadatafield":
00199 $metafieldlist = $metafield->child_nodes();
00200 $md = array("label" => "", "entry" => "");
00201 foreach ($metafieldlist as $attr)
00202 {
00203 switch ($attr->node_name())
00204 {
00205 case "fieldlabel":
00206 $md["label"] = $attr->get_content();
00207 break;
00208 case "fieldentry":
00209 $md["entry"] = $attr->get_content();
00210 break;
00211 }
00212 }
00213 array_push($md_array, $md);
00214 break;
00215 }
00216 }
00217 break;
00218 }
00219 }
00220 foreach ($md_array as $md)
00221 {
00222 switch ($md["label"])
00223 {
00224 case "ILIAS_VERSION":
00225 break;
00226 case "QUESTIONTYPE":
00227 break;
00228 case "AUTHOR":
00229 $this->setAuthor($md["entry"]);
00230 break;
00231 }
00232 }
00233 break;
00234 case "duration":
00235 $iso8601period = $node->get_content();
00236 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
00237 {
00238 $this->setEstimatedWorkingTime($matches[4], $matches[5], $matches[6]);
00239 }
00240 break;
00241 case "presentation":
00242 $flow = $node->first_child();
00243 $flownodes = $flow->child_nodes();
00244 foreach ($flownodes as $idx => $flownode)
00245 {
00246 if (strcmp($flownode->node_name(), "material") == 0)
00247 {
00248 $mattext = $flownode->first_child();
00249 $this->set_question($mattext->get_content());
00250 }
00251 elseif (strcmp($flownode->node_name(), "response_lid") == 0)
00252 {
00253 $ident = $flownode->get_attribute("ident");
00254 if (strcmp($ident, "MCSR") == 0)
00255 {
00256 $this->set_response(RESPONSE_SINGLE);
00257 }
00258 else
00259 {
00260 $this->set_response(RESPONSE_MULTIPLE);
00261 }
00262 $shuffle = "";
00263
00264 $subnodes = $flownode->child_nodes();
00265 foreach ($subnodes as $node_type)
00266 {
00267 switch ($node_type->node_name())
00268 {
00269 case "render_choice":
00270 $render_choice = $node_type;
00271 if (strcmp($render_choice->node_name(), "render_choice") == 0)
00272 {
00273 $shuffle = $render_choice->get_attribute("shuffle");
00274 $shuf = 0;
00275 if (strcmp(strtolower($shuffle), "yes") == 0)
00276 {
00277 $shuf = 1;
00278 }
00279 $this->setShuffle($shuf);
00280 $labels = $render_choice->child_nodes();
00281 foreach ($labels as $lidx => $response_label)
00282 {
00283 $material = $response_label->first_child();
00284 $mattext = $material->first_child();
00285 $this->add_answer($mattext->get_content(), 0, 0, $response_label->get_attribute("ident"));
00286 }
00287 }
00288 break;
00289 case "material":
00290 $matlabel = $node_type->get_attribute("label");
00291 if (strcmp($matlabel, "suggested_solution") == 0)
00292 {
00293 $mattype = $node_type->first_child();
00294 if (strcmp($mattype->node_name(), "mattext") == 0)
00295 {
00296 $suggested_solution = $mattype->get_content();
00297 if ($suggested_solution)
00298 {
00299 if ($this->getId() < 1)
00300 {
00301 $this->saveToDb();
00302 }
00303 $this->setSuggestedSolution($suggested_solution, 0, true);
00304 }
00305 }
00306 }
00307 break;
00308 }
00309 }
00310 }
00311 }
00312 break;
00313 case "resprocessing":
00314 $resproc_nodes = $node->child_nodes();
00315 foreach ($resproc_nodes as $index => $respcondition)
00316 {
00317 if (strcmp($respcondition->node_name(), "respcondition") == 0)
00318 {
00319 $respcondition_array =& ilQTIUtils::_getRespcondition($respcondition);
00320 $found_answer = 0;
00321 $this->answers[$respcondition_array["conditionvar"]["value"]]->set_points($respcondition_array["setvar"]["points"]);
00322 if ($respcondition_array["conditionvar"]["selected"])
00323 {
00324 $this->answers[$respcondition_array["conditionvar"]["value"]]->setChecked();
00325 }
00326 $feedbacks[$respcondition_array["displayfeedback"]["linkrefid"]] = array(
00327 "type" => $respcondition_array["conditionvar"]["respident"],
00328 "value" => $respcondition_array["conditionvar"]["value"],
00329 "not" => $respcondition_array["conditionvar"]["not"],
00330 "points" => $respcondition_array["setvar"]["points"],
00331 "feedback" => ""
00332 );
00333 }
00334 }
00335 break;
00336 }
00337 }
00338 $result = true;
00339 }
00340 return $result;
00341 }
00342
00352 function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false)
00353 {
00354 if (!empty($this->domxml))
00355 {
00356 $this->domxml->free();
00357 }
00358 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
00359 $xml_header .= "<questestinterop></questestinterop>\n";
00360 $this->domxml = domxml_open_mem($xml_header);
00361 $root = $this->domxml->document_element();
00362
00363 $qtiIdent = $this->domxml->create_element("item");
00364 $qtiIdent->set_attribute("ident", "il_".IL_INST_ID."_qst_".$this->getId());
00365 $qtiIdent->set_attribute("title", $this->getTitle());
00366 $root->append_child($qtiIdent);
00367
00368 $qtiComment = $this->domxml->create_element("qticomment");
00369 $qtiCommentText = $this->domxml->create_text_node($this->getComment());
00370 $qtiComment->append_child($qtiCommentText);
00371 $qtiIdent->append_child($qtiComment);
00372
00373 $qtiDuration = $this->domxml->create_element("duration");
00374 $workingtime = $this->getEstimatedWorkingTime();
00375 $qtiDurationText = $this->domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]));
00376 $qtiDuration->append_child($qtiDurationText);
00377 $qtiIdent->append_child($qtiDuration);
00378
00379 $qtiItemmetadata = $this->domxml->create_element("itemmetadata");
00380 $qtiMetadata = $this->domxml->create_element("qtimetadata");
00381
00382 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00383 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00384 $qtiFieldlabelText = $this->domxml->create_text_node("ILIAS_VERSION");
00385 $qtiFieldlabel->append_child($qtiFieldlabelText);
00386 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00387 $qtiFieldentryText = $this->domxml->create_text_node($this->ilias->getSetting("ilias_version"));
00388 $qtiFieldentry->append_child($qtiFieldentryText);
00389 $qtiMetadatafield->append_child($qtiFieldlabel);
00390 $qtiMetadatafield->append_child($qtiFieldentry);
00391 $qtiMetadata->append_child($qtiMetadatafield);
00392
00393 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00394 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00395 $qtiFieldlabelText = $this->domxml->create_text_node("QUESTIONTYPE");
00396 $qtiFieldlabel->append_child($qtiFieldlabelText);
00397 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00398 $qtiFieldentryText = $this->domxml->create_text_node(MULTIPLE_CHOICE_QUESTION_IDENTIFIER);
00399 $qtiFieldentry->append_child($qtiFieldentryText);
00400 $qtiMetadatafield->append_child($qtiFieldlabel);
00401 $qtiMetadatafield->append_child($qtiFieldentry);
00402 $qtiMetadata->append_child($qtiMetadatafield);
00403
00404 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00405 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00406 $qtiFieldlabelText = $this->domxml->create_text_node("AUTHOR");
00407 $qtiFieldlabel->append_child($qtiFieldlabelText);
00408 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00409 $qtiFieldentryText = $this->domxml->create_text_node($this->getAuthor());
00410 $qtiFieldentry->append_child($qtiFieldentryText);
00411 $qtiMetadatafield->append_child($qtiFieldlabel);
00412 $qtiMetadatafield->append_child($qtiFieldentry);
00413 $qtiMetadata->append_child($qtiMetadatafield);
00414
00415 $qtiItemmetadata->append_child($qtiMetadata);
00416 $qtiIdent->append_child($qtiItemmetadata);
00417
00418
00419 $qtiPresentation = $this->domxml->create_element("presentation");
00420 $qtiPresentation->set_attribute("label", $this->getTitle());
00421
00422 $qtiFlow = $this->domxml->create_element("flow");
00423
00424 $qtiMaterial = $this->domxml->create_element("material");
00425 $qtiMatText = $this->domxml->create_element("mattext");
00426 $qtiMatTextText = $this->domxml->create_text_node($this->get_question());
00427 $qtiMatText->append_child($qtiMatTextText);
00428 $qtiMaterial->append_child($qtiMatText);
00429 $qtiFlow->append_child($qtiMaterial);
00430
00431 $qtiResponseLid = $this->domxml->create_element("response_lid");
00432 if ($this->response == RESPONSE_SINGLE)
00433 {
00434 $qtiResponseLid->set_attribute("ident", "MCSR");
00435 $qtiResponseLid->set_attribute("rcardinality", "Single");
00436 }
00437 else
00438 {
00439 $qtiResponseLid->set_attribute("ident", "MCMR");
00440 $qtiResponseLid->set_attribute("rcardinality", "Multiple");
00441 }
00442 $solution = $this->getSuggestedSolution(0);
00443 if (count($solution))
00444 {
00445 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00446 {
00447 $qtiMaterial = $this->domxml->create_element("material");
00448 $qtiMaterial->set_attribute("label", "suggested_solution");
00449 $qtiMatText = $this->domxml->create_element("mattext");
00450 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00451 if (strcmp($matches[1], "") != 0)
00452 {
00453 $intlink = $solution["internal_link"];
00454 }
00455 $qtiMatTextText = $this->domxml->create_text_node($intlink);
00456 $qtiMatText->append_child($qtiMatTextText);
00457 $qtiMaterial->append_child($qtiMatText);
00458 $qtiResponseLid->append_child($qtiMaterial);
00459 }
00460 }
00461 $qtiRenderChoice = $this->domxml->create_element("render_choice");
00462
00463 if ($this->getShuffle())
00464 {
00465 $qtiRenderChoice->set_attribute("shuffle", "Yes");
00466 }
00467 else
00468 {
00469 $qtiRenderChoice->set_attribute("shuffle", "No");
00470 }
00471
00472 $akeys = array_keys($this->answers);
00473 if ($this->getshuffle() && $a_shuffle)
00474 {
00475 $akeys = $this->pcArrayShuffle($akeys);
00476 }
00477
00478
00479 foreach ($akeys as $index)
00480 {
00481 $answer = $this->answers[$index];
00482 $qtiResponseLabel = $this->domxml->create_element("response_label");
00483 $qtiResponseLabel->set_attribute("ident", $index);
00484 $qtiMaterial = $this->domxml->create_element("material");
00485 $qtiMatText = $this->domxml->create_element("mattext");
00486 $qtiMatTextText = $this->domxml->create_text_node($answer->get_answertext());
00487 $qtiMatText->append_child($qtiMatTextText);
00488 $qtiMaterial->append_child($qtiMatText);
00489 $qtiResponseLabel->append_child($qtiMaterial);
00490 $qtiRenderChoice->append_child($qtiResponseLabel);
00491 }
00492 $qtiResponseLid->append_child($qtiRenderChoice);
00493 $qtiFlow->append_child($qtiResponseLid);
00494 $qtiPresentation->append_child($qtiFlow);
00495 $qtiIdent->append_child($qtiPresentation);
00496
00497 $qtiResprocessing = $this->domxml->create_element("resprocessing");
00498 $qtiOutcomes = $this->domxml->create_element("outcomes");
00499 $qtiDecvar = $this->domxml->create_element("decvar");
00500 $qtiOutcomes->append_child($qtiDecvar);
00501 $qtiResprocessing->append_child($qtiOutcomes);
00502
00503 foreach ($this->answers as $index => $answer)
00504 {
00505 $qtiRespcondition = $this->domxml->create_element("respcondition");
00506 $qtiRespcondition->set_attribute("continue", "Yes");
00507
00508 $qtiConditionvar = $this->domxml->create_element("conditionvar");
00509 if (!$answer->isStateSet())
00510 {
00511 $qtinot = $this->domxml->create_element("not");
00512 }
00513 $qtiVarequal = $this->domxml->create_element("varequal");
00514 if ($this->response == RESPONSE_SINGLE)
00515 {
00516 $qtiVarequal->set_attribute("respident", "MCSR");
00517 }
00518 else
00519 {
00520 $qtiVarequal->set_attribute("respident", "MCMR");
00521 }
00522 $qtiVarequalText = $this->domxml->create_text_node($index);
00523 $qtiVarequal->append_child($qtiVarequalText);
00524 if (!$answer->isStateSet())
00525 {
00526 $qtiConditionvar->append_child($qtinot);
00527 $qtinot->append_child($qtiVarequal);
00528 }
00529 else
00530 {
00531 $qtiConditionvar->append_child($qtiVarequal);
00532 }
00533
00534 $qtiSetvar = $this->domxml->create_element("setvar");
00535 $qtiSetvar->set_attribute("action", "Add");
00536 $qtiSetvarText = $this->domxml->create_text_node($answer->get_points());
00537 $qtiSetvar->append_child($qtiSetvarText);
00538
00539 $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00540 $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00541 $linkrefid = "";
00542 if ($answer->isStateChecked())
00543 {
00544 if ($this->response == RESPONSE_SINGLE)
00545 {
00546 $linkrefid = "True";
00547 }
00548 else
00549 {
00550 $linkrefid = "True_$index";
00551 }
00552 }
00553 else
00554 {
00555 $linkrefid = "False_$index";
00556 }
00557 $qtiDisplayfeedback->set_attribute("linkrefid", $linkrefid);
00558 $qtiRespcondition->append_child($qtiConditionvar);
00559 $qtiRespcondition->append_child($qtiSetvar);
00560 $qtiRespcondition->append_child($qtiDisplayfeedback);
00561 $qtiResprocessing->append_child($qtiRespcondition);
00562 }
00563 $qtiIdent->append_child($qtiResprocessing);
00564
00565
00566 foreach ($this->answers as $index => $answer)
00567 {
00568 $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00569 $linkrefid = "";
00570 if ($answer->isStateChecked())
00571 {
00572 if ($this->response == RESPONSE_SINGLE)
00573 {
00574 $linkrefid = "True";
00575 }
00576 else
00577 {
00578 $linkrefid = "True_$index";
00579 }
00580 }
00581 else
00582 {
00583 $linkrefid = "False_$index";
00584 }
00585 $qtiItemfeedback->set_attribute("ident", $linkrefid);
00586 $qtiItemfeedback->set_attribute("view", "All");
00587
00588 $qtiFlowmat = $this->domxml->create_element("flow_mat");
00589 $qtiMaterial = $this->domxml->create_element("material");
00590 $qtiMattext = $this->domxml->create_element("mattext");
00591
00592 $qtiMattextText = $this->domxml->create_text_node("");
00593 $qtiMattext->append_child($qtiMattextText);
00594 $qtiMaterial->append_child($qtiMattext);
00595 $qtiFlowmat->append_child($qtiMaterial);
00596 $qtiItemfeedback->append_child($qtiFlowmat);
00597 $qtiIdent->append_child($qtiItemfeedback);
00598 }
00599 $xml = $this->domxml->dump_mem(true);
00600 if (!$a_include_header)
00601 {
00602 $pos = strpos($xml, "?>");
00603 $xml = substr($xml, $pos + 2);
00604 }
00605
00606 return $xml;
00607 }
00608
00617 function saveToDb($original_id = "")
00618 {
00619 global $ilias;
00620
00621 $complete = 0;
00622 if ($this->isComplete())
00623 {
00624 $complete = 1;
00625 }
00626 $db = & $ilias->db;
00627
00628 $estw_time = $this->getEstimatedWorkingTime();
00629 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00630
00631 if ($original_id)
00632 {
00633 $original_id = $db->quote($original_id);
00634 }
00635 else
00636 {
00637 $original_id = "NULL";
00638 }
00639
00640 if ($this->id == -1)
00641 {
00642
00643 $now = getdate();
00644 $question_type = $this->getQuestionType();
00645 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00646 $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, shuffle, choice_response, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00647 $db->quote($question_type),
00648 $db->quote($this->obj_id),
00649 $db->quote($this->title),
00650 $db->quote($this->comment),
00651 $db->quote($this->author),
00652 $db->quote($this->owner),
00653 $db->quote($this->question),
00654 $db->quote($estw_time),
00655 $db->quote("$this->shuffle"),
00656 $db->quote($this->response),
00657 $db->quote("$complete"),
00658 $db->quote($created),
00659 $original_id
00660 );
00661 $result = $db->query($query);
00662
00663 if ($result == DB_OK)
00664 {
00665 $this->id = $this->ilias->db->getLastInsertId();
00666
00667
00668 $this->createPageObject();
00669
00670
00671 if ($this->getTestId() > 0)
00672 {
00673 $this->insertIntoTest($this->getTestId());
00674 }
00675 }
00676 }
00677 else
00678 {
00679
00680 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time=%s, shuffle = %s, choice_response = %s, complete = %s WHERE question_id = %s",
00681 $db->quote($this->obj_id. ""),
00682 $db->quote($this->title),
00683 $db->quote($this->comment),
00684 $db->quote($this->author),
00685 $db->quote($this->question),
00686 $db->quote($estw_time),
00687 $db->quote("$this->shuffle"),
00688 $db->quote($this->response),
00689 $db->quote("$complete"),
00690 $db->quote($this->id)
00691 );
00692 $result = $db->query($query);
00693 }
00694 if ($result == DB_OK)
00695 {
00696
00697
00698 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00699 $db->quote($this->id)
00700 );
00701 $result = $db->query($query);
00702
00703
00704 foreach ($this->answers as $key => $value)
00705 {
00706 $answer_obj = $this->answers[$key];
00707 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, correctness, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
00708 $db->quote($this->id),
00709 $db->quote($answer_obj->get_answertext()),
00710 $db->quote($answer_obj->get_points() . ""),
00711 $db->quote($answer_obj->get_order() . ""),
00712 $db->quote($answer_obj->getState() . "")
00713 );
00714 $answer_result = $db->query($query);
00715 }
00716 }
00717 parent::saveToDb($original_id);
00718 }
00719
00729 function loadFromDb($question_id)
00730 {
00731 global $ilias;
00732
00733 $db = & $ilias->db;
00734 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00735 $db->quote($question_id));
00736 $result = $db->query($query);
00737 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00738 {
00739 if ($result->numRows() == 1)
00740 {
00741 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00742 $this->id = $question_id;
00743 $this->title = $data->title;
00744 $this->comment = $data->comment;
00745 $this->solution_hint = $data->solution_hint;
00746 $this->original_id = $data->original_id;
00747 $this->obj_id = $data->obj_fi;
00748 $this->author = $data->author;
00749 $this->owner = $data->owner;
00750 $this->question = $data->question_text;
00751 $this->response = $data->choice_response;
00752 $this->setShuffle($data->shuffle);
00753 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00754 }
00755
00756 $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY aorder ASC",
00757 $db->quote($question_id));
00758
00759 $result = $db->query($query);
00760
00761 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00762 {
00763 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00764 {
00765 if ($this->response == RESPONSE_SINGLE)
00766 {
00767 if ($data->correctness == 0)
00768 {
00769
00770 $data->correctness = 1;
00771 $data->points = 0;
00772 }
00773 }
00774 array_push($this->answers, new ASS_AnswerBinaryState($data->answertext, $data->points, $data->aorder, $data->correctness));
00775 }
00776 }
00777 }
00778 parent::loadFromDb($question_id);
00779 }
00780
00788 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00789 {
00790 if ($this->id <= 0)
00791 {
00792
00793 return;
00794 }
00795
00796 $clone = $this;
00797 include_once ("./assessment/classes/class.assQuestion.php");
00798 $original_id = ASS_Question::_getOriginalId($this->id);
00799 $clone->id = -1;
00800 if ($title)
00801 {
00802 $clone->setTitle($title);
00803 }
00804
00805 if ($author)
00806 {
00807 $clone->setAuthor($author);
00808 }
00809 if ($owner)
00810 {
00811 $clone->setOwner($owner);
00812 }
00813
00814 if ($for_test)
00815 {
00816 $clone->saveToDb($original_id);
00817 }
00818 else
00819 {
00820 $clone->saveToDb();
00821 }
00822
00823
00824 $clone->copyPageOfQuestion($original_id);
00825
00826 return $clone->id;
00827 }
00828
00838 function get_question()
00839 {
00840 return $this->question;
00841 }
00842
00852 function set_question($question = "")
00853 {
00854 $this->question = $question;
00855 }
00856
00866 function get_response()
00867 {
00868 return $this->response;
00869 }
00870
00880 function set_response($response = "")
00881 {
00882 $this->response = $response;
00883 }
00884
00894 function get_output_type()
00895 {
00896 return $this->output_type;
00897 }
00898
00908 function set_output_type($output_type = OUTPUT_ORDER)
00909 {
00910 $this->output_type = $output_type;
00911 }
00912
00927 function add_answer(
00928 $answertext = "",
00929 $points = 0.0,
00930 $state = 0,
00931 $order = 0
00932 )
00933 {
00934 $found = -1;
00935 foreach ($this->answers as $key => $value)
00936 {
00937 if ($value->get_order() == $order)
00938 {
00939 $found = $order;
00940 }
00941 }
00942 if ($found >= 0)
00943 {
00944
00945 $answer = new ASS_AnswerBinaryState($answertext, $points, $found, $state);
00946 array_push($this->answers, $answer);
00947 for ($i = $found + 1; $i < count($this->answers); $i++)
00948 {
00949 $this->answers[$i] = $this->answers[$i-1];
00950 }
00951 $this->answers[$found] = $answer;
00952 }
00953 else
00954 {
00955
00956 $answer = new ASS_AnswerBinaryState($answertext, $points, count($this->answers), $state);
00957 array_push($this->answers, $answer);
00958 }
00959 }
00960
00970 function get_answer_count()
00971 {
00972 return count($this->answers);
00973 }
00974
00986 function get_answer($index = 0)
00987 {
00988 if ($index < 0) return NULL;
00989 if (count($this->answers) < 1) return NULL;
00990 if ($index >= count($this->answers)) return NULL;
00991
00992 return $this->answers[$index];
00993 }
00994
01005 function delete_answer($index = 0)
01006 {
01007 if ($index < 0) return;
01008 if (count($this->answers) < 1) return;
01009 if ($index >= count($this->answers)) return;
01010 unset($this->answers[$index]);
01011 $this->answers = array_values($this->answers);
01012 for ($i = 0; $i < count($this->answers); $i++)
01013 {
01014 if ($this->answers[$i]->get_order() > $index)
01015 {
01016 $this->answers[$i]->set_order($i);
01017 }
01018 }
01019 }
01020
01029 function flush_answers()
01030 {
01031 $this->answers = array();
01032 }
01033
01042 function getMaximumPoints()
01043 {
01044 $points = array("set" => 0, "unset" => 0);
01045 if ($this->get_response() == RESPONSE_SINGLE)
01046 {
01047 foreach ($this->answers as $key => $value)
01048 {
01049 if ($value->get_points() > $points["set"])
01050 {
01051 $points["set"] = $value->get_points();
01052 }
01053 }
01054 return $points["set"];
01055 }
01056 else
01057 {
01058 $allpoints = 0;
01059 foreach ($this->answers as $key => $value) {
01060 $allpoints += $value->get_points();
01061 }
01062 return $allpoints;
01063 }
01064 }
01065
01075 function getReachedPoints($user_id, $test_id)
01076 {
01077 global $ilDB;
01078
01079 $found_values = array();
01080 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01081 $ilDB->quote($user_id),
01082 $ilDB->quote($test_id),
01083 $ilDB->quote($this->getId())
01084 );
01085 $result = $ilDB->query($query);
01086 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01087 {
01088 if (strcmp($data->value1, "") != 0)
01089 {
01090 array_push($found_values, $data->value1);
01091 }
01092 }
01093 $points = 0;
01094 if (count($found_values) > 0)
01095
01096 {
01097 foreach ($this->answers as $key => $answer)
01098 {
01099 if ($answer->isStateChecked())
01100 {
01101 if (in_array($key, $found_values))
01102 {
01103 $points += $answer->get_points();
01104 }
01105 }
01106 else
01107 {
01108 if (!in_array($key, $found_values))
01109 {
01110 $points += $answer->get_points();
01111 }
01112 }
01113 }
01114 }
01115 return $points;
01116 }
01117
01129 function _getReachedPoints($user_id, $test_id)
01130 {
01131 return 0;
01132 }
01133
01143 function getReachedInformation($user_id, $test_id)
01144 {
01145 $found_values = array();
01146 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01147 $this->ilias->db->quote($user_id),
01148 $this->ilias->db->quote($test_id),
01149 $this->ilias->db->quote($this->getId())
01150 );
01151 $result = $this->ilias->db->query($query);
01152 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01153 {
01154 array_push($found_values, $data->value1);
01155 }
01156 $counter = 1;
01157 $user_result = array();
01158 foreach ($found_values as $key => $value)
01159 {
01160 $solution = array(
01161 "order" => "$counter",
01162 "points" => 0,
01163 "true" => 0,
01164 "value" => "",
01165 );
01166 if (strlen($value) > 0)
01167 {
01168 $solution["value"] = $value;
01169 $solution["points"] = $this->answers[$value]->get_points();
01170 if ($this->answers[$value]->isStateChecked())
01171 {
01172 $solution["true"] = 1;
01173 }
01174 }
01175 $counter++;
01176 $user_result[$value] = $solution;
01177 }
01178 return $user_result;
01179 }
01180
01191 function saveWorkingData($test_id, $limit_to = LIMIT_NO_LIMIT)
01192 {
01193 global $ilDB;
01194 global $ilUser;
01195
01196 $db =& $ilDB->db;
01197
01198 if ($this->response == RESPONSE_SINGLE)
01199 {
01200 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01201 $db->quote($ilUser->id),
01202 $db->quote($test_id),
01203 $db->quote($this->getId())
01204 );
01205 $result = $db->query($query);
01206 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
01207 $update = $row->solution_id;
01208 if ($update)
01209 {
01210 $query = sprintf("UPDATE tst_solutions SET value1 = %s WHERE solution_id = %s",
01211 $db->quote($_POST["multiple_choice_result"]),
01212 $db->quote($update));
01213 }
01214 else
01215 {
01216 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL, NULL)",
01217 $db->quote($ilUser->id),
01218 $db->quote($test_id),
01219 $db->quote($this->getId()),
01220 $db->quote($_POST["multiple_choice_result"])
01221 );
01222 }
01223 $result = $db->query($query);
01224 }
01225 else
01226 {
01227 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01228 $db->quote($ilUser->id),
01229 $db->quote($test_id),
01230 $db->quote($this->getId())
01231 );
01232 $result = $db->query($query);
01233 foreach ($_POST as $key => $value)
01234 {
01235 if (preg_match("/^multiple_choice_result_(\d+)/", $key, $matches))
01236 {
01237 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL, NULL)",
01238 $db->quote($ilUser->id),
01239 $db->quote($test_id),
01240 $db->quote($this->getId()),
01241 $db->quote($value)
01242 );
01243 $result = $db->query($query);
01244 }
01245 }
01246 }
01247
01248 return true;
01249 }
01250
01251 function syncWithOriginal()
01252 {
01253 global $ilias;
01254 if ($this->original_id)
01255 {
01256 $complete = 0;
01257 if ($this->isComplete())
01258 {
01259 $complete = 1;
01260 }
01261 $db = & $ilias->db;
01262
01263 $estw_time = $this->getEstimatedWorkingTime();
01264 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01265
01266 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time=%s, shuffle = %s, choice_response = %s, complete = %s WHERE question_id = %s",
01267 $db->quote($this->obj_id. ""),
01268 $db->quote($this->title. ""),
01269 $db->quote($this->comment. ""),
01270 $db->quote($this->author. ""),
01271 $db->quote($this->question. ""),
01272 $db->quote($estw_time. ""),
01273 $db->quote($this->shuffle. ""),
01274 $db->quote($this->response. ""),
01275 $db->quote($complete. ""),
01276 $db->quote($this->original_id. "")
01277 );
01278 $result = $db->query($query);
01279
01280 if ($result == DB_OK)
01281 {
01282
01283
01284 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01285 $db->quote($this->original_id)
01286 );
01287 $result = $db->query($query);
01288
01289 foreach ($this->answers as $key => $value)
01290 {
01291 $answer_obj = $this->answers[$key];
01292 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, correctness, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01293 $db->quote($this->original_id. ""),
01294 $db->quote($answer_obj->get_answertext(). ""),
01295 $db->quote($answer_obj->get_points() . ""),
01296 $db->quote($answer_obj->get_order() . ""),
01297 $db->quote($answer_obj->getState() . "")
01298 );
01299 $answer_result = $db->query($query);
01300 }
01301 }
01302 parent::syncWithOriginal();
01303 }
01304 }
01305
01306 function createRandomSolution($test_id, $user_id)
01307 {
01308 mt_srand((double)microtime()*1000000);
01309 $answer = mt_rand(0, count($this->answers)-1);
01310
01311 global $ilDB;
01312 global $ilUser;
01313
01314 $db =& $ilDB->db;
01315
01316 if ($this->response == RESPONSE_SINGLE)
01317 {
01318 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01319 $db->quote($user_id),
01320 $db->quote($test_id),
01321 $db->quote($this->getId())
01322 );
01323 $result = $db->query($query);
01324 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
01325 $update = $row->solution_id;
01326 if ($update)
01327 {
01328 $query = sprintf("UPDATE tst_solutions SET value1 = %s WHERE solution_id = %s",
01329 $db->quote($answer),
01330 $db->quote($update));
01331 }
01332 else
01333 {
01334 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL, NULL)",
01335 $db->quote($user_id),
01336 $db->quote($test_id),
01337 $db->quote($this->getId()),
01338 $db->quote($answer)
01339 );
01340 }
01341 $result = $db->query($query);
01342 }
01343 else
01344 {
01345 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01346 $db->quote($user_id),
01347 $db->quote($test_id),
01348 $db->quote($this->getId())
01349 );
01350 $result = $db->query($query);
01351 $answerarray = array();
01352 for ($i = 0; $i < $answer; $i++)
01353 {
01354 $manswer = mt_rand(0, count($this->answers)-1);
01355 $answerarray[$manswer]++;
01356 }
01357 foreach ($answerarray as $key => $value)
01358 {
01359 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL, NULL)",
01360 $db->quote($user_id),
01361 $db->quote($test_id),
01362 $db->quote($this->getId()),
01363 $db->quote($key)
01364 );
01365 $result = $db->query($query);
01366 }
01367 }
01368 }
01369
01378 function getQuestionType()
01379 {
01380 if ($this->response == RESPONSE_SINGLE)
01381 {
01382 $question_type = 1;
01383 }
01384 else
01385 {
01386 $question_type = 2;
01387 }
01388 return $question_type;
01389 }
01390
01391 }
01392
01393 ?>