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 include_once "./assessment/classes/class.assQuestion.php";
00025 include_once "./assessment/classes/inc.AssessmentConstants.php";
00026
00037 class assOrderingQuestion extends assQuestion
00038 {
00046 var $question;
00047
00055 var $answers;
00056
00065 var $ordering_type;
00066
00079 function assOrderingQuestion (
00080 $title = "",
00081 $comment = "",
00082 $author = "",
00083 $owner = -1,
00084 $question = "",
00085 $ordering_type = OQ_TERMS
00086 )
00087 {
00088 $this->assQuestion($title, $comment, $author, $owner);
00089 $this->answers = array();
00090 $this->question = $question;
00091 $this->ordering_type = $ordering_type;
00092 }
00093
00102 function isComplete()
00103 {
00104 if (($this->title) and ($this->author) and ($this->question) and (count($this->answers)) and ($this->getMaximumPoints() > 0))
00105 {
00106 return true;
00107 }
00108 else
00109 {
00110 return false;
00111 }
00112 }
00113
00127 function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
00128 {
00129 global $ilUser;
00130
00131
00132 unset($_SESSION["import_mob_xhtml"]);
00133 $presentation = $item->getPresentation();
00134 $duration = $item->getDuration();
00135 $shuffle = 0;
00136 $now = getdate();
00137 $foundimage = FALSE;
00138 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00139 $answers = array();
00140 foreach ($presentation->order as $entry)
00141 {
00142 switch ($entry["type"])
00143 {
00144 case "response":
00145 $response = $presentation->response[$entry["index"]];
00146 $rendertype = $response->getRenderType();
00147 switch (strtolower(get_class($rendertype)))
00148 {
00149 case "ilqtirenderchoice":
00150 $shuffle = $rendertype->getShuffle();
00151 $answerorder = 0;
00152 foreach ($rendertype->response_labels as $response_label)
00153 {
00154 $ident = $response_label->getIdent();
00155 $answertext = "";
00156 foreach ($response_label->material as $mat)
00157 {
00158 for ($m = 0; $m < $mat->getMaterialCount(); $m++)
00159 {
00160 $foundmat = $mat->getMaterial($m);
00161 if (strcmp($foundmat["type"], "mattext") == 0)
00162 {
00163 $answertext .= $foundmat["material"]->getContent();
00164 }
00165 if (strcmp($foundmat["type"], "matimage") == 0)
00166 {
00167 $foundimage = TRUE;
00168 $answerimage = array(
00169 "imagetype" => $foundmat["material"]->getImageType(),
00170 "label" => $foundmat["material"]->getLabel(),
00171 "content" => $foundmat["material"]->getContent()
00172 );
00173 }
00174 }
00175 }
00176 $answers[$ident] = array(
00177 "answertext" => $answertext,
00178 "answerimage" => $answerimage,
00179 "points" => 0,
00180 "answerorder" => $answerorder++,
00181 "correctness" => "",
00182 "action" => ""
00183 );
00184 }
00185 break;
00186 }
00187 break;
00188 }
00189 }
00190 $responses = array();
00191 foreach ($item->resprocessing as $resprocessing)
00192 {
00193 foreach ($resprocessing->respcondition as $respcondition)
00194 {
00195 $ident = "";
00196 $correctness = 1;
00197 $conditionvar = $respcondition->getConditionvar();
00198 foreach ($conditionvar->order as $order)
00199 {
00200 switch ($order["field"])
00201 {
00202 case "arr_not":
00203 $correctness = 0;
00204 break;
00205 case "varequal":
00206 $ident = $conditionvar->varequal[$order["index"]]->getContent();
00207 $orderindex = $conditionvar->varequal[$order["index"]]->getIndex();
00208 break;
00209 }
00210 }
00211 foreach ($respcondition->setvar as $setvar)
00212 {
00213 if (strcmp($ident, "") != 0)
00214 {
00215 $answers[$ident]["solutionorder"] = $orderindex;
00216 $answers[$ident]["action"] = $setvar->getAction();
00217 $answers[$ident]["points"] = $setvar->getContent();
00218 }
00219 }
00220 }
00221 }
00222 $type = 1;
00223 if ($foundimage)
00224 {
00225 $type = 0;
00226 }
00227 $this->setTitle($item->getTitle());
00228 $this->setComment($item->getComment());
00229 $this->setAuthor($item->getAuthor());
00230 $this->setOwner($ilUser->getId());
00231 $this->setQuestion($this->QTIMaterialToString($item->getQuestiontext()));
00232 $this->setOrderingType($type);
00233 $this->setObjId($questionpool_id);
00234 $this->setEstimatedWorkingTime($duration["h"], $duration["m"], $duration["s"]);
00235 $this->setShuffle($shuffle);
00236 foreach ($answers as $answer)
00237 {
00238 if ($type == 1)
00239 {
00240 $this->addAnswer($answer["answertext"], $answer["points"], $answer["answerorder"], $answer["solutionorder"]);
00241 }
00242 else
00243 {
00244 $this->addAnswer($answer["answerimage"]["label"], $answer["points"], $answer["answerorder"], $answer["solutionorder"]);
00245 }
00246 }
00247 $this->saveToDb();
00248 if (count($item->suggested_solutions))
00249 {
00250 foreach ($item->suggested_solutions as $suggested_solution)
00251 {
00252 $this->setSuggestedSolution($suggested_solution["solution"]->getContent(), $suggested_solution["gap_index"], true);
00253 }
00254 $this->saveToDb();
00255 }
00256 foreach ($answers as $answer)
00257 {
00258 if ($type == 0)
00259 {
00260 include_once "./classes/class.ilUtil.php";
00261 $image =& base64_decode($answer["answerimage"]["content"]);
00262 $imagepath = $this->getImagePath();
00263 if (!file_exists($imagepath))
00264 {
00265 ilUtil::makeDirParents($imagepath);
00266 }
00267 $imagepath .= $answer["answerimage"]["label"];
00268 $fh = fopen($imagepath, "wb");
00269 if ($fh == false)
00270 {
00271
00272
00273
00274 }
00275 else
00276 {
00277 $imagefile = fwrite($fh, $image);
00278 fclose($fh);
00279 }
00280
00281 $thumbpath = $imagepath . "." . "thumb.jpg";
00282 ilUtil::convertImage($imagepath, $thumbpath, "JPEG", 100);
00283 }
00284 }
00285
00286 if (is_array($_SESSION["import_mob_xhtml"]))
00287 {
00288 include_once "./content/classes/Media/class.ilObjMediaObject.php";
00289 include_once "./Services/RTE/classes/class.ilRTE.php";
00290 foreach ($_SESSION["import_mob_xhtml"] as $mob)
00291 {
00292 if ($tst_id > 0)
00293 {
00294 include_once "./assessment/classes/class.ilObjTest.php";
00295 $importfile = ilObjTest::_getImportDirectory() . "/" . $_SESSION["tst_import_subdir"] . "/" . $mob["uri"];
00296 }
00297 else
00298 {
00299 include_once "./assessment/classes/class.ilObjQuestionPool.php";
00300 $importfile = ilObjQuestionPool::_getImportDirectory() . "/" . $_SESSION["qpl_import_subdir"] . "/" . $mob["uri"];
00301 }
00302 $media_object =& ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, FALSE);
00303 ilObjMediaObject::_saveUsage($media_object->getId(), "qpl:html", $this->getId());
00304 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getQuestion()), 1));
00305 foreach ($this->answers as $key => $value)
00306 {
00307 $answer_obj = $this->answers[$key];
00308 $answer_obj->setAnswertext(ilRTE::_replaceMediaObjectImageSrc(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $answer_obj->getAnswertext()), 1));
00309 }
00310 }
00311 $this->saveToDb();
00312 }
00313 if ($tst_id > 0)
00314 {
00315 $q_1_id = $this->getId();
00316 $question_id = $this->duplicate(true);
00317 $tst_object->questions[$question_counter++] = $question_id;
00318 $import_mapping[$item->getIdent()] = array("pool" => $q_1_id, "test" => $question_id);
00319 }
00320 else
00321 {
00322 $import_mapping[$item->getIdent()] = array("pool" => $this->getId(), "test" => 0);
00323 }
00324
00325 }
00326
00336 function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
00337 {
00338 global $ilDB;
00339 global $ilUser;
00340
00341 include_once("./classes/class.ilXmlWriter.php");
00342 $a_xml_writer = new ilXmlWriter;
00343
00344 $a_xml_writer->xmlHeader();
00345 $a_xml_writer->xmlStartTag("questestinterop");
00346 $attrs = array(
00347 "ident" => "il_".IL_INST_ID."_qst_".$this->getId(),
00348 "title" => $this->getTitle()
00349 );
00350 $a_xml_writer->xmlStartTag("item", $attrs);
00351
00352 $a_xml_writer->xmlElement("qticomment", NULL, $this->getComment());
00353
00354 $workingtime = $this->getEstimatedWorkingTime();
00355 $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]);
00356 $a_xml_writer->xmlElement("duration", NULL, $duration);
00357
00358 $a_xml_writer->xmlStartTag("itemmetadata");
00359 $a_xml_writer->xmlStartTag("qtimetadata");
00360 $a_xml_writer->xmlStartTag("qtimetadatafield");
00361 $a_xml_writer->xmlElement("fieldlabel", NULL, "ILIAS_VERSION");
00362 $a_xml_writer->xmlElement("fieldentry", NULL, $this->ilias->getSetting("ilias_version"));
00363 $a_xml_writer->xmlEndTag("qtimetadatafield");
00364 $a_xml_writer->xmlStartTag("qtimetadatafield");
00365 $a_xml_writer->xmlElement("fieldlabel", NULL, "QUESTIONTYPE");
00366 $a_xml_writer->xmlElement("fieldentry", NULL, ORDERING_QUESTION_IDENTIFIER);
00367 $a_xml_writer->xmlEndTag("qtimetadatafield");
00368 $a_xml_writer->xmlStartTag("qtimetadatafield");
00369 $a_xml_writer->xmlElement("fieldlabel", NULL, "AUTHOR");
00370 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getAuthor());
00371 $a_xml_writer->xmlEndTag("qtimetadatafield");
00372 $a_xml_writer->xmlEndTag("qtimetadata");
00373 $a_xml_writer->xmlEndTag("itemmetadata");
00374
00375
00376 $attrs = array(
00377 "label" => $this->getTitle()
00378 );
00379 $a_xml_writer->xmlStartTag("presentation", $attrs);
00380
00381 $a_xml_writer->xmlStartTag("flow");
00382
00383 $this->addQTIMaterial($a_xml_writer, $this->getQuestion());
00384
00385 $attrs = array();
00386 if ($this->getOrderingType() == OQ_PICTURES)
00387 {
00388 $attrs = array(
00389 "ident" => "OQP",
00390 "rcardinality" => "Ordered"
00391 );
00392 }
00393 else
00394 {
00395 $attrs = array(
00396 "ident" => "OQT",
00397 "rcardinality" => "Ordered"
00398 );
00399 }
00400 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00401 {
00402 $attrs["output"] = "javascript";
00403 }
00404 $a_xml_writer->xmlStartTag("response_lid", $attrs);
00405 $solution = $this->getSuggestedSolution(0);
00406 if (count($solution))
00407 {
00408 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00409 {
00410 $a_xml_writer->xmlStartTag("material");
00411 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00412 if (strcmp($matches[1], "") != 0)
00413 {
00414 $intlink = $solution["internal_link"];
00415 }
00416 $attrs = array(
00417 "label" => "suggested_solution"
00418 );
00419 $a_xml_writer->xmlElement("mattext", $attrs, $intlink);
00420 $a_xml_writer->xmlEndTag("material");
00421 }
00422 }
00423
00424 $attrs = array();
00425 if ($this->getShuffle())
00426 {
00427 $attrs = array(
00428 "shuffle" => "Yes"
00429 );
00430 }
00431 else
00432 {
00433 $attrs = array(
00434 "shuffle" => "No"
00435 );
00436 }
00437 $a_xml_writer->xmlStartTag("render_choice", $attrs);
00438
00439 $akeys = array_keys($this->answers);
00440 if ($this->getshuffle() && $a_shuffle)
00441 {
00442 $akeys = $this->pcArrayShuffle($akeys);
00443 }
00444
00445
00446 foreach ($akeys as $index)
00447 {
00448 $answer = $this->answers[$index];
00449 $attrs = array(
00450 "ident" => $index
00451 );
00452 $a_xml_writer->xmlStartTag("response_label", $attrs);
00453 if ($this->getOrderingType() == OQ_PICTURES)
00454 {
00455 $a_xml_writer->xmlStartTag("material");
00456 if ($force_image_references)
00457 {
00458 $attrs = array(
00459 "imagtype" => $imagetype,
00460 "label" => $answer->getAnswertext(),
00461 "uri" => $this->getImagePathWeb() . $answer->getAnswertext()
00462 );
00463 $a_xml_writer->xmlElement("matimage", $attrs);
00464 }
00465 else
00466 {
00467 $imagepath = $this->getImagePath() . $answer->getAnswertext();
00468 $fh = @fopen($imagepath, "rb");
00469 if ($fh != false)
00470 {
00471 $imagefile = fread($fh, filesize($imagepath));
00472 fclose($fh);
00473 $base64 = base64_encode($imagefile);
00474 $imagetype = "image/jpeg";
00475 if (preg_match("/.*\.(png|gif)$/", $answer->getAnswertext(), $matches))
00476 {
00477 $imagetype = "image/".$matches[1];
00478 }
00479 $attrs = array(
00480 "imagtype" => $imagetype,
00481 "label" => $answer->getAnswertext(),
00482 "embedded" => "base64"
00483 );
00484 $a_xml_writer->xmlElement("matimage", $attrs, $base64, FALSE, FALSE);
00485 }
00486 }
00487 $a_xml_writer->xmlEndTag("material");
00488 }
00489 else
00490 {
00491 $a_xml_writer->xmlStartTag("material");
00492 $this->addQTIMaterial($a_xml_writer, $answer->getAnswertext(), TRUE, FALSE);
00493 $a_xml_writer->xmlEndTag("material");
00494 }
00495 $a_xml_writer->xmlEndTag("response_label");
00496 }
00497 $a_xml_writer->xmlEndTag("render_choice");
00498 $a_xml_writer->xmlEndTag("response_lid");
00499 $a_xml_writer->xmlEndTag("flow");
00500 $a_xml_writer->xmlEndTag("presentation");
00501
00502
00503 $a_xml_writer->xmlStartTag("resprocessing");
00504 $a_xml_writer->xmlStartTag("outcomes");
00505 $a_xml_writer->xmlStartTag("decvar");
00506 $a_xml_writer->xmlEndTag("decvar");
00507 $a_xml_writer->xmlEndTag("outcomes");
00508
00509 foreach ($this->answers as $index => $answer)
00510 {
00511 $attrs = array(
00512 "continue" => "Yes"
00513 );
00514 $a_xml_writer->xmlStartTag("respcondition", $attrs);
00515
00516 $a_xml_writer->xmlStartTag("conditionvar");
00517 $attrs = array();
00518 if ($this->getOrderingType() == OQ_PICTURES)
00519 {
00520 $attrs = array(
00521 "respident" => "OQP"
00522 );
00523 }
00524 else
00525 {
00526 $attrs = array(
00527 "respident" => "OQT"
00528 );
00529 }
00530 $attrs["index"] = $answer->getSolutionOrder();
00531 $a_xml_writer->xmlElement("varequal", $attrs, $index);
00532 $a_xml_writer->xmlEndTag("conditionvar");
00533
00534 $attrs = array(
00535 "action" => "Add"
00536 );
00537 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
00538
00539 $attrs = array(
00540 "feedbacktype" => "Response",
00541 "linkrefid" => "link_$index"
00542 );
00543 $a_xml_writer->xmlElement("displayfeedback", $attrs);
00544 $a_xml_writer->xmlEndTag("respcondition");
00545 }
00546 $a_xml_writer->xmlEndTag("resprocessing");
00547
00548
00549 foreach ($this->answers as $index => $answer)
00550 {
00551 $attrs = array(
00552 "ident" => "link_$index",
00553 "view" => "All"
00554 );
00555 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
00556
00557 $a_xml_writer->xmlStartTag("flow_mat");
00558 $a_xml_writer->xmlStartTag("material");
00559 $a_xml_writer->xmlElement("mattext");
00560 $a_xml_writer->xmlEndTag("material");
00561 $a_xml_writer->xmlEndTag("flow_mat");
00562 $a_xml_writer->xmlEndTag("itemfeedback");
00563 }
00564
00565 $a_xml_writer->xmlEndTag("item");
00566 $a_xml_writer->xmlEndTag("questestinterop");
00567
00568 $xml = $a_xml_writer->xmlDumpMem(FALSE);
00569 if (!$a_include_header)
00570 {
00571 $pos = strpos($xml, "?>");
00572 $xml = substr($xml, $pos + 2);
00573 }
00574 return $xml;
00575 }
00576
00577
00586 function saveToDb($original_id = "")
00587 {
00588 global $ilDB;
00589
00590 $complete = 0;
00591 if ($this->isComplete())
00592 {
00593 $complete = 1;
00594 }
00595
00596 $estw_time = $this->getEstimatedWorkingTime();
00597 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00598
00599 if ($original_id)
00600 {
00601 $original_id = $ilDB->quote($original_id);
00602 }
00603 else
00604 {
00605 $original_id = "NULL";
00606 }
00607
00608 include_once("./Services/RTE/classes/class.ilRTE.php");
00609 $combinedtext = $this->question;
00610 if ($this->id == -1)
00611 {
00612
00613 $now = getdate();
00614 $question_type = $this->getQuestionType();
00615 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00616 $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, points, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00617 $ilDB->quote($question_type . ""),
00618 $ilDB->quote($this->obj_id . ""),
00619 $ilDB->quote($this->title . ""),
00620 $ilDB->quote($this->comment . ""),
00621 $ilDB->quote($this->author . ""),
00622 $ilDB->quote($this->owner . ""),
00623 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
00624 $ilDB->quote($estw_time . ""),
00625 $ilDB->quote($this->getMaximumPoints() . ""),
00626 $ilDB->quote($complete . ""),
00627 $ilDB->quote($created . ""),
00628 $original_id
00629 );
00630 $result = $ilDB->query($query);
00631 if ($result == DB_OK)
00632 {
00633 $this->id = $ilDB->getLastInsertId();
00634 $query = sprintf("INSERT INTO qpl_question_ordering (question_fi, ordering_type) VALUES (%s, %s)",
00635 $ilDB->quote($this->id . ""),
00636 $ilDB->quote($this->ordering_type . "")
00637 );
00638 $ilDB->query($query);
00639
00640
00641 $this->createPageObject();
00642
00643 if ($this->getTestId() > 0)
00644 {
00645 $this->insertIntoTest($this->getTestId());
00646 }
00647 }
00648 }
00649 else
00650 {
00651
00652 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, points = %s, complete = %s WHERE question_id = %s",
00653 $ilDB->quote($this->obj_id. ""),
00654 $ilDB->quote($this->title . ""),
00655 $ilDB->quote($this->comment . ""),
00656 $ilDB->quote($this->author . ""),
00657 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
00658 $ilDB->quote($estw_time . ""),
00659 $ilDB->quote($this->getMaximumPoints() . ""),
00660 $ilDB->quote($complete . ""),
00661 $ilDB->quote($this->id . "")
00662 );
00663 $result = $ilDB->query($query);
00664 $query = sprintf("UPDATE qpl_question_ordering SET ordering_type = %s WHERE question_fi = %s",
00665 $ilDB->quote($this->ordering_type . ""),
00666 $ilDB->quote($this->id . "")
00667 );
00668 $result = $ilDB->query($query);
00669 }
00670 if ($result == DB_OK)
00671 {
00672
00673
00674 $query = sprintf("DELETE FROM qpl_answer_ordering WHERE question_fi = %s",
00675 $ilDB->quote($this->id)
00676 );
00677 $result = $ilDB->query($query);
00678
00679
00680 foreach ($this->answers as $key => $value)
00681 {
00682 $answer_obj = $this->answers[$key];
00683 $query = sprintf("INSERT INTO qpl_answer_ordering (answer_id, question_fi, answertext, points, aorder, solution_order) VALUES (NULL, %s, %s, %s, %s, %s)",
00684 $ilDB->quote($this->id),
00685 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($answer_obj->getAnswertext(), 0)),
00686 $ilDB->quote($answer_obj->getPoints() . ""),
00687 $ilDB->quote($answer_obj->getOrder() . ""),
00688 $ilDB->quote($answer_obj->getSolutionOrder() . "")
00689 );
00690 $combinedtext .= $answer_obj->getAnswertext();
00691 $answer_result = $ilDB->query($query);
00692 }
00693 }
00694
00695 ilRTE::_cleanupMediaObjectUsage($combinedtext, "qpl:html",
00696 $this->getId());
00697
00698 parent::saveToDb($original_id);
00699 }
00700
00710 function loadFromDb($question_id)
00711 {
00712 global $ilDB;
00713
00714 $query = sprintf("SELECT qpl_questions.*, qpl_question_ordering.* FROM qpl_questions, qpl_question_ordering WHERE question_id = %s AND qpl_questions.question_id = qpl_question_ordering.question_fi",
00715 $ilDB->quote($question_id)
00716 );
00717 $result = $ilDB->query($query);
00718 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00719 {
00720 if ($result->numRows() == 1)
00721 {
00722 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00723 $this->id = $question_id;
00724 $this->title = $data->title;
00725 $this->obj_id = $data->obj_fi;
00726 $this->comment = $data->comment;
00727 $this->original_id = $data->original_id;
00728 $this->author = $data->author;
00729 $this->owner = $data->owner;
00730 include_once("./Services/RTE/classes/class.ilRTE.php");
00731 $this->question = ilRTE::_replaceMediaObjectImageSrc($data->question_text, 1);
00732 $this->solution_hint = $data->solution_hint;
00733 $this->ordering_type = $data->ordering_type;
00734 $this->points = $data->points;
00735 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00736 }
00737
00738 $query = sprintf("SELECT * FROM qpl_answer_ordering WHERE question_fi = %s ORDER BY aorder ASC",
00739 $ilDB->quote($question_id)
00740 );
00741 $result = $ilDB->query($query);
00742 include_once "./assessment/classes/class.assAnswerOrdering.php";
00743 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00744 {
00745 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00746 {
00747 include_once("./Services/RTE/classes/class.ilRTE.php");
00748 $data->answertext = ilRTE::_replaceMediaObjectImageSrc($data->answertext, 1);
00749 array_push($this->answers, new ASS_AnswerOrdering($data->answertext, $data->points, $data->aorder, $data->solution_order));
00750 }
00751 }
00752 }
00753 parent::loadFromDb($question_id);
00754 }
00755
00763 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00764 {
00765 if ($this->id <= 0)
00766 {
00767
00768 return;
00769 }
00770
00771 $this_id = $this->getId();
00772 $clone = $this;
00773 include_once ("./assessment/classes/class.assQuestion.php");
00774 $original_id = assQuestion::_getOriginalId($this->id);
00775 $clone->id = -1;
00776 if ($title)
00777 {
00778 $clone->setTitle($title);
00779 }
00780 if ($author)
00781 {
00782 $clone->setAuthor($author);
00783 }
00784 if ($owner)
00785 {
00786 $clone->setOwner($owner);
00787 }
00788 if ($for_test)
00789 {
00790 $clone->saveToDb($original_id);
00791 }
00792 else
00793 {
00794 $clone->saveToDb();
00795 }
00796
00797
00798 $clone->copyPageOfQuestion($this_id);
00799
00800 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
00801
00802
00803 $clone->duplicateImages($this_id);
00804 return $clone->id;
00805 }
00806
00814 function copyObject($target_questionpool, $title = "")
00815 {
00816 if ($this->id <= 0)
00817 {
00818
00819 return;
00820 }
00821
00822 $clone = $this;
00823 include_once ("./assessment/classes/class.assQuestion.php");
00824 $original_id = assQuestion::_getOriginalId($this->id);
00825 $clone->id = -1;
00826 $source_questionpool = $this->getObjId();
00827 $clone->setObjId($target_questionpool);
00828 if ($title)
00829 {
00830 $clone->setTitle($title);
00831 }
00832
00833 $clone->saveToDb();
00834
00835
00836 $clone->copyPageOfQuestion($original_id);
00837
00838 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
00839
00840
00841 $clone->copyImages($original_id, $source_questionpool);
00842 return $clone->id;
00843 }
00844
00845 function duplicateImages($question_id)
00846 {
00847 if ($this->getOrderingType() == OQ_PICTURES)
00848 {
00849 $imagepath = $this->getImagePath();
00850 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00851 if (!file_exists($imagepath)) {
00852 ilUtil::makeDirParents($imagepath);
00853 }
00854 foreach ($this->answers as $answer)
00855 {
00856 $filename = $answer->getAnswertext();
00857 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
00858 print "image could not be duplicated!!!! ";
00859 }
00860 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg")) {
00861 print "image thumbnail could not be duplicated!!!! ";
00862 }
00863 }
00864 }
00865 }
00866
00867 function copyImages($question_id, $source_questionpool)
00868 {
00869 if ($this->getOrderingType() == OQ_PICTURES)
00870 {
00871 $imagepath = $this->getImagePath();
00872 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00873 $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
00874 if (!file_exists($imagepath)) {
00875 ilUtil::makeDirParents($imagepath);
00876 }
00877 foreach ($this->answers as $answer)
00878 {
00879 $filename = $answer->getAnswertext();
00880 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
00881 print "image could not be copied!!!! ";
00882 }
00883 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg")) {
00884 print "image thumbnail could not be copied!!!! ";
00885 }
00886 }
00887 }
00888 }
00889
00899 function setQuestion($question = "")
00900 {
00901 $this->question = $question;
00902 }
00903
00913 function setOrderingType($ordering_type = OQ_TERMS)
00914 {
00915 $this->ordering_type = $ordering_type;
00916 }
00917
00927 function getQuestion()
00928 {
00929 return $this->question;
00930 }
00931
00941 function getOrderingType()
00942 {
00943 return $this->ordering_type;
00944 }
00945
00961 function addAnswer(
00962 $answertext = "",
00963 $points = 0.0,
00964 $order = 0,
00965 $solution_order = 0
00966 )
00967 {
00968 $found = -1;
00969 foreach ($this->answers as $key => $value)
00970 {
00971 if ($value->getOrder() == $order)
00972 {
00973 $found = $order;
00974 }
00975 }
00976 include_once "./assessment/classes/class.assAnswerOrdering.php";
00977 if ($found >= 0)
00978 {
00979
00980 $answer = new ASS_AnswerOrdering($answertext, $points, $found, $solution_order);
00981 array_push($this->answers, $answer);
00982 for ($i = $found + 1; $i < count($this->answers); $i++)
00983 {
00984 $this->answers[$i] = $this->answers[$i-1];
00985 }
00986 $this->answers[$found] = $answer;
00987 }
00988 else
00989 {
00990
00991 $answer = new ASS_AnswerOrdering($answertext, $points,
00992 count($this->answers), $solution_order);
00993 array_push($this->answers, $answer);
00994 }
00995 }
00996
01008 function getAnswer($index = 0)
01009 {
01010 if ($index < 0) return NULL;
01011 if (count($this->answers) < 1) return NULL;
01012 if ($index >= count($this->answers)) return NULL;
01013 return $this->answers[$index];
01014 }
01015
01026 function deleteAnswer($index = 0)
01027 {
01028 if ($index < 0)
01029 {
01030 return;
01031 }
01032 if (count($this->answers) < 1)
01033 {
01034 return;
01035 }
01036 if ($index >= count($this->answers))
01037 {
01038 return;
01039 }
01040 unset($this->answers[$index]);
01041 $this->answers = array_values($this->answers);
01042 for ($i = 0; $i < count($this->answers); $i++)
01043 {
01044 if ($this->answers[$i]->getOrder() > $index)
01045 {
01046 $this->answers[$i]->setOrder($i);
01047 }
01048 }
01049 }
01050
01059 function flushAnswers()
01060 {
01061 $this->answers = array();
01062 }
01063
01073 function getAnswerCount()
01074 {
01075 return count($this->answers);
01076 }
01077
01086 function getMaxSolutionOrder()
01087 {
01088 if (count($this->answers) == 0)
01089 {
01090 $max = 0;
01091 }
01092 else
01093 {
01094 $max = $this->answers[0]->getSolutionOrder();
01095 }
01096 foreach ($this->answers as $key => $value)
01097 {
01098 if ($value->getSolutionOrder() > $max)
01099 {
01100 $max = $value->getSolutionOrder();
01101 }
01102 }
01103 return $max;
01104 }
01105
01117 function calculateReachedPoints($active_id, $pass = NULL)
01118 {
01119 global $ilDB;
01120
01121 $found_value1 = array();
01122 $found_value2 = array();
01123 if (is_null($pass))
01124 {
01125 $pass = $this->getSolutionMaxPass($active_id);
01126 }
01127 $query = sprintf("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
01128 $ilDB->quote($active_id . ""),
01129 $ilDB->quote($this->getId() . ""),
01130 $ilDB->quote($pass . "")
01131 );
01132 $result = $ilDB->query($query);
01133 $user_order = array();
01134 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01135 {
01136 if ((strcmp($data->value1, "") != 0) && (strcmp($data->value2, "") != 0))
01137 {
01138 $user_order[$data->value2] = $data->value1;
01139 }
01140 }
01141 ksort($user_order);
01142 $user_order = array_values($user_order);
01143 $answer_order = array();
01144 foreach ($this->answers as $key => $answer)
01145 {
01146 $answer_order[$answer->getSolutionOrder()] = $key;
01147 }
01148 ksort($answer_order);
01149 $answer_order = array_values($answer_order);
01150 $points = 0;
01151 foreach ($answer_order as $index => $answer_id)
01152 {
01153 if (strcmp($user_order[$index], "") != 0)
01154 {
01155 if ($answer_id == $user_order[$index])
01156 {
01157 $points += $this->answers[$answer_id]->getPoints();
01158 }
01159 }
01160 }
01161
01162 $points = parent::calculateReachedPoints($active_id, $pass = NULL, $points);
01163 return $points;
01164 }
01165
01174 function getMaximumPoints()
01175 {
01176 $points = 0;
01177 foreach ($this->answers as $key => $value)
01178 {
01179 $points += $value->getPoints();
01180 }
01181 return $points;
01182 }
01183
01194 function setImageFile($image_filename, $image_tempfilename = "")
01195 {
01196 $result = 0;
01197 if (!empty($image_tempfilename))
01198 {
01199 $imagepath = $this->getImagePath();
01200 if (!file_exists($imagepath))
01201 {
01202 ilUtil::makeDirParents($imagepath);
01203 }
01204 if (!ilUtil::moveUploadedFile($image_tempfilename,$image_filename, $imagepath.$image_filename))
01205 {
01206 $result = 2;
01207 }
01208 else
01209 {
01210 include_once "./content/classes/Media/class.ilObjMediaObject.php";
01211 $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
01212 if (!preg_match("/^image/", $mimetype))
01213 {
01214 unlink($imagepath . $image_filename);
01215 $result = 1;
01216 }
01217 else
01218 {
01219
01220 $thumbpath = $imagepath . $image_filename . "." . "thumb.jpg";
01221 ilUtil::convertImage($imagepath.$image_filename, $thumbpath, strtoupper($extension), 100);
01222 }
01223 }
01224 }
01225 return $result;
01226 }
01227
01237 function checkSaveData()
01238 {
01239 $result = true;
01240 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
01241 {
01242 if (strlen($_POST["orderresult"]))
01243 {
01244 return $result;
01245 }
01246 }
01247 $order_values = array();
01248 foreach ($_POST as $key => $value)
01249 {
01250 if (preg_match("/^order_(\d+)/", $key, $matches))
01251 {
01252 if (strcmp($value, "") != 0)
01253 {
01254 array_push($order_values, $value);
01255 }
01256 }
01257 }
01258 $check_order = array_flip($order_values);
01259 if (count($check_order) != count($order_values))
01260 {
01261
01262 $result = false;
01263 sendInfo($this->lng->txt("duplicate_order_values_entered"), TRUE);
01264 }
01265 return $result;
01266 }
01267
01278 function saveWorkingData($active_id, $pass = NULL)
01279 {
01280 global $ilDB;
01281 global $ilUser;
01282
01283 $saveWorkingDataResult = $this->checkSaveData();
01284 $entered_values = 0;
01285 if ($saveWorkingDataResult)
01286 {
01287 include_once "./assessment/classes/class.ilObjTest.php";
01288 $activepass = ilObjTest::_getPass($active_id);
01289
01290 $query = sprintf("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
01291 $ilDB->quote($active_id . ""),
01292 $ilDB->quote($this->getId() . ""),
01293 $ilDB->quote($activepass . "")
01294 );
01295 $result = $ilDB->query($query);
01296 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
01297 {
01298 $orderresult = $_POST["orderresult"];
01299 if (strlen($orderresult))
01300 {
01301 $orderarray = explode(":", $orderresult);
01302 $ordervalue = 1;
01303 foreach ($orderarray as $index)
01304 {
01305 $query = sprintf("INSERT INTO tst_solutions (solution_id, active_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01306 $ilDB->quote($active_id . ""),
01307 $ilDB->quote($this->getId() . ""),
01308 $ilDB->quote(trim($index) . ""),
01309 $ilDB->quote(trim($ordervalue) . ""),
01310 $ilDB->quote($activepass . "")
01311 );
01312 $result = $ilDB->query($query);
01313 $ordervalue++;
01314 $entered_values++;
01315 }
01316 }
01317 }
01318 else
01319 {
01320 foreach ($_POST as $key => $value)
01321 {
01322 if (preg_match("/^order_(\d+)/", $key, $matches))
01323 {
01324 if (!(preg_match("/initial_value_\d+/", $value)))
01325 {
01326 if (strlen($value))
01327 {
01328 $query = sprintf("INSERT INTO tst_solutions (solution_id, active_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01329 $ilDB->quote($active_id . ""),
01330 $ilDB->quote($this->getId() . ""),
01331 $ilDB->quote($matches[1] . ""),
01332 $ilDB->quote($value . ""),
01333 $ilDB->quote($activepass . "")
01334 );
01335 $result = $ilDB->query($query);
01336 $entered_values++;
01337 }
01338 }
01339 }
01340 }
01341 }
01342 }
01343 if ($entered_values)
01344 {
01345 include_once ("./classes/class.ilObjAssessmentFolder.php");
01346 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01347 {
01348 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
01349 }
01350 }
01351 else
01352 {
01353 include_once ("./classes/class.ilObjAssessmentFolder.php");
01354 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01355 {
01356 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
01357 }
01358 }
01359 parent::saveWorkingData($active_id, $pass);
01360 return $saveWorkingDataResult;
01361 }
01362
01363 function syncWithOriginal()
01364 {
01365 global $ilDB;
01366
01367 if ($this->original_id)
01368 {
01369 $complete = 0;
01370 if ($this->isComplete())
01371 {
01372 $complete = 1;
01373 }
01374 $estw_time = $this->getEstimatedWorkingTime();
01375 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01376
01377 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, points = %s, complete = %s WHERE question_id = %s",
01378 $ilDB->quote($this->obj_id. ""),
01379 $ilDB->quote($this->title . ""),
01380 $ilDB->quote($this->comment . ""),
01381 $ilDB->quote($this->author . ""),
01382 $ilDB->quote($this->question . ""),
01383 $ilDB->quote($estw_time . ""),
01384 $ilDB->quote($this->getMaximumPoints() . ""),
01385 $ilDB->quote($complete . ""),
01386 $ilDB->quote($this->original_id . "")
01387 );
01388 $result = $ilDB->query($query);
01389 $query = sprintf("UPDATE qpl_question_ordering SET ordering_type = %s WHERE question_fi = %s",
01390 $ilDB->quote($this->ordering_type . ""),
01391 $ilDB->quote($this->original_id . "")
01392 );
01393 $result = $ilDB->query($query);
01394
01395 if ($result == DB_OK)
01396 {
01397
01398
01399 $query = sprintf("DELETE FROM qpl_answer_ordering WHERE question_fi = %s",
01400 $ilDB->quote($this->original_id)
01401 );
01402 $result = $ilDB->query($query);
01403
01404 foreach ($this->answers as $key => $value)
01405 {
01406 $answer_obj = $this->answers[$key];
01407 $query = sprintf("INSERT INTO qpl_answer_ordering (answer_id, question_fi, answertext, points, aorder, solution_order) VALUES (NULL, %s, %s, %s, %s, %s)",
01408 $ilDB->quote($this->original_id . ""),
01409 $ilDB->quote($answer_obj->getAnswertext() . ""),
01410 $ilDB->quote($answer_obj->getPoints() . ""),
01411 $ilDB->quote($answer_obj->getOrder() . ""),
01412 $ilDB->quote($answer_obj->getSolutionOrder() . "")
01413 );
01414 $answer_result = $ilDB->query($query);
01415 }
01416 }
01417 parent::syncWithOriginal();
01418 }
01419 }
01420
01421 function pc_array_shuffle($array) {
01422 mt_srand((double)microtime()*1000000);
01423 $i = count($array);
01424 while(--$i)
01425 {
01426 $j = mt_rand(0, $i);
01427 if ($i != $j)
01428 {
01429
01430 $tmp = $array[$j];
01431 $array[$j] = $array[$i];
01432 $array[$i] = $tmp;
01433 }
01434 }
01435 return $array;
01436 }
01437
01446 function getQuestionType()
01447 {
01448 return 5;
01449 }
01450
01459 function getAdditionalTableName()
01460 {
01461 return "qpl_question_ordering";
01462 }
01463
01472 function getAnswerTableName()
01473 {
01474 return "qpl_answer_ordering";
01475 }
01476 }
01477
01478 ?>