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.assAnswerOrdering.php";
00026
00027 define ("OQ_PICTURES", 0);
00028 define ("OQ_TERMS", 1);
00029
00030 define ("ORDERING_QUESTION_IDENTIFIER", "ORDERING QUESTION");
00031
00042 class ASS_OrderingQuestion extends ASS_Question
00043 {
00051 var $question;
00052
00060 var $answers;
00061
00070 var $ordering_type;
00071
00081 var $points;
00082
00096 function ASS_OrderingQuestion (
00097 $title = "",
00098 $comment = "",
00099 $author = "",
00100 $owner = -1,
00101 $question = "",
00102 $points = 0.0,
00103 $ordering_type = OQ_TERMS
00104 )
00105 {
00106 $this->ASS_Question($title, $comment, $author, $owner);
00107 $this->answers = array();
00108 $this->question = $question;
00109 $this->points = $points;
00110 $this->ordering_type = $ordering_type;
00111 }
00112
00121 function isComplete()
00122 {
00123 if (($this->title) and ($this->author) and ($this->question) and (count($this->answers)))
00124 {
00125 return true;
00126 }
00127 else
00128 {
00129 return false;
00130 }
00131 }
00132
00142 function from_xml($xml_text)
00143 {
00144 $result = false;
00145 if (!empty($this->domxml))
00146 {
00147 $this->domxml->free();
00148 }
00149 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
00150 $this->domxml = domxml_open_mem($xml_text);
00151 if (!empty($this->domxml))
00152 {
00153 $root = $this->domxml->document_element();
00154 $item = $root->first_child();
00155 $this->setTitle($item->get_attribute("title"));
00156 $this->gaps = array();
00157 $itemnodes = $item->child_nodes();
00158 $materials = array();
00159 $images = array();
00160 $shuffle = "";
00161 foreach ($itemnodes as $index => $node)
00162 {
00163 switch ($node->node_name())
00164 {
00165 case "qticomment":
00166 $comment = $node->get_content();
00167 if (strpos($comment, "ILIAS Version=") !== false)
00168 {
00169 }
00170 elseif (strpos($comment, "Questiontype=") !== false)
00171 {
00172 }
00173 elseif (strpos($comment, "Author=") !== false)
00174 {
00175 $comment = str_replace("Author=", "", $comment);
00176 $this->setAuthor($comment);
00177 }
00178 else
00179 {
00180 $this->setComment($comment);
00181 }
00182 break;
00183 case "itemmetadata":
00184 $md_array = array();
00185 $metanodes = $node->child_nodes();
00186 foreach ($metanodes as $metanode)
00187 {
00188 switch ($metanode->node_name())
00189 {
00190 case "qtimetadata":
00191 $metafields = $metanode->child_nodes();
00192 foreach ($metafields as $metafield)
00193 {
00194 switch ($metafield->node_name())
00195 {
00196 case "qtimetadatafield":
00197 $metafieldlist = $metafield->child_nodes();
00198 $md = array("label" => "", "entry" => "");
00199 foreach ($metafieldlist as $attr)
00200 {
00201 switch ($attr->node_name())
00202 {
00203 case "fieldlabel":
00204 $md["label"] = $attr->get_content();
00205 break;
00206 case "fieldentry":
00207 $md["entry"] = $attr->get_content();
00208 break;
00209 }
00210 }
00211 array_push($md_array, $md);
00212 break;
00213 }
00214 }
00215 break;
00216 }
00217 }
00218 foreach ($md_array as $md)
00219 {
00220 switch ($md["label"])
00221 {
00222 case "ILIAS_VERSION":
00223 break;
00224 case "QUESTIONTYPE":
00225 break;
00226 case "AUTHOR":
00227 $this->setAuthor($md["entry"]);
00228 break;
00229 }
00230 }
00231 break;
00232 case "duration":
00233 $iso8601period = $node->get_content();
00234 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
00235 {
00236 $this->setEstimatedWorkingTime($matches[4], $matches[5], $matches[6]);
00237 }
00238 break;
00239 case "presentation":
00240 $flow = $node->first_child();
00241 $flownodes = $flow->child_nodes();
00242 foreach ($flownodes as $idx => $flownode)
00243 {
00244 if (strcmp($flownode->node_name(), "material") == 0)
00245 {
00246 $mattext = $flownode->first_child();
00247 $this->set_question($mattext->get_content());
00248 }
00249 elseif (strcmp($flownode->node_name(), "response_lid") == 0)
00250 {
00251 $ident = $flownode->get_attribute("ident");
00252 if (strcmp($ident, "OQT") == 0)
00253 {
00254 $this->set_ordering_type(OQ_TERMS);
00255 }
00256 elseif (strcmp($ident, "OQP") == 0)
00257 {
00258 $this->set_ordering_type(OQ_PICTURES);
00259 }
00260 $subnodes = $flownode->child_nodes();
00261 foreach ($subnodes as $node_type)
00262 {
00263 switch ($node_type->node_name())
00264 {
00265 case "material":
00266 $matlabel = $node_type->get_attribute("label");
00267 if (strcmp($matlabel, "suggested_solution") == 0)
00268 {
00269 $mattype = $node_type->first_child();
00270 if (strcmp($mattype->node_name(), "mattext") == 0)
00271 {
00272 $suggested_solution = $mattype->get_content();
00273 if ($suggested_solution)
00274 {
00275 if ($this->getId() < 1)
00276 {
00277 $this->saveToDb();
00278 }
00279 $this->setSuggestedSolution($suggested_solution, 0, true);
00280 }
00281 }
00282 }
00283 break;
00284 case "render_choice":
00285 $render_choice = $node_type;
00286 $shuffle = $render_choice->get_attribute("shuffle");
00287 $shuf = 0;
00288 if (strcmp(strtolower($shuffle), "yes") == 0)
00289 {
00290 $shuf = 1;
00291 }
00292 $this->setShuffle($shuf);
00293 $labels = $render_choice->child_nodes();
00294 foreach ($labels as $lidx => $response_label)
00295 {
00296 $material = $response_label->first_child();
00297 if ($this->get_ordering_type() == OQ_PICTURES)
00298 {
00299 $matimage = $material->first_child();
00300 $filename = $matimage->get_attribute("label");
00301 $image = base64_decode($matimage->get_content());
00302 $images["$filename"] = $image;
00303 $materials[$response_label->get_attribute("ident")] = $filename;
00304 }
00305 else
00306 {
00307 $mattext = $material->first_child();
00308 $materials[$response_label->get_attribute("ident")] = $mattext->get_content();
00309 }
00310 }
00311 }
00312 }
00313 }
00314 }
00315 break;
00316 case "resprocessing":
00317 $resproc_nodes = $node->child_nodes();
00318 foreach ($resproc_nodes as $index => $respcondition)
00319 {
00320 if (strcmp($respcondition->node_name(), "respcondition") == 0)
00321 {
00322 $respcondition_array =& ilQTIUtils::_getRespcondition($respcondition);
00323 $this->add_answer($materials[$respcondition_array["conditionvar"]["value"]], $respcondition_array["setvar"]["points"], count($this->answers), $respcondition_array["conditionvar"]["index"]);
00324 }
00325 }
00326 break;
00327 }
00328 }
00329 if (count($images))
00330 {
00331 $this->saveToDb();
00332 foreach ($images as $filename => $image)
00333 {
00334 if ($filename)
00335 {
00336 $imagepath = $this->getImagePath();
00337 if (!file_exists($imagepath))
00338 {
00339 ilUtil::makeDirParents($imagepath);
00340 }
00341 $imagepath .= $filename;
00342 $fh = fopen($imagepath, "wb");
00343 if ($fh == false)
00344 {
00345 global $ilErr;
00346 $ilErr->raiseError($this->lng->txt("error_save_image_file") . ": $php_errormsg", $ilErr->MESSAGE);
00347 return;
00348 }
00349 $imagefile = fwrite($fh, $image);
00350 fclose($fh);
00351
00352 $thumbpath = $imagepath . "." . "thumb.jpg";
00353 ilUtil::convertImage($imagepath, $thumbpath, "JPEG", 100);
00354 }
00355 }
00356 }
00357 $result = true;
00358 }
00359 return $result;
00360 }
00361
00371 function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false)
00372 {
00373 if (!empty($this->domxml))
00374 {
00375 $this->domxml->free();
00376 }
00377 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<questestinterop></questestinterop>\n";
00378 $this->domxml = domxml_open_mem($xml_header);
00379 $root = $this->domxml->document_element();
00380
00381 $qtiIdent = $this->domxml->create_element("item");
00382 $qtiIdent->set_attribute("ident", "il_".IL_INST_ID."_qst_".$this->getId());
00383 $qtiIdent->set_attribute("title", $this->getTitle());
00384 $root->append_child($qtiIdent);
00385
00386 $qtiComment = $this->domxml->create_element("qticomment");
00387 $qtiCommentText = $this->domxml->create_text_node($this->getComment());
00388 $qtiComment->append_child($qtiCommentText);
00389 $qtiIdent->append_child($qtiComment);
00390
00391 $qtiDuration = $this->domxml->create_element("duration");
00392 $workingtime = $this->getEstimatedWorkingTime();
00393 $qtiDurationText = $this->domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]));
00394 $qtiDuration->append_child($qtiDurationText);
00395 $qtiIdent->append_child($qtiDuration);
00396
00397 $qtiItemmetadata = $this->domxml->create_element("itemmetadata");
00398 $qtiMetadata = $this->domxml->create_element("qtimetadata");
00399
00400 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00401 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00402 $qtiFieldlabelText = $this->domxml->create_text_node("ILIAS_VERSION");
00403 $qtiFieldlabel->append_child($qtiFieldlabelText);
00404 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00405 $qtiFieldentryText = $this->domxml->create_text_node($this->ilias->getSetting("ilias_version"));
00406 $qtiFieldentry->append_child($qtiFieldentryText);
00407 $qtiMetadatafield->append_child($qtiFieldlabel);
00408 $qtiMetadatafield->append_child($qtiFieldentry);
00409 $qtiMetadata->append_child($qtiMetadatafield);
00410
00411 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00412 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00413 $qtiFieldlabelText = $this->domxml->create_text_node("QUESTIONTYPE");
00414 $qtiFieldlabel->append_child($qtiFieldlabelText);
00415 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00416 $qtiFieldentryText = $this->domxml->create_text_node(ORDERING_QUESTION_IDENTIFIER);
00417 $qtiFieldentry->append_child($qtiFieldentryText);
00418 $qtiMetadatafield->append_child($qtiFieldlabel);
00419 $qtiMetadatafield->append_child($qtiFieldentry);
00420 $qtiMetadata->append_child($qtiMetadatafield);
00421
00422 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00423 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00424 $qtiFieldlabelText = $this->domxml->create_text_node("AUTHOR");
00425 $qtiFieldlabel->append_child($qtiFieldlabelText);
00426 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00427 $qtiFieldentryText = $this->domxml->create_text_node($this->getAuthor());
00428 $qtiFieldentry->append_child($qtiFieldentryText);
00429 $qtiMetadatafield->append_child($qtiFieldlabel);
00430 $qtiMetadatafield->append_child($qtiFieldentry);
00431 $qtiMetadata->append_child($qtiMetadatafield);
00432
00433 $qtiItemmetadata->append_child($qtiMetadata);
00434 $qtiIdent->append_child($qtiItemmetadata);
00435
00436
00437 $qtiPresentation = $this->domxml->create_element("presentation");
00438 $qtiPresentation->set_attribute("label", $this->getTitle());
00439
00440 $qtiFlow = $this->domxml->create_element("flow");
00441
00442 $qtiMaterial = $this->domxml->create_element("material");
00443 $qtiMatText = $this->domxml->create_element("mattext");
00444 $qtiMatTextText = $this->domxml->create_text_node($this->get_question());
00445 $qtiMatText->append_child($qtiMatTextText);
00446 $qtiMaterial->append_child($qtiMatText);
00447 $qtiFlow->append_child($qtiMaterial);
00448
00449 $qtiResponseLid = $this->domxml->create_element("response_lid");
00450 if ($this->get_ordering_type() == OQ_PICTURES)
00451 {
00452 $qtiResponseLid->set_attribute("ident", "OQP");
00453 $qtiResponseLid->set_attribute("rcardinality", "Ordered");
00454 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00455 {
00456 $qtiResponseLid->set_attribute("output", "javascript");
00457 }
00458 }
00459 else
00460 {
00461 $qtiResponseLid->set_attribute("ident", "OQT");
00462 $qtiResponseLid->set_attribute("rcardinality", "Ordered");
00463 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00464 {
00465 $qtiResponseLid->set_attribute("output", "javascript");
00466 }
00467 }
00468 $solution = $this->getSuggestedSolution(0);
00469 if (count($solution))
00470 {
00471 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00472 {
00473 $qtiMaterial = $this->domxml->create_element("material");
00474 $qtiMaterial->set_attribute("label", "suggested_solution");
00475 $qtiMatText = $this->domxml->create_element("mattext");
00476 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00477 if (strcmp($matches[1], "") != 0)
00478 {
00479 $intlink = $solution["internal_link"];
00480 }
00481 $qtiMatTextText = $this->domxml->create_text_node($intlink);
00482 $qtiMatText->append_child($qtiMatTextText);
00483 $qtiMaterial->append_child($qtiMatText);
00484 $qtiResponseLid->append_child($qtiMaterial);
00485 }
00486 }
00487 $qtiRenderChoice = $this->domxml->create_element("render_choice");
00488
00489 if ($this->getShuffle())
00490 {
00491 $qtiRenderChoice->set_attribute("shuffle", "Yes");
00492 }
00493 else
00494 {
00495 $qtiRenderChoice->set_attribute("shuffle", "No");
00496 }
00497
00498
00499 $akeys = array_keys($this->answers);
00500 if ($this->getshuffle() && $a_shuffle)
00501 {
00502 $akeys = $this->pcArrayShuffle($akeys);
00503 }
00504
00505
00506 foreach ($akeys as $index)
00507 {
00508 $answer = $this->answers[$index];
00509
00510 $qtiResponseLabel = $this->domxml->create_element("response_label");
00511 $qtiResponseLabel->set_attribute("ident", $index);
00512 $qtiMaterial = $this->domxml->create_element("material");
00513 if ($this->get_ordering_type() == OQ_PICTURES)
00514 {
00515 $qtiMatImage = $this->domxml->create_element("matimage");
00516 $qtiMatImage->set_attribute("imagtype", "image/jpeg");
00517 $qtiMatImage->set_attribute("label", $answer->get_answertext());
00518 $qtiMatImage->set_attribute("embedded", "base64");
00519 $imagepath = $this->getImagePath() . $answer->get_answertext();
00520 $fh = fopen($imagepath, "rb");
00521 if ($fh == false)
00522 {
00523
00524
00525
00526 }
00527 else
00528 {
00529 $imagefile = fread($fh, filesize($imagepath));
00530 fclose($fh);
00531 $base64 = base64_encode($imagefile);
00532 $qtiBase64Data = $this->domxml->create_text_node($base64);
00533 $qtiMatImage->append_child($qtiBase64Data);
00534 $qtiMaterial->append_child($qtiMatImage);
00535 }
00536 }
00537 else
00538 {
00539 $qtiMatText = $this->domxml->create_element("mattext");
00540 $qtiMatTextText = $this->domxml->create_text_node($answer->get_answertext());
00541 $qtiMatText->append_child($qtiMatTextText);
00542 $qtiMaterial->append_child($qtiMatText);
00543 }
00544 $qtiResponseLabel->append_child($qtiMaterial);
00545 $qtiRenderChoice->append_child($qtiResponseLabel);
00546 }
00547 $qtiResponseLid->append_child($qtiRenderChoice);
00548 $qtiFlow->append_child($qtiResponseLid);
00549 $qtiPresentation->append_child($qtiFlow);
00550 $qtiIdent->append_child($qtiPresentation);
00551
00552
00553 $qtiResprocessing = $this->domxml->create_element("resprocessing");
00554 $qtiOutcomes = $this->domxml->create_element("outcomes");
00555 $qtiDecvar = $this->domxml->create_element("decvar");
00556 $qtiOutcomes->append_child($qtiDecvar);
00557 $qtiResprocessing->append_child($qtiOutcomes);
00558
00559 foreach ($this->answers as $index => $answer)
00560 {
00561 $qtiRespcondition = $this->domxml->create_element("respcondition");
00562 $qtiRespcondition->set_attribute("continue", "Yes");
00563
00564 $qtiConditionvar = $this->domxml->create_element("conditionvar");
00565 $qtiVarequal = $this->domxml->create_element("varequal");
00566 if ($this->get_ordering_type() == OQ_PICTURES)
00567 {
00568 $qtiVarequal->set_attribute("respident", "OQP");
00569 }
00570 else
00571 {
00572 $qtiVarequal->set_attribute("respident", "OQT");
00573 }
00574 $qtiVarequal->set_attribute("index", $answer->get_solution_order());
00575 $qtiVarequalText = $this->domxml->create_text_node($index);
00576 $qtiVarequal->append_child($qtiVarequalText);
00577 $qtiConditionvar->append_child($qtiVarequal);
00578
00579 $qtiSetvar = $this->domxml->create_element("setvar");
00580 $qtiSetvar->set_attribute("action", "Add");
00581 $qtiSetvarText = $this->domxml->create_text_node($answer->get_points());
00582 $qtiSetvar->append_child($qtiSetvarText);
00583
00584 $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00585 $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00586 $qtiDisplayfeedback->set_attribute("linkrefid", "link_$index");
00587 $qtiRespcondition->append_child($qtiConditionvar);
00588 $qtiRespcondition->append_child($qtiSetvar);
00589 $qtiRespcondition->append_child($qtiDisplayfeedback);
00590 $qtiResprocessing->append_child($qtiRespcondition);
00591 }
00592 $qtiIdent->append_child($qtiResprocessing);
00593
00594
00595 foreach ($this->answers as $index => $answer)
00596 {
00597 $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00598 $qtiItemfeedback->set_attribute("ident", "link_$index");
00599 $qtiItemfeedback->set_attribute("view", "All");
00600
00601 $qtiFlowmat = $this->domxml->create_element("flow_mat");
00602 $qtiMaterial = $this->domxml->create_element("material");
00603 $qtiMattext = $this->domxml->create_element("mattext");
00604
00605 $qtiMattextText = $this->domxml->create_text_node("");
00606 $qtiMattext->append_child($qtiMattextText);
00607 $qtiMaterial->append_child($qtiMattext);
00608 $qtiFlowmat->append_child($qtiMaterial);
00609 $qtiItemfeedback->append_child($qtiFlowmat);
00610 $qtiIdent->append_child($qtiItemfeedback);
00611 }
00612
00613 $xml = $this->domxml->dump_mem(true);
00614 if (!$a_include_header)
00615 {
00616 $pos = strpos($xml, "?>");
00617 $xml = substr($xml, $pos + 2);
00618 }
00619
00620 return $xml;
00621
00622 }
00623
00624
00633 function saveToDb($original_id = "")
00634 {
00635 global $ilias;
00636
00637 $db =& $ilias->db;
00638 $complete = 0;
00639 if ($this->isComplete())
00640 {
00641 $complete = 1;
00642 }
00643
00644 $estw_time = $this->getEstimatedWorkingTime();
00645 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00646
00647 if ($original_id)
00648 {
00649 $original_id = $db->quote($original_id);
00650 }
00651 else
00652 {
00653 $original_id = "NULL";
00654 }
00655
00656 if ($this->id == -1)
00657 {
00658
00659 $now = getdate();
00660 $question_type = $this->getQuestionType();
00661 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00662 $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, ordering_type, points, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00663 $db->quote($question_type . ""),
00664 $db->quote($this->obj_id . ""),
00665 $db->quote($this->title . ""),
00666 $db->quote($this->comment . ""),
00667 $db->quote($this->author . ""),
00668 $db->quote($this->owner . ""),
00669 $db->quote($this->question . ""),
00670 $db->quote($estw_time . ""),
00671 $db->quote($this->ordering_type . ""),
00672 $db->quote($this->points . ""),
00673 $db->quote($complete . ""),
00674 $db->quote($created . ""),
00675 $original_id
00676 );
00677 $result = $db->query($query);
00678 if ($result == DB_OK)
00679 {
00680 $this->id = $this->ilias->db->getLastInsertId();
00681
00682
00683 $this->createPageObject();
00684
00685
00686 if ($this->getTestId() > 0)
00687 {
00688 $this->insertIntoTest($this->getTestId());
00689 }
00690 }
00691 }
00692 else
00693 {
00694
00695 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, ordering_type = %s, points = %s, complete = %s WHERE question_id = %s",
00696 $db->quote($this->obj_id. ""),
00697 $db->quote($this->title . ""),
00698 $db->quote($this->comment . ""),
00699 $db->quote($this->author . ""),
00700 $db->quote($this->question . ""),
00701 $db->quote($estw_time . ""),
00702 $db->quote($this->ordering_type . ""),
00703 $db->quote($this->points . ""),
00704 $db->quote($complete . ""),
00705 $db->quote($this->id . "")
00706 );
00707 $result = $db->query($query);
00708 }
00709 if ($result == DB_OK)
00710 {
00711
00712
00713 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00714 $db->quote($this->id)
00715 );
00716 $result = $db->query($query);
00717
00718
00719 foreach ($this->answers as $key => $value)
00720 {
00721 $answer_obj = $this->answers[$key];
00722 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, solution_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
00723 $db->quote($this->id),
00724 $db->quote($answer_obj->get_answertext() . ""),
00725 $db->quote($answer_obj->get_points() . ""),
00726 $db->quote($answer_obj->get_order() . ""),
00727 $db->quote($answer_obj->get_solution_order() . "")
00728 );
00729 $answer_result = $db->query($query);
00730 }
00731 }
00732 parent::saveToDb($original_id);
00733 }
00734
00744 function loadFromDb($question_id)
00745 {
00746 global $ilias;
00747 $db =& $ilias->db;
00748
00749 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00750 $db->quote($question_id)
00751 );
00752 $result = $db->query($query);
00753 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00754 {
00755 if ($result->numRows() == 1)
00756 {
00757 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00758 $this->id = $question_id;
00759 $this->title = $data->title;
00760 $this->obj_id = $data->obj_fi;
00761 $this->comment = $data->comment;
00762 $this->original_id = $data->original_id;
00763 $this->author = $data->author;
00764 $this->owner = $data->owner;
00765 $this->question = $data->question_text;
00766 $this->solution_hint = $data->solution_hint;
00767 $this->ordering_type = $data->ordering_type;
00768 $this->points = $data->points;
00769 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00770 }
00771
00772 $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY aorder ASC",
00773 $db->quote($question_id)
00774 );
00775 $result = $db->query($query);
00776 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00777 {
00778 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00779 {
00780 array_push($this->answers, new ASS_AnswerOrdering($data->answertext, $data->points, $data->aorder, $data->solution_order));
00781 }
00782 }
00783 }
00784 parent::loadFromDb($question_id);
00785 }
00786
00794 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00795 {
00796 if ($this->id <= 0)
00797 {
00798
00799 return;
00800 }
00801
00802 $clone = $this;
00803 include_once ("./assessment/classes/class.assQuestion.php");
00804 $original_id = ASS_Question::_getOriginalId($this->id);
00805 $clone->id = -1;
00806 if ($title)
00807 {
00808 $clone->setTitle($title);
00809 }
00810 if ($author)
00811 {
00812 $clone->setAuthor($author);
00813 }
00814 if ($owner)
00815 {
00816 $clone->setOwner($owner);
00817 }
00818 if ($for_test)
00819 {
00820 $clone->saveToDb($original_id);
00821 }
00822 else
00823 {
00824 $clone->saveToDb();
00825 }
00826
00827
00828 $clone->copyPageOfQuestion($original_id);
00829
00830
00831 $clone->duplicateImages($original_id);
00832 return $clone->id;
00833 }
00834
00835 function duplicateImages($question_id)
00836 {
00837 if ($this->get_ordering_type() == OQ_PICTURES)
00838 {
00839 $imagepath = $this->getImagePath();
00840 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00841 if (!file_exists($imagepath)) {
00842 ilUtil::makeDirParents($imagepath);
00843 }
00844 foreach ($this->answers as $answer)
00845 {
00846 $filename = $answer->get_answertext();
00847 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
00848 print "image could not be duplicated!!!! ";
00849 }
00850 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg")) {
00851 print "image thumbnail could not be duplicated!!!! ";
00852 }
00853 }
00854 }
00855 }
00856
00866 function set_question($question = "")
00867 {
00868 $this->question = $question;
00869 }
00870
00880 function set_ordering_type($ordering_type = OQ_TERMS)
00881 {
00882 $this->ordering_type = $ordering_type;
00883 }
00884
00894 function get_question()
00895 {
00896 return $this->question;
00897 }
00898
00908 function get_ordering_type()
00909 {
00910 return $this->ordering_type;
00911 }
00912
00928 function add_answer(
00929 $answertext = "",
00930 $points = 0.0,
00931 $order = 0,
00932 $solution_order = 0
00933 )
00934 {
00935 $found = -1;
00936 foreach ($this->answers as $key => $value)
00937 {
00938 if ($value->get_order() == $order)
00939 {
00940 $found = $order;
00941 }
00942 }
00943 if ($found >= 0)
00944 {
00945
00946 $answer = new ASS_AnswerOrdering($answertext, $points, $found, $solution_order);
00947 array_push($this->answers, $answer);
00948 for ($i = $found + 1; $i < count($this->answers); $i++)
00949 {
00950 $this->answers[$i] = $this->answers[$i-1];
00951 }
00952 $this->answers[$found] = $answer;
00953 }
00954 else
00955 {
00956
00957 $answer = new ASS_AnswerOrdering($answertext, $points,
00958 count($this->answers), $solution_order);
00959 array_push($this->answers, $answer);
00960 }
00961 }
00962
00974 function get_answer($index = 0)
00975 {
00976 if ($index < 0) return NULL;
00977 if (count($this->answers) < 1) return NULL;
00978 if ($index >= count($this->answers)) return NULL;
00979 return $this->answers[$index];
00980 }
00981
00992 function delete_answer($index = 0)
00993 {
00994 if ($index < 0)
00995 {
00996 return;
00997 }
00998 if (count($this->answers) < 1)
00999 {
01000 return;
01001 }
01002 if ($index >= count($this->answers))
01003 {
01004 return;
01005 }
01006 unset($this->answers[$index]);
01007 $this->answers = array_values($this->answers);
01008 for ($i = 0; $i < count($this->answers); $i++)
01009 {
01010 if ($this->answers[$i]->get_order() > $index)
01011 {
01012 $this->answers[$i]->set_order($i);
01013 }
01014 }
01015 }
01016
01025 function flush_answers()
01026 {
01027 $this->answers = array();
01028 }
01029
01039 function get_answer_count()
01040 {
01041 return count($this->answers);
01042 }
01043
01053 function get_points()
01054 {
01055 return $this->points;
01056 }
01057
01067 function set_points($points = 0.0)
01068 {
01069 $this->points = $points;
01070 }
01071
01081 function get_max_solution_order()
01082 {
01083 if (count($this->answers) == 0)
01084 {
01085 $max = 0;
01086 }
01087 else
01088 {
01089 $max = $this->answers[0]->get_solution_order();
01090 }
01091 foreach ($this->answers as $key => $value)
01092 {
01093 if ($value->get_solution_order() > $max)
01094 {
01095 $max = $value->get_solution_order();
01096 }
01097 }
01098 return $max;
01099 }
01100
01110 function getReachedPoints($user_id, $test_id)
01111 {
01112 $found_value1 = array();
01113 $found_value2 = array();
01114 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01115 $this->ilias->db->quote($user_id),
01116 $this->ilias->db->quote($test_id),
01117 $this->ilias->db->quote($this->getId())
01118 );
01119 $result = $this->ilias->db->query($query);
01120 $user_order = array();
01121 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01122 {
01123 if ((strcmp($data->value1, "") != 0) && (strcmp($data->value2, "") != 0))
01124 {
01125 $user_order[$data->value2] = $data->value1;
01126 }
01127 }
01128 ksort($user_order);
01129 $user_order = array_values($user_order);
01130 $answer_order = array();
01131 foreach ($this->answers as $key => $answer)
01132 {
01133 $answer_order[$answer->get_solution_order()] = $key;
01134 }
01135 ksort($answer_order);
01136 $answer_order = array_values($answer_order);
01137 $points = 0;
01138 foreach ($answer_order as $index => $answer_id)
01139 {
01140 if (strcmp($user_order[$index], "") != 0)
01141 {
01142 if ($answer_id == $user_order[$index])
01143 {
01144 $points += $this->answers[$answer_id]->get_points();
01145 }
01146 }
01147 }
01148 return $points;
01149 }
01150
01160 function getReachedInformation($user_id, $test_id)
01161 {
01162 $found_value1 = array();
01163 $found_value2 = array();
01164 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01165 $this->ilias->db->quote($user_id),
01166 $this->ilias->db->quote($test_id),
01167 $this->ilias->db->quote($this->getId())
01168 );
01169 $result = $this->ilias->db->query($query);
01170 $user_result = array();
01171 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01172 {
01173 $solution = array(
01174 "answer_id" => $data->value1,
01175 "order" => $data->value2
01176 );
01177 $user_result[$data->value1] = $solution;
01178 }
01179 return $user_result;
01180 }
01181
01190 function getMaximumPoints()
01191 {
01192 $points = 0;
01193 foreach ($this->answers as $key => $value)
01194 {
01195 $points += $value->get_points();
01196 }
01197 return $points;
01198 }
01199
01210 function set_image_file($image_filename, $image_tempfilename = "")
01211 {
01212 $result = 0;
01213 if (!empty($image_tempfilename))
01214 {
01215 $image_filename = str_replace(" ", "_", $image_filename);
01216 $imagepath = $this->getImagePath();
01217 if (!file_exists($imagepath))
01218 {
01219 ilUtil::makeDirParents($imagepath);
01220 }
01221 if (!ilUtil::moveUploadedFile($image_tempfilename,$image_filename, $imagepath.$image_filename))
01222 {
01223 $result = 2;
01224 }
01225 else
01226 {
01227 require_once "./content/classes/Media/class.ilObjMediaObject.php";
01228 $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
01229 if (!preg_match("/^image/", $mimetype))
01230 {
01231 unlink($imagepath . $image_filename);
01232 $result = 1;
01233 }
01234 else
01235 {
01236
01237 $thumbpath = $imagepath . $image_filename . "." . "thumb.jpg";
01238 ilUtil::convertImage($imagepath.$image_filename, $thumbpath, "JPEG", 100);
01239 }
01240 }
01241 }
01242 return $result;
01243 }
01244
01254 function checkSaveData()
01255 {
01256 $result = true;
01257 $order_values = array();
01258 foreach ($_POST as $key => $value)
01259 {
01260 if (preg_match("/^order_(\d+)/", $key, $matches))
01261 {
01262 if (strcmp($value, "") != 0)
01263 {
01264 array_push($order_values, $value);
01265 }
01266 }
01267 }
01268 $check_order = array_flip($order_values);
01269 if (count($check_order) != count($order_values))
01270 {
01271
01272 $result = false;
01273 sendInfo($this->lng->txt("duplicate_order_values_entered"));
01274 }
01275 return $result;
01276 }
01277
01288 function saveWorkingData($test_id, $limit_to = LIMIT_NO_LIMIT)
01289 {
01290 global $ilDB;
01291 global $ilUser;
01292
01293 $saveWorkingDataResult = $this->checkSaveData();
01294 if ($saveWorkingDataResult)
01295 {
01296 $db =& $ilDB->db;
01297
01298 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01299 $db->quote($ilUser->id),
01300 $db->quote($test_id),
01301 $db->quote($this->getId())
01302 );
01303 $result = $db->query($query);
01304
01305 foreach ($_POST as $key => $value)
01306 {
01307 if (preg_match("/^order_(\d+)/", $key, $matches))
01308 {
01309 if (!(preg_match("/initial_value_\d+/", $value)))
01310 {
01311 $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)",
01312 $db->quote($ilUser->id),
01313 $db->quote($test_id),
01314 $db->quote($this->getId()),
01315 $db->quote($matches[1]),
01316 $db->quote($value)
01317 );
01318 $result = $db->query($query);
01319 }
01320 }
01321 }
01322
01323 }
01324 return $saveWorkingDataResult;
01325 }
01326
01327 function syncWithOriginal()
01328 {
01329 global $ilias;
01330 if ($this->original_id)
01331 {
01332 $complete = 0;
01333 if ($this->isComplete())
01334 {
01335 $complete = 1;
01336 }
01337 $db = & $ilias->db;
01338
01339 $estw_time = $this->getEstimatedWorkingTime();
01340 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01341
01342 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, ordering_type = %s, points = %s, complete = %s WHERE question_id = %s",
01343 $db->quote($this->obj_id. ""),
01344 $db->quote($this->title . ""),
01345 $db->quote($this->comment . ""),
01346 $db->quote($this->author . ""),
01347 $db->quote($this->question . ""),
01348 $db->quote($estw_time . ""),
01349 $db->quote($this->ordering_type . ""),
01350 $db->quote($this->points . ""),
01351 $db->quote($complete . ""),
01352 $db->quote($this->original_id . "")
01353 );
01354 $result = $db->query($query);
01355
01356 if ($result == DB_OK)
01357 {
01358
01359
01360 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01361 $db->quote($this->original_id)
01362 );
01363 $result = $db->query($query);
01364
01365 foreach ($this->answers as $key => $value)
01366 {
01367 $answer_obj = $this->answers[$key];
01368 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, solution_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01369 $db->quote($this->original_id . ""),
01370 $db->quote($answer_obj->get_answertext() . ""),
01371 $db->quote($answer_obj->get_points() . ""),
01372 $db->quote($answer_obj->get_order() . ""),
01373 $db->quote($answer_obj->get_solution_order() . "")
01374 );
01375 $answer_result = $db->query($query);
01376 }
01377 }
01378 parent::syncWithOriginal();
01379 }
01380 }
01381
01382 function pc_array_shuffle($array) {
01383 mt_srand((double)microtime()*1000000);
01384 $i = count($array);
01385 while(--$i)
01386 {
01387 $j = mt_rand(0, $i);
01388 if ($i != $j)
01389 {
01390
01391 $tmp = $array[$j];
01392 $array[$j] = $array[$i];
01393 $array[$i] = $tmp;
01394 }
01395 }
01396 return $array;
01397 }
01398
01399 function createRandomSolution($test_id, $user_id)
01400 {
01401 global $ilDB;
01402 global $ilUser;
01403
01404 $db =& $ilDB->db;
01405
01406 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01407 $db->quote($user_id),
01408 $db->quote($test_id),
01409 $db->quote($this->getId())
01410 );
01411 $result = $db->query($query);
01412
01413 $orders = range(1, count($this->answers));
01414 $orders = $this->pc_array_shuffle($orders);
01415 foreach ($this->answers as $key => $value)
01416 {
01417 $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)",
01418 $db->quote($user_id),
01419 $db->quote($test_id),
01420 $db->quote($this->getId()),
01421 $db->quote($key),
01422 $db->quote(array_pop($orders))
01423 );
01424 $result = $db->query($query);
01425 }
01426 }
01427
01436 function getQuestionType()
01437 {
01438 return 5;
01439 }
01440 }
01441
01442 ?>