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.assAnswerImagemap.php";
00026
00027 define ("IMAGEMAP_QUESTION_IDENTIFIER", "IMAGE MAP QUESTION");
00028
00039 class ASS_ImagemapQuestion extends ASS_Question {
00040
00048 var $question;
00049
00057 var $answers;
00058
00066 var $imagemap_filename;
00067
00075 var $image_filename;
00076
00084 var $imagemap_contents;
00085 var $coords;
00086
00101 function ASS_ImagemapQuestion(
00102 $title = "",
00103 $comment = "",
00104 $author = "",
00105 $owner = -1,
00106 $question = "",
00107 $imagemap_filename = "",
00108 $image_filename = ""
00109
00110 )
00111 {
00112 $this->ASS_Question($title, $comment, $author, $owner);
00113 $this->question = $question;
00114 $this->imagemap_filename = $imagemap_filename;
00115 $this->image_filename = $image_filename;
00116 $this->answers = array();
00117 $this->coords = array();
00118 }
00119
00128 function isComplete()
00129 {
00130 if (($this->title) and ($this->author) and ($this->question) and ($this->image_filename) and (count($this->answers)))
00131 {
00132 return true;
00133 }
00134 else
00135 {
00136 return false;
00137 }
00138 }
00139
00148 function saveToDb($original_id = "")
00149 {
00150 global $ilias;
00151
00152 $complete = 0;
00153 if ($this->isComplete())
00154 {
00155 $complete = 1;
00156 }
00157
00158 $db = & $ilias->db;
00159
00160 $estw_time = $this->getEstimatedWorkingTime();
00161 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00162 if ($original_id)
00163 {
00164 $original_id = $db->quote($original_id);
00165 }
00166 else
00167 {
00168 $original_id = "NULL";
00169 }
00170
00171 if ($this->id == -1)
00172 {
00173
00174 $now = getdate();
00175 $question_type = $this->getQuestionType();
00176 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00177 $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, points, image_file, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00178 $db->quote($question_type),
00179 $db->quote($this->obj_id),
00180 $db->quote($this->title),
00181 $db->quote($this->comment),
00182 $db->quote($this->author),
00183 $db->quote($this->owner),
00184 $db->quote($this->question),
00185 $db->quote($estw_time),
00186 $db->quote($this->getMaximumPoints() . ""),
00187 $db->quote($this->image_filename),
00188 $db->quote("$complete"),
00189 $db->quote($created),
00190 $original_id
00191 );
00192 $result = $db->query($query);
00193 if ($result == DB_OK)
00194 {
00195 $this->id = $db->getLastInsertId();
00196
00197
00198 $this->createPageObject();
00199
00200
00201 if ($this->getTestId() > 0)
00202 {
00203 $this->insertIntoTest($this->getTestId());
00204 }
00205 }
00206 }
00207 else
00208 {
00209
00210 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, points = %s, image_file = %s, complete = %s WHERE question_id = %s",
00211 $db->quote($this->obj_id. ""),
00212 $db->quote($this->title),
00213 $db->quote($this->comment),
00214 $db->quote($this->author),
00215 $db->quote($this->question),
00216 $db->quote($estw_time),
00217 $db->quote($this->getMaximumPoints() . ""),
00218 $db->quote($this->image_filename),
00219 $db->quote("$complete"),
00220 $db->quote($this->id)
00221 );
00222 $result = $db->query($query);
00223 }
00224
00225 if ($result == DB_OK)
00226 {
00227 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00228 $db->quote($this->id)
00229 );
00230 $result = $db->query($query);
00231
00232 foreach ($this->answers as $key => $value)
00233 {
00234 $answer_obj = $this->answers[$key];
00235
00236 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, correctness, coords, area, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, NULL)",
00237 $db->quote($this->id),
00238 $db->quote($answer_obj->get_answertext() . ""),
00239 $db->quote($answer_obj->get_points() . ""),
00240 $db->quote($answer_obj->get_order() . ""),
00241 $db->quote($answer_obj->getState() . ""),
00242 $db->quote($answer_obj->get_coords() . ""),
00243 $db->quote($answer_obj->get_area() . "")
00244 );
00245 $answer_result = $db->query($query);
00246 }
00247 }
00248 parent::saveToDb($original_id);
00249 }
00250
00258 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00259 {
00260 if ($this->id <= 0)
00261 {
00262
00263 return;
00264 }
00265
00266 $clone = $this;
00267 include_once ("./assessment/classes/class.assQuestion.php");
00268 $original_id = ASS_Question::_getOriginalId($this->id);
00269 $clone->id = -1;
00270 if ($title)
00271 {
00272 $clone->setTitle($title);
00273 }
00274 if ($author)
00275 {
00276 $clone->setAuthor($author);
00277 }
00278 if ($owner)
00279 {
00280 $clone->setOwner($owner);
00281 }
00282 if ($for_test)
00283 {
00284 $clone->saveToDb($original_id);
00285 }
00286 else
00287 {
00288 $clone->saveToDb();
00289 }
00290
00291
00292 $clone->copyPageOfQuestion($original_id);
00293
00294
00295 $clone->duplicateImage($original_id);
00296 return $clone->id;
00297 }
00298
00299 function duplicateImage($question_id)
00300 {
00301 $imagepath = $this->getImagePath();
00302 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00303 if (!file_exists($imagepath)) {
00304 ilUtil::makeDirParents($imagepath);
00305 }
00306 $filename = $this->get_image_filename();
00307 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
00308 print "image could not be duplicated!!!! ";
00309 }
00310 }
00311
00321 function loadFromDb($question_id)
00322 {
00323 global $ilias;
00324
00325 $db = & $ilias->db;
00326 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00327 $db->quote($question_id)
00328 );
00329 $result = $db->query($query);
00330 if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00331 if ($result->numRows() == 1) {
00332 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00333 $this->id = $question_id;
00334 $this->obj_id = $data->obj_fi;
00335 $this->title = $data->title;
00336 $this->comment = $data->comment;
00337 $this->author = $data->author;
00338 $this->original_id = $data->original_id;
00339 $this->solution_hint = $data->solution_hint;
00340 $this->owner = $data->owner;
00341 $this->question = $data->question_text;
00342 $this->image_filename = $data->image_file;
00343 $this->points = $data->points;
00344 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00345 }
00346 $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY aorder ASC",
00347 $db->quote($question_id)
00348 );
00349 $result = $db->query($query);
00350 if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00351 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
00352 if ($data->correctness == 0)
00353 {
00354
00355 $data->correctness = 1;
00356 $data->points = 0;
00357 }
00358 array_push($this->answers, new ASS_AnswerImagemap($data->answertext, $data->points, $data->aorder, $data->correctness, $data->coords, $data->area));
00359 }
00360 }
00361 }
00362 parent::loadFromDb($question_id);
00363 }
00364
00372 function addAnswer($answertext, $points, $answerorder, $correctness, $coords, $area)
00373 {
00374 array_push($this->answers, new ASS_AnswerImagemap($answertext, $points, $answerorder, $correctness, $coords, $area));
00375 }
00376
00386 function from_xml($xml_text)
00387 {
00388 $result = false;
00389 if (!empty($this->domxml))
00390 {
00391 $this->domxml->free();
00392 }
00393 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
00394 $this->domxml = domxml_open_mem($xml_text);
00395 if (!empty($this->domxml))
00396 {
00397 $root = $this->domxml->document_element();
00398 $item = $root->first_child();
00399 $this->setTitle($item->get_attribute("title"));
00400 $this->gaps = array();
00401 $itemnodes = $item->child_nodes();
00402 $materials = array();
00403 $filename = "";
00404 $image = "";
00405 $shuffle = "";
00406 foreach ($itemnodes as $index => $node)
00407 {
00408 switch ($node->node_name())
00409 {
00410 case "qticomment":
00411 $comment = $node->node_value();
00412 if (strpos($comment, "ILIAS Version=") !== false)
00413 {
00414 }
00415 elseif (strpos($comment, "Questiontype=") !== false)
00416 {
00417 }
00418 elseif (strpos($comment, "Author=") !== false)
00419 {
00420 $comment = str_replace("Author=", "", $comment);
00421 $this->setAuthor($comment);
00422 }
00423 else
00424 {
00425 $this->setComment($comment);
00426 }
00427 break;
00428 case "itemmetadata":
00429 $md_array = array();
00430 $metanodes = $node->child_nodes();
00431 foreach ($metanodes as $metanode)
00432 {
00433 switch ($metanode->node_name())
00434 {
00435 case "qtimetadata":
00436 $metafields = $metanode->child_nodes();
00437 foreach ($metafields as $metafield)
00438 {
00439 switch ($metafield->node_name())
00440 {
00441 case "qtimetadatafield":
00442 $metafieldlist = $metafield->child_nodes();
00443 $md = array("label" => "", "entry" => "");
00444 foreach ($metafieldlist as $attr)
00445 {
00446 switch ($attr->node_name())
00447 {
00448 case "fieldlabel":
00449 $md["label"] = $attr->get_content();
00450 break;
00451 case "fieldentry":
00452 $md["entry"] = $attr->get_content();
00453 break;
00454 }
00455 }
00456 array_push($md_array, $md);
00457 break;
00458 }
00459 }
00460 break;
00461 }
00462 }
00463 foreach ($md_array as $md)
00464 {
00465 switch ($md["label"])
00466 {
00467 case "ILIAS_VERSION":
00468 break;
00469 case "QUESTIONTYPE":
00470 break;
00471 case "AUTHOR":
00472 $this->setAuthor($md["entry"]);
00473 break;
00474 }
00475 }
00476 break;
00477 case "duration":
00478 $iso8601period = $node->node_value();
00479 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
00480 {
00481 $this->setEstimatedWorkingTime($matches[4], $matches[5], $matches[6]);
00482 }
00483 break;
00484 case "presentation":
00485 $flow = $node->first_child();
00486 $flownodes = $flow->child_nodes();
00487 foreach ($flownodes as $idx => $flownode)
00488 {
00489 if (strcmp($flownode->node_name(), "material") == 0)
00490 {
00491 $mattext = $flownode->first_child();
00492 $this->set_question($mattext->node_value());
00493 }
00494 elseif (strcmp($flownode->node_name(), "response_xy") == 0)
00495 {
00496 $ident = $flownode->get_attribute("ident");
00497 $subnodes = $flownode->child_nodes();
00498 foreach ($subnodes as $node_type)
00499 {
00500 switch ($node_type->node_name())
00501 {
00502 case "material":
00503 $matlabel = $node_type->get_attribute("label");
00504 if (strcmp($matlabel, "suggested_solution") == 0)
00505 {
00506 $mattype = $node_type->first_child();
00507 if (strcmp($mattype->node_name(), "mattext") == 0)
00508 {
00509 $suggested_solution = $mattype->node_value();
00510 if ($suggested_solution)
00511 {
00512 if ($this->getId() < 1)
00513 {
00514 $this->saveToDb();
00515 }
00516 $this->setSuggestedSolution($suggested_solution, 0, true);
00517 }
00518 }
00519 }
00520 break;
00521 case "render_hotspot":
00522 $render_hotspot = $node_type;
00523 $labels = $render_hotspot->child_nodes();
00524 foreach ($labels as $lidx => $response_label)
00525 {
00526 if (strcmp($response_label->node_name(), "material") == 0)
00527 {
00528
00529 $mattype = $response_label->first_child();
00530 if (strcmp($mattype->node_name(), "matimage") == 0)
00531 {
00532 $filename = $mattype->get_attribute("label");
00533 $image = base64_decode($mattype->node_value());
00534 }
00535 }
00536 else
00537 {
00538 $matident = $response_label->get_attribute("ident");
00539 switch ($response_label->get_attribute("rarea"))
00540 {
00541 case "Ellipse":
00542 $materials[$matident]["area"] = "circle";
00543 break;
00544 case "Bounded":
00545 $materials[$matident]["area"] = "poly";
00546 break;
00547 case "Rectangle":
00548 $materials[$matident]["area"] = "rect";
00549 break;
00550 }
00551 $material_children = $response_label->child_nodes();
00552 foreach ($material_children as $midx => $childnode)
00553 {
00554 if (strcmp($childnode->node_name(), "#text") == 0)
00555 {
00556 $materials[$matident]["coords"] = $childnode->node_value();
00557 }
00558 elseif (strcmp($childnode->node_name(), "material") == 0)
00559 {
00560 $materials[$matident]["answertext"] = $childnode->node_value();
00561 }
00562 }
00563 }
00564 }
00565 break;
00566 }
00567 }
00568 }
00569 }
00570 break;
00571 case "resprocessing":
00572 $resproc_nodes = $node->child_nodes();
00573 foreach ($resproc_nodes as $index => $respcondition)
00574 {
00575 if (strcmp($respcondition->node_name(), "respcondition") == 0)
00576 {
00577 $respcondition_array =& ilQTIUtils::_getRespcondition($respcondition);
00578 foreach ($materials as $index => $material)
00579 {
00580 if (strcmp($material["coords"], $respcondition_array["conditionvar"]["value"]) == 0)
00581 {
00582 $this->add_answer(
00583 $material["answertext"],
00584 $respcondition_array["setvar"]["points"],
00585 $respcondition_array["conditionvar"]["selected"],
00586 $index,
00587 $material["coords"],
00588 $material["area"]
00589 );
00590 }
00591 }
00592 }
00593 }
00594 break;
00595 }
00596 }
00597 if ($filename)
00598 {
00599 $this->saveToDb();
00600 $imagepath = $this->getImagePath();
00601 if (!file_exists($imagepath))
00602 {
00603 ilUtil::makeDirParents($imagepath);
00604 }
00605 $imagepath .= $filename;
00606 $fh = fopen($imagepath, "wb");
00607 if ($fh == false)
00608 {
00609 global $ilErr;
00610 $ilErr->raiseError($this->lng->txt("error_save_image_file") . ": $php_errormsg", $ilErr->MESSAGE);
00611 return;
00612 }
00613 $imagefile = fwrite($fh, $image);
00614 fclose($fh);
00615 $this->image_filename = $filename;
00616 }
00617 $result = true;
00618 }
00619 return $result;
00620 }
00621
00631 function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false)
00632 {
00633 if (!empty($this->domxml))
00634 {
00635 $this->domxml->free();
00636 }
00637 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<questestinterop></questestinterop>\n";
00638 $this->domxml = domxml_open_mem($xml_header);
00639 $root = $this->domxml->document_element();
00640
00641 $qtiIdent = $this->domxml->create_element("item");
00642 $qtiIdent->set_attribute("ident", "il_".IL_INST_ID."_qst_".$this->getId());
00643 $qtiIdent->set_attribute("title", $this->getTitle());
00644 $root->append_child($qtiIdent);
00645
00646 $qtiComment = $this->domxml->create_element("qticomment");
00647 $qtiCommentText = $this->domxml->create_text_node($this->getComment());
00648 $qtiComment->append_child($qtiCommentText);
00649 $qtiIdent->append_child($qtiComment);
00650
00651 $qtiDuration = $this->domxml->create_element("duration");
00652 $workingtime = $this->getEstimatedWorkingTime();
00653 $qtiDurationText = $this->domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]));
00654 $qtiDuration->append_child($qtiDurationText);
00655 $qtiIdent->append_child($qtiDuration);
00656
00657 $qtiItemmetadata = $this->domxml->create_element("itemmetadata");
00658 $qtiMetadata = $this->domxml->create_element("qtimetadata");
00659
00660 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00661 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00662 $qtiFieldlabelText = $this->domxml->create_text_node("ILIAS_VERSION");
00663 $qtiFieldlabel->append_child($qtiFieldlabelText);
00664 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00665 $qtiFieldentryText = $this->domxml->create_text_node($this->ilias->getSetting("ilias_version"));
00666 $qtiFieldentry->append_child($qtiFieldentryText);
00667 $qtiMetadatafield->append_child($qtiFieldlabel);
00668 $qtiMetadatafield->append_child($qtiFieldentry);
00669 $qtiMetadata->append_child($qtiMetadatafield);
00670
00671 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00672 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00673 $qtiFieldlabelText = $this->domxml->create_text_node("QUESTIONTYPE");
00674 $qtiFieldlabel->append_child($qtiFieldlabelText);
00675 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00676 $qtiFieldentryText = $this->domxml->create_text_node(IMAGEMAP_QUESTION_IDENTIFIER);
00677 $qtiFieldentry->append_child($qtiFieldentryText);
00678 $qtiMetadatafield->append_child($qtiFieldlabel);
00679 $qtiMetadatafield->append_child($qtiFieldentry);
00680 $qtiMetadata->append_child($qtiMetadatafield);
00681
00682 $qtiMetadatafield = $this->domxml->create_element("qtimetadatafield");
00683 $qtiFieldlabel = $this->domxml->create_element("fieldlabel");
00684 $qtiFieldlabelText = $this->domxml->create_text_node("AUTHOR");
00685 $qtiFieldlabel->append_child($qtiFieldlabelText);
00686 $qtiFieldentry = $this->domxml->create_element("fieldentry");
00687 $qtiFieldentryText = $this->domxml->create_text_node($this->getAuthor());
00688 $qtiFieldentry->append_child($qtiFieldentryText);
00689 $qtiMetadatafield->append_child($qtiFieldlabel);
00690 $qtiMetadatafield->append_child($qtiFieldentry);
00691 $qtiMetadata->append_child($qtiMetadatafield);
00692
00693 $qtiItemmetadata->append_child($qtiMetadata);
00694 $qtiIdent->append_child($qtiItemmetadata);
00695
00696
00697 $qtiPresentation = $this->domxml->create_element("presentation");
00698 $qtiPresentation->set_attribute("label", $this->getTitle());
00699
00700 $qtiFlow = $this->domxml->create_element("flow");
00701
00702 $qtiMaterial = $this->domxml->create_element("material");
00703 $qtiMatText = $this->domxml->create_element("mattext");
00704 $qtiMatTextText = $this->domxml->create_text_node($this->get_question());
00705 $qtiMatText->append_child($qtiMatTextText);
00706 $qtiMaterial->append_child($qtiMatText);
00707 $qtiFlow->append_child($qtiMaterial);
00708
00709 $qtiResponseXy = $this->domxml->create_element("response_xy");
00710 $qtiResponseXy->set_attribute("ident", "IM");
00711 $qtiResponseXy->set_attribute("rcardinality", "Single");
00712 $solution = $this->getSuggestedSolution(0);
00713 if (count($solution))
00714 {
00715 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00716 {
00717 $qtiMaterial = $this->domxml->create_element("material");
00718 $qtiMaterial->set_attribute("label", "suggested_solution");
00719 $qtiMatText = $this->domxml->create_element("mattext");
00720 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00721 if (strcmp($matches[1], "") != 0)
00722 {
00723 $intlink = $solution["internal_link"];
00724 }
00725 $qtiMatTextText = $this->domxml->create_text_node($intlink);
00726 $qtiMatText->append_child($qtiMatTextText);
00727 $qtiMaterial->append_child($qtiMatText);
00728 $qtiResponseXy->append_child($qtiMaterial);
00729 }
00730 }
00731 $qtiRenderHotspot = $this->domxml->create_element("render_hotspot");
00732 $qtiMaterial = $this->domxml->create_element("material");
00733 $qtiMatImage = $this->domxml->create_element("matimage");
00734 $imagetype = "image/jpeg";
00735 if (preg_match("/.*\.(png|gif)$/", $this->get_image_filename(), $matches))
00736 {
00737 $imagetype = "image/" . $matches[1];
00738 }
00739 $qtiMatImage->set_attribute("imagtype", $imagetype);
00740 $qtiMatImage->set_attribute("label", $this->get_image_filename());
00741 if ($a_include_binary)
00742 {
00743 if ($test_output)
00744 {
00745 $qtiMatImage->set_attribute("uri", $this->getImagePathWeb() . $this->get_image_filename());
00746 }
00747 else
00748 {
00749 $qtiMatImage->set_attribute("embedded", "base64");
00750 $imagepath = $this->getImagePath() . $this->get_image_filename();
00751 $fh = fopen($imagepath, "rb");
00752 if ($fh == false)
00753 {
00754 global $ilErr;
00755 $ilErr->raiseError($this->lng->txt("error_open_image_file"), $ilErr->MESSAGE);
00756 return;
00757 }
00758 $imagefile = fread($fh, filesize($imagepath));
00759 fclose($fh);
00760 $base64 = base64_encode($imagefile);
00761 $qtiBase64Data = $this->domxml->create_text_node($base64);
00762 $qtiMatImage->append_child($qtiBase64Data);
00763 }
00764 }
00765 $qtiMaterial->append_child($qtiMatImage);
00766 $qtiRenderHotspot->append_child($qtiMaterial);
00767
00768 foreach ($this->answers as $index => $answer)
00769 {
00770 $qtiResponseLabel = $this->domxml->create_element("response_label");
00771 $qtiResponseLabel->set_attribute("ident", $index);
00772 switch ($answer->get_area())
00773 {
00774 case "rect":
00775 $qtiResponseLabel->set_attribute("rarea", "Rectangle");
00776 break;
00777 case "circle":
00778 $qtiResponseLabel->set_attribute("rarea", "Ellipse");
00779 break;
00780 case "poly":
00781 $qtiResponseLabel->set_attribute("rarea", "Bounded");
00782 break;
00783 }
00784 $qtiResponseLabelCoords = $this->domxml->create_text_node($answer->get_coords());
00785 $qtiMaterial = $this->domxml->create_element("material");
00786 $qtiMatText = $this->domxml->create_element("mattext");
00787 $qtiMatTextText = $this->domxml->create_text_node($answer->get_answertext());
00788 $qtiMatText->append_child($qtiMatTextText);
00789 $qtiMaterial->append_child($qtiMatText);
00790 $qtiResponseLabel->append_child($qtiResponseLabelCoords);
00791 $qtiResponseLabel->append_child($qtiMaterial);
00792 $qtiRenderHotspot->append_child($qtiResponseLabel);
00793 }
00794 $qtiResponseXy->append_child($qtiRenderHotspot);
00795 $qtiFlow->append_child($qtiResponseXy);
00796 $qtiPresentation->append_child($qtiFlow);
00797 $qtiIdent->append_child($qtiPresentation);
00798
00799
00800 $qtiResprocessing = $this->domxml->create_element("resprocessing");
00801 $qtiOutcomes = $this->domxml->create_element("outcomes");
00802 $qtiDecvar = $this->domxml->create_element("decvar");
00803 $qtiOutcomes->append_child($qtiDecvar);
00804 $qtiResprocessing->append_child($qtiOutcomes);
00805
00806 foreach ($this->answers as $index => $answer)
00807 {
00808 $qtiRespcondition = $this->domxml->create_element("respcondition");
00809 $qtiRespcondition->set_attribute("continue", "Yes");
00810
00811 $qtiConditionvar = $this->domxml->create_element("conditionvar");
00812 if (!$answer->isStateSet())
00813 {
00814 $qtinot = $this->domxml->create_element("not");
00815 }
00816 $qtiVarinside = $this->domxml->create_element("varinside");
00817 $qtiVarinside->set_attribute("respident", "IM");
00818 switch ($answer->get_area())
00819 {
00820 case "rect":
00821 $qtiVarinside->set_attribute("areatype", "Rectangle");
00822 break;
00823 case "circle":
00824 $qtiVarinside->set_attribute("areatype", "Ellipse");
00825 break;
00826 case "poly":
00827 $qtiVarinside->set_attribute("areatype", "Bounded");
00828 break;
00829 }
00830 $qtiVarinsideText = $this->domxml->create_text_node($answer->get_coords());
00831 $qtiVarinside->append_child($qtiVarinsideText);
00832 if (!$answer->isStateSet())
00833 {
00834 $qtiConditionvar->append_child($qtinot);
00835 $qtinot->append_child($qtiVarinside);
00836 }
00837 else
00838 {
00839 $qtiConditionvar->append_child($qtiVarinside);
00840 }
00841
00842 $qtiSetvar = $this->domxml->create_element("setvar");
00843 $qtiSetvar->set_attribute("action", "Add");
00844 $qtiSetvarText = $this->domxml->create_text_node($answer->get_points());
00845 $qtiSetvar->append_child($qtiSetvarText);
00846
00847 $qtiDisplayfeedback = $this->domxml->create_element("displayfeedback");
00848 $qtiDisplayfeedback->set_attribute("feedbacktype", "Response");
00849 $linkrefid = "";
00850 if ($answer->isStateSet())
00851 {
00852 $linkrefid = "True";
00853 }
00854 else
00855 {
00856 $linkrefid = "False_$index";
00857 }
00858 $qtiDisplayfeedback->set_attribute("linkrefid", $linkrefid);
00859 $qtiRespcondition->append_child($qtiConditionvar);
00860 $qtiRespcondition->append_child($qtiSetvar);
00861 $qtiRespcondition->append_child($qtiDisplayfeedback);
00862 $qtiResprocessing->append_child($qtiRespcondition);
00863 }
00864 $qtiIdent->append_child($qtiResprocessing);
00865
00866
00867 foreach ($this->answers as $index => $answer)
00868 {
00869 $qtiItemfeedback = $this->domxml->create_element("itemfeedback");
00870 $linkrefid = "";
00871 if ($answer->isStateSet())
00872 {
00873 $linkrefid = "True";
00874 }
00875 else
00876 {
00877 $linkrefid = "False_$index";
00878 }
00879 $qtiItemfeedback->set_attribute("ident", $linkrefid);
00880 $qtiItemfeedback->set_attribute("view", "All");
00881
00882 $qtiFlowmat = $this->domxml->create_element("flow_mat");
00883 $qtiMaterial = $this->domxml->create_element("material");
00884 $qtiMattext = $this->domxml->create_element("mattext");
00885
00886 $qtiMattextText = $this->domxml->create_text_node("");
00887 $qtiMattext->append_child($qtiMattextText);
00888 $qtiMaterial->append_child($qtiMattext);
00889 $qtiFlowmat->append_child($qtiMaterial);
00890 $qtiItemfeedback->append_child($qtiFlowmat);
00891 $qtiIdent->append_child($qtiItemfeedback);
00892 }
00893
00894 $xml = $this->domxml->dump_mem(true);
00895 if (!$a_include_header)
00896 {
00897 $pos = strpos($xml, "?>");
00898 $xml = substr($xml, $pos + 2);
00899 }
00900
00901 return $xml;
00902
00903 }
00904
00914 function get_question() {
00915 return $this->question;
00916 }
00917
00927 function set_question($question = "") {
00928 $this->question = $question;
00929 }
00930
00940 function get_imagemap_filename() {
00941 return $this->imagemap_filename;
00942 }
00943
00953 function set_imagemap_filename($imagemap_filename, $imagemap_tempfilename = "") {
00954 if (!empty($imagemap_filename)) {
00955 $this->imagemap_filename = $imagemap_filename;
00956 }
00957 if (!empty($imagemap_tempfilename)) {
00958 $fp = fopen($imagemap_tempfilename, "r");
00959 $contents = fread($fp, filesize($imagemap_tempfilename));
00960 fclose($fp);
00961 if (preg_match_all("/<area(.+)>/siU", $contents, $matches)) {
00962 for ($i=0; $i< count($matches[1]); $i++) {
00963 preg_match("/alt\s*=\s*\"(.+)\"\s*/siU", $matches[1][$i], $alt);
00964 preg_match("/coords\s*=\s*\"(.+)\"\s*/siU", $matches[1][$i], $coords);
00965 preg_match("/shape\s*=\s*\"(.+)\"\s*/siU", $matches[1][$i], $shape);
00966 $this->add_answer($alt[1], 0.0, FALSE, count($this->answers), $coords[1], $shape[1]);
00967 }
00968 }
00969 }
00970 }
00971
00981 function get_image_filename() {
00982 return $this->image_filename;
00983 }
00984
00994 function set_image_filename($image_filename, $image_tempfilename = "") {
00995
00996 if (!empty($image_filename))
00997 {
00998 $image_filename = str_replace(" ", "_", $image_filename);
00999 $this->image_filename = $image_filename;
01000 }
01001 if (!empty($image_tempfilename)) {
01002 $imagepath = $this->getImagePath();
01003 if (!file_exists($imagepath)) {
01004 ilUtil::makeDirParents($imagepath);
01005 }
01006
01007 if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
01008 {
01009 $this->ilias->raiseError("The image could not be uploaded!", $this->ilias->error_obj->MESSAGE);
01010 }
01011 }
01012 }
01013
01023 function get_imagemap_contents($href = "#") {
01024 $imagemap_contents = "<map name=\"".$this->title."\"> ";
01025 for ($i = 0; $i < count($this->answers); $i++) {
01026 $imagemap_contents .= "<area alt=\"".$this->answers[$i]->get_answertext()."\" ";
01027 $imagemap_contents .= "shape=\"".$this->answers[$i]->get_area()."\" ";
01028 $imagemap_contents .= "coords=\"".$this->answers[$i]->get_coords()."\" ";
01029 $imagemap_contents .= "href=\"$href&selimage=" . $this->answers[$i]->get_order() . "\" /> ";
01030 }
01031 $imagemap_contents .= "</map>";
01032 return $imagemap_contents;
01033 }
01034
01049 function add_answer(
01050 $answertext = "",
01051 $points = 0.0,
01052 $status = 0,
01053 $order = 0,
01054 $coords="",
01055 $area=""
01056 )
01057 {
01058 if (array_key_exists($order, $this->answers)) {
01059
01060 $answer = new ASS_AnswerImagemap($answertext, $points, $order, $status, $coords, $area);
01061 for ($i = count($this->answers) - 1; $i >= $order; $i--) {
01062 $this->answers[$i+1] = $this->answers[$i];
01063 $this->answers[$i+1]->set_order($i+1);
01064 }
01065 $this->answers[$order] = $answer;
01066 } else {
01067
01068 $answer = new ASS_AnswerImagemap($answertext, $points, count($this->answers), $status, $coords, $area);
01069 array_push($this->answers, $answer);
01070 }
01071 }
01072
01082 function get_answer_count() {
01083 return count($this->answers);
01084 }
01085
01097 function get_answer($index = 0) {
01098 if ($index < 0) return NULL;
01099 if (count($this->answers) < 1) return NULL;
01100 if ($index >= count($this->answers)) return NULL;
01101 return $this->answers[$index];
01102 }
01103
01114 function deleteArea($index = 0) {
01115 if ($index < 0) return;
01116 if (count($this->answers) < 1) return;
01117 if ($index >= count($this->answers)) return;
01118 unset($this->answers[$index]);
01119 $this->answers = array_values($this->answers);
01120 for ($i = 0; $i < count($this->answers); $i++) {
01121 if ($this->answers[$i]->get_order() > $index) {
01122 $this->answers[$i]->set_order($i);
01123 }
01124 }
01125 }
01126
01135 function flush_answers() {
01136 $this->answers = array();
01137 }
01138
01147 function getMaximumPoints() {
01148 $points = array("set" => 0, "unset" => 0);
01149 foreach ($this->answers as $key => $value) {
01150 if ($value->get_points() > $points["set"])
01151 {
01152 $points["set"] = $value->get_points();
01153 }
01154 }
01155 return $points["set"];
01156 }
01157
01169 function calculateReachedPoints($user_id, $test_id)
01170 {
01171 global $ilDB;
01172
01173 $found_values = array();
01174 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01175 $ilDB->quote($user_id),
01176 $ilDB->quote($test_id),
01177 $ilDB->quote($this->getId())
01178 );
01179 $result = $ilDB->query($query);
01180 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01181 {
01182 if (strcmp($data->value1, "") != 0)
01183 {
01184 array_push($found_values, $data->value1);
01185 }
01186 }
01187 $points = 0;
01188 if (count($found_values) > 0)
01189 {
01190 foreach ($this->answers as $key => $answer)
01191 {
01192 if ($answer->isStateChecked())
01193 {
01194 if (in_array($key, $found_values))
01195 {
01196 $points += $answer->get_points();
01197 }
01198 }
01199 }
01200 }
01201
01202
01203 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
01204 $ilDB->quote($test_id)
01205 );
01206 $result = $ilDB->query($query);
01207 if ($result->numRows() == 1)
01208 {
01209 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01210 if ($row["count_system"] == 1)
01211 {
01212 if ($points != $this->getMaximumPoints())
01213 {
01214 $points = 0;
01215 }
01216 }
01217 }
01218 else
01219 {
01220 $points = 0;
01221 }
01222 return $points;
01223 }
01224
01234 function getReachedInformation($user_id, $test_id) {
01235 $found_values = array();
01236 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01237 $this->ilias->db->quote($user_id),
01238 $this->ilias->db->quote($test_id),
01239 $this->ilias->db->quote($this->getId())
01240 );
01241 $result = $this->ilias->db->query($query);
01242 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01243 {
01244 array_push($found_values, $data->value1);
01245 }
01246 $counter = 1;
01247 $user_result = array();
01248 foreach ($found_values as $key => $value)
01249 {
01250 $solution = array(
01251 "order" => "$counter",
01252 "points" => 0,
01253 "true" => 0,
01254 "value" => "",
01255 );
01256 if (strlen($value) > 0)
01257 {
01258 $solution["value"] = $value;
01259 $solution["points"] = $this->answers[$value]->get_points();
01260 if ($this->answers[$value]->isStateChecked())
01261 {
01262 $solution["true"] = 1;
01263 }
01264 }
01265 $counter++;
01266 array_push($user_result, $solution);
01267 }
01268 return $user_result;
01269 }
01270
01281 function saveWorkingData($test_id, $limit_to = LIMIT_NO_LIMIT) {
01282 global $ilDB;
01283 global $ilUser;
01284 $db =& $ilDB->db;
01285
01286 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
01287 $db->quote($ilUser->id),
01288 $db->quote($test_id),
01289 $db->quote($this->getId())
01290 );
01291 $result = $db->query($query);
01292
01293 $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)",
01294 $db->quote($ilUser->id),
01295 $db->quote($test_id),
01296 $db->quote($this->getId()),
01297 $db->quote($_GET["selImage"])
01298 );
01299 $result = $db->query($query);
01300 parent::saveWorkingData($test_id);
01301 return true;
01302 }
01303
01304 function syncWithOriginal()
01305 {
01306 global $ilias;
01307 if ($this->original_id)
01308 {
01309 $complete = 0;
01310 if ($this->isComplete())
01311 {
01312 $complete = 1;
01313 }
01314 $db = & $ilias->db;
01315
01316 $estw_time = $this->getEstimatedWorkingTime();
01317 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01318
01319 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, points = %s, image_file = %s, complete = %s WHERE question_id = %s",
01320 $db->quote($this->obj_id. ""),
01321 $db->quote($this->title . ""),
01322 $db->quote($this->comment . ""),
01323 $db->quote($this->author . ""),
01324 $db->quote($this->question . ""),
01325 $db->quote($estw_time . ""),
01326 $db->quote($this->getMaximumPoints() . ""),
01327 $db->quote($this->image_filename . ""),
01328 $db->quote($complete . ""),
01329 $db->quote($this->original_id . "")
01330 );
01331 $result = $db->query($query);
01332
01333 if ($result == DB_OK)
01334 {
01335
01336
01337 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01338 $db->quote($this->original_id)
01339 );
01340 $result = $db->query($query);
01341
01342 foreach ($this->answers as $key => $value)
01343 {
01344 $answer_obj = $this->answers[$key];
01345 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, correctness, coords, area, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, NULL)",
01346 $db->quote($this->original_id . ""),
01347 $db->quote($answer_obj->get_answertext() . ""),
01348 $db->quote($answer_obj->get_points() . ""),
01349 $db->quote($answer_obj->get_order() . ""),
01350 $db->quote($answer_obj->getState() . ""),
01351 $db->quote($answer_obj->get_coords() . ""),
01352 $db->quote($answer_obj->get_area() . "")
01353 );
01354 $answer_result = $db->query($query);
01355 }
01356 }
01357 parent::syncWithOriginal();
01358 }
01359 }
01360
01369 function getQuestionType()
01370 {
01371 return 6;
01372 }
01373 }
01374
01375 ?>