00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 include_once "./assessment/classes/class.assQuestion.php";
00024 include_once "./assessment/classes/inc.AssessmentConstants.php";
00025
00036 class assMultipleChoice extends assQuestion
00037 {
00045 var $question;
00046
00054 var $answers;
00055
00064 var $output_type;
00065
00080 function assMultipleChoice(
00081 $title = "",
00082 $comment = "",
00083 $author = "",
00084 $owner = -1,
00085 $question = "",
00086 $output_type = OUTPUT_ORDER
00087 )
00088 {
00089 $this->assQuestion($title, $comment, $author, $owner);
00090 $this->question = $question;
00091 $this->output_type = $output_type;
00092 $this->answers = array();
00093 }
00094
00103 function isComplete()
00104 {
00105 if (($this->title) and ($this->author) and ($this->question) and (count($this->answers)) and ($this->getMaximumPoints() > 0))
00106 {
00107 return true;
00108 }
00109 else
00110 {
00111 return false;
00112 }
00113 }
00114
00128 function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
00129 {
00130 global $ilUser;
00131
00132
00133 unset($_SESSION["import_mob_xhtml"]);
00134 $presentation = $item->getPresentation();
00135 $duration = $item->getDuration();
00136 $shuffle = 0;
00137 $now = getdate();
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($response->getRenderType())))
00148 {
00149 case "ilqtirenderchoice":
00150 $shuffle = $rendertype->getShuffle();
00151 $answerorder = 0;
00152 $foundimage = FALSE;
00153 foreach ($rendertype->response_labels as $response_label)
00154 {
00155 $ident = $response_label->getIdent();
00156 $answertext = "";
00157 $answerimage = array();
00158 foreach ($response_label->material as $mat)
00159 {
00160 for ($m = 0; $m < $mat->getMaterialCount(); $m++)
00161 {
00162 $foundmat = $mat->getMaterial($m);
00163 if (strcmp($foundmat["type"], "mattext") == 0)
00164 {
00165 $answertext .= $foundmat["material"]->getContent();
00166 }
00167 if (strcmp($foundmat["type"], "matimage") == 0)
00168 {
00169 $foundimage = TRUE;
00170 $answerimage = array(
00171 "imagetype" => $foundmat["material"]->getImageType(),
00172 "label" => $foundmat["material"]->getLabel(),
00173 "content" => $foundmat["material"]->getContent()
00174 );
00175 }
00176 }
00177 }
00178 $answers[$ident] = array(
00179 "answertext" => $answertext,
00180 "imagefile" => $answerimage,
00181 "points" => 0,
00182 "answerorder" => $answerorder++,
00183 "points_unchecked" => 0,
00184 "action" => ""
00185 );
00186 }
00187 break;
00188 }
00189 break;
00190 }
00191 }
00192 $responses = array();
00193 foreach ($item->resprocessing as $resprocessing)
00194 {
00195 foreach ($resprocessing->respcondition as $respcondition)
00196 {
00197 $ident = "";
00198 $correctness = 1;
00199 $conditionvar = $respcondition->getConditionvar();
00200 foreach ($conditionvar->order as $order)
00201 {
00202 switch ($order["field"])
00203 {
00204 case "arr_not":
00205 $correctness = 0;
00206 break;
00207 case "varequal":
00208 $ident = $conditionvar->varequal[$order["index"]]->getContent();
00209 break;
00210 }
00211 }
00212 foreach ($respcondition->setvar as $setvar)
00213 {
00214 if (strcmp($ident, "") != 0)
00215 {
00216 if ($correctness)
00217 {
00218 $answers[$ident]["action"] = $setvar->getAction();
00219 $answers[$ident]["points"] = $setvar->getContent();
00220 }
00221 else
00222 {
00223 $answers[$ident]["action"] = $setvar->getAction();
00224 $answers[$ident]["points_unchecked"] = $setvar->getContent();
00225 }
00226 }
00227 }
00228 }
00229 }
00230 $this->setTitle($item->getTitle());
00231 $this->setComment($item->getComment());
00232 $this->setAuthor($item->getAuthor());
00233 $this->setOwner($ilUser->getId());
00234 $this->setQuestion($this->QTIMaterialToString($item->getQuestiontext()));
00235 $this->setObjId($questionpool_id);
00236 $this->setEstimatedWorkingTime($duration["h"], $duration["m"], $duration["s"]);
00237 $this->setShuffle($shuffle);
00238 foreach ($answers as $answer)
00239 {
00240 $this->addAnswer($answer["answertext"], $answer["points"], $answer["points_unchecked"], $answer["answerorder"], $answer["imagefile"]["label"]);
00241 }
00242 $this->saveToDb();
00243 foreach ($answers as $answer)
00244 {
00245 if (is_array($answer["imagefile"]) && (count($answer["imagefile"]) > 0))
00246 {
00247 $image =& base64_decode($answer["imagefile"]["content"]);
00248 $imagepath = $this->getImagePath();
00249 include_once "./classes/class.ilUtil.php";
00250 if (!file_exists($imagepath))
00251 {
00252 ilUtil::makeDirParents($imagepath);
00253 }
00254 $imagepath .= $answer["imagefile"]["label"];
00255 $fh = fopen($imagepath, "wb");
00256 if ($fh == false)
00257 {
00258
00259
00260
00261 }
00262 else
00263 {
00264 $imagefile = fwrite($fh, $image);
00265 fclose($fh);
00266 }
00267
00268 $thumbpath = $imagepath . "." . "thumb.jpg";
00269 ilUtil::convertImage($imagepath, $thumbpath, "JPEG", 100);
00270 }
00271 }
00272
00273 if (is_array($_SESSION["import_mob_xhtml"]))
00274 {
00275 include_once "./content/classes/Media/class.ilObjMediaObject.php";
00276 include_once "./Services/RTE/classes/class.ilRTE.php";
00277 foreach ($_SESSION["import_mob_xhtml"] as $mob)
00278 {
00279 if ($tst_id > 0)
00280 {
00281 include_once "./assessment/classes/class.ilObjTest.php";
00282 $importfile = ilObjTest::_getImportDirectory() . "/" . $_SESSION["tst_import_subdir"] . "/" . $mob["uri"];
00283 }
00284 else
00285 {
00286 include_once "./assessment/classes/class.ilObjQuestionPool.php";
00287 $importfile = ilObjQuestionPool::_getImportDirectory() . "/" . $_SESSION["qpl_import_subdir"] . "/" . $mob["uri"];
00288 }
00289 $media_object =& ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, FALSE);
00290 ilObjMediaObject::_saveUsage($media_object->getId(), "qpl:html", $this->getId());
00291 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getQuestion()), 1));
00292 foreach ($this->answers as $key => $value)
00293 {
00294 $answer_obj = $this->answers[$key];
00295 $answer_obj->setAnswertext(ilRTE::_replaceMediaObjectImageSrc(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $answer_obj->getAnswertext()), 1));
00296 }
00297 }
00298 $this->saveToDb();
00299 }
00300 if (count($item->suggested_solutions))
00301 {
00302 foreach ($item->suggested_solutions as $suggested_solution)
00303 {
00304 $this->setSuggestedSolution($suggested_solution["solution"]->getContent(), $suggested_solution["gap_index"], true);
00305 }
00306 $this->saveToDb();
00307 }
00308 if ($tst_id > 0)
00309 {
00310 $q_1_id = $this->getId();
00311 $question_id = $this->duplicate(true);
00312 $tst_object->questions[$question_counter++] = $question_id;
00313 $import_mapping[$item->getIdent()] = array("pool" => $q_1_id, "test" => $question_id);
00314 }
00315 else
00316 {
00317 $import_mapping[$item->getIdent()] = array("pool" => $this->getId(), "test" => 0);
00318 }
00319
00320 }
00321
00331 function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
00332 {
00333 include_once("./classes/class.ilXmlWriter.php");
00334 $a_xml_writer = new ilXmlWriter;
00335
00336 $a_xml_writer->xmlHeader();
00337 $a_xml_writer->xmlStartTag("questestinterop");
00338 $attrs = array(
00339 "ident" => "il_".IL_INST_ID."_qst_".$this->getId(),
00340 "title" => $this->getTitle()
00341 );
00342 $a_xml_writer->xmlStartTag("item", $attrs);
00343
00344 $a_xml_writer->xmlElement("qticomment", NULL, $this->getComment());
00345
00346 $workingtime = $this->getEstimatedWorkingTime();
00347 $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]);
00348 $a_xml_writer->xmlElement("duration", NULL, $duration);
00349
00350 $a_xml_writer->xmlStartTag("itemmetadata");
00351 $a_xml_writer->xmlStartTag("qtimetadata");
00352 $a_xml_writer->xmlStartTag("qtimetadatafield");
00353 $a_xml_writer->xmlElement("fieldlabel", NULL, "ILIAS_VERSION");
00354 $a_xml_writer->xmlElement("fieldentry", NULL, $this->ilias->getSetting("ilias_version"));
00355 $a_xml_writer->xmlEndTag("qtimetadatafield");
00356 $a_xml_writer->xmlStartTag("qtimetadatafield");
00357 $a_xml_writer->xmlElement("fieldlabel", NULL, "QUESTIONTYPE");
00358 $a_xml_writer->xmlElement("fieldentry", NULL, MULTIPLE_CHOICE_QUESTION_IDENTIFIER);
00359 $a_xml_writer->xmlEndTag("qtimetadatafield");
00360 $a_xml_writer->xmlStartTag("qtimetadatafield");
00361 $a_xml_writer->xmlElement("fieldlabel", NULL, "AUTHOR");
00362 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getAuthor());
00363 $a_xml_writer->xmlEndTag("qtimetadatafield");
00364 $a_xml_writer->xmlEndTag("qtimetadata");
00365 $a_xml_writer->xmlEndTag("itemmetadata");
00366
00367
00368 $attrs = array(
00369 "label" => $this->getTitle()
00370 );
00371 $a_xml_writer->xmlStartTag("presentation", $attrs);
00372
00373 $a_xml_writer->xmlStartTag("flow");
00374
00375 $this->addQTIMaterial($a_xml_writer, $this->getQuestion());
00376
00377 $attrs = array();
00378 $attrs = array(
00379 "ident" => "MCMR",
00380 "rcardinality" => "Multiple"
00381 );
00382 $a_xml_writer->xmlStartTag("response_lid", $attrs);
00383 $solution = $this->getSuggestedSolution(0);
00384 if (count($solution))
00385 {
00386 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00387 {
00388 $a_xml_writer->xmlStartTag("material");
00389 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00390 if (strcmp($matches[1], "") != 0)
00391 {
00392 $intlink = $solution["internal_link"];
00393 }
00394 $attrs = array(
00395 "label" => "suggested_solution"
00396 );
00397 $a_xml_writer->xmlElement("mattext", $attrs, $intlink);
00398 $a_xml_writer->xmlEndTag("material");
00399 }
00400 }
00401
00402 $attrs = array();
00403 if ($this->getShuffle())
00404 {
00405 $attrs = array(
00406 "shuffle" => "Yes"
00407 );
00408 }
00409 else
00410 {
00411 $attrs = array(
00412 "shuffle" => "No"
00413 );
00414 }
00415 $a_xml_writer->xmlStartTag("render_choice", $attrs);
00416 $akeys = array_keys($this->answers);
00417 if ($this->getshuffle() && $a_shuffle)
00418 {
00419 $akeys = $this->pcArrayShuffle($akeys);
00420 }
00421
00422 foreach ($akeys as $index)
00423 {
00424 $answer = $this->answers[$index];
00425 $attrs = array(
00426 "ident" => $index
00427 );
00428 $a_xml_writer->xmlStartTag("response_label", $attrs);
00429 $this->addQTIMaterial($a_xml_writer, $answer->getAnswertext(), FALSE, FALSE);
00430
00431 if (strlen($answer->getImage()))
00432 {
00433 $imagetype = "image/jpeg";
00434 if (preg_match("/.*\.(png|gif)$/", $answer->getImage(), $matches))
00435 {
00436 $imagetype = "image/" . $matches[1];
00437 }
00438 if ($force_image_references)
00439 {
00440 $attrs = array(
00441 "imagtype" => $imagetype,
00442 "label" => $answer->getImage(),
00443 "uri" => $this->getImagePathWeb() . $answer->getImage()
00444 );
00445 $a_xml_writer->xmlElement("matimage", $attrs);
00446 }
00447 else
00448 {
00449 $imagepath = $this->getImagePath() . $answer->getImage();
00450 $fh = @fopen($imagepath, "rb");
00451 if ($fh != false)
00452 {
00453 $imagefile = fread($fh, filesize($imagepath));
00454 fclose($fh);
00455 $base64 = base64_encode($imagefile);
00456 $attrs = array(
00457 "imagtype" => $imagetype,
00458 "label" => $answer->getImage(),
00459 "embedded" => "base64"
00460 );
00461 $a_xml_writer->xmlElement("matimage", $attrs, $base64, FALSE, FALSE);
00462 }
00463 }
00464 }
00465 $a_xml_writer->xmlEndTag("material");
00466 $a_xml_writer->xmlEndTag("response_label");
00467 }
00468 $a_xml_writer->xmlEndTag("render_choice");
00469 $a_xml_writer->xmlEndTag("response_lid");
00470 $a_xml_writer->xmlEndTag("flow");
00471 $a_xml_writer->xmlEndTag("presentation");
00472
00473
00474 $a_xml_writer->xmlStartTag("resprocessing");
00475 $a_xml_writer->xmlStartTag("outcomes");
00476 $a_xml_writer->xmlStartTag("decvar");
00477 $a_xml_writer->xmlEndTag("decvar");
00478 $a_xml_writer->xmlEndTag("outcomes");
00479
00480 foreach ($this->answers as $index => $answer)
00481 {
00482 $attrs = array(
00483 "continue" => "Yes"
00484 );
00485 $a_xml_writer->xmlStartTag("respcondition", $attrs);
00486
00487 $a_xml_writer->xmlStartTag("conditionvar");
00488 $attrs = array();
00489 $attrs = array(
00490 "respident" => "MCMR"
00491 );
00492 $a_xml_writer->xmlElement("varequal", $attrs, $index);
00493 $a_xml_writer->xmlEndTag("conditionvar");
00494
00495 $attrs = array(
00496 "action" => "Add"
00497 );
00498 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
00499
00500 if ($this->response == RESPONSE_SINGLE)
00501 {
00502 $linkrefid = "response_$index";
00503 }
00504 $attrs = array(
00505 "feedbacktype" => "Response",
00506 "linkrefid" => $linkrefid
00507 );
00508 $a_xml_writer->xmlElement("displayfeedback", $attrs);
00509 $a_xml_writer->xmlEndTag("respcondition");
00510 $attrs = array(
00511 "continue" => "Yes"
00512 );
00513 $a_xml_writer->xmlStartTag("respcondition", $attrs);
00514
00515
00516 $a_xml_writer->xmlStartTag("conditionvar");
00517 $attrs = array();
00518 $attrs = array(
00519 "respident" => "MCMR"
00520 );
00521 $a_xml_writer->xmlStartTag("not");
00522 $a_xml_writer->xmlElement("varequal", $attrs, $index);
00523 $a_xml_writer->xmlEndTag("not");
00524 $a_xml_writer->xmlEndTag("conditionvar");
00525
00526 $attrs = array(
00527 "action" => "Add"
00528 );
00529 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPointsUnchecked());
00530
00531 $linkrefid = "response_$index";
00532 $attrs = array(
00533 "feedbacktype" => "Response",
00534 "linkrefid" => $linkrefid
00535 );
00536 $a_xml_writer->xmlElement("displayfeedback", $attrs);
00537 $a_xml_writer->xmlEndTag("respcondition");
00538 }
00539 $a_xml_writer->xmlEndTag("resprocessing");
00540
00541
00542 foreach ($this->answers as $index => $answer)
00543 {
00544 $linkrefid = "response_$index";
00545 $attrs = array(
00546 "ident" => $linkrefid,
00547 "view" => "All"
00548 );
00549 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
00550
00551 $a_xml_writer->xmlStartTag("flow_mat");
00552 $a_xml_writer->xmlStartTag("material");
00553 $a_xml_writer->xmlElement("mattext");
00554 $a_xml_writer->xmlEndTag("material");
00555 $a_xml_writer->xmlEndTag("flow_mat");
00556 $a_xml_writer->xmlEndTag("itemfeedback");
00557 }
00558
00559 $a_xml_writer->xmlEndTag("item");
00560 $a_xml_writer->xmlEndTag("questestinterop");
00561
00562 $xml = $a_xml_writer->xmlDumpMem(FALSE);
00563 if (!$a_include_header)
00564 {
00565 $pos = strpos($xml, "?>");
00566 $xml = substr($xml, $pos + 2);
00567 }
00568 return $xml;
00569 }
00570
00579 function saveToDb($original_id = "")
00580 {
00581 global $ilDB;
00582
00583 $complete = 0;
00584 if ($this->isComplete())
00585 {
00586 $complete = 1;
00587 }
00588
00589 $estw_time = $this->getEstimatedWorkingTime();
00590 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00591
00592 if ($original_id)
00593 {
00594 $original_id = $ilDB->quote($original_id);
00595 }
00596 else
00597 {
00598 $original_id = "NULL";
00599 }
00600
00601 $combinedtext = "";
00602
00603 include_once("./Services/RTE/classes/class.ilRTE.php");
00604
00605 if ($this->id == -1)
00606 {
00607
00608 $now = getdate();
00609 $question_type = $this->getQuestionType();
00610 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00611 $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, points, working_time, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00612 $ilDB->quote($question_type),
00613 $ilDB->quote($this->obj_id),
00614 $ilDB->quote($this->title),
00615 $ilDB->quote($this->comment),
00616 $ilDB->quote($this->author),
00617 $ilDB->quote($this->owner),
00618 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
00619 $ilDB->quote($this->getMaximumPoints() . ""),
00620 $ilDB->quote($estw_time),
00621 $ilDB->quote("$complete"),
00622 $ilDB->quote($created),
00623 $original_id
00624 );
00625 $result = $ilDB->query($query);
00626
00627 if ($result == DB_OK)
00628 {
00629 $this->id = $ilDB->getLastInsertId();
00630 $query = sprintf("INSERT INTO qpl_question_multiplechoice (question_fi, shuffle) VALUES (%s, %s)",
00631 $ilDB->quote($this->id . ""),
00632 $ilDB->quote("$this->shuffle")
00633 );
00634 $ilDB->query($query);
00635
00636
00637 $this->createPageObject();
00638
00639
00640 if ($this->getTestId() > 0)
00641 {
00642 $this->insertIntoTest($this->getTestId());
00643 }
00644 }
00645 }
00646 else
00647 {
00648
00649 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, points = %s, working_time=%s, complete = %s WHERE question_id = %s",
00650 $ilDB->quote($this->obj_id. ""),
00651 $ilDB->quote($this->title),
00652 $ilDB->quote($this->comment),
00653 $ilDB->quote($this->author),
00654 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
00655 $ilDB->quote($this->getMaximumPoints() . ""),
00656 $ilDB->quote($estw_time),
00657 $ilDB->quote("$complete"),
00658 $ilDB->quote($this->id)
00659 );
00660 $result = $ilDB->query($query);
00661 $query = sprintf("UPDATE qpl_question_multiplechoice SET shuffle = %s WHERE question_fi = %s",
00662 $ilDB->quote("$this->shuffle"),
00663 $ilDB->quote($this->id . "")
00664 );
00665 $result = $ilDB->query($query);
00666 }
00667
00668 $combinedtext = $this->question;
00669
00670 if ($result == DB_OK)
00671 {
00672
00673
00674 $query = sprintf("DELETE FROM qpl_answer_multiplechoice 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
00684 $query = sprintf("INSERT INTO qpl_answer_multiplechoice (answer_id, question_fi, answertext, points, points_unchecked, aorder, imagefile) VALUES (NULL, %s, %s, %s, %s, %s, %s)",
00685 $ilDB->quote($this->id),
00686 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($answer_obj->getAnswertext(), 0)),
00687 $ilDB->quote($answer_obj->getPoints() . ""),
00688 $ilDB->quote($answer_obj->getPointsUnchecked() . ""),
00689 $ilDB->quote($answer_obj->getOrder() . ""),
00690 $ilDB->quote($answer_obj->getImage() . "")
00691 );
00692 $combinedtext .= $answer_obj->getAnswertext();
00693 $answer_result = $ilDB->query($query);
00694 }
00695 }
00696
00697
00698 ilRTE::_cleanupMediaObjectUsage($combinedtext, "qpl:html",
00699 $this->getId());
00700
00701 parent::saveToDb($original_id);
00702 }
00703
00713 function loadFromDb($question_id)
00714 {
00715 global $ilDB;
00716
00717 $hasimages = 0;
00718 $query = sprintf("SELECT qpl_questions.*, qpl_question_multiplechoice.* FROM qpl_questions, qpl_question_multiplechoice WHERE question_id = %s AND qpl_questions.question_id = qpl_question_multiplechoice.question_fi",
00719 $ilDB->quote($question_id));
00720 $result = $ilDB->query($query);
00721 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00722 {
00723 if ($result->numRows() == 1)
00724 {
00725 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00726 $this->id = $question_id;
00727 $this->title = $data->title;
00728 $this->comment = $data->comment;
00729 $this->solution_hint = $data->solution_hint;
00730 $this->original_id = $data->original_id;
00731 $this->obj_id = $data->obj_fi;
00732 $this->author = $data->author;
00733 $this->owner = $data->owner;
00734 $this->points = $data->points;
00735 include_once("./Services/RTE/classes/class.ilRTE.php");
00736 $this->question = ilRTE::_replaceMediaObjectImageSrc($data->question_text, 1);
00737 $this->setShuffle($data->shuffle);
00738 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00739 }
00740
00741 $query = sprintf("SELECT * FROM qpl_answer_multiplechoice WHERE question_fi = %s ORDER BY aorder ASC",
00742 $ilDB->quote($question_id));
00743
00744 $result = $ilDB->query($query);
00745
00746 include_once "./assessment/classes/class.assAnswerMultipleResponseImage.php";
00747 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00748 {
00749 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00750 {
00751 $imagefilename = $this->getImagePath() . $data->imagefile;
00752 if (!@file_exists($imagefilename))
00753 {
00754 $data->imagefile = "";
00755 }
00756 include_once("./Services/RTE/classes/class.ilRTE.php");
00757 $data->answertext = ilRTE::_replaceMediaObjectImageSrc($data->answertext, 1);
00758 if (strlen($data->imagefile)) $hasimages = 1;
00759 array_push($this->answers, new ASS_AnswerMultipleResponseImage($data->answertext, $data->points, $data->aorder, $data->points_unchecked, $data->imagefile));
00760 }
00761 }
00762 }
00763 $this->setGraphicalAnswerSetting($hasimages);
00764 parent::loadFromDb($question_id);
00765 }
00766
00774
00775
00776
00777
00778
00779
00787 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00788 {
00789 if ($this->id <= 0)
00790 {
00791
00792 return;
00793 }
00794
00795 $this_id = $this->getId();
00796 $clone = $this;
00797 include_once ("./assessment/classes/class.assQuestion.php");
00798 $original_id = assQuestion::_getOriginalId($this->id);
00799 $clone->id = -1;
00800 if ($title)
00801 {
00802 $clone->setTitle($title);
00803 }
00804
00805 if ($author)
00806 {
00807 $clone->setAuthor($author);
00808 }
00809 if ($owner)
00810 {
00811 $clone->setOwner($owner);
00812 }
00813
00814 if ($for_test)
00815 {
00816 $clone->saveToDb($original_id);
00817 }
00818 else
00819 {
00820 $clone->saveToDb();
00821 }
00822
00823
00824 $clone->copyPageOfQuestion($this_id);
00825
00826 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
00827
00828 $clone->duplicateImages($this_id);
00829
00830 return $clone->id;
00831 }
00832
00840 function copyObject($target_questionpool, $title = "")
00841 {
00842 if ($this->id <= 0)
00843 {
00844
00845 return;
00846 }
00847
00848 $clone = $this;
00849 include_once ("./assessment/classes/class.assQuestion.php");
00850 $original_id = assQuestion::_getOriginalId($this->id);
00851 $clone->id = -1;
00852 $source_questionpool = $this->getObjId();
00853 $clone->setObjId($target_questionpool);
00854 if ($title)
00855 {
00856 $clone->setTitle($title);
00857 }
00858 $clone->saveToDb();
00859
00860
00861 $clone->copyPageOfQuestion($original_id);
00862
00863 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
00864
00865 $clone->copyImages($original_id, $source_questionpool);
00866
00867 return $clone->id;
00868 }
00869
00879 function getQuestion()
00880 {
00881 return $this->question;
00882 }
00883
00893 function setQuestion($question = "")
00894 {
00895 $this->question = $question;
00896 }
00897
00907 function getOutputType()
00908 {
00909 return $this->output_type;
00910 }
00911
00921 function setOutputType($output_type = OUTPUT_ORDER)
00922 {
00923 $this->output_type = $output_type;
00924 }
00925
00941 function addAnswer(
00942 $answertext = "",
00943 $points = 0.0,
00944 $points_unchecked = 0.0,
00945 $order = 0,
00946 $answerimage = ""
00947 )
00948 {
00949 $found = -1;
00950 foreach ($this->answers as $key => $value)
00951 {
00952 if ($value->getOrder() == $order)
00953 {
00954 $found = $order;
00955 }
00956 }
00957 include_once "./assessment/classes/class.assAnswerMultipleResponseImage.php";
00958 if ($found >= 0)
00959 {
00960
00961 $answer = new ASS_AnswerMultipleResponseImage($answertext, $points, $found, $points_unchecked, $answerimage);
00962 array_push($this->answers, $answer);
00963 for ($i = $found + 1; $i < count($this->answers); $i++)
00964 {
00965 $this->answers[$i] = $this->answers[$i-1];
00966 }
00967 $this->answers[$found] = $answer;
00968 }
00969 else
00970 {
00971
00972 $answer = new ASS_AnswerMultipleResponseImage($answertext, $points, count($this->answers), $points_unchecked, $answerimage);
00973 array_push($this->answers, $answer);
00974 }
00975 }
00976
00986 function getAnswerCount()
00987 {
00988 return count($this->answers);
00989 }
00990
01002 function getAnswer($index = 0)
01003 {
01004 if ($index < 0) return NULL;
01005 if (count($this->answers) < 1) return NULL;
01006 if ($index >= count($this->answers)) return NULL;
01007
01008 return $this->answers[$index];
01009 }
01010
01021 function deleteAnswer($index = 0)
01022 {
01023 if ($index < 0) return;
01024 if (count($this->answers) < 1) return;
01025 if ($index >= count($this->answers)) return;
01026 $answer = $this->answers[$index];
01027 if (strlen($answer->getImage())) $this->deleteImage($answer->getImage());
01028 unset($this->answers[$index]);
01029 $this->answers = array_values($this->answers);
01030 for ($i = 0; $i < count($this->answers); $i++)
01031 {
01032 if ($this->answers[$i]->getOrder() > $index)
01033 {
01034 $this->answers[$i]->setOrder($i);
01035 }
01036 }
01037 }
01038
01047 function flushAnswers()
01048 {
01049 $this->answers = array();
01050 }
01051
01060 function getMaximumPoints()
01061 {
01062 $points = 0;
01063 $allpoints = 0;
01064 foreach ($this->answers as $key => $value)
01065 {
01066 if ($value->getPoints() > $value->getPointsUnchecked())
01067 {
01068 $allpoints += $value->getPoints();
01069 }
01070 else
01071 {
01072 $allpoints += $value->getPointsUnchecked();
01073 }
01074 }
01075 return $allpoints;
01076 }
01077
01089 function calculateReachedPoints($active_id, $pass = NULL)
01090 {
01091 global $ilDB;
01092
01093 $found_values = array();
01094 if (is_null($pass))
01095 {
01096 $pass = $this->getSolutionMaxPass($active_id);
01097 }
01098 $query = sprintf("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
01099 $ilDB->quote($active_id . ""),
01100 $ilDB->quote($this->getId() . ""),
01101 $ilDB->quote($pass . "")
01102 );
01103 $result = $ilDB->query($query);
01104 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01105 {
01106 if (strcmp($data->value1, "") != 0)
01107 {
01108 array_push($found_values, $data->value1);
01109 }
01110 }
01111 $points = 0;
01112 foreach ($this->answers as $key => $answer)
01113 {
01114 if (in_array($key, $found_values))
01115 {
01116 $points += $answer->getPoints();
01117 }
01118 else
01119 {
01120 $points += $answer->getPointsUnchecked();
01121 }
01122 }
01123
01124 include_once "./assessment/classes/class.ilObjTest.php";
01125 $mc_scoring = ilObjTest::_getMCScoring($active_id);
01126 if (($mc_scoring == 0) && (count($found_values) == 0))
01127 {
01128 $points = 0;
01129 }
01130 $points = parent::calculateReachedPoints($active_id, $pass = NULL, $points);
01131 return $points;
01132 }
01133
01144 function saveWorkingData($active_id, $pass = NULL)
01145 {
01146 global $ilDB;
01147 global $ilUser;
01148
01149 include_once "./assessment/classes/class.ilObjTest.php";
01150 $activepass = ilObjTest::_getPass($active_id);
01151
01152 $entered_values = 0;
01153 $query = sprintf("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
01154 $ilDB->quote($active_id . ""),
01155 $ilDB->quote($this->getId() . ""),
01156 $ilDB->quote($activepass . "")
01157 );
01158 $result = $ilDB->query($query);
01159 foreach ($_POST as $key => $value)
01160 {
01161 if (preg_match("/^multiple_choice_result_(\d+)/", $key, $matches))
01162 {
01163 if (strlen($value))
01164 {
01165 $query = sprintf("INSERT INTO tst_solutions (solution_id, active_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL, %s, NULL)",
01166 $ilDB->quote($active_id),
01167 $ilDB->quote($this->getId()),
01168 $ilDB->quote($value),
01169 $ilDB->quote($activepass . "")
01170 );
01171 $result = $ilDB->query($query);
01172 $entered_values++;
01173 }
01174 }
01175 }
01176 if ($entered_values)
01177 {
01178 include_once ("./classes/class.ilObjAssessmentFolder.php");
01179 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01180 {
01181 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
01182 }
01183 }
01184 else
01185 {
01186 include_once ("./classes/class.ilObjAssessmentFolder.php");
01187 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01188 {
01189 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
01190 }
01191 }
01192 parent::saveWorkingData($active_id, $pass);
01193 return true;
01194 }
01195
01196 function syncWithOriginal()
01197 {
01198 global $ilDB;
01199
01200 if ($this->original_id)
01201 {
01202 $complete = 0;
01203 if ($this->isComplete())
01204 {
01205 $complete = 1;
01206 }
01207 $estw_time = $this->getEstimatedWorkingTime();
01208 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01209
01210 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, points = %s, working_time=%s, complete = %s WHERE question_id = %s",
01211 $ilDB->quote($this->obj_id. ""),
01212 $ilDB->quote($this->title. ""),
01213 $ilDB->quote($this->comment. ""),
01214 $ilDB->quote($this->author. ""),
01215 $ilDB->quote($this->question. ""),
01216 $ilDB->quote($this->getMaximumPoints() . ""),
01217 $ilDB->quote($estw_time. ""),
01218 $ilDB->quote($complete. ""),
01219 $ilDB->quote($this->original_id. "")
01220 );
01221 $result = $ilDB->query($query);
01222 $query = sprintf("UPDATE qpl_question_multiplechoice SET shuffle = %s WHERE question_fi = %s",
01223 $ilDB->quote($this->shuffle. ""),
01224 $ilDB->quote($this->original_id . "")
01225 );
01226 $result = $ilDB->query($query);
01227
01228 if ($result == DB_OK)
01229 {
01230
01231
01232 $query = sprintf("DELETE FROM qpl_answer_multiplechoice WHERE question_fi = %s",
01233 $ilDB->quote($this->original_id)
01234 );
01235 $result = $ilDB->query($query);
01236 $points_unchecked = 0;
01237 foreach ($this->answers as $key => $value)
01238 {
01239 $answer_obj = $this->answers[$key];
01240 $points_unchecked = $answer_obj->getPointsUnchecked();
01241 $query = sprintf("INSERT INTO qpl_answer_multiplechoice (answer_id, question_fi, answertext, points, aorder, points_unchecked) VALUES (NULL, %s, %s, %s, %s, %s)",
01242 $ilDB->quote($this->original_id. ""),
01243 $ilDB->quote($answer_obj->getAnswertext(). ""),
01244 $ilDB->quote($answer_obj->getPoints() . ""),
01245 $ilDB->quote($answer_obj->getOrder() . ""),
01246 $ilDB->quote($points_unchecked . "")
01247 );
01248 $answer_result = $ilDB->query($query);
01249 }
01250 }
01251 parent::syncWithOriginal();
01252 }
01253 }
01254
01263 function getQuestionType()
01264 {
01265 $question_type = 2;
01266 return $question_type;
01267 }
01268
01277 function getAdditionalTableName()
01278 {
01279 return "qpl_question_multiplechoice";
01280 }
01281
01290 function getAnswerTableName()
01291 {
01292 return "qpl_answer_multiplechoice";
01293 }
01294
01295 function getGraphicalAnswerSetting()
01296 {
01297 global $ilUser;
01298
01299 $graphicalAnswerSetting = $ilUser->getPref("graphicalAnswerSetting");
01300 if ($graphicalAnswerSetting != 1)
01301 {
01302 $graphicalAnswerSetting = 0;
01303 }
01304 return $graphicalAnswerSetting;
01305 }
01306
01307 function setGraphicalAnswerSetting($a_setting = 0)
01308 {
01309 global $ilUser;
01310 $ilUser->writePref("graphicalAnswerSetting", $a_setting);
01311 }
01312
01323 function setImageFile($image_filename, $image_tempfilename = "")
01324 {
01325 $result = 0;
01326 if (!empty($image_tempfilename))
01327 {
01328 $image_filename = str_replace(" ", "_", $image_filename);
01329 $imagepath = $this->getImagePath();
01330 if (!file_exists($imagepath))
01331 {
01332 ilUtil::makeDirParents($imagepath);
01333 }
01334
01335 if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
01336 {
01337 $result = 2;
01338 }
01339 else
01340 {
01341 include_once "./content/classes/Media/class.ilObjMediaObject.php";
01342 $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
01343 if (!preg_match("/^image/", $mimetype))
01344 {
01345 unlink($imagepath . $image_filename);
01346 $result = 1;
01347 }
01348 else
01349 {
01350
01351 $thumbpath = $imagepath . $image_filename . "." . "thumb.jpg";
01352 ilUtil::convertImage($imagepath.$image_filename, $thumbpath, "JPEG", 100);
01353 }
01354 }
01355 }
01356 return $result;
01357 }
01358
01367 function deleteImage($image_filename)
01368 {
01369 $imagepath = $this->getImagePath();
01370 unlink($imagepath . $image_filename);
01371 $thumbpath = $imagepath . $image_filename . "." . "thumb.jpg";
01372 unlink($thumbpath);
01373 }
01374
01375 function duplicateImages($question_id)
01376 {
01377 global $ilLog;
01378 $imagepath = $this->getImagePath();
01379 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
01380 if (!file_exists($imagepath))
01381 {
01382 ilUtil::makeDirParents($imagepath);
01383 }
01384 foreach ($this->answers as $answer)
01385 {
01386 $filename = $answer->getImage();
01387 if (strlen($filename))
01388 {
01389 if (!copy($imagepath_original . $filename, $imagepath . $filename))
01390 {
01391 $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
01392 $ilLog->write("object: " . print_r($this), $ilLog->ERROR);
01393 }
01394 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg"))
01395 {
01396 $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
01397 $ilLog->write("object: " . print_r($this), $ilLog->ERROR);
01398 }
01399 }
01400 }
01401 }
01402
01403 function copyImages($question_id, $source_questionpool)
01404 {
01405 global $ilLog;
01406 $imagepath = $this->getImagePath();
01407 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
01408 $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
01409 if (!file_exists($imagepath))
01410 {
01411 ilUtil::makeDirParents($imagepath);
01412 }
01413 foreach ($this->answers as $answer)
01414 {
01415 $filename = $answer->getImage();
01416 if (strlen($filename))
01417 {
01418 if (!copy($imagepath_original . $filename, $imagepath . $filename))
01419 {
01420 $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
01421 $ilLog->write("object: " . print_r($this), $ilLog->ERROR);
01422 }
01423 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg"))
01424 {
01425 $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
01426 $ilLog->write("object: " . print_r($this), $ilLog->ERROR);
01427 }
01428 }
01429 }
01430 }
01431
01432 }
01433
01434 ?>