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, points, 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, %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($this->getMaximumPoints() . ""),
00655 $db->quote($estw_time),
00656 $db->quote("$this->shuffle"),
00657 $db->quote($this->response),
00658 $db->quote("$complete"),
00659 $db->quote($created),
00660 $original_id
00661 );
00662 $result = $db->query($query);
00663
00664 if ($result == DB_OK)
00665 {
00666 $this->id = $this->ilias->db->getLastInsertId();
00667
00668
00669 $this->createPageObject();
00670
00671
00672 if ($this->getTestId() > 0)
00673 {
00674 $this->insertIntoTest($this->getTestId());
00675 }
00676 }
00677 }
00678 else
00679 {
00680
00681 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, points = %s, working_time=%s, shuffle = %s, choice_response = %s, complete = %s WHERE question_id = %s",
00682 $db->quote($this->obj_id. ""),
00683 $db->quote($this->title),
00684 $db->quote($this->comment),
00685 $db->quote($this->author),
00686 $db->quote($this->question),
00687 $db->quote($this->getMaximumPoints() . ""),
00688 $db->quote($estw_time),
00689 $db->quote("$this->shuffle"),
00690 $db->quote($this->response),
00691 $db->quote("$complete"),
00692 $db->quote($this->id)
00693 );
00694 $result = $db->query($query);
00695 }
00696 if ($result == DB_OK)
00697 {
00698
00699
00700 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00701 $db->quote($this->id)
00702 );
00703 $result = $db->query($query);
00704
00705
00706 foreach ($this->answers as $key => $value)
00707 {
00708 $answer_obj = $this->answers[$key];
00709 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, correctness, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
00710 $db->quote($this->id),
00711 $db->quote($answer_obj->get_answertext()),
00712 $db->quote($answer_obj->get_points() . ""),
00713 $db->quote($answer_obj->get_order() . ""),
00714 $db->quote($answer_obj->getState() . "")
00715 );
00716 $answer_result = $db->query($query);
00717 }
00718 }
00719 parent::saveToDb($original_id);
00720 }
00721
00731 function loadFromDb($question_id)
00732 {
00733 global $ilias;
00734
00735 $db = & $ilias->db;
00736 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00737 $db->quote($question_id));
00738 $result = $db->query($query);
00739 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00740 {
00741 if ($result->numRows() == 1)
00742 {
00743 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00744 $this->id = $question_id;
00745 $this->title = $data->title;
00746 $this->comment = $data->comment;
00747 $this->solution_hint = $data->solution_hint;
00748 $this->original_id = $data->original_id;
00749 $this->obj_id = $data->obj_fi;
00750 $this->author = $data->author;
00751 $this->owner = $data->owner;
00752 $this->points = $data->points;
00753 $this->question = $data->question_text;
00754 $this->response = $data->choice_response;
00755 $this->setShuffle($data->shuffle);
00756 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00757 }
00758
00759 $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY aorder ASC",
00760 $db->quote($question_id));
00761
00762 $result = $db->query($query);
00763
00764 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00765 {
00766 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00767 {
00768 if ($this->response == RESPONSE_SINGLE)
00769 {
00770 if ($data->correctness == 0)
00771 {
00772
00773 $data->correctness = 1;
00774 $data->points = 0;
00775 }
00776 }
00777 array_push($this->answers, new ASS_AnswerBinaryState($data->answertext, $data->points, $data->aorder, $data->correctness));
00778 }
00779 }
00780 }
00781 parent::loadFromDb($question_id);
00782 }
00783
00791 function addAnswer($answertext, $points, $answerorder, $correctness)
00792 {
00793 array_push($this->answers, new ASS_AnswerBinaryState($answertext, $points, $answerorder, $correctness));
00794 }
00795
00803 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00804 {
00805 if ($this->id <= 0)
00806 {
00807
00808 return;
00809 }
00810
00811 $clone = $this;
00812 include_once ("./assessment/classes/class.assQuestion.php");
00813 $original_id = ASS_Question::_getOriginalId($this->id);
00814 $clone->id = -1;
00815 if ($title)
00816 {
00817 $clone->setTitle($title);
00818 }
00819
00820 if ($author)
00821 {
00822 $clone->setAuthor($author);
00823 }
00824 if ($owner)
00825 {
00826 $clone->setOwner($owner);
00827 }
00828
00829 if ($for_test)
00830 {
00831 $clone->saveToDb($original_id);
00832 }
00833 else
00834 {
00835 $clone->saveToDb();
00836 }
00837
00838
00839 $clone->copyPageOfQuestion($original_id);
00840
00841 return $clone->id;
00842 }
00843
00853 function get_question()
00854 {
00855 return $this->question;
00856 }
00857
00867 function set_question($question = "")
00868 {
00869 $this->question = $question;
00870 }
00871
00881 function get_response()
00882 {
00883 return $this->response;
00884 }
00885
00895 function set_response($response = "")
00896 {
00897 $this->response = $response;
00898 }
00899
00909 function get_output_type()
00910 {
00911 return $this->output_type;
00912 }
00913
00923 function set_output_type($output_type = OUTPUT_ORDER)
00924 {
00925 $this->output_type = $output_type;
00926 }
00927
00942 function add_answer(
00943 $answertext = "",
00944 $points = 0.0,
00945 $state = 0,
00946 $order = 0
00947 )
00948 {
00949 $found = -1;
00950 foreach ($this->answers as $key => $value)
00951 {
00952 if ($value->get_order() == $order)
00953 {
00954 $found = $order;
00955 }
00956 }
00957 if ($found >= 0)
00958 {
00959
00960 $answer = new ASS_AnswerBinaryState($answertext, $points, $found, $state);
00961 array_push($this->answers, $answer);
00962 for ($i = $found + 1; $i < count($this->answers); $i++)
00963 {
00964 $this->answers[$i] = $this->answers[$i-1];
00965 }
00966 $this->answers[$found] = $answer;
00967 }
00968 else
00969 {
00970
00971 $answer = new ASS_AnswerBinaryState($answertext, $points, count($this->answers), $state);
00972 array_push($this->answers, $answer);
00973 }
00974 }
00975
00985 function get_answer_count()
00986 {
00987 return count($this->answers);
00988 }
00989
01001 function get_answer($index = 0)
01002 {
01003 if ($index < 0) return NULL;
01004 if (count($this->answers) < 1) return NULL;
01005 if ($index >= count($this->answers)) return NULL;
01006
01007 return $this->answers[$index];
01008 }
01009
01020 function delete_answer($index = 0)
01021 {
01022 if ($index < 0) return;
01023 if (count($this->answers) < 1) return;
01024 if ($index >= count($this->answers)) return;
01025 unset($this->answers[$index]);
01026 $this->answers = array_values($this->answers);
01027 for ($i = 0; $i < count($this->answers); $i++)
01028 {
01029 if ($this->answers[$i]->get_order() > $index)
01030 {
01031 $this->answers[$i]->set_order($i);
01032 }
01033 }
01034 }
01035
01044 function flush_answers()
01045 {
01046 $this->answers = array();
01047 }
01048
01057 function getMaximumPoints()
01058 {
01059 $points = array("set" => 0, "unset" => 0);
01060 if ($this->get_response() == RESPONSE_SINGLE)
01061 {
01062 foreach ($this->answers as $key => $value)
01063 {
01064 if ($value->get_points() > $points["set"])
01065 {
01066 $points["set"] = $value->get_points();
01067 }
01068 }
01069 return $points["set"];
01070 }
01071 else
01072 {
01073 $allpoints = 0;
01074 foreach ($this->answers as $key => $value) {
01075 $allpoints += $value->get_points();
01076 }
01077 return $allpoints;
01078 }
01079 }
01080
01092 function calculateReachedPoints($user_id, $test_id)
01093 {
01094 global $ilDB;
01095
01096 $found_values = array();
01097 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01098 $ilDB->quote($user_id),
01099 $ilDB->quote($test_id),
01100 $ilDB->quote($this->getId())
01101 );
01102 $result = $ilDB->query($query);
01103 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01104 {
01105 if (strcmp($data->value1, "") != 0)
01106 {
01107 array_push($found_values, $data->value1);
01108 }
01109 }
01110 $points = 0;
01111 foreach ($this->answers as $key => $answer)
01112 {
01113 if ((count($found_values) > 0) || ($this->get_response() == RESPONSE_MULTIPLE))
01114 {
01115 if ($answer->isStateChecked())
01116 {
01117 if (in_array($key, $found_values))
01118 {
01119 $points += $answer->get_points();
01120 }
01121 }
01122 else
01123 {
01124 if (!in_array($key, $found_values))
01125 {
01126 $points += $answer->get_points();
01127 }
01128 }
01129 }
01130 }
01131
01132
01133 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
01134 $ilDB->quote($test_id)
01135 );
01136 $result = $ilDB->query($query);
01137 if ($result->numRows() == 1)
01138 {
01139 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01140 if ($row["mc_scoring"] == 0)
01141 {
01142 if (!$this->wasAnsweredByUser($user_id, $test_id))
01143 {
01144 $points = 0;
01145 }
01146 }
01147 if ($row["count_system"] == 1)
01148 {
01149 if ($points != $this->getMaximumPoints())
01150 {
01151 $points = 0;
01152 }
01153 }
01154 }
01155 else
01156 {
01157 $points = 0;
01158 }
01159 return $points;
01160 }
01161
01172 function wasAnsweredByUser($user_id, $test_id)
01173 {
01174 global $ilDB;
01175 $found_values = array();
01176 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01177 $ilDB->quote($user_id),
01178 $ilDB->quote($test_id),
01179 $ilDB->quote($this->getId())
01180 );
01181 $result = $ilDB->query($query);
01182 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01183 {
01184 if (strcmp($data->value1, "") != 0)
01185 {
01186 array_push($found_values, $data->value1);
01187 }
01188 }
01189 if (count($found_values) == 0)
01190 {
01191 return FALSE;
01192 }
01193 else
01194 {
01195 return TRUE;
01196 }
01197 }
01198
01208 function getReachedInformation($user_id, $test_id)
01209 {
01210 $found_values = array();
01211 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01212 $this->ilias->db->quote($user_id),
01213 $this->ilias->db->quote($test_id),
01214 $this->ilias->db->quote($this->getId())
01215 );
01216 $result = $this->ilias->db->query($query);
01217 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01218 {
01219 array_push($found_values, $data->value1);
01220 }
01221 $counter = 1;
01222 $user_result = array();
01223 foreach ($found_values as $key => $value)
01224 {
01225 $solution = array(
01226 "order" => "$counter",
01227 "points" => 0,
01228 "true" => 0,
01229 "value" => "",
01230 );
01231 if (strlen($value) > 0)
01232 {
01233 $solution["value"] = $value;
01234 $solution["points"] = $this->answers[$value]->get_points();
01235 if ($this->answers[$value]->isStateChecked())
01236 {
01237 $solution["true"] = 1;
01238 }
01239 }
01240 $counter++;
01241 $user_result[$value] = $solution;
01242 }
01243 return $user_result;
01244 }
01245
01256 function saveWorkingData($test_id, $limit_to = LIMIT_NO_LIMIT)
01257 {
01258 global $ilDB;
01259 global $ilUser;
01260
01261 $db =& $ilDB->db;
01262
01263 if ($this->response == RESPONSE_SINGLE)
01264 {
01265 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01266 $db->quote($ilUser->id),
01267 $db->quote($test_id),
01268 $db->quote($this->getId())
01269 );
01270 $result = $db->query($query);
01271 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
01272 $update = $row->solution_id;
01273 if ($update)
01274 {
01275 $query = sprintf("UPDATE tst_solutions SET value1 = %s WHERE solution_id = %s",
01276 $db->quote($_POST["multiple_choice_result"]),
01277 $db->quote($update));
01278 }
01279 else
01280 {
01281 $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)",
01282 $db->quote($ilUser->id),
01283 $db->quote($test_id),
01284 $db->quote($this->getId()),
01285 $db->quote($_POST["multiple_choice_result"])
01286 );
01287 }
01288 $result = $db->query($query);
01289 }
01290 else
01291 {
01292 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01293 $db->quote($ilUser->id),
01294 $db->quote($test_id),
01295 $db->quote($this->getId())
01296 );
01297 $result = $db->query($query);
01298 foreach ($_POST as $key => $value)
01299 {
01300 if (preg_match("/^multiple_choice_result_(\d+)/", $key, $matches))
01301 {
01302 $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)",
01303 $db->quote($ilUser->id),
01304 $db->quote($test_id),
01305 $db->quote($this->getId()),
01306 $db->quote($value)
01307 );
01308 $result = $db->query($query);
01309 }
01310 }
01311 }
01312 parent::saveWorkingData($test_id);
01313 return true;
01314 }
01315
01316 function syncWithOriginal()
01317 {
01318 global $ilias;
01319 if ($this->original_id)
01320 {
01321 $complete = 0;
01322 if ($this->isComplete())
01323 {
01324 $complete = 1;
01325 }
01326 $db = & $ilias->db;
01327
01328 $estw_time = $this->getEstimatedWorkingTime();
01329 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01330
01331 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, points = %s, working_time=%s, shuffle = %s, choice_response = %s, complete = %s WHERE question_id = %s",
01332 $db->quote($this->obj_id. ""),
01333 $db->quote($this->title. ""),
01334 $db->quote($this->comment. ""),
01335 $db->quote($this->author. ""),
01336 $db->quote($this->question. ""),
01337 $db->quote($this->getMaximumPoints() . ""),
01338 $db->quote($estw_time. ""),
01339 $db->quote($this->shuffle. ""),
01340 $db->quote($this->response. ""),
01341 $db->quote($complete. ""),
01342 $db->quote($this->original_id. "")
01343 );
01344 $result = $db->query($query);
01345
01346 if ($result == DB_OK)
01347 {
01348
01349
01350 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01351 $db->quote($this->original_id)
01352 );
01353 $result = $db->query($query);
01354
01355 foreach ($this->answers as $key => $value)
01356 {
01357 $answer_obj = $this->answers[$key];
01358 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, correctness, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01359 $db->quote($this->original_id. ""),
01360 $db->quote($answer_obj->get_answertext(). ""),
01361 $db->quote($answer_obj->get_points() . ""),
01362 $db->quote($answer_obj->get_order() . ""),
01363 $db->quote($answer_obj->getState() . "")
01364 );
01365 $answer_result = $db->query($query);
01366 }
01367 }
01368 parent::syncWithOriginal();
01369 }
01370 }
01371
01372 function createRandomSolution($test_id, $user_id)
01373 {
01374 mt_srand((double)microtime()*1000000);
01375 $answer = mt_rand(0, count($this->answers)-1);
01376
01377 global $ilDB;
01378 global $ilUser;
01379
01380 $db =& $ilDB->db;
01381
01382 if ($this->response == RESPONSE_SINGLE)
01383 {
01384 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01385 $db->quote($user_id),
01386 $db->quote($test_id),
01387 $db->quote($this->getId())
01388 );
01389 $result = $db->query($query);
01390 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
01391 $update = $row->solution_id;
01392 if ($update)
01393 {
01394 $query = sprintf("UPDATE tst_solutions SET value1 = %s WHERE solution_id = %s",
01395 $db->quote($answer),
01396 $db->quote($update));
01397 }
01398 else
01399 {
01400 $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)",
01401 $db->quote($user_id),
01402 $db->quote($test_id),
01403 $db->quote($this->getId()),
01404 $db->quote($answer)
01405 );
01406 }
01407 $result = $db->query($query);
01408 }
01409 else
01410 {
01411 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01412 $db->quote($user_id),
01413 $db->quote($test_id),
01414 $db->quote($this->getId())
01415 );
01416 $result = $db->query($query);
01417 $answerarray = array();
01418 for ($i = 0; $i < $answer; $i++)
01419 {
01420 $manswer = mt_rand(0, count($this->answers)-1);
01421 $answerarray[$manswer]++;
01422 }
01423 foreach ($answerarray as $key => $value)
01424 {
01425 $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)",
01426 $db->quote($user_id),
01427 $db->quote($test_id),
01428 $db->quote($this->getId()),
01429 $db->quote($key)
01430 );
01431 $result = $db->query($query);
01432 }
01433 }
01434 }
01435
01444 function getQuestionType()
01445 {
01446 if ($this->response == RESPONSE_SINGLE)
01447 {
01448 $question_type = 1;
01449 }
01450 else
01451 {
01452 $question_type = 2;
01453 }
01454 return $question_type;
01455 }
01456
01457 }
01458
01459 ?>