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 ASS_OrderingQuestion extends ASS_Question
00038 {
00046 var $question;
00047
00055 var $answers;
00056
00065 var $ordering_type;
00066
00079 function ASS_OrderingQuestion (
00080 $title = "",
00081 $comment = "",
00082 $author = "",
00083 $owner = -1,
00084 $question = "",
00085 $ordering_type = OQ_TERMS
00086 )
00087 {
00088 $this->ASS_Question($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
00123 function to_xml($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
00124 {
00125 global $ilDB;
00126 global $ilUser;
00127
00128 include_once("./classes/class.ilXmlWriter.php");
00129 $a_xml_writer = new ilXmlWriter;
00130
00131 $a_xml_writer->xmlHeader();
00132 $a_xml_writer->xmlStartTag("questestinterop");
00133 $attrs = array(
00134 "ident" => "il_".IL_INST_ID."_qst_".$this->getId(),
00135 "title" => $this->getTitle()
00136 );
00137 $a_xml_writer->xmlStartTag("item", $attrs);
00138
00139 $a_xml_writer->xmlElement("qticomment", NULL, $this->getComment());
00140
00141 $workingtime = $this->getEstimatedWorkingTime();
00142 $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]);
00143 $a_xml_writer->xmlElement("duration", NULL, $duration);
00144
00145 $a_xml_writer->xmlStartTag("itemmetadata");
00146 $a_xml_writer->xmlStartTag("qtimetadata");
00147 $a_xml_writer->xmlStartTag("qtimetadatafield");
00148 $a_xml_writer->xmlElement("fieldlabel", NULL, "ILIAS_VERSION");
00149 $a_xml_writer->xmlElement("fieldentry", NULL, $this->ilias->getSetting("ilias_version"));
00150 $a_xml_writer->xmlEndTag("qtimetadatafield");
00151 $a_xml_writer->xmlStartTag("qtimetadatafield");
00152 $a_xml_writer->xmlElement("fieldlabel", NULL, "QUESTIONTYPE");
00153 $a_xml_writer->xmlElement("fieldentry", NULL, ORDERING_QUESTION_IDENTIFIER);
00154 $a_xml_writer->xmlEndTag("qtimetadatafield");
00155 $a_xml_writer->xmlStartTag("qtimetadatafield");
00156 $a_xml_writer->xmlElement("fieldlabel", NULL, "AUTHOR");
00157 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getAuthor());
00158 $a_xml_writer->xmlEndTag("qtimetadatafield");
00159 $a_xml_writer->xmlEndTag("qtimetadata");
00160 $a_xml_writer->xmlEndTag("itemmetadata");
00161
00162
00163 $attrs = array(
00164 "label" => $this->getTitle()
00165 );
00166 $a_xml_writer->xmlStartTag("presentation", $attrs);
00167
00168 $a_xml_writer->xmlStartTag("flow");
00169
00170 $a_xml_writer->xmlStartTag("material");
00171 $a_xml_writer->xmlElement("mattext", NULL, $this->get_question());
00172 $a_xml_writer->xmlEndTag("material");
00173
00174 $attrs = array();
00175 if ($this->get_ordering_type() == OQ_PICTURES)
00176 {
00177 $attrs = array(
00178 "ident" => "OQP",
00179 "rcardinality" => "Ordered"
00180 );
00181 }
00182 else
00183 {
00184 $attrs = array(
00185 "ident" => "OQT",
00186 "rcardinality" => "Ordered"
00187 );
00188 }
00189 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00190 {
00191 $attrs["output"] = "javascript";
00192 }
00193 $a_xml_writer->xmlStartTag("response_lid", $attrs);
00194 $solution = $this->getSuggestedSolution(0);
00195 if (count($solution))
00196 {
00197 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00198 {
00199 $a_xml_writer->xmlStartTag("material");
00200 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00201 if (strcmp($matches[1], "") != 0)
00202 {
00203 $intlink = $solution["internal_link"];
00204 }
00205 $attrs = array(
00206 "label" => "suggested_solution"
00207 );
00208 $a_xml_writer->xmlElement("mattext", $attrs, $intlink);
00209 $a_xml_writer->xmlEndTag("material");
00210 }
00211 }
00212
00213 $attrs = array();
00214 if ($this->getShuffle())
00215 {
00216 $attrs = array(
00217 "shuffle" => "Yes"
00218 );
00219 }
00220 else
00221 {
00222 $attrs = array(
00223 "shuffle" => "No"
00224 );
00225 }
00226 $a_xml_writer->xmlStartTag("render_choice", $attrs);
00227
00228 $akeys = array_keys($this->answers);
00229 if ($this->getshuffle() && $a_shuffle)
00230 {
00231 $akeys = $this->pcArrayShuffle($akeys);
00232 }
00233
00234 if ($test_output)
00235 {
00236 include_once "./assessment/classes/class.ilObjTest.php";
00237 if (ilObjTest::_getHidePreviousResults($test_output, true))
00238 {
00239 $pass = ilObjTest::_getPass($ilUser->id, $test_output);
00240 }
00241 else
00242 {
00243 $pass = $this->getSolutionMaxPass($user_id, $test_output);
00244 }
00245
00246 $query = sprintf("SELECT * FROM tst_solutions WHERE test_fi = %s AND user_fi = %s AND question_fi = %s AND pass = %s ORDER BY value2",
00247 $ilDB->quote($test_output . ""),
00248 $ilDB->quote($ilUser->id . ""),
00249 $ilDB->quote($this->getId() . ""),
00250 $ilDB->quote($pass . "")
00251 );
00252 $queryres = $ilDB->query($query);
00253 if ($queryres->numRows() == count($this->answers))
00254 {
00255
00256
00257
00258
00259
00260 }
00261 }
00262
00263
00264 foreach ($akeys as $index)
00265 {
00266 $answer = $this->answers[$index];
00267 $attrs = array(
00268 "ident" => $index
00269 );
00270 $a_xml_writer->xmlStartTag("response_label", $attrs);
00271 $a_xml_writer->xmlStartTag("material");
00272 if ($this->get_ordering_type() == OQ_PICTURES)
00273 {
00274 if ($force_image_references)
00275 {
00276 $attrs = array(
00277 "imagtype" => $imagetype,
00278 "label" => $answer->get_answertext(),
00279 "uri" => $this->getImagePathWeb() . $answer->get_answertext()
00280 );
00281 $a_xml_writer->xmlElement("matimage", $attrs);
00282 }
00283 else
00284 {
00285 $imagepath = $this->getImagePath() . $answer->get_answertext();
00286 $fh = @fopen($imagepath, "rb");
00287 if ($fh != false)
00288 {
00289 $imagefile = fread($fh, filesize($imagepath));
00290 fclose($fh);
00291 $base64 = base64_encode($imagefile);
00292 $imagetype = "image/jpeg";
00293 if (preg_match("/.*\.(png|gif)$/", $answer->get_answertext(), $matches))
00294 {
00295 $imagetype = "image/".$matches[1];
00296 }
00297 $attrs = array(
00298 "imagtype" => $imagetype,
00299 "label" => $answer->get_answertext(),
00300 "embedded" => "base64"
00301 );
00302 $a_xml_writer->xmlElement("matimage", $attrs, $base64, FALSE, FALSE);
00303 }
00304 }
00305 }
00306 else
00307 {
00308 $a_xml_writer->xmlElement("mattext", NULL, $answer->get_answertext());
00309 }
00310 $a_xml_writer->xmlEndTag("material");
00311 $a_xml_writer->xmlEndTag("response_label");
00312 }
00313 $a_xml_writer->xmlEndTag("render_choice");
00314 $a_xml_writer->xmlEndTag("response_lid");
00315 $a_xml_writer->xmlEndTag("flow");
00316 $a_xml_writer->xmlEndTag("presentation");
00317
00318
00319 $a_xml_writer->xmlStartTag("resprocessing");
00320 $a_xml_writer->xmlStartTag("outcomes");
00321 $a_xml_writer->xmlStartTag("decvar");
00322 $a_xml_writer->xmlEndTag("decvar");
00323 $a_xml_writer->xmlEndTag("outcomes");
00324
00325 foreach ($this->answers as $index => $answer)
00326 {
00327 $attrs = array(
00328 "continue" => "Yes"
00329 );
00330 $a_xml_writer->xmlStartTag("respcondition", $attrs);
00331
00332 $a_xml_writer->xmlStartTag("conditionvar");
00333 $attrs = array();
00334 if ($this->get_ordering_type() == OQ_PICTURES)
00335 {
00336 $attrs = array(
00337 "respident" => "OQP"
00338 );
00339 }
00340 else
00341 {
00342 $attrs = array(
00343 "respident" => "OQT"
00344 );
00345 }
00346 $attrs["index"] = $answer->get_solution_order();
00347 $a_xml_writer->xmlElement("varequal", $attrs, $index);
00348 $a_xml_writer->xmlEndTag("conditionvar");
00349
00350 $attrs = array(
00351 "action" => "Add"
00352 );
00353 $a_xml_writer->xmlElement("setvar", $attrs, $answer->get_points());
00354
00355 $attrs = array(
00356 "feedbacktype" => "Response",
00357 "linkrefid" => "link_$index"
00358 );
00359 $a_xml_writer->xmlElement("displayfeedback", $attrs);
00360 $a_xml_writer->xmlEndTag("respcondition");
00361 }
00362 $a_xml_writer->xmlEndTag("resprocessing");
00363
00364
00365 foreach ($this->answers as $index => $answer)
00366 {
00367 $attrs = array(
00368 "ident" => "link_$index",
00369 "view" => "All"
00370 );
00371 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
00372
00373 $a_xml_writer->xmlStartTag("flow_mat");
00374 $a_xml_writer->xmlStartTag("material");
00375 $a_xml_writer->xmlElement("mattext");
00376 $a_xml_writer->xmlEndTag("material");
00377 $a_xml_writer->xmlEndTag("flow_mat");
00378 $a_xml_writer->xmlEndTag("itemfeedback");
00379 }
00380
00381 $a_xml_writer->xmlEndTag("item");
00382 $a_xml_writer->xmlEndTag("questestinterop");
00383
00384 $xml = $a_xml_writer->xmlDumpMem(FALSE);
00385 if (!$a_include_header)
00386 {
00387 $pos = strpos($xml, "?>");
00388 $xml = substr($xml, $pos + 2);
00389 }
00390 return $xml;
00391 }
00392
00393
00402 function saveToDb($original_id = "")
00403 {
00404 global $ilias;
00405
00406 $db =& $ilias->db;
00407 $complete = 0;
00408 if ($this->isComplete())
00409 {
00410 $complete = 1;
00411 }
00412
00413 $estw_time = $this->getEstimatedWorkingTime();
00414 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00415
00416 if ($original_id)
00417 {
00418 $original_id = $db->quote($original_id);
00419 }
00420 else
00421 {
00422 $original_id = "NULL";
00423 }
00424
00425 if ($this->id == -1)
00426 {
00427
00428 $now = getdate();
00429 $question_type = $this->getQuestionType();
00430 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00431 $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, ordering_type, points, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00432 $db->quote($question_type . ""),
00433 $db->quote($this->obj_id . ""),
00434 $db->quote($this->title . ""),
00435 $db->quote($this->comment . ""),
00436 $db->quote($this->author . ""),
00437 $db->quote($this->owner . ""),
00438 $db->quote($this->question . ""),
00439 $db->quote($estw_time . ""),
00440 $db->quote($this->ordering_type . ""),
00441 $db->quote($this->getMaximumPoints() . ""),
00442 $db->quote($complete . ""),
00443 $db->quote($created . ""),
00444 $original_id
00445 );
00446 $result = $db->query($query);
00447 if ($result == DB_OK)
00448 {
00449 $this->id = $this->ilias->db->getLastInsertId();
00450
00451
00452 $this->createPageObject();
00453
00454
00455 if ($this->getTestId() > 0)
00456 {
00457 $this->insertIntoTest($this->getTestId());
00458 }
00459 }
00460 }
00461 else
00462 {
00463
00464 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, ordering_type = %s, points = %s, complete = %s WHERE question_id = %s",
00465 $db->quote($this->obj_id. ""),
00466 $db->quote($this->title . ""),
00467 $db->quote($this->comment . ""),
00468 $db->quote($this->author . ""),
00469 $db->quote($this->question . ""),
00470 $db->quote($estw_time . ""),
00471 $db->quote($this->ordering_type . ""),
00472 $db->quote($this->getMaximumPoints() . ""),
00473 $db->quote($complete . ""),
00474 $db->quote($this->id . "")
00475 );
00476 $result = $db->query($query);
00477 }
00478 if ($result == DB_OK)
00479 {
00480
00481
00482 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00483 $db->quote($this->id)
00484 );
00485 $result = $db->query($query);
00486
00487
00488 foreach ($this->answers as $key => $value)
00489 {
00490 $answer_obj = $this->answers[$key];
00491 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, solution_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
00492 $db->quote($this->id),
00493 $db->quote($answer_obj->get_answertext() . ""),
00494 $db->quote($answer_obj->get_points() . ""),
00495 $db->quote($answer_obj->get_order() . ""),
00496 $db->quote($answer_obj->get_solution_order() . "")
00497 );
00498 $answer_result = $db->query($query);
00499 }
00500 }
00501 parent::saveToDb($original_id);
00502 }
00503
00513 function loadFromDb($question_id)
00514 {
00515 global $ilias;
00516 $db =& $ilias->db;
00517
00518 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00519 $db->quote($question_id)
00520 );
00521 $result = $db->query($query);
00522 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00523 {
00524 if ($result->numRows() == 1)
00525 {
00526 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00527 $this->id = $question_id;
00528 $this->title = $data->title;
00529 $this->obj_id = $data->obj_fi;
00530 $this->comment = $data->comment;
00531 $this->original_id = $data->original_id;
00532 $this->author = $data->author;
00533 $this->owner = $data->owner;
00534 $this->question = $data->question_text;
00535 $this->solution_hint = $data->solution_hint;
00536 $this->ordering_type = $data->ordering_type;
00537 $this->points = $data->points;
00538 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00539 }
00540
00541 $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY aorder ASC",
00542 $db->quote($question_id)
00543 );
00544 $result = $db->query($query);
00545 include_once "./assessment/classes/class.assAnswerOrdering.php";
00546 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00547 {
00548 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00549 {
00550 array_push($this->answers, new ASS_AnswerOrdering($data->answertext, $data->points, $data->aorder, $data->solution_order));
00551 }
00552 }
00553 }
00554 parent::loadFromDb($question_id);
00555 }
00556
00564 function addAnswer($answertext, $points, $answerorder, $solutionorder)
00565 {
00566 include_once "./assessment/classes/class.assAnswerOrdering.php";
00567 array_push($this->answers, new ASS_AnswerOrdering($answertext, $points, $answerorder, $solutionorder));
00568 }
00569
00577 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00578 {
00579 if ($this->id <= 0)
00580 {
00581
00582 return;
00583 }
00584
00585 $this_id = $this->getId();
00586 $clone = $this;
00587 include_once ("./assessment/classes/class.assQuestion.php");
00588 $original_id = ASS_Question::_getOriginalId($this->id);
00589 $clone->id = -1;
00590 if ($title)
00591 {
00592 $clone->setTitle($title);
00593 }
00594 if ($author)
00595 {
00596 $clone->setAuthor($author);
00597 }
00598 if ($owner)
00599 {
00600 $clone->setOwner($owner);
00601 }
00602 if ($for_test)
00603 {
00604 $clone->saveToDb($original_id);
00605 }
00606 else
00607 {
00608 $clone->saveToDb();
00609 }
00610
00611
00612 $clone->copyPageOfQuestion($this_id);
00613
00614
00615 $clone->duplicateImages($this_id);
00616 return $clone->id;
00617 }
00618
00626 function copyObject($target_questionpool, $title = "")
00627 {
00628 if ($this->id <= 0)
00629 {
00630
00631 return;
00632 }
00633
00634 $clone = $this;
00635 include_once ("./assessment/classes/class.assQuestion.php");
00636 $original_id = ASS_Question::_getOriginalId($this->id);
00637 $clone->id = -1;
00638 $source_questionpool = $this->getObjId();
00639 $clone->setObjId($target_questionpool);
00640 if ($title)
00641 {
00642 $clone->setTitle($title);
00643 }
00644
00645 $clone->saveToDb();
00646
00647
00648 $clone->copyPageOfQuestion($original_id);
00649
00650
00651 $clone->copyImages($original_id, $source_questionpool);
00652 return $clone->id;
00653 }
00654
00655 function duplicateImages($question_id)
00656 {
00657 if ($this->get_ordering_type() == OQ_PICTURES)
00658 {
00659 $imagepath = $this->getImagePath();
00660 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00661 if (!file_exists($imagepath)) {
00662 ilUtil::makeDirParents($imagepath);
00663 }
00664 foreach ($this->answers as $answer)
00665 {
00666 $filename = $answer->get_answertext();
00667 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
00668 print "image could not be duplicated!!!! ";
00669 }
00670 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg")) {
00671 print "image thumbnail could not be duplicated!!!! ";
00672 }
00673 }
00674 }
00675 }
00676
00677 function copyImages($question_id, $source_questionpool)
00678 {
00679 if ($this->get_ordering_type() == OQ_PICTURES)
00680 {
00681 $imagepath = $this->getImagePath();
00682 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00683 $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
00684 if (!file_exists($imagepath)) {
00685 ilUtil::makeDirParents($imagepath);
00686 }
00687 foreach ($this->answers as $answer)
00688 {
00689 $filename = $answer->get_answertext();
00690 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
00691 print "image could not be copied!!!! ";
00692 }
00693 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg")) {
00694 print "image thumbnail could not be copied!!!! ";
00695 }
00696 }
00697 }
00698 }
00699
00709 function set_question($question = "")
00710 {
00711 $this->question = $question;
00712 }
00713
00723 function set_ordering_type($ordering_type = OQ_TERMS)
00724 {
00725 $this->ordering_type = $ordering_type;
00726 }
00727
00737 function get_question()
00738 {
00739 return $this->question;
00740 }
00741
00751 function get_ordering_type()
00752 {
00753 return $this->ordering_type;
00754 }
00755
00771 function add_answer(
00772 $answertext = "",
00773 $points = 0.0,
00774 $order = 0,
00775 $solution_order = 0
00776 )
00777 {
00778 $found = -1;
00779 foreach ($this->answers as $key => $value)
00780 {
00781 if ($value->get_order() == $order)
00782 {
00783 $found = $order;
00784 }
00785 }
00786 include_once "./assessment/classes/class.assAnswerOrdering.php";
00787 if ($found >= 0)
00788 {
00789
00790 $answer = new ASS_AnswerOrdering($answertext, $points, $found, $solution_order);
00791 array_push($this->answers, $answer);
00792 for ($i = $found + 1; $i < count($this->answers); $i++)
00793 {
00794 $this->answers[$i] = $this->answers[$i-1];
00795 }
00796 $this->answers[$found] = $answer;
00797 }
00798 else
00799 {
00800
00801 $answer = new ASS_AnswerOrdering($answertext, $points,
00802 count($this->answers), $solution_order);
00803 array_push($this->answers, $answer);
00804 }
00805 }
00806
00818 function get_answer($index = 0)
00819 {
00820 if ($index < 0) return NULL;
00821 if (count($this->answers) < 1) return NULL;
00822 if ($index >= count($this->answers)) return NULL;
00823 return $this->answers[$index];
00824 }
00825
00836 function delete_answer($index = 0)
00837 {
00838 if ($index < 0)
00839 {
00840 return;
00841 }
00842 if (count($this->answers) < 1)
00843 {
00844 return;
00845 }
00846 if ($index >= count($this->answers))
00847 {
00848 return;
00849 }
00850 unset($this->answers[$index]);
00851 $this->answers = array_values($this->answers);
00852 for ($i = 0; $i < count($this->answers); $i++)
00853 {
00854 if ($this->answers[$i]->get_order() > $index)
00855 {
00856 $this->answers[$i]->set_order($i);
00857 }
00858 }
00859 }
00860
00869 function flush_answers()
00870 {
00871 $this->answers = array();
00872 }
00873
00883 function get_answer_count()
00884 {
00885 return count($this->answers);
00886 }
00887
00896 function get_max_solution_order()
00897 {
00898 if (count($this->answers) == 0)
00899 {
00900 $max = 0;
00901 }
00902 else
00903 {
00904 $max = $this->answers[0]->get_solution_order();
00905 }
00906 foreach ($this->answers as $key => $value)
00907 {
00908 if ($value->get_solution_order() > $max)
00909 {
00910 $max = $value->get_solution_order();
00911 }
00912 }
00913 return $max;
00914 }
00915
00927 function calculateReachedPoints($user_id, $test_id, $pass = NULL)
00928 {
00929 global $ilDB;
00930
00931 $found_value1 = array();
00932 $found_value2 = array();
00933 if (is_null($pass))
00934 {
00935 $pass = $this->getSolutionMaxPass($user_id, $test_id);
00936 }
00937 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
00938 $ilDB->quote($user_id . ""),
00939 $ilDB->quote($test_id . ""),
00940 $ilDB->quote($this->getId() . ""),
00941 $ilDB->quote($pass . "")
00942 );
00943 $result = $ilDB->query($query);
00944 $user_order = array();
00945 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00946 {
00947 if ((strcmp($data->value1, "") != 0) && (strcmp($data->value2, "") != 0))
00948 {
00949 $user_order[$data->value2] = $data->value1;
00950 }
00951 }
00952 ksort($user_order);
00953 $user_order = array_values($user_order);
00954 $answer_order = array();
00955 foreach ($this->answers as $key => $answer)
00956 {
00957 $answer_order[$answer->get_solution_order()] = $key;
00958 }
00959 ksort($answer_order);
00960 $answer_order = array_values($answer_order);
00961 $points = 0;
00962 foreach ($answer_order as $index => $answer_id)
00963 {
00964 if (strcmp($user_order[$index], "") != 0)
00965 {
00966 if ($answer_id == $user_order[$index])
00967 {
00968 $points += $this->answers[$answer_id]->get_points();
00969 }
00970 }
00971 }
00972
00973
00974 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
00975 $ilDB->quote($test_id)
00976 );
00977 $result = $ilDB->query($query);
00978 if ($result->numRows() == 1)
00979 {
00980 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00981 if ($row["count_system"] == 1)
00982 {
00983 if ($points != $this->getMaximumPoints())
00984 {
00985 $points = 0;
00986 }
00987 }
00988 }
00989 else
00990 {
00991 $points = 0;
00992 }
00993 return $points;
00994 }
00995
01005 function getReachedInformation($user_id, $test_id, $pass = NULL)
01006 {
01007 $found_value1 = array();
01008 $found_value2 = array();
01009 if (is_null($pass))
01010 {
01011 $pass = $this->getSolutionMaxPass($user_id, $test_id);
01012 }
01013 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
01014 $this->ilias->db->quote($user_id . ""),
01015 $this->ilias->db->quote($test_id . ""),
01016 $this->ilias->db->quote($this->getId() . ""),
01017 $this->ilias->db->quote($pass . "")
01018 );
01019 $result = $this->ilias->db->query($query);
01020 $user_result = array();
01021 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01022 {
01023 $solution = array(
01024 "answer_id" => $data->value1,
01025 "order" => $data->value2
01026 );
01027 $user_result[$data->value1] = $solution;
01028 }
01029 return $user_result;
01030 }
01031
01040 function getMaximumPoints()
01041 {
01042 $points = 0;
01043 foreach ($this->answers as $key => $value)
01044 {
01045 $points += $value->get_points();
01046 }
01047 return $points;
01048 }
01049
01060 function set_image_file($image_filename, $image_tempfilename = "")
01061 {
01062 $result = 0;
01063 if (!empty($image_tempfilename))
01064 {
01065 $image_filename = str_replace(" ", "_", $image_filename);
01066 $imagepath = $this->getImagePath();
01067 if (!file_exists($imagepath))
01068 {
01069 ilUtil::makeDirParents($imagepath);
01070 }
01071 if (!ilUtil::moveUploadedFile($image_tempfilename,$image_filename, $imagepath.$image_filename))
01072 {
01073 $result = 2;
01074 }
01075 else
01076 {
01077 include_once "./content/classes/Media/class.ilObjMediaObject.php";
01078 $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
01079 if (!preg_match("/^image/", $mimetype))
01080 {
01081 unlink($imagepath . $image_filename);
01082 $result = 1;
01083 }
01084 else
01085 {
01086
01087 $thumbpath = $imagepath . $image_filename . "." . "thumb.jpg";
01088 ilUtil::convertImage($imagepath.$image_filename, $thumbpath, strtoupper($extension), 100);
01089 }
01090 }
01091 }
01092 return $result;
01093 }
01094
01104 function checkSaveData()
01105 {
01106 $result = true;
01107 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
01108 {
01109 if (strlen($_POST["orderresult"]))
01110 {
01111 return $result;
01112 }
01113 }
01114 $order_values = array();
01115 foreach ($_POST as $key => $value)
01116 {
01117 if (preg_match("/^order_(\d+)/", $key, $matches))
01118 {
01119 if (strcmp($value, "") != 0)
01120 {
01121 array_push($order_values, $value);
01122 }
01123 }
01124 }
01125 $check_order = array_flip($order_values);
01126 if (count($check_order) != count($order_values))
01127 {
01128
01129 $result = false;
01130 sendInfo($this->lng->txt("duplicate_order_values_entered"), TRUE);
01131 }
01132 return $result;
01133 }
01134
01145 function saveWorkingData($test_id, $pass = NULL)
01146 {
01147 global $ilDB;
01148 global $ilUser;
01149
01150 $saveWorkingDataResult = $this->checkSaveData();
01151 $entered_values = 0;
01152 if ($saveWorkingDataResult)
01153 {
01154 $db =& $ilDB->db;
01155
01156 include_once "./assessment/classes/class.ilObjTest.php";
01157 $activepass = ilObjTest::_getPass($ilUser->id, $test_id);
01158
01159 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
01160 $db->quote($ilUser->id . ""),
01161 $db->quote($test_id . ""),
01162 $db->quote($this->getId() . ""),
01163 $db->quote($activepass . "")
01164 );
01165 $result = $db->query($query);
01166 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
01167 {
01168 $orderresult = $_POST["orderresult"];
01169 if (strlen($orderresult))
01170 {
01171 $orderarray = explode(":", $orderresult);
01172 $ordervalue = 1;
01173 foreach ($orderarray as $index)
01174 {
01175 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
01176 $db->quote($ilUser->id . ""),
01177 $db->quote($test_id . ""),
01178 $db->quote($this->getId() . ""),
01179 $db->quote($index . ""),
01180 $db->quote($ordervalue . ""),
01181 $db->quote($activepass . "")
01182 );
01183 $result = $db->query($query);
01184 $ordervalue++;
01185 $entered_values++;
01186 }
01187 }
01188 }
01189 else
01190 {
01191 foreach ($_POST as $key => $value)
01192 {
01193 if (preg_match("/^order_(\d+)/", $key, $matches))
01194 {
01195 if (!(preg_match("/initial_value_\d+/", $value)))
01196 {
01197 if (strlen($value))
01198 {
01199 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
01200 $db->quote($ilUser->id . ""),
01201 $db->quote($test_id . ""),
01202 $db->quote($this->getId() . ""),
01203 $db->quote($matches[1] . ""),
01204 $db->quote($value . ""),
01205 $db->quote($activepass . "")
01206 );
01207 $result = $db->query($query);
01208 $entered_values++;
01209 }
01210 }
01211 }
01212 }
01213 }
01214 }
01215 if ($entered_values)
01216 {
01217 include_once ("./classes/class.ilObjAssessmentFolder.php");
01218 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01219 {
01220 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $test_id, $this->getId());
01221 }
01222 }
01223 else
01224 {
01225 include_once ("./classes/class.ilObjAssessmentFolder.php");
01226 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01227 {
01228 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $test_id, $this->getId());
01229 }
01230 }
01231 parent::saveWorkingData($test_id, $pass);
01232 return $saveWorkingDataResult;
01233 }
01234
01235 function syncWithOriginal()
01236 {
01237 global $ilias;
01238 if ($this->original_id)
01239 {
01240 $complete = 0;
01241 if ($this->isComplete())
01242 {
01243 $complete = 1;
01244 }
01245 $db = & $ilias->db;
01246
01247 $estw_time = $this->getEstimatedWorkingTime();
01248 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01249
01250 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, ordering_type = %s, points = %s, complete = %s WHERE question_id = %s",
01251 $db->quote($this->obj_id. ""),
01252 $db->quote($this->title . ""),
01253 $db->quote($this->comment . ""),
01254 $db->quote($this->author . ""),
01255 $db->quote($this->question . ""),
01256 $db->quote($estw_time . ""),
01257 $db->quote($this->ordering_type . ""),
01258 $db->quote($this->getMaximumPoints() . ""),
01259 $db->quote($complete . ""),
01260 $db->quote($this->original_id . "")
01261 );
01262 $result = $db->query($query);
01263
01264 if ($result == DB_OK)
01265 {
01266
01267
01268 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01269 $db->quote($this->original_id)
01270 );
01271 $result = $db->query($query);
01272
01273 foreach ($this->answers as $key => $value)
01274 {
01275 $answer_obj = $this->answers[$key];
01276 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, solution_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01277 $db->quote($this->original_id . ""),
01278 $db->quote($answer_obj->get_answertext() . ""),
01279 $db->quote($answer_obj->get_points() . ""),
01280 $db->quote($answer_obj->get_order() . ""),
01281 $db->quote($answer_obj->get_solution_order() . "")
01282 );
01283 $answer_result = $db->query($query);
01284 }
01285 }
01286 parent::syncWithOriginal();
01287 }
01288 }
01289
01290 function pc_array_shuffle($array) {
01291 mt_srand((double)microtime()*1000000);
01292 $i = count($array);
01293 while(--$i)
01294 {
01295 $j = mt_rand(0, $i);
01296 if ($i != $j)
01297 {
01298
01299 $tmp = $array[$j];
01300 $array[$j] = $array[$i];
01301 $array[$i] = $tmp;
01302 }
01303 }
01304 return $array;
01305 }
01306
01307 function createRandomSolution($test_id, $user_id, $pass = NULL)
01308 {
01309 global $ilDB;
01310 global $ilUser;
01311
01312 $db =& $ilDB->db;
01313
01314 if (is_null($pass))
01315 {
01316 $pass = $this->getSolutionMaxPass($user_id, $test_id);
01317 }
01318
01319 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
01320 $db->quote($user_id . ""),
01321 $db->quote($test_id . ""),
01322 $db->quote($this->getId() . ""),
01323 $db->quote($pass . "")
01324 );
01325 $result = $db->query($query);
01326
01327 $orders = range(1, count($this->answers));
01328 $orders = $this->pc_array_shuffle($orders);
01329 foreach ($this->answers as $key => $value)
01330 {
01331 $query = sprintf("INSERT INTO tst_solutions (solution_id, user_fi, test_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
01332 $db->quote($user_id . ""),
01333 $db->quote($test_id . ""),
01334 $db->quote($this->getId() . ""),
01335 $db->quote($key . ""),
01336 $db->quote(array_pop($orders) . ""),
01337 $db->quote($pass . "")
01338 );
01339 $result = $db->query($query);
01340 }
01341 }
01342
01351 function getQuestionType()
01352 {
01353 return 5;
01354 }
01355 }
01356
01357 ?>