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 "./Modules/Test/classes/inc.AssessmentConstants.php";
00025
00036 class assQuestion
00037 {
00045 var $id;
00046
00054 var $title;
00055
00063 var $comment;
00064
00073 var $owner;
00074
00083 var $author;
00084
00092 var $question;
00093
00103 var $points;
00104
00112 var $est_working_time;
00113
00121 var $shuffle;
00122
00130 var $test_id;
00131
00139 var $obj_id;
00140
00148 var $ilias;
00149
00157 var $tpl;
00158
00166 var $lng;
00167
00175 var $domxml;
00176
00184 var $outputType;
00185
00186 var $suggested_solutions;
00198 function assQuestion(
00199 $title = "",
00200 $comment = "",
00201 $author = "",
00202 $owner = -1,
00203 $question = ""
00204 )
00205 {
00206 global $ilias;
00207 global $lng;
00208 global $tpl;
00209
00210 $this->ilias =& $ilias;
00211 $this->lng =& $lng;
00212 $this->tpl =& $tpl;
00213
00214 $this->title = $title;
00215 $this->comment = $comment;
00216 $this->author = $author;
00217 $this->setQuestion($question);
00218 if (!$this->author)
00219 {
00220 $this->author = $this->ilias->account->fullname;
00221 }
00222 $this->owner = $owner;
00223 if ($this->owner == -1)
00224 {
00225 $this->owner = $this->ilias->account->id;
00226 }
00227 $this->id = -1;
00228 $this->test_id = -1;
00229 $this->suggested_solutions = array();
00230 $this->shuffle = 1;
00231 $this->setEstimatedWorkingTime(0,1,0);
00232 $this->outputType = OUTPUT_HTML;
00233 register_shutdown_function(array(&$this, '_assQuestion'));
00234 }
00235
00236 function _assQuestion()
00237 {
00238 if (!empty($this->domxml))
00239 {
00240 $this->domxml->free();
00241 }
00242 }
00243
00257 function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
00258 {
00259 include_once "./Modules/TestQuestionPool/classes/import/qti12/class." . $this->getQuestionType() . "Import.php";
00260 $classname = $this->getQuestionType() . "Import";
00261 $import = new $classname($this);
00262 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
00263 }
00264
00274 function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
00275 {
00276 include_once "./Modules/TestQuestionPool/classes/export/qti12/class." . $this->getQuestionType() . "Export.php";
00277 $classname = $this->getQuestionType() . "Export";
00278 $export = new $classname($this);
00279 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
00280 }
00281
00290 function isComplete()
00291 {
00292 return false;
00293 }
00294
00304 function questionTitleExists($questionpool_id, $title)
00305 {
00306 global $ilDB;
00307
00308 $query = sprintf("SELECT * FROM qpl_questions WHERE obj_fi = %s AND title = %s",
00309 $ilDB->quote($questionpool_id . ""),
00310 $ilDB->quote($title)
00311 );
00312 $result = $ilDB->query($query);
00313 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00314 {
00315 if ($result->numRows() == 1)
00316 {
00317 return TRUE;
00318 }
00319 }
00320 return FALSE;
00321 }
00322
00332 function setTitle($title = "")
00333 {
00334 $this->title = $title;
00335 }
00336
00346 function setId($id = -1)
00347 {
00348 $this->id = $id;
00349 }
00350
00360 function setTestId($id = -1)
00361 {
00362 $this->test_id = $id;
00363 }
00364
00374 function setComment($comment = "")
00375 {
00376 $this->comment = $comment;
00377 }
00378
00388 function setOutputType($outputType = OUTPUT_HTML)
00389 {
00390 $this->outputType = $outputType;
00391 }
00392
00393
00403 function setShuffle($shuffle = true)
00404 {
00405 if ($shuffle)
00406 {
00407 $this->shuffle = 1;
00408 }
00409 else
00410 {
00411 $this->shuffle = 0;
00412 }
00413 }
00414
00426 function setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
00427 {
00428 $this->est_working_time = array("h" => (int)$hour, "m" => (int)$min, "s" => (int)$sec);
00429 }
00430
00440 function keyInArray($searchkey, $array)
00441 {
00442 if ($searchKey)
00443 {
00444 foreach ($array as $key => $value)
00445 {
00446 if (strcmp($key, $searchkey)==0)
00447 {
00448 return true;
00449 }
00450 }
00451 }
00452 return false;
00453 }
00454
00464 function setAuthor($author = "")
00465 {
00466 if (!$author)
00467 {
00468 $author = $this->ilias->account->fullname;
00469 }
00470 $this->author = $author;
00471 }
00472
00482 function setOwner($owner = "")
00483 {
00484 $this->owner = $owner;
00485 }
00486
00496 function getTitle()
00497 {
00498 return $this->title;
00499 }
00500
00510 function getId()
00511 {
00512 return $this->id;
00513 }
00514
00524 function getShuffle()
00525 {
00526 return $this->shuffle;
00527 }
00528
00538 function getTestId()
00539 {
00540 return $this->test_id;
00541 }
00542
00552 function getComment()
00553 {
00554 return $this->comment;
00555 }
00556
00566 function getOutputType()
00567 {
00568 return $this->outputType;
00569 }
00570
00579 function supportsJavascriptOutput()
00580 {
00581 return FALSE;
00582 }
00583
00593 function getEstimatedWorkingTime()
00594 {
00595 if (!$this->est_working_time)
00596 {
00597 $this->est_working_time = array("h" => 0, "m" => 0, "s" => 0);
00598 }
00599 return $this->est_working_time;
00600 }
00601
00611 function getAuthor()
00612 {
00613 return $this->author;
00614 }
00615
00625 function getOwner()
00626 {
00627 return $this->owner;
00628 }
00629
00639 function getObjId()
00640 {
00641 return $this->obj_id;
00642 }
00643
00653 function setObjId($obj_id = 0)
00654 {
00655 $this->obj_id = $obj_id;
00656 }
00657
00661 function createPageObject()
00662 {
00663 $qpl_id = $this->getObjId();
00664
00665 include_once "./Services/COPage/classes/class.ilPageObject.php";
00666 $this->page = new ilPageObject("qpl", 0);
00667 $this->page->setId($this->getId());
00668 $this->page->setParentId($qpl_id);
00669 $this->page->setXMLContent("<PageObject><PageContent>".
00670 "<Question QRef=\"il__qst_".$this->getId()."\"/>".
00671 "</PageContent></PageObject>");
00672 $this->page->create();
00673 }
00674
00683 function insertIntoTest($test_id)
00684 {
00685 global $ilDB;
00686
00687
00688 $query = sprintf("SELECT MAX(sequence) AS seq FROM dum_test_question WHERE test_fi=%s",
00689 $ilDB->quote($test_id)
00690 );
00691 $result = $ilDB->query($query);
00692 $sequence = 1;
00693 if ($result->numRows() == 1)
00694 {
00695 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00696 $sequence = $data->seq + 1;
00697 }
00698 $query = sprintf("INSERT INTO dum_test_question (test_question_id, test_fi, question_fi, sequence, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
00699 $ilDB->quote($test_id),
00700 $ilDB->quote($this->getId()),
00701 $ilDB->quote($sequence)
00702 );
00703 $result = $ilDB->query($query);
00704 if ($result != DB_OK)
00705 {
00706
00707 }
00708 }
00709
00719 function _getMaximumPoints($question_id)
00720 {
00721 global $ilDB;
00722
00723 $points = 0;
00724 $query = sprintf("SELECT points FROM qpl_questions WHERE question_id = %s",
00725 $ilDB->quote($question_id . "")
00726 );
00727 $result = $ilDB->query($query);
00728 if ($result->numRows() == 1)
00729 {
00730 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00731 $points = $row["points"];
00732 }
00733 return $points;
00734 }
00735
00745 function &_getQuestionInfo($question_id)
00746 {
00747 global $ilDB;
00748
00749 $query = sprintf("SELECT qpl_questions.*, qpl_question_type.type_tag FROM qpl_question_type, qpl_questions WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_question_type.question_type_id",
00750 $ilDB->quote($question_id . "")
00751 );
00752 $result = $ilDB->query($query);
00753 if ($result->numRows())
00754 {
00755 return $result->fetchRow(DB_FETCHMODE_ASSOC);
00756 }
00757 else return array();
00758 }
00759
00769 function _getSuggestedSolutionCount($question_id)
00770 {
00771 global $ilDB;
00772
00773 $query = sprintf("SELECT suggested_solution_id FROM qpl_suggested_solutions WHERE question_fi = %s",
00774 $ilDB->quote($question_id . "")
00775 );
00776 $result = $ilDB->query($query);
00777 return $result->numRows();
00778 }
00779
00790 function &_getSuggestedSolution($question_id, $subquestion_index = 0)
00791 {
00792 global $ilDB;
00793
00794 $query = sprintf("SELECT * FROM qpl_suggested_solutions WHERE question_fi = %s AND subquestion_index = %s",
00795 $ilDB->quote($question_id . ""),
00796 $ilDB->quote($subquestion_index . "")
00797 );
00798 $result = $ilDB->query($query);
00799 if ($result->numRows() == 1)
00800 {
00801 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00802 return array(
00803 "internal_link" => $row["internal_link"],
00804 "import_id" => $row["import_id"]
00805 );
00806 }
00807 else
00808 {
00809 return array();
00810 }
00811 }
00812
00823 function _getReachedPoints($active_id, $question_id, $pass = NULL)
00824 {
00825 global $ilDB;
00826
00827 $points = 0;
00828 if (is_null($pass))
00829 {
00830 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
00831 $pass = assQuestion::_getSolutionMaxPass($question_id, $active_id);
00832 }
00833 $query = sprintf("SELECT * FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
00834 $ilDB->quote($active_id . ""),
00835 $ilDB->quote($question_id . ""),
00836 $ilDB->quote($pass . "")
00837 );
00838 $result = $ilDB->query($query);
00839 if ($result->numRows() == 1)
00840 {
00841 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00842 $points = $row["points"];
00843 }
00844 return $points;
00845 }
00846
00857 function getReachedPoints($active_id, $pass = NULL)
00858 {
00859 return $this->_getReachedPoints($active_id, $this->getId(), $pass);
00860 }
00861
00870 function getMaximumPoints()
00871 {
00872 return 0;
00873 }
00874
00884 function saveWorkingData($active_id, $pass = NULL)
00885 {
00886 global $ilDB;
00887 global $ilUser;
00888 if (is_null($pass))
00889 {
00890 include_once "./Modules/Test/classes/class.ilObjTest.php";
00891 $pass = ilObjTest::_getPass($active_id);
00892 }
00893 $reached_points = $this->calculateReachedPoints($active_id, $pass);
00894 $query = sprintf("REPLACE INTO tst_test_result (active_fi, question_fi, pass, points) VALUES (%s, %s, %s, %s)",
00895 $ilDB->quote($active_id . ""),
00896 $ilDB->quote($this->getId() . ""),
00897 $ilDB->quote($pass . ""),
00898 $ilDB->quote($reached_points . "")
00899 );
00900 $result = $ilDB->query($query);
00901 include_once ("./classes/class.ilObjAssessmentFolder.php");
00902 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
00903 {
00904 $this->logAction(sprintf($this->lng->txtlng("assessment", "log_user_answered_question", ilObjAssessmentFolder::_getLogLanguage()), $reached_points), $active_id, $this->getId());
00905 }
00906
00907
00908 $this->_updateTestPassResults($active_id, $pass);
00909
00910
00911 include_once 'Modules/Course/classes/class.ilCourseObjectiveResult.php';
00912 ilCourseObjectiveResult::_updateObjectiveResult($ilUser->getId(),$active_id,$this->getId());
00913
00914 }
00915
00916 function _updateTestPassResults($active_id, $pass)
00917 {
00918 global $ilDB;
00919
00920 $query = sprintf("SELECT SUM(points) AS reachedpoints FROM tst_test_result WHERE active_fi = %s AND pass = %s",
00921 $ilDB->quote($active_id . ""),
00922 $ilDB->quote($pass . "")
00923 );
00924 $result = $ilDB->query($query);
00925 if ($result->numRows() > 0)
00926 {
00927 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00928 $newresultquery = sprintf("REPLACE INTO tst_test_pass_result SET active_fi = %s, pass = %s, points = %s",
00929 $ilDB->quote($active_id . ""),
00930 $ilDB->quote($pass . ""),
00931 $ilDB->quote((($row["reachedpoints"]) ? $row["reachedpoints"] : 0) . "")
00932 );
00933 $ilDB->query($newresultquery);
00934 }
00935 }
00945 function logAction($logtext = "", $active_id = "", $question_id = "")
00946 {
00947 global $ilUser;
00948
00949 $original_id = "";
00950 if (strcmp($question_id, "") != 0)
00951 {
00952 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
00953 $original_id = assQuestion::_getOriginalId($question_id);
00954 }
00955 include_once "./classes/class.ilObjAssessmentFolder.php";
00956 include_once "./Modules/Test/classes/class.ilObjTest.php";
00957 ilObjAssessmentFolder::_addLog($ilUser->id, ilObjTest::_getObjectIDFromActiveID($active_id), $logtext, $question_id, $original_id);
00958 }
00959
00969 function _logAction($logtext = "", $active_id = "", $question_id = "")
00970 {
00971 global $ilUser;
00972
00973 $original_id = "";
00974 if (strcmp($question_id, "") != 0)
00975 {
00976 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
00977 $original_id = assQuestion::_getOriginalId($question_id);
00978 }
00979 include_once "./classes/class.ilObjAssessmentFolder.php";
00980 include_once "./Modules/Test/classes/class.ilObjTest.php";
00981 ilObjAssessmentFolder::_addLog($ilUser->id, ilObjTest::_getObjectIDFromActiveID($active_id), $logtext, $question_id, $original_id);
00982 }
00983
00992 function getJavaPath() {
00993 return CLIENT_WEB_DIR . "/assessment/$this->obj_id/$this->id/java/";
00994 }
00995
01004 function getImagePath()
01005 {
01006 return CLIENT_WEB_DIR . "/assessment/$this->obj_id/$this->id/images/";
01007 }
01008
01017 function getFlashPath()
01018 {
01019 return CLIENT_WEB_DIR . "/assessment/$this->obj_id/$this->id/flash/";
01020 }
01021
01030 function getJavaPathWeb()
01031 {
01032 include_once "./Services/Utilities/classes/class.ilUtil.php";
01033 $webdir = ilUtil::removeTrailingPathSeparators(CLIENT_WEB_DIR) . "/assessment/$this->obj_id/$this->id/java/";
01034 return str_replace(ilUtil::removeTrailingPathSeparators(ILIAS_ABSOLUTE_PATH), ilUtil::removeTrailingPathSeparators(ILIAS_HTTP_PATH), $webdir);
01035 }
01036
01045 function getImagePathWeb()
01046 {
01047 include_once "./Services/Utilities/classes/class.ilUtil.php";
01048 $webdir = ilUtil::removeTrailingPathSeparators(CLIENT_WEB_DIR) . "/assessment/$this->obj_id/$this->id/images/";
01049 return str_replace(ilUtil::removeTrailingPathSeparators(ILIAS_ABSOLUTE_PATH), ilUtil::removeTrailingPathSeparators(ILIAS_HTTP_PATH), $webdir);
01050 }
01051
01060 function getFlashPathWeb()
01061 {
01062 include_once "./Services/Utilities/classes/class.ilUtil.php";
01063 $webdir = ilUtil::removeTrailingPathSeparators(CLIENT_WEB_DIR) . "/assessment/$this->obj_id/$this->id/flash/";
01064 return str_replace(ilUtil::removeTrailingPathSeparators(ILIAS_ABSOLUTE_PATH), ilUtil::removeTrailingPathSeparators(ILIAS_HTTP_PATH), $webdir);
01065 }
01066
01076 function &getSolutionValues($active_id, $pass = NULL)
01077 {
01078 global $ilDB;
01079
01080 $values = array();
01081
01082 if (is_null($pass))
01083 {
01084 $pass = $this->getSolutionMaxPass($active_id);
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101 }
01102
01103 $query = sprintf("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
01104 $ilDB->quote($active_id . ""),
01105 $ilDB->quote($this->getId() . ""),
01106 $ilDB->quote($pass . "")
01107 );
01108 $result = $ilDB->query($query);
01109 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01110 {
01111 array_push($values, $row);
01112 }
01113
01114 return $values;
01115 }
01116
01125 function isInUse($question_id = "")
01126 {
01127 global $ilDB;
01128
01129 if ($question_id < 1) $question_id = $this->id;
01130 $query = sprintf("SELECT COUNT(qpl_questions.question_id) AS question_count FROM qpl_questions, tst_test_question WHERE qpl_questions.original_id = %s AND qpl_questions.question_id = tst_test_question.question_fi",
01131 $ilDB->quote($question_id . "")
01132 );
01133 $result = $ilDB->query($query);
01134 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01135 $count = $row["question_count"];
01136
01137 $query = sprintf("SELECT DISTINCT tst_active.test_fi, qpl_questions.question_id FROM qpl_questions, tst_test_random_question, tst_active WHERE qpl_questions.original_id = %s AND qpl_questions.question_id = tst_test_random_question.question_fi AND tst_test_random_question.active_fi = tst_active.active_id",
01138 $ilDB->quote($question_id . "")
01139 );
01140 $result = $ilDB->query($query);
01141 $count += $result->numRows();
01142
01143 return $count;
01144 }
01145
01154 function isClone($question_id = "")
01155 {
01156 global $ilDB;
01157
01158 if ($question_id < 1) $question_id = $this->id;
01159 $query = sprintf("SELECT original_id FROM qpl_questions WHERE question_id = %s",
01160 $ilDB->quote($question_id . "")
01161 );
01162 $result = $ilDB->query($query);
01163 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
01164 if ($row->original_id > 0)
01165 {
01166 return TRUE;
01167 }
01168 else
01169 {
01170 return FALSE;
01171 }
01172 }
01173
01182 function pcArrayShuffle($array)
01183 {
01184 mt_srand((double)microtime()*1000000);
01185 $i = count($array);
01186 if ($i > 0)
01187 {
01188 while(--$i)
01189 {
01190 $j = mt_rand(0, $i);
01191 if ($i != $j)
01192 {
01193
01194 $tmp = $array[$j];
01195 $array[$j] = $array[$i];
01196 $array[$i] = $tmp;
01197 }
01198 }
01199 }
01200 return $array;
01201 }
01202
01208 function getQuestionTypeFromDb($question_id)
01209 {
01210 global $ilDB;
01211
01212 $query = sprintf("SELECT qpl_question_type.type_tag FROM qpl_question_type, qpl_questions WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_question_type.question_type_id",
01213 $ilDB->quote($question_id));
01214
01215 $result = $ilDB->query($query);
01216 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
01217
01218 return $data->type_tag;
01219 }
01220
01229 function getAdditionalTableName()
01230 {
01231 return "";
01232 }
01233
01242 function getAnswerTableName()
01243 {
01244 return "";
01245 }
01246
01255 function deleteAnswers($question_id)
01256 {
01257 global $ilDB;
01258 $answer_table_name = $this->getAnswerTableName();
01259 if (strlen($answer_table_name))
01260 {
01261 $query = sprintf("DELETE FROM $answer_table_name WHERE question_fi = %s",
01262 $ilDB->quote($question_id . "")
01263 );
01264 $result = $ilDB->query($query);
01265 }
01266 }
01267
01276 function deleteAdditionalTableData($question_id)
01277 {
01278 global $ilDB;
01279 $additional_table_name = $this->getAdditionalTableName();
01280 $query = sprintf("DELETE FROM $additional_table_name WHERE question_fi = %s",
01281 $ilDB->quote($question_id . "")
01282 );
01283 $result = $ilDB->query($query);
01284 }
01285
01292 protected function deletePageOfQuestion($question_id)
01293 {
01294 include_once "./Services/COPage/classes/class.ilPageObject.php";
01295 $page = new ilPageObject("qpl", $question_id);
01296 $page->delete();
01297 }
01298
01307 function delete($question_id)
01308 {
01309 global $ilDB;
01310
01311 if ($question_id < 1)
01312 return;
01313
01314 $query = sprintf("SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
01315 $ilDB->quote($question_id)
01316 );
01317 $result = $ilDB->query($query);
01318 if ($result->numRows() == 1)
01319 {
01320 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01321 $obj_id = $row["obj_fi"];
01322 }
01323 else
01324 {
01325 return;
01326 }
01327
01328 $this->deletePageOfQuestion($question_id);
01329
01330 $query = sprintf("DELETE FROM qpl_questions WHERE question_id = %s",
01331 $ilDB->quote($question_id)
01332 );
01333 $result = $ilDB->query($query);
01334
01335 $this->deleteAdditionalTableData($question_id);
01336 $this->deleteAnswers($question_id);
01337
01338
01339 $querydelete = sprintf("DELETE FROM tst_test_question WHERE question_fi = %s", $ilDB->quote($question_id));
01340 $deleteresult = $ilDB->query($querydelete);
01341
01342
01343 $querydelete = sprintf("DELETE FROM qpl_suggested_solutions WHERE question_fi = %s", $ilDB->quote($question_id));
01344 $deleteresult = $ilDB->query($querydelete);
01345
01346 $directory = CLIENT_WEB_DIR . "/assessment/" . $obj_id . "/$question_id";
01347 if (preg_match("/\d+/", $obj_id) and preg_match("/\d+/", $question_id) and is_dir($directory))
01348 {
01349 include_once "./Services/Utilities/classes/class.ilUtil.php";
01350 ilUtil::delDir($directory);
01351 }
01352
01353 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
01354 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $question_id);
01355
01356
01357
01358
01359 foreach($mobs as $mob)
01360 {
01361 ilObjMediaObject::_removeUsage($mob, "qpl:html", $question_id);
01362 $mob_obj =& new ilObjMediaObject($mob);
01363 $mob_obj->delete();
01364 }
01365
01366
01367 include_once "./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
01368 ilObjQuestionPool::_updateQuestionCount($this->obj_id);
01369 }
01370
01374 function getTotalAnswers()
01375 {
01376 return $this->_getTotalAnswers($this->id);
01377 }
01378
01385 function _getTotalAnswers($a_q_id)
01386 {
01387 global $ilDB;
01388
01389
01390 $query = sprintf("SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
01391 $ilDB->quote($a_q_id),
01392 $ilDB->quote($a_q_id)
01393 );
01394
01395 $result = $ilDB->query($query);
01396
01397 if ($result->numRows() == 0)
01398 {
01399 return 0;
01400 }
01401 $found_id = array();
01402 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
01403 {
01404 array_push($found_id, $row->question_id);
01405 }
01406
01407 $query = sprintf("SELECT * FROM tst_test_result WHERE question_fi IN ('%s')",
01408 join($found_id, "','"));
01409 $result = $ilDB->query($query);
01410
01411 return $result->numRows();
01412 }
01413
01414
01421 function _getTotalRightAnswers($a_q_id)
01422 {
01423 global $ilDB;
01424 $query = sprintf("SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
01425 $ilDB->quote($a_q_id),
01426 $ilDB->quote($a_q_id)
01427 );
01428 $result = $ilDB->query($query);
01429 if ($result->numRows() == 0)
01430 {
01431 return 0;
01432 }
01433 $found_id = array();
01434 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
01435 {
01436 array_push($found_id, $row->question_id);
01437 }
01438 $query = sprintf("SELECT * FROM tst_test_result WHERE question_fi IN ('%s')",
01439 join($found_id, "','"));
01440 $result = $ilDB->query($query);
01441 $answers = array();
01442 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
01443 {
01444 $reached = $row->points;
01445 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
01446 $max = assQuestion::_getMaximumPoints($row->question_fi);
01447 array_push($answers, array("reached" => $reached, "max" => $max));
01448 }
01449 $max = 0.0;
01450 $reached = 0.0;
01451 foreach ($answers as $key => $value)
01452 {
01453 $max += $value["max"];
01454 $reached += $value["reached"];
01455 }
01456 if ($max > 0)
01457 {
01458 return $reached / $max;
01459 }
01460 else
01461 {
01462 return 0;
01463 }
01464 }
01465
01471 function _getTitle($a_q_id)
01472 {
01473 global $ilDB;
01474 $query = sprintf("SELECT title FROM qpl_questions WHERE question_id = %s",
01475 $ilDB->quote($a_q_id)
01476 );
01477 $result = $ilDB->query($query);
01478 if ($result->numRows() == 1)
01479 {
01480 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01481 return $row["title"];
01482 }
01483 else
01484 {
01485 return "";
01486 }
01487 }
01488
01489 function copyXHTMLMediaObjectsOfQuestion($a_q_id)
01490 {
01491 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
01492 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $a_q_id);
01493 foreach ($mobs as $mob)
01494 {
01495 ilObjMediaObject::_saveUsage($mob, "qpl:html", $this->getId());
01496 }
01497 }
01498
01499 function syncXHTMLMediaObjectsOfQuestion()
01500 {
01501 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
01502 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
01503 foreach ($mobs as $mob)
01504 {
01505 ilObjMediaObject::_saveUsage($mob, "qpl:html", $this->original_id);
01506 }
01507 }
01508
01509 function copyPageOfQuestion($a_q_id)
01510 {
01511 if ($a_q_id > 0)
01512 {
01513 include_once "./Services/COPage/classes/class.ilPageObject.php";
01514 $page = new ilPageObject("qpl", $a_q_id);
01515
01516 $xml = str_replace("il__qst_".$a_q_id, "il__qst_".$this->id,
01517 $page->getXMLContent());
01518 $this->page->setXMLContent($xml);
01519 $this->page->saveMobUsage($xml);
01520 $this->page->updateFromXML();
01521 }
01522 }
01523
01524 function getPageOfQuestion()
01525 {
01526 include_once "./Services/COPage/classes/class.ilPageObject.php";
01527 $page = new ilPageObject("qpl", $this->id);
01528 return $page->getXMLContent();
01529 }
01530
01540 function _getQuestionType($question_id) {
01541 global $ilDB;
01542
01543 if ($question_id < 1)
01544 return "";
01545
01546 $query = sprintf("SELECT type_tag FROM qpl_questions, qpl_question_type WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_question_type.question_type_id",
01547 $ilDB->quote($question_id)
01548 );
01549 $result = $ilDB->query($query);
01550 if ($result->numRows() == 1) {
01551 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
01552 return $data->type_tag;
01553 } else {
01554 return "";
01555 }
01556 }
01557
01567 function _getQuestionTitle($question_id) {
01568 global $ilDB;
01569
01570 if ($question_id < 1)
01571 return "";
01572
01573 $query = sprintf("SELECT title FROM qpl_questions WHERE qpl_questions.question_id = %s",
01574 $ilDB->quote($question_id)
01575 );
01576 $result = $ilDB->query($query);
01577 if ($result->numRows() == 1) {
01578 $data = $result->fetchRow(DB_FETCHMODE_ASSOC);
01579 return $data["title"];
01580 } else {
01581 return "";
01582 }
01583 }
01584
01593 function loadFromDb($question_id)
01594 {
01595 global $ilDB;
01596
01597 $query = sprintf("SELECT * FROM qpl_suggested_solutions WHERE question_fi = %s",
01598 $ilDB->quote($this->getId() . "")
01599 );
01600 $result = $ilDB->query($query);
01601 $this->suggested_solutions = array();
01602 if ($result->numRows())
01603 {
01604 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01605 {
01606 $this->suggested_solutions[$row["subquestion_index"]] = array(
01607 "internal_link" => $row["internal_link"],
01608 "import_id" => $row["import_id"]
01609 );
01610 }
01611 }
01612 }
01613
01622 function saveToDb($original_id = "")
01623 {
01624 global $ilDB;
01625
01626 include_once "./Services/COPage/classes/class.ilInternalLink.php";
01627 $query = sprintf("DELETE FROM qpl_suggested_solutions WHERE question_fi = %s",
01628 $ilDB->quote($this->getId() . "")
01629 );
01630 $result = $ilDB->query($query);
01631 ilInternalLink::_deleteAllLinksOfSource("qst", $this->getId());
01632 foreach ($this->suggested_solutions as $index => $solution)
01633 {
01634 $query = sprintf("INSERT INTO qpl_suggested_solutions (suggested_solution_id, question_fi, internal_link, import_id, subquestion_index, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL)",
01635 $ilDB->quote($this->getId() . ""),
01636 $ilDB->quote($solution["internal_link"] . ""),
01637 $ilDB->quote($solution["import_id"] . ""),
01638 $ilDB->quote($index . "")
01639 );
01640 $ilDB->query($query);
01641 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
01642 {
01643 ilInternalLink::_saveLink("qst", $this->getId(), $matches[2], $matches[3], $matches[1]);
01644 }
01645 }
01646
01647 $this->cleanupMediaObjectUsage();
01648
01649 include_once "./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
01650 ilObjQuestionPool::_updateQuestionCount($this->obj_id);
01651
01652
01653 $query = sprintf("UPDATE qpl_questions SET TIMESTAMP = NULL WHERE question_id = %s",
01654 $this->getId()
01655 );
01656 $ilDB->query($query);
01657 }
01658
01666 function deleteSuggestedSolutions()
01667 {
01668 global $ilDB;
01669
01670 $query = sprintf("DELETE FROM qpl_suggested_solutions WHERE question_fi = %s",
01671 $ilDB->quote($this->getId() . "")
01672 );
01673 $result = $ilDB->query($query);
01674
01675 include_once "./Services/COPage/classes/class.ilInternalLink.php";
01676 ilInternalLink::_deleteAllLinksOfSource("qst", $this->getId());
01677 }
01678
01688 function getSuggestedSolution($subquestion_index = 0)
01689 {
01690 if (array_key_exists($subquestion_index, $this->suggested_solutions))
01691 {
01692 return $this->suggested_solutions[$subquestion_index];
01693 }
01694 else
01695 {
01696 return array();
01697 }
01698 }
01699
01710 function getSuggestedSolutionTitle($subquestion_index = 0)
01711 {
01712 if (array_key_exists($subquestion_index, $this->suggested_solutions))
01713 {
01714 $title = $this->suggested_solutions[$subquestion_index]["internal_link"];
01715
01716 }
01717 else
01718 {
01719 $title = "";
01720 }
01721 return $title;
01722 }
01723
01735 function setSuggestedSolution($solution_id = "", $subquestion_index = 0, $is_import = false)
01736 {
01737 if (strcmp($solution_id, "") != 0)
01738 {
01739 $import_id = "";
01740 if ($is_import)
01741 {
01742 $import_id = $solution_id;
01743 $solution_id = $this->_resolveInternalLink($import_id);
01744 }
01745 $this->suggested_solutions[$subquestion_index] = array(
01746 "internal_link" => $solution_id,
01747 "import_id" => $import_id
01748 );
01749 }
01750 }
01751
01752 function _resolveInternalLink($internal_link)
01753 {
01754 if (preg_match("/il_(\d+)_(\w+)_(\d+)/", $internal_link, $matches))
01755 {
01756 include_once "./Services/COPage/classes/class.ilInternalLink.php";
01757 include_once "./Modules/LearningModule/classes/class.ilLMObject.php";
01758 include_once "./Modules/Glossary/classes/class.ilGlossaryTerm.php";
01759 switch ($matches[2])
01760 {
01761 case "lm":
01762 $resolved_link = ilLMObject::_getIdForImportId($internal_link);
01763 break;
01764 case "pg":
01765 $resolved_link = ilInternalLink::_getIdForImportId("PageObject", $internal_link);
01766 break;
01767 case "st":
01768 $resolved_link = ilInternalLink::_getIdForImportId("StructureObject", $internal_link);
01769 break;
01770 case "git":
01771 $resolved_link = ilInternalLink::_getIdForImportId("GlossaryItem", $internal_link);
01772 break;
01773 case "mob":
01774 $resolved_link = ilInternalLink::_getIdForImportId("MediaObject", $internal_link);
01775 break;
01776 }
01777 if (strcmp($resolved_link, "") == 0)
01778 {
01779 $resolved_link = $internal_link;
01780 }
01781 }
01782 else
01783 {
01784 $resolved_link = $internal_link;
01785 }
01786 return $resolved_link;
01787 }
01788
01789 function _resolveIntLinks($question_id)
01790 {
01791 global $ilDB;
01792 $resolvedlinks = 0;
01793 $query = sprintf("SELECT * FROM qpl_suggested_solutions WHERE question_fi = %s",
01794 $ilDB->quote($question_id . "")
01795 );
01796 $result = $ilDB->query($query);
01797 if ($result->numRows())
01798 {
01799 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01800 {
01801 $internal_link = $row["internal_link"];
01802 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
01803 $resolved_link = assQuestion::_resolveInternalLink($internal_link);
01804 if (strcmp($internal_link, $resolved_link) != 0)
01805 {
01806
01807 $queryupdate = sprintf("UPDATE qpl_suggested_solutions SET internal_link = %s WHERE suggested_solution_id = %s",
01808 $ilDB->quote($resolved_link),
01809 $ilDB->quote($row["suggested_solution_id"] . "")
01810 );
01811 $updateresult = $ilDB->query($queryupdate);
01812 $resolvedlinks++;
01813 }
01814 }
01815 }
01816 if ($resolvedlinks)
01817 {
01818
01819
01820
01821 include_once "./Services/COPage/classes/class.ilInternalLink.php";
01822 ilInternalLink::_deleteAllLinksOfSource("qst", $question_id);
01823
01824 $query = sprintf("SELECT * FROM qpl_suggested_solutions WHERE question_fi = %s",
01825 $ilDB->quote($question_id . "")
01826 );
01827 $result = $ilDB->query($query);
01828 if ($result->numRows())
01829 {
01830 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01831 {
01832 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $row["internal_link"], $matches))
01833 {
01834 ilInternalLink::_saveLink("qst", $question_id, $matches[2], $matches[3], $matches[1]);
01835 }
01836 }
01837 }
01838 }
01839 }
01840
01841 function _getInternalLinkHref($target = "")
01842 {
01843 global $ilDB;
01844 $linktypes = array(
01845 "lm" => "LearningModule",
01846 "pg" => "PageObject",
01847 "st" => "StructureObject",
01848 "git" => "GlossaryItem",
01849 "mob" => "MediaObject"
01850 );
01851 $href = "";
01852 if (preg_match("/il__(\w+)_(\d+)/", $target, $matches))
01853 {
01854 $type = $matches[1];
01855 $target_id = $matches[2];
01856 include_once "./Services/Utilities/classes/class.ilUtil.php";
01857 switch($linktypes[$matches[1]])
01858 {
01859 case "LearningModule":
01860 $href = "./goto.php?target=" . $type . "_" . $target_id;
01861 break;
01862 case "PageObject":
01863 case "StructureObject":
01864 $href = "./goto.php?target=" . $type . "_" . $target_id;
01865 break;
01866 case "GlossaryItem":
01867 $href = "./goto.php?target=" . $type . "_" . $target_id;
01868 break;
01869 case "MediaObject":
01870 $href = "./ilias.php?baseClass=ilLMPresentationGUI&obj_type=" . $linktypes[$type] . "&cmd=media&ref_id=".$_GET["ref_id"]."&mob_id=".$target_id;
01871 break;
01872 }
01873 }
01874 return $href;
01875 }
01876
01886 function _getOriginalId($question_id)
01887 {
01888 global $ilDB;
01889 $query = sprintf("SELECT * FROM qpl_questions WHERE question_id = %s",
01890 $ilDB->quote($question_id . "")
01891 );
01892 $result = $ilDB->query($query);
01893 if ($result->numRows() > 0)
01894 {
01895 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01896 if ($row["original_id"] > 0)
01897 {
01898 return $row["original_id"];
01899 }
01900 else
01901 {
01902 return $row["question_id"];
01903 }
01904 }
01905 else
01906 {
01907 return "";
01908 }
01909 }
01910
01911 function syncWithOriginal()
01912 {
01913 global $ilDB;
01914
01915 if ($this->getOriginalId())
01916 {
01917 $id = $this->getId();
01918 $original = $this->getOriginalId();
01919
01920 $this->setId($this->getOriginalId());
01921 $this->setOriginalId(NULL);
01922 $this->saveToDb();
01923 $this->deletePageOfQuestion($original);
01924 $this->createPageObject();
01925 $this->copyPageOfQuestion($id);
01926
01927 $this->setId($id);
01928 $this->setOriginalId($original);
01929
01930 include_once "./Services/COPage/classes/class.ilInternalLink.php";
01931 $query = sprintf("DELETE FROM qpl_suggested_solutions WHERE question_fi = %s",
01932 $ilDB->quote($this->getOriginalId() . "")
01933 );
01934 $result = $ilDB->query($query);
01935 ilInternalLink::_deleteAllLinksOfSource("qst", $this->original_id);
01936 foreach ($this->suggested_solutions as $index => $solution)
01937 {
01938 $query = sprintf("INSERT INTO qpl_suggested_solutions (suggested_solution_id, question_fi, internal_link, import_id, subquestion_index, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL)",
01939 $ilDB->quote($this->getOriginalId() . ""),
01940 $ilDB->quote($solution["internal_link"] . ""),
01941 $ilDB->quote($solution["import_id"] . ""),
01942 $ilDB->quote($index . "")
01943 );
01944 $ilDB->query($query);
01945 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
01946 {
01947 ilInternalLink::_saveLink("qst", $this->getOriginalId(), $matches[2], $matches[3], $matches[1]);
01948 }
01949 }
01950 $this->syncFeedbackGeneric();
01951 $this->syncXHTMLMediaObjectsOfQuestion();
01952 }
01953 }
01954
01955 function setOriginalId($original_id)
01956 {
01957 $this->original_id = $original_id;
01958 }
01959
01960 function getOriginalId()
01961 {
01962 return $this->original_id;
01963 }
01964
01965 function createRandomSolution($test_id, $user_id)
01966 {
01967 }
01968
01978 function _questionExists($question_id)
01979 {
01980 global $ilDB;
01981
01982 if ($question_id < 1)
01983 {
01984 return false;
01985 }
01986
01987 $query = sprintf("SELECT question_id FROM qpl_questions WHERE question_id = %s",
01988 $ilDB->quote($question_id)
01989 );
01990 $result = $ilDB->query($query);
01991 if ($result->numRows() == 1)
01992 {
01993 return true;
01994 }
01995 else
01996 {
01997 return false;
01998 }
01999 }
02000
02010 function &_instanciateQuestion($question_id)
02011 {
02012 if (strcmp($question_id, "") != 0)
02013 {
02014 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
02015 $question_type = assQuestion::_getQuestionType($question_id);
02016 include_once "./Modules/TestQuestionPool/classes/class.".$question_type.".php";
02017 $question = new $question_type();
02018 $question->loadFromDb($question_id);
02019 return $question;
02020 }
02021 }
02022
02031 function getPoints()
02032 {
02033 if (strcmp($this->points, "") == 0)
02034 {
02035 return 0;
02036 }
02037 else
02038 {
02039 return $this->points;
02040 }
02041 }
02042
02043
02052 function setPoints($a_points)
02053 {
02054 $this->points = $a_points;
02055 }
02056
02065 function getSolutionMaxPass($active_id)
02066 {
02067 return $this->_getSolutionMaxPass($this->getId(), $active_id);
02068 }
02069
02078 function _getSolutionMaxPass($question_id, $active_id)
02079 {
02080
02081
02082
02083
02084
02085
02086
02087 global $ilDB;
02088
02089 $query = sprintf("SELECT MAX(pass) as maxpass FROM tst_test_result WHERE active_fi = %s AND question_fi = %s",
02090 $ilDB->quote($active_id . ""),
02091 $ilDB->quote($question_id . "")
02092 );
02093 $result = $ilDB->query($query);
02094 if ($result->numRows() == 1)
02095 {
02096 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
02097 return $row["maxpass"];
02098 }
02099 else
02100 {
02101 return 0;
02102 }
02103 }
02104
02115 function _isWriteable($question_id, $user_id)
02116 {
02117 global $ilDB;
02118
02119 if (($question_id < 1) || ($user_id < 1))
02120 {
02121 return false;
02122 }
02123
02124 $query = sprintf("SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
02125 $ilDB->quote($question_id . "")
02126 );
02127 $result = $ilDB->query($query);
02128 if ($result->numRows() == 1)
02129 {
02130 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
02131 $qpl_object_id = $row["obj_fi"];
02132 include_once "./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
02133 return ilObjQuestionPool::_isWriteable($qpl_object_id, $user_id);
02134 }
02135 else
02136 {
02137 return false;
02138 }
02139 }
02140
02149 function _isUsedInRandomTest($question_id = "")
02150 {
02151 global $ilDB;
02152
02153 if ($question_id < 1) return 0;
02154 $query = sprintf("SELECT test_random_question_id FROM tst_test_random_question WHERE question_fi = %s",
02155 $ilDB->quote($question_id . "")
02156 );
02157 $result = $ilDB->query($query);
02158 return $result->numRows();
02159 }
02160
02172 function calculateReachedPoints($active_id, $pass = NULL, $points = 0)
02173 {
02174 include_once "./Modules/Test/classes/class.ilObjTest.php";
02175 $count_system = ilObjTest::_getCountSystem($active_id);
02176 if ($count_system == 1)
02177 {
02178 if ($points != $this->getMaximumPoints())
02179 {
02180 $points = 0;
02181 }
02182 }
02183 $score_cutting = ilObjTest::_getScoreCutting($active_id);
02184 if ($score_cutting == 0)
02185 {
02186 if ($points < 0)
02187 {
02188 $points = 0;
02189 }
02190 }
02191 return $points;
02192 }
02193
02205 function _isWorkedThrough($active_id, $question_id, $pass = NULL)
02206 {
02207 global $ilDB;
02208
02209 $points = 0;
02210 if (is_null($pass))
02211 {
02212 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
02213 $pass = assQuestion::_getSolutionMaxPass($question_id, $active_id);
02214 }
02215 $query = sprintf("SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
02216 $ilDB->quote($active_id . ""),
02217 $ilDB->quote($question_id . ""),
02218 $ilDB->quote($pass . "")
02219 );
02220 $result = $ilDB->query($query);
02221 if ($result->numRows())
02222 {
02223 return TRUE;
02224 }
02225 else
02226 {
02227 return FALSE;
02228 }
02229 }
02230
02231 function getMultilineAnswerSetting()
02232 {
02233 global $ilUser;
02234
02235 $multilineAnswerSetting = $ilUser->getPref("tst_multiline_answers");
02236 if ($multilineAnswerSetting != 1)
02237 {
02238 $multilineAnswerSetting = 0;
02239 }
02240 return $multilineAnswerSetting;
02241 }
02242
02243 function setMultilineAnswerSetting($a_setting = 0)
02244 {
02245 global $ilUser;
02246 $ilUser->writePref("tst_multiline_answers", $a_setting);
02247 }
02257 function _areAnswered($a_user_id,$a_question_ids)
02258 {
02259 global $ilDB;
02260
02261 $query = "SELECT DISTINCT(question_fi) FROM tst_test_result JOIN tst_active ".
02262 "ON (active_id = active_fi) ".
02263 "WHERE question_fi IN ('".implode("','",$a_question_ids)."') ".
02264 "AND user_fi = '".$a_user_id."'";
02265 $res = $ilDB->query($query);
02266 return ($res->numRows() == count($a_question_ids)) ? true : false;
02267 }
02268
02276 function isHTML($a_text)
02277 {
02278 if (preg_match("/<[^>]*?>/", $a_text))
02279 {
02280 return TRUE;
02281 }
02282 else
02283 {
02284 return FALSE;
02285 }
02286 }
02287
02294 function prepareTextareaOutput($txt_output, $prepare_for_latex_output = FALSE)
02295 {
02296 include_once "./Services/Utilities/classes/class.ilUtil.php";
02297 return ilUtil::prepareTextareaOutput($txt_output, $prepare_for_latex_output);
02298 }
02299
02307 function QTIMaterialToString($a_material)
02308 {
02309 $result = "";
02310 for ($i = 0; $i < $a_material->getMaterialCount(); $i++)
02311 {
02312 $material = $a_material->getMaterial($i);
02313 if (strcmp($material["type"], "mattext") == 0)
02314 {
02315 $result .= $material["material"]->getContent();
02316 }
02317 if (strcmp($material["type"], "matimage") == 0)
02318 {
02319 $matimage = $material["material"];
02320 if (preg_match("/(il_([0-9]+)_mob_([0-9]+))/", $matimage->getLabel(), $matches))
02321 {
02322
02323 if (!is_array($_SESSION["import_mob_xhtml"])) $_SESSION["import_mob_xhtml"] = array();
02324 array_push($_SESSION["import_mob_xhtml"], array("mob" => $matimage->getLabel(), "uri" => $matimage->getUri()));
02325 }
02326 }
02327 }
02328 return $result;
02329 }
02330
02339 function addQTIMaterial(&$a_xml_writer, $a_material, $close_material_tag = TRUE, $add_mobs = TRUE)
02340 {
02341 include_once "./Services/RTE/classes/class.ilRTE.php";
02342 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
02343
02344 $a_xml_writer->xmlStartTag("material");
02345 $attrs = array(
02346 "texttype" => "text/plain"
02347 );
02348 if ($this->isHTML($a_material))
02349 {
02350 $attrs["texttype"] = "text/xhtml";
02351 }
02352 $a_xml_writer->xmlElement("mattext", $attrs, ilRTE::_replaceMediaObjectImageSrc($a_material, 0));
02353 if ($add_mobs)
02354 {
02355 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
02356 foreach ($mobs as $mob)
02357 {
02358 $moblabel = "il_" . IL_INST_ID . "_mob_" . $mob;
02359 if (strpos($a_material, "mm_$mob") !== FALSE)
02360 {
02361 $mob_obj =& new ilObjMediaObject($mob);
02362 $imgattrs = array(
02363 "label" => $moblabel,
02364 "uri" => "objects/" . "il_" . IL_INST_ID . "_mob_" . $mob . "/" . $mob_obj->getTitle()
02365 );
02366 $a_xml_writer->xmlElement("matimage", $imgattrs, NULL);
02367 }
02368 }
02369 }
02370 if ($close_material_tag) $a_xml_writer->xmlEndTag("material");
02371 }
02372
02373 function createNewImageFileName($image_filename)
02374 {
02375 $extension = "";
02376 if (preg_match("/.*\.(png|jpg|gif|jpeg)$/i", $image_filename, $matches))
02377 {
02378 $extension = "." . $matches[1];
02379 }
02380 $image_filename = md5($image_filename) . $extension;
02381 return $image_filename;
02382 }
02383
02396 function _setReachedPoints($active_id, $question_id, $points, $maxpoints, $pass = NULL)
02397 {
02398 global $ilDB;
02399
02400 if ($points <= $maxpoints)
02401 {
02402 if (is_null($pass))
02403 {
02404 $pass = assQuestion::_getSolutionMaxPass($question_id, $active_id);
02405 }
02406
02407
02408 $old_points = 0;
02409 $query = sprintf("SELECT points FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
02410 $ilDB->quote($active_id . ""),
02411 $ilDB->quote($question_id . ""),
02412 $ilDB->quote($pass . "")
02413 );
02414 $result = $ilDB->query($query);
02415 if ($result->numRows())
02416 {
02417 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
02418 $old_points = $row["points"];
02419 $query = sprintf("UPDATE tst_test_result SET points = %s WHERE active_fi = %s AND question_fi = %s AND pass = %s",
02420 $ilDB->quote($points . ""),
02421 $ilDB->quote($active_id . ""),
02422 $ilDB->quote($question_id . ""),
02423 $ilDB->quote($pass . "")
02424 );
02425 }
02426 else
02427 {
02428 $query = sprintf("INSERT INTO tst_test_result (active_fi, question_fi, points, pass) VALUES (%s, %s, %s, %s)",
02429 $ilDB->quote($active_id . ""),
02430 $ilDB->quote($question_id . ""),
02431 $ilDB->quote($points . ""),
02432 $ilDB->quote($pass . "")
02433 );
02434 }
02435 $result = $ilDB->query($query);
02436 if ($result != DB_OK)
02437 {
02438 return FALSE;
02439 }
02440 assQuestion::_updateTestPassResults($active_id, $pass);
02441
02442 include_once "./Modules/Test/classes/class.ilObjTest.php";
02443 include_once './Modules/Course/classes/class.ilCourseObjectiveResult.php';
02444 ilCourseObjectiveResult::_updateObjectiveResult(ilObjTest::_getUserIdFromActiveId($active_id),$question_id,$points);
02445
02446 include_once ("./classes/class.ilObjAssessmentFolder.php");
02447 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
02448 {
02449 global $lng, $ilUser;
02450 include_once "./Modules/Test/classes/class.ilObjTestAccess.php";
02451 $username = ilObjTestAccess::_getParticipantData($active_id);
02452 assQuestion::_logAction(sprintf($lng->txtlng("assessment", "log_answer_changed_points", ilObjAssessmentFolder::_getLogLanguage()), $username, $old_points, $points, $ilUser->getFullname() . " (" . $ilUser->getLogin() . ")"), $active_id, $question_id);
02453 }
02454
02455 return TRUE;
02456 }
02457 else
02458 {
02459 return FALSE;
02460 }
02461 }
02462
02472 function getQuestion()
02473 {
02474 return $this->question;
02475 }
02476
02486 function setQuestion($question = "")
02487 {
02488 $this->question = $question;
02489 }
02490
02499 function getQuestionType()
02500 {
02501
02502 return "";
02503 }
02504
02513 function getQuestionTypeID()
02514 {
02515 global $ilDB;
02516
02517 $query = sprintf("SELECT question_type_id FROM qpl_question_type WHERE type_tag = %s",
02518 $ilDB->quote($this->getQuestionType() . "")
02519 );
02520 $result = $ilDB->query($query);
02521 if ($result->numRows() == 1)
02522 {
02523 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
02524 return $row["question_type_id"];
02525 }
02526 return 0;
02527 }
02528
02540 function saveFeedbackGeneric($correctness, $feedback)
02541 {
02542 global $ilDB;
02543
02544 switch ($correctness)
02545 {
02546 case 0:
02547 $correctness = 0;
02548 break;
02549 case 1:
02550 default:
02551 $correctness = 1;
02552 break;
02553 }
02554 $query = sprintf("DELETE FROM qpl_feedback_generic WHERE question_fi = %s AND correctness = %s",
02555 $ilDB->quote($this->getId() . ""),
02556 $ilDB->quote($correctness . "")
02557 );
02558 $result = $ilDB->query($query);
02559 if (strlen($feedback))
02560 {
02561 include_once("./Services/RTE/classes/class.ilRTE.php");
02562 $query = sprintf("INSERT INTO qpl_feedback_generic VALUES (NULL, %s, %s, %s, NULL)",
02563 $ilDB->quote($this->getId() . ""),
02564 $ilDB->quote($correctness . ""),
02565 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($feedback, 0))
02566 );
02567 $result = $ilDB->query($query);
02568 }
02569 }
02570
02582 function getFeedbackGeneric($correctness)
02583 {
02584 global $ilDB;
02585
02586 $feedback = "";
02587 $query = sprintf("SELECT * FROM qpl_feedback_generic WHERE question_fi = %s AND correctness = %s",
02588 $ilDB->quote($this->getId() . ""),
02589 $ilDB->quote($correctness . "")
02590 );
02591 $result = $ilDB->query($query);
02592 if ($result->numRows())
02593 {
02594 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
02595 include_once("./Services/RTE/classes/class.ilRTE.php");
02596 $feedback = ilRTE::_replaceMediaObjectImageSrc($row["feedback"], 1);
02597 }
02598 return $feedback;
02599 }
02600
02609 function duplicateFeedbackGeneric($original_id)
02610 {
02611 global $ilDB;
02612
02613 $feedback = "";
02614 $query = sprintf("SELECT * FROM qpl_feedback_generic WHERE question_fi = %s",
02615 $ilDB->quote($original_id . "")
02616 );
02617 $result = $ilDB->query($query);
02618 if ($result->numRows())
02619 {
02620 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
02621 {
02622 $duplicatequery = sprintf("INSERT INTO qpl_feedback_generic VALUES (NULL, %s, %s, %s, NULL)",
02623 $ilDB->quote($this->getId() . ""),
02624 $ilDB->quote($row["correctness"] . ""),
02625 $ilDB->quote($row["feedback"] . "")
02626 );
02627 $duplicateresult = $ilDB->query($duplicatequery);
02628 }
02629 }
02630 }
02631
02632 function syncFeedbackGeneric()
02633 {
02634 global $ilDB;
02635
02636 $feedback = "";
02637
02638
02639 $deletequery = sprintf("DELETE FROM qpl_feedback_generic WHERE question_fi = %s",
02640 $ilDB->quote($this->original_id . "")
02641 );
02642 $result = $ilDB->query($deletequery);
02643
02644
02645 $query = sprintf("SELECT * FROM qpl_feedback_generic WHERE question_fi = %s",
02646 $ilDB->quote($this->getId() . "")
02647 );
02648 $result = $ilDB->query($query);
02649
02650
02651 if ($result->numRows())
02652 {
02653 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
02654 {
02655 $duplicatequery = sprintf("INSERT INTO qpl_feedback_generic VALUES (NULL, %s, %s, %s, NULL)",
02656 $ilDB->quote($this->original_id . ""),
02657 $ilDB->quote($row["correctness"] . ""),
02658 $ilDB->quote($row["feedback"] . "")
02659 );
02660 $duplicateresult = $ilDB->query($duplicatequery);
02661 }
02662 }
02663 }
02664
02669 function getRTETextWithMediaObjects()
02670 {
02671
02672
02673 $collected = $this->getQuestion();
02674 $collected .= $this->getFeedbackGeneric(0);
02675 $collected .= $this->getFeedbackGeneric(1);
02676 return $collected;
02677 }
02678
02683 function cleanupMediaObjectUsage()
02684 {
02685 $combinedtext = $this->getRTETextWithMediaObjects();
02686 include_once("./Services/RTE/classes/class.ilRTE.php");
02687 ilRTE::_cleanupMediaObjectUsage($combinedtext, "qpl:html", $this->getId());
02688 }
02689
02695 function &getInstances()
02696 {
02697 global $ilDB;
02698 $query = sprintf("SELECT question_id FROM qpl_questions WHERE original_id = %s",
02699 $ilDB->quote($this->getId())
02700 );
02701 $result = $ilDB->query($query);
02702 $instances = array();
02703 $ids = array();
02704 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
02705 {
02706 array_push($ids, $row["question_id"]);
02707 }
02708 foreach ($ids as $question_id)
02709 {
02710 $query = sprintf("SELECT DISTINCT object_data.obj_id, object_data.title FROM tst_test_question, object_data, tst_tests WHERE question_fi = %s AND tst_tests.test_id = tst_test_question.test_fi AND object_data.obj_id = tst_tests.obj_fi",
02711 $ilDB->quote($question_id . "")
02712 );
02713 $result = $ilDB->query($query);
02714 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
02715 {
02716 $instances[$row["obj_id"]] = $row["title"];
02717 }
02718 $query = sprintf("SELECT DISTINCT object_data.obj_id, object_data.title FROM tst_test_random_question, tst_active, object_data, tst_tests WHERE tst_test_random_question.active_fi = tst_active.active_id AND tst_test_random_question.question_fi = %s AND tst_tests.test_id = tst_active.test_fi AND object_data.obj_id = tst_tests.obj_fi",
02719 $ilDB->quote($question_id . "")
02720 );
02721 $result = $ilDB->query($query);
02722 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
02723 {
02724 $instances[$row["obj_id"]] = $row["title"];
02725 }
02726 }
02727 include_once "./Modules/Test/classes/class.ilObjTest.php";
02728 foreach ($instances as $key => $value)
02729 {
02730 $query = sprintf("SELECT object_reference.ref_id FROM object_reference WHERE obj_id = %s",
02731 $ilDB->quote($key . "")
02732 );
02733 $result = $ilDB->query($query);
02734 $refs = array();
02735 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
02736 {
02737 array_push($refs, $row["ref_id"]);
02738 }
02739 $instances[$key] = array("obj_id" => $key, "title" => $value, "author" => ilObjTest::_lookupAuthor($key), "refs" => $refs);
02740 }
02741 return $instances;
02742 }
02743
02744 function _needsManualScoring($question_id)
02745 {
02746 include_once "./classes/class.ilObjAssessmentFolder.php";
02747 $scoring = ilObjAssessmentFolder::_getManualScoringTypes();
02748 $questiontype = assQuestion::_getQuestionType($question_id);
02749 if (in_array($questiontype, $scoring))
02750 {
02751 return TRUE;
02752 }
02753 else
02754 {
02755 return FALSE;
02756 }
02757 }
02758
02766 function getActiveUserData($active_id)
02767 {
02768 global $ilDB;
02769 $query = sprintf("SELECT * FROM tst_active WHERE active_id = %s",
02770 $ilDB->quote($active_id . "")
02771 );
02772 $result = $ilDB->query($query);
02773 if ($result->numRows())
02774 {
02775 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
02776 return array("user_id" => $row["user_fi"], "test_id" => $row["test_fi"]);
02777 }
02778 else
02779 {
02780 return array();
02781 }
02782 }
02783 }
02784
02785 ?>