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_MatchingQuestion extends ASS_Question
00038 {
00046 var $question;
00047
00055 var $matchingpairs;
00056
00065 var $matching_type;
00066
00079 function ASS_MatchingQuestion (
00080 $title = "",
00081 $comment = "",
00082 $author = "",
00083 $owner = -1,
00084 $question = "",
00085 $matching_type = MT_TERMS_DEFINITIONS
00086 )
00087 {
00088 $this->ASS_Question($title, $comment, $author, $owner);
00089 $this->matchingpairs = array();
00090 $this->question = $question;
00091 $this->matching_type = $matching_type;
00092 }
00093
00102 function isComplete()
00103 {
00104 if (($this->title) and ($this->author) and ($this->question) and (count($this->matchingpairs)) 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 include_once("./classes/class.ilXmlWriter.php");
00126 $a_xml_writer = new ilXmlWriter;
00127
00128 $a_xml_writer->xmlHeader();
00129 $a_xml_writer->xmlStartTag("questestinterop");
00130 $attrs = array(
00131 "ident" => "il_".IL_INST_ID."_qst_".$this->getId(),
00132 "title" => $this->getTitle()
00133 );
00134 $a_xml_writer->xmlStartTag("item", $attrs);
00135
00136 $a_xml_writer->xmlElement("qticomment", NULL, $this->getComment());
00137
00138 $workingtime = $this->getEstimatedWorkingTime();
00139 $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]);
00140 $a_xml_writer->xmlElement("duration", NULL, $duration);
00141
00142 $a_xml_writer->xmlStartTag("itemmetadata");
00143 $a_xml_writer->xmlStartTag("qtimetadata");
00144 $a_xml_writer->xmlStartTag("qtimetadatafield");
00145 $a_xml_writer->xmlElement("fieldlabel", NULL, "ILIAS_VERSION");
00146 $a_xml_writer->xmlElement("fieldentry", NULL, $this->ilias->getSetting("ilias_version"));
00147 $a_xml_writer->xmlEndTag("qtimetadatafield");
00148 $a_xml_writer->xmlStartTag("qtimetadatafield");
00149 $a_xml_writer->xmlElement("fieldlabel", NULL, "QUESTIONTYPE");
00150 $a_xml_writer->xmlElement("fieldentry", NULL, MATCHING_QUESTION_IDENTIFIER);
00151 $a_xml_writer->xmlEndTag("qtimetadatafield");
00152 $a_xml_writer->xmlStartTag("qtimetadatafield");
00153 $a_xml_writer->xmlElement("fieldlabel", NULL, "AUTHOR");
00154 $a_xml_writer->xmlElement("fieldentry", NULL, $this->getAuthor());
00155 $a_xml_writer->xmlEndTag("qtimetadatafield");
00156 $a_xml_writer->xmlEndTag("qtimetadata");
00157 $a_xml_writer->xmlEndTag("itemmetadata");
00158
00159
00160 $attrs = array(
00161 "label" => $this->getTitle()
00162 );
00163 $a_xml_writer->xmlStartTag("presentation", $attrs);
00164
00165 $a_xml_writer->xmlStartTag("flow");
00166
00167 $a_xml_writer->xmlStartTag("material");
00168 $a_xml_writer->xmlElement("mattext", NULL, $this->get_question());
00169 $a_xml_writer->xmlEndTag("material");
00170
00171 $attrs = array();
00172 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00173 {
00174 $attrs = array(
00175 "ident" => "MQP",
00176 "rcardinality" => "Multiple"
00177 );
00178 }
00179 else
00180 {
00181 $attrs = array(
00182 "ident" => "MQT",
00183 "rcardinality" => "Multiple"
00184 );
00185 }
00186 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00187 {
00188 $attrs["output"] = "javascript";
00189 }
00190 $a_xml_writer->xmlStartTag("response_grp", $attrs);
00191 $solution = $this->getSuggestedSolution(0);
00192 if (count($solution))
00193 {
00194 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
00195 {
00196 $a_xml_writer->xmlStartTag("material");
00197 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
00198 if (strcmp($matches[1], "") != 0)
00199 {
00200 $intlink = $solution["internal_link"];
00201 }
00202 $attrs = array(
00203 "label" => "suggested_solution"
00204 );
00205 $a_xml_writer->xmlElement("mattext", $attrs, $intlink);
00206 $a_xml_writer->xmlEndTag("material");
00207 }
00208 }
00209
00210 $attrs = array();
00211 if ($this->getShuffle())
00212 {
00213 $attrs = array(
00214 "shuffle" => "Yes"
00215 );
00216 }
00217 else
00218 {
00219 $attrs = array(
00220 "shuffle" => "No"
00221 );
00222 }
00223 $a_xml_writer->xmlStartTag("render_choice", $attrs);
00224
00225 $matchingtext_orders = array();
00226 foreach ($this->matchingpairs as $index => $matchingpair)
00227 {
00228 array_push($matchingtext_orders, $matchingpair->getTermId());
00229 }
00230
00231
00232 $pkeys = array_keys($this->matchingpairs);
00233 if ($this->getshuffle() && $a_shuffle)
00234 {
00235 $pkeys = $this->pcArrayShuffle($pkeys);
00236 }
00237
00238 foreach ($pkeys as $index)
00239 {
00240 $matchingpair = $this->matchingpairs[$index];
00241 $attrs = array(
00242 "ident" => $matchingpair->getDefinitionId(),
00243 "match_max" => "1",
00244 "match_group" => join($matchingtext_orders, ",")
00245 );
00246 $a_xml_writer->xmlStartTag("response_label", $attrs);
00247 $a_xml_writer->xmlStartTag("material");
00248 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00249 {
00250 if ($force_image_references)
00251 {
00252 $attrs = array(
00253 "imagtype" => "image/jpeg",
00254 "label" => $matchingpair->getPicture(),
00255 "uri" => $this->getImagePathWeb() . $matchingpair->getPicture()
00256 );
00257 $a_xml_writer->xmlElement("matimage", $attrs);
00258 }
00259 else
00260 {
00261 $imagepath = $this->getImagePath() . $matchingpair->getPicture();
00262 $fh = @fopen($imagepath, "rb");
00263 if ($fh != false)
00264 {
00265 $imagefile = fread($fh, filesize($imagepath));
00266 fclose($fh);
00267 $base64 = base64_encode($imagefile);
00268 $attrs = array(
00269 "imagtype" => "image/jpeg",
00270 "label" => $matchingpair->getPicture(),
00271 "embedded" => "base64"
00272 );
00273 $a_xml_writer->xmlElement("matimage", $attrs, $base64, FALSE, FALSE);
00274 }
00275 }
00276 }
00277 else
00278 {
00279 $a_xml_writer->xmlElement("mattext", NULL, $matchingpair->getDefinition());
00280 }
00281 $a_xml_writer->xmlEndTag("material");
00282 $a_xml_writer->xmlEndTag("response_label");
00283 }
00284
00285 if ($this->getshuffle() && $a_shuffle)
00286 {
00287 $pkeys = $this->pcArrayShuffle($pkeys);
00288 }
00289
00290 foreach ($pkeys as $index)
00291 {
00292 $matchingpair = $this->matchingpairs[$index];
00293 $attrs = array(
00294 "ident" => $matchingpair->getTermId()
00295 );
00296 $a_xml_writer->xmlStartTag("response_label", $attrs);
00297 $a_xml_writer->xmlStartTag("material");
00298 $a_xml_writer->xmlElement("mattext", NULL, $matchingpair->getTerm());
00299 $a_xml_writer->xmlEndTag("material");
00300 $a_xml_writer->xmlEndTag("response_label");
00301 }
00302 $a_xml_writer->xmlEndTag("render_choice");
00303 $a_xml_writer->xmlEndTag("response_grp");
00304 $a_xml_writer->xmlEndTag("flow");
00305 $a_xml_writer->xmlEndTag("presentation");
00306
00307
00308 $a_xml_writer->xmlStartTag("resprocessing");
00309 $a_xml_writer->xmlStartTag("outcomes");
00310 $a_xml_writer->xmlStartTag("decvar");
00311 $a_xml_writer->xmlEndTag("decvar");
00312 $a_xml_writer->xmlEndTag("outcomes");
00313
00314 foreach ($this->matchingpairs as $index => $matchingpair)
00315 {
00316 $attrs = array(
00317 "continue" => "Yes"
00318 );
00319 $a_xml_writer->xmlStartTag("respcondition", $attrs);
00320
00321 $a_xml_writer->xmlStartTag("conditionvar");
00322 $attrs = array();
00323 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00324 {
00325 $attrs = array(
00326 "respident" => "MQP"
00327 );
00328 }
00329 else
00330 {
00331 $attrs = array(
00332 "respident" => "MQT"
00333 );
00334 }
00335 $a_xml_writer->xmlElement("varsubset", $attrs, $matchingpair->getTermId() . "," . $matchingpair->getDefinitionId());
00336 $a_xml_writer->xmlEndTag("conditionvar");
00337
00338
00339 $attrs = array(
00340 "action" => "Add"
00341 );
00342 $a_xml_writer->xmlElement("setvar", $attrs, $matchingpair->getPoints());
00343
00344 $attrs = array(
00345 "feedbacktype" => "Response",
00346 "linkrefid" => "correct_" . $matchingpair->getTermId() . "_" . $matchingpair->getDefinitionId()
00347 );
00348 $a_xml_writer->xmlElement("displayfeedback", $attrs);
00349 $a_xml_writer->xmlEndTag("respcondition");
00350 }
00351 $a_xml_writer->xmlEndTag("resprocessing");
00352
00353
00354 foreach ($this->matchingpairs as $index => $matchingpair)
00355 {
00356 $attrs = array(
00357 "ident" => "correct_" . $matchingpair->getTermId() . "_" . $matchingpair->getDefinitionId(),
00358 "view" => "All"
00359 );
00360 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
00361
00362 $a_xml_writer->xmlStartTag("flow_mat");
00363 $a_xml_writer->xmlStartTag("material");
00364 $a_xml_writer->xmlElement("mattext");
00365 $a_xml_writer->xmlEndTag("material");
00366 $a_xml_writer->xmlEndTag("flow_mat");
00367 $a_xml_writer->xmlEndTag("itemfeedback");
00368 }
00369 $a_xml_writer->xmlEndTag("item");
00370 $a_xml_writer->xmlEndTag("questestinterop");
00371
00372 $xml = $a_xml_writer->xmlDumpMem(FALSE);
00373 if (!$a_include_header)
00374 {
00375 $pos = strpos($xml, "?>");
00376 $xml = substr($xml, $pos + 2);
00377 }
00378 return $xml;
00379 }
00380
00389 function saveToDb($original_id = "")
00390 {
00391 global $ilias;
00392
00393 $db =& $ilias->db;
00394 $complete = 0;
00395 if ($this->isComplete())
00396 {
00397 $complete = 1;
00398 }
00399 $estw_time = $this->getEstimatedWorkingTime();
00400 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00401
00402 if ($original_id)
00403 {
00404 $original_id = $db->quote($original_id);
00405 }
00406 else
00407 {
00408 $original_id = "NULL";
00409 }
00410
00411 if ($this->id == -1)
00412 {
00413
00414 $now = getdate();
00415 $question_type = $this->getQuestionType();
00416 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00417 $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, shuffle, matching_type, points, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00418 $db->quote($question_type. ""),
00419 $db->quote($this->obj_id. ""),
00420 $db->quote($this->title. ""),
00421 $db->quote($this->comment. ""),
00422 $db->quote($this->author. ""),
00423 $db->quote($this->owner. ""),
00424 $db->quote($this->question. ""),
00425 $db->quote($estw_time. ""),
00426 $db->quote($this->shuffle . ""),
00427 $db->quote($this->matching_type. ""),
00428 $db->quote($this->getMaximumPoints() . ""),
00429 $db->quote($complete. ""),
00430 $db->quote($created. ""),
00431 $original_id
00432 );
00433
00434 $result = $db->query($query);
00435 if ($result == DB_OK)
00436 {
00437 $this->id = $this->ilias->db->getLastInsertId();
00438
00439
00440 $this->createPageObject();
00441
00442
00443 if ($this->getTestId() > 0)
00444 {
00445 $this->insertIntoTest($this->getTestId());
00446 }
00447 }
00448 }
00449 else
00450 {
00451
00452 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time=%s, shuffle = %s, matching_type = %s, points = %s, complete = %s WHERE question_id = %s",
00453 $db->quote($this->obj_id. ""),
00454 $db->quote($this->title. ""),
00455 $db->quote($this->comment. ""),
00456 $db->quote($this->author. ""),
00457 $db->quote($this->question. ""),
00458 $db->quote($estw_time. ""),
00459 $db->quote($this->shuffle . ""),
00460 $db->quote($this->matching_type. ""),
00461 $db->quote($this->getMaximumPoints() . ""),
00462 $db->quote($complete. ""),
00463 $db->quote($this->id. "")
00464 );
00465 $result = $db->query($query);
00466 }
00467
00468 if ($result == DB_OK)
00469 {
00470
00471
00472 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
00473 $db->quote($this->id)
00474 );
00475 $result = $db->query($query);
00476
00477
00478 foreach ($this->matchingpairs as $key => $value)
00479 {
00480 $matching_obj = $this->matchingpairs[$key];
00481 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, matchingtext, matching_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
00482 $db->quote($this->id),
00483 $db->quote($matching_obj->getTerm() . ""),
00484 $db->quote($matching_obj->getPoints() . ""),
00485 $db->quote($matching_obj->getTermId() . ""),
00486 $db->quote($matching_obj->getDefinition() . ""),
00487 $db->quote($matching_obj->getDefinitionId() . "")
00488 );
00489 $matching_result = $db->query($query);
00490 }
00491 }
00492 parent::saveToDb($original_id);
00493 }
00494
00504 function loadFromDb($question_id)
00505 {
00506 global $ilias;
00507 $db =& $ilias->db;
00508
00509 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
00510 $db->quote($question_id)
00511 );
00512 $result = $db->query($query);
00513 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00514 {
00515 if ($result->numRows() == 1)
00516 {
00517 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00518 $this->id = $question_id;
00519 $this->title = $data->title;
00520 $this->comment = $data->comment;
00521 $this->author = $data->author;
00522 $this->solution_hint = $data->solution_hint;
00523 $this->obj_id = $data->obj_fi;
00524 $this->original_id = $data->original_id;
00525 $this->owner = $data->owner;
00526 $this->matching_type = $data->matching_type;
00527 $this->question = $data->question_text;
00528 $this->points = $data->points;
00529 $this->shuffle = $data->shuffle;
00530 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00531 }
00532
00533 $query = sprintf("SELECT * FROM qpl_answers WHERE question_fi = %s ORDER BY answer_id ASC",
00534 $db->quote($question_id)
00535 );
00536 $result = $db->query($query);
00537 include_once "./assessment/classes/class.assAnswerMatching.php";
00538 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00539 {
00540 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00541 {
00542 array_push($this->matchingpairs, new ASS_AnswerMatching($data->answertext, $data->points, $data->aorder, $data->matchingtext, $data->matching_order));
00543 }
00544 }
00545 }
00546 parent::loadFromDb($question_id);
00547 }
00548
00556 function addMatchingPair($answertext, $points, $answerorder, $matchingtext, $matchingorder)
00557 {
00558 include_once "./assessment/classes/class.assAnswerMatching.php";
00559 array_push($this->matchingpairs, new ASS_AnswerMatching($answertext, $points, $answerorder, $matchingtext, $matchingorder));
00560 }
00561
00562
00570 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00571 {
00572 if ($this->id <= 0)
00573 {
00574
00575 return;
00576 }
00577
00578 $this_id = $this->getId();
00579 $clone = $this;
00580 include_once ("./assessment/classes/class.assQuestion.php");
00581 $original_id = ASS_Question::_getOriginalId($this->id);
00582 $clone->id = -1;
00583 if ($title)
00584 {
00585 $clone->setTitle($title);
00586 }
00587 if ($author)
00588 {
00589 $clone->setAuthor($author);
00590 }
00591 if ($owner)
00592 {
00593 $clone->setOwner($owner);
00594 }
00595 if ($for_test)
00596 {
00597 $clone->saveToDb($original_id);
00598 }
00599 else
00600 {
00601 $clone->saveToDb();
00602 }
00603
00604
00605 $clone->copyPageOfQuestion($this_id);
00606
00607
00608 $clone->duplicateImages($this_id);
00609 return $clone->id;
00610 }
00611
00619 function copyObject($target_questionpool, $title = "")
00620 {
00621 if ($this->id <= 0)
00622 {
00623
00624 return;
00625 }
00626
00627 $clone = $this;
00628 include_once ("./assessment/classes/class.assQuestion.php");
00629 $original_id = ASS_Question::_getOriginalId($this->id);
00630 $clone->id = -1;
00631 if ($title)
00632 {
00633 $clone->setTitle($title);
00634 }
00635 $source_questionpool = $this->getObjId();
00636 $clone->setObjId($target_questionpool);
00637 $clone->saveToDb();
00638
00639
00640 $clone->copyPageOfQuestion($original_id);
00641
00642
00643 $clone->copyImages($original_id, $source_questionpool);
00644 return $clone->id;
00645 }
00646
00647 function duplicateImages($question_id)
00648 {
00649 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00650 {
00651 $imagepath = $this->getImagePath();
00652 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00653 if (!file_exists($imagepath))
00654 {
00655 ilUtil::makeDirParents($imagepath);
00656 }
00657 foreach ($this->matchingpairs as $answer)
00658 {
00659 $filename = $answer->getPicture();
00660 if (!copy($imagepath_original . $filename, $imagepath . $filename))
00661 {
00662 print "image could not be duplicated!!!! ";
00663 }
00664 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg"))
00665 {
00666 print "image thumbnail could not be duplicated!!!! ";
00667 }
00668 }
00669 }
00670 }
00671
00672 function copyImages($question_id, $source_questionpool)
00673 {
00674 if ($this->get_matching_type() == MT_TERMS_PICTURES)
00675 {
00676 $imagepath = $this->getImagePath();
00677 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00678 $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
00679 if (!file_exists($imagepath))
00680 {
00681 ilUtil::makeDirParents($imagepath);
00682 }
00683 foreach ($this->matchingpairs as $answer)
00684 {
00685 $filename = $answer->getPicture();
00686 if (!copy($imagepath_original . $filename, $imagepath . $filename))
00687 {
00688 print "image could not be duplicated!!!! ";
00689 }
00690 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg"))
00691 {
00692 print "image thumbnail could not be duplicated!!!! ";
00693 }
00694 }
00695 }
00696 }
00697
00707 function set_question($question = "")
00708 {
00709 $this->question = $question;
00710 }
00711
00721 function set_matching_type($matching_type = MT_TERMS_DEFINITIONS)
00722 {
00723 $this->matching_type = $matching_type;
00724 }
00725
00735 function get_question()
00736 {
00737 return $this->question;
00738 }
00739
00749 function get_matching_type()
00750 {
00751 return $this->matching_type;
00752 }
00753
00768 function add_matchingpair(
00769 $term = "",
00770 $picture_or_definition = "",
00771 $points = 0.0,
00772 $term_id = 0,
00773 $picture_or_definition_id = 0
00774 )
00775 {
00776
00777 if ($term_id == 0)
00778 {
00779 $term_id = $this->get_random_id();
00780 }
00781
00782 if ($picture_or_definition_id == 0)
00783 {
00784 $picture_or_definition_id = $this->get_random_id();
00785 }
00786 include_once "./assessment/classes/class.assAnswerMatching.php";
00787 $matchingpair = new ASS_AnswerMatching($term, $points, $term_id, $picture_or_definition, $picture_or_definition_id);
00788 array_push($this->matchingpairs, $matchingpair);
00789 }
00790
00802 function get_matchingpair($index = 0)
00803 {
00804 if ($index < 0)
00805 {
00806 return NULL;
00807 }
00808 if (count($this->matchingpairs) < 1)
00809 {
00810 return NULL;
00811 }
00812 if ($index >= count($this->matchingpairs))
00813 {
00814 return NULL;
00815 }
00816 return $this->matchingpairs[$index];
00817 }
00818
00829 function delete_matchingpair($index = 0)
00830 {
00831 if ($index < 0)
00832 {
00833 return;
00834 }
00835 if (count($this->matchingpairs) < 1)
00836 {
00837 return;
00838 }
00839 if ($index >= count($this->matchingpairs))
00840 {
00841 return;
00842 }
00843 unset($this->matchingpairs[$index]);
00844 $this->matchingpairs = array_values($this->matchingpairs);
00845 }
00846
00855 function flush_matchingpairs()
00856 {
00857 $this->matchingpairs = array();
00858 }
00859
00869 function get_matchingpair_count()
00870 {
00871 return count($this->matchingpairs);
00872 }
00873
00885 function calculateReachedPoints($user_id, $test_id, $pass = NULL)
00886 {
00887 global $ilDB;
00888
00889 $found_value1 = array();
00890 $found_value2 = array();
00891 if (is_null($pass))
00892 {
00893 $pass = $this->getSolutionMaxPass($user_id, $test_id);
00894 }
00895 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
00896 $ilDB->quote($user_id . ""),
00897 $ilDB->quote($test_id . ""),
00898 $ilDB->quote($this->getId() . ""),
00899 $ilDB->quote($pass . "")
00900 );
00901 $result = $ilDB->query($query);
00902 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00903 {
00904 if (strcmp($data->value1, "") != 0)
00905 {
00906 array_push($found_value1, $data->value1);
00907 array_push($found_value2, $data->value2);
00908 }
00909 }
00910 $points = 0;
00911 foreach ($found_value2 as $key => $value)
00912 {
00913 foreach ($this->matchingpairs as $answer_key => $answer_value)
00914 {
00915 if (($answer_value->getDefinitionId() == $value) and ($answer_value->getTermId() == $found_value1[$key]))
00916 {
00917 $points += $answer_value->getPoints();
00918 }
00919 }
00920 }
00921
00922
00923 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
00924 $ilDB->quote($test_id)
00925 );
00926 $result = $ilDB->query($query);
00927 if ($result->numRows() == 1)
00928 {
00929 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00930 if ($row["count_system"] == 1)
00931 {
00932 if ($points != $this->getMaximumPoints())
00933 {
00934 $points = 0;
00935 }
00936 }
00937 }
00938 else
00939 {
00940 $points = 0;
00941 }
00942 return $points;
00943 }
00944
00954 function getReachedInformation($user_id, $test_id, $pass = NULL)
00955 {
00956 $found_value1 = array();
00957 $found_value2 = array();
00958 if (is_null($pass))
00959 {
00960 $pass = $this->getSolutionMaxPass($user_id, $test_id);
00961 }
00962 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
00963 $this->ilias->db->quote($user_id . ""),
00964 $this->ilias->db->quote($test_id . ""),
00965 $this->ilias->db->quote($this->getId() . ""),
00966 $this->ilias->db->quote($pass . "")
00967 );
00968 $result = $this->ilias->db->query($query);
00969 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00970 {
00971 array_push($found_value1, $data->value1);
00972 array_push($found_value2, $data->value2);
00973 }
00974 $counter = 1;
00975 $user_result = array();
00976 foreach ($found_value1 as $key => $value)
00977 {
00978 $solution = array(
00979 "order" => "$counter",
00980 "points" => 0,
00981 "true" => 0,
00982 "term" => "",
00983 "definition" => ""
00984 );
00985 foreach ($this->matchingpairs as $answer_key => $answer_value)
00986 {
00987 if (($answer_value->getDefinitionId() == $found_value2[$key]) and ($answer_value->getTermId() == $value))
00988 {
00989 $points += $answer_value->getPoints();
00990 $solution["points"] = $answer_value->getPoints();
00991 $solution["term"] = $value;
00992 $solution["definition"] = $found_value2[$key];
00993 $solution["true"] = 1;
00994 }
00995 else
00996 {
00997 $solution["term"] = $value;
00998 $solution["definition"] = $found_value2[$key];
00999 }
01000 }
01001 $counter++;
01002 array_push($user_result, $solution);
01003 }
01004 return $user_result;
01005 }
01006
01015 function getMaximumPoints()
01016 {
01017 $points = 0;
01018 foreach ($this->matchingpairs as $key => $value)
01019 {
01020 if ($value->getPoints() > 0)
01021 {
01022 $points += $value->getPoints();
01023 }
01024 }
01025 return $points;
01026 }
01027
01038 function set_image_file($image_filename, $image_tempfilename = "")
01039 {
01040 $result = 0;
01041 if (!empty($image_tempfilename))
01042 {
01043 $image_filename = str_replace(" ", "_", $image_filename);
01044 $imagepath = $this->getImagePath();
01045 if (!file_exists($imagepath))
01046 {
01047 ilUtil::makeDirParents($imagepath);
01048 }
01049
01050 if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
01051 {
01052 $result = 2;
01053 }
01054 else
01055 {
01056 include_once "./content/classes/Media/class.ilObjMediaObject.php";
01057 $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
01058 if (!preg_match("/^image/", $mimetype))
01059 {
01060 unlink($imagepath . $image_filename);
01061 $result = 1;
01062 }
01063 else
01064 {
01065
01066 $thumbpath = $imagepath . $image_filename . "." . "thumb.jpg";
01067 ilUtil::convertImage($imagepath.$image_filename, $thumbpath, "JPEG", 100);
01068 }
01069 }
01070 }
01071 return $result;
01072 }
01073
01083 function checkSaveData()
01084 {
01085 $result = true;
01086 $matching_values = array();
01087 foreach ($_POST as $key => $value)
01088 {
01089 if (preg_match("/^sel_matching_(\d+)/", $key, $matches))
01090 {
01091 if ((strcmp($value, "") != 0) && ($value != -1))
01092 {
01093 array_push($matching_values, $value);
01094 }
01095 }
01096 }
01097 $check_matching = array_flip($matching_values);
01098 if (count($check_matching) != count($matching_values))
01099 {
01100
01101 $result = false;
01102 sendInfo($this->lng->txt("duplicate_matching_values_selected"), TRUE);
01103 }
01104 return $result;
01105 }
01106
01117 function saveWorkingData($test_id, $pass = NULL)
01118 {
01119 global $ilDB;
01120 global $ilUser;
01121 $saveWorkingDataResult = $this->checkSaveData();
01122 $entered_values = 0;
01123 if ($saveWorkingDataResult)
01124 {
01125 $db =& $ilDB->db;
01126
01127 include_once ("./assessment/classes/class.ilObjTest.php");
01128 $activepass = ilObjTest::_getPass($ilUser->id, $test_id);
01129
01130 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
01131 $db->quote($ilUser->id . ""),
01132 $db->quote($test_id . ""),
01133 $db->quote($this->getId() . ""),
01134 $db->quote($activepass . "")
01135 );
01136 $result = $db->query($query);
01137 foreach ($_POST as $key => $value)
01138 {
01139 if (preg_match("/^sel_matching_(\d+)/", $key, $matches))
01140 {
01141 if (!(preg_match("/initial_value_\d+/", $value)))
01142 {
01143 if ($value > -1)
01144 {
01145 $entered_values++;
01146 $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)",
01147 $db->quote($ilUser->id),
01148 $db->quote($test_id),
01149 $db->quote($this->getId()),
01150 $db->quote($value),
01151 $db->quote($matches[1]),
01152 $db->quote($activepass . "")
01153 );
01154 $result = $db->query($query);
01155 }
01156 }
01157 }
01158 }
01159 $saveWorkingDataResult = true;
01160 }
01161 if ($entered_values)
01162 {
01163 include_once ("./classes/class.ilObjAssessmentFolder.php");
01164 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01165 {
01166 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $test_id, $this->getId());
01167 }
01168 }
01169 else
01170 {
01171 include_once ("./classes/class.ilObjAssessmentFolder.php");
01172 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01173 {
01174 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $test_id, $this->getId());
01175 }
01176 }
01177 parent::saveWorkingData($test_id, $pass);
01178 return $saveWorkingDataResult;
01179 }
01180
01181 function get_random_id()
01182 {
01183 mt_srand((double)microtime()*1000000);
01184 $random_number = mt_rand(1, 100000);
01185 $found = FALSE;
01186 while ($found)
01187 {
01188 $found = FALSE;
01189 foreach ($this->matchingpairs as $key => $value)
01190 {
01191 if (($value->getTermId() == $random_number) || ($value->getDefinitionId() == $random_number))
01192 {
01193 $found = TRUE;
01194 $random_number++;
01195 }
01196 }
01197 }
01198 return $random_number;
01199 }
01200
01201 function syncWithOriginal()
01202 {
01203 global $ilias;
01204 if ($this->original_id)
01205 {
01206 $complete = 0;
01207 if ($this->isComplete())
01208 {
01209 $complete = 1;
01210 }
01211 $db = & $ilias->db;
01212
01213 $estw_time = $this->getEstimatedWorkingTime();
01214 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
01215
01216 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time=%s, matching_type = %s, points = %s, complete = %s WHERE question_id = %s",
01217 $db->quote($this->obj_id. ""),
01218 $db->quote($this->title. ""),
01219 $db->quote($this->comment. ""),
01220 $db->quote($this->author. ""),
01221 $db->quote($this->question. ""),
01222 $db->quote($estw_time. ""),
01223 $db->quote($this->matching_type. ""),
01224 $db->quote($this->getMaximumPoints() . ""),
01225 $db->quote($complete. ""),
01226 $db->quote($this->original_id. "")
01227 );
01228 $result = $db->query($query);
01229
01230 if ($result == DB_OK)
01231 {
01232
01233
01234 $query = sprintf("DELETE FROM qpl_answers WHERE question_fi = %s",
01235 $db->quote($this->original_id)
01236 );
01237 $result = $db->query($query);
01238
01239 foreach ($this->matchingpairs as $key => $value)
01240 {
01241 $matching_obj = $this->matchingpairs[$key];
01242 $query = sprintf("INSERT INTO qpl_answers (answer_id, question_fi, answertext, points, aorder, matchingtext, matching_order, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
01243 $db->quote($this->original_id . ""),
01244 $db->quote($matching_obj->getTerm() . ""),
01245 $db->quote($matching_obj->getPoints() . ""),
01246 $db->quote($matching_obj->getTermId() . ""),
01247 $db->quote($matching_obj->getDefinition() . ""),
01248 $db->quote($matching_obj->getDefinitionId() . "")
01249 );
01250 $matching_result = $db->query($query);
01251 }
01252 }
01253 parent::syncWithOriginal();
01254 }
01255 }
01256
01257 function pc_array_shuffle($array) {
01258 $i = count($array);
01259 mt_srand((double)microtime()*1000000);
01260 while(--$i)
01261 {
01262 $j = mt_rand(0, $i);
01263 if ($i != $j)
01264 {
01265
01266 $tmp = $array[$j];
01267 $array[$j] = $array[$i];
01268 $array[$i] = $tmp;
01269 }
01270 }
01271 return $array;
01272 }
01273
01274 function createRandomSolution($test_id, $user_id, $pass = NULL)
01275 {
01276 global $ilDB;
01277 global $ilUser;
01278 $db =& $ilDB->db;
01279
01280 if (is_null($pass))
01281 {
01282 $pass = $this->getSolutionMaxPass($user_id, $test_id);
01283 }
01284 $query = sprintf("DELETE FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
01285 $db->quote($user_id),
01286 $db->quote($test_id),
01287 $db->quote($this->getId()),
01288 $db->quote($pass . "")
01289 );
01290 $result = $db->query($query);
01291
01292 $terms = array();
01293 $definitions = array();
01294
01295 foreach ($this->matchingpairs as $key => $pair)
01296 {
01297 array_push($terms, $pair->getTermId());
01298 array_push($definitions, $pair->getDefinitionId());
01299 }
01300 $definitions = $this->pc_array_shuffle($definitions);
01301 foreach ($terms as $key => $value)
01302 {
01303 $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)",
01304 $db->quote($user_id),
01305 $db->quote($test_id),
01306 $db->quote($this->getId()),
01307 $db->quote($value),
01308 $db->quote($definitions[$key]),
01309 $db->quote($pass . "")
01310 );
01311 $result = $db->query($query);
01312 }
01313 }
01314
01323 function getQuestionType()
01324 {
01325 return 4;
01326 }
01327
01328 }
01329
01330 ?>