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/TestQuestionPool/classes/class.assQuestion.php";
00025 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
00026
00036 class assOrderingQuestion extends assQuestion
00037 {
00045 var $answers;
00046
00055 var $ordering_type;
00056
00069 function assOrderingQuestion (
00070 $title = "",
00071 $comment = "",
00072 $author = "",
00073 $owner = -1,
00074 $question = "",
00075 $ordering_type = OQ_TERMS
00076 )
00077 {
00078 $this->assQuestion($title, $comment, $author, $owner, $question);
00079 $this->answers = array();
00080 $this->ordering_type = $ordering_type;
00081 }
00082
00091 function isComplete()
00092 {
00093 if (($this->title) and ($this->author) and ($this->question) and (count($this->answers)) and ($this->getMaximumPoints() > 0))
00094 {
00095 return true;
00096 }
00097 else
00098 {
00099 return false;
00100 }
00101 }
00102
00111 function saveToDb($original_id = "")
00112 {
00113 global $ilDB;
00114
00115 $complete = 0;
00116 if ($this->isComplete())
00117 {
00118 $complete = 1;
00119 }
00120
00121 $estw_time = $this->getEstimatedWorkingTime();
00122 $estw_time = sprintf("%02d:%02d:%02d", $estw_time['h'], $estw_time['m'], $estw_time['s']);
00123
00124 if ($original_id)
00125 {
00126 $original_id = $ilDB->quote($original_id);
00127 }
00128 else
00129 {
00130 $original_id = "NULL";
00131 }
00132
00133 include_once("./Services/RTE/classes/class.ilRTE.php");
00134 if ($this->id == -1)
00135 {
00136
00137 $now = getdate();
00138 $question_type = $this->getQuestionTypeID();
00139 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00140 $query = sprintf("INSERT INTO qpl_questions (question_id, question_type_fi, obj_fi, title, comment, author, owner, question_text, working_time, points, complete, created, original_id, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
00141 $ilDB->quote($question_type . ""),
00142 $ilDB->quote($this->obj_id . ""),
00143 $ilDB->quote($this->title . ""),
00144 $ilDB->quote($this->comment . ""),
00145 $ilDB->quote($this->author . ""),
00146 $ilDB->quote($this->owner . ""),
00147 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
00148 $ilDB->quote($estw_time . ""),
00149 $ilDB->quote($this->getMaximumPoints() . ""),
00150 $ilDB->quote($complete . ""),
00151 $ilDB->quote($created . ""),
00152 $original_id
00153 );
00154 $result = $ilDB->query($query);
00155 if ($result == DB_OK)
00156 {
00157 $this->id = $ilDB->getLastInsertId();
00158 $query = sprintf("INSERT INTO qpl_question_ordering (question_fi, ordering_type) VALUES (%s, %s)",
00159 $ilDB->quote($this->id . ""),
00160 $ilDB->quote($this->ordering_type . "")
00161 );
00162 $ilDB->query($query);
00163
00164
00165 $this->createPageObject();
00166
00167 if ($this->getTestId() > 0)
00168 {
00169 $this->insertIntoTest($this->getTestId());
00170 }
00171 }
00172 }
00173 else
00174 {
00175
00176 $query = sprintf("UPDATE qpl_questions SET obj_fi = %s, title = %s, comment = %s, author = %s, question_text = %s, working_time = %s, points = %s, complete = %s WHERE question_id = %s",
00177 $ilDB->quote($this->obj_id. ""),
00178 $ilDB->quote($this->title . ""),
00179 $ilDB->quote($this->comment . ""),
00180 $ilDB->quote($this->author . ""),
00181 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($this->question, 0)),
00182 $ilDB->quote($estw_time . ""),
00183 $ilDB->quote($this->getMaximumPoints() . ""),
00184 $ilDB->quote($complete . ""),
00185 $ilDB->quote($this->id . "")
00186 );
00187 $result = $ilDB->query($query);
00188 $query = sprintf("UPDATE qpl_question_ordering SET ordering_type = %s WHERE question_fi = %s",
00189 $ilDB->quote($this->ordering_type . ""),
00190 $ilDB->quote($this->id . "")
00191 );
00192 $result = $ilDB->query($query);
00193 }
00194 if ($result == DB_OK)
00195 {
00196
00197
00198 $query = sprintf("DELETE FROM qpl_answer_ordering WHERE question_fi = %s",
00199 $ilDB->quote($this->id)
00200 );
00201 $result = $ilDB->query($query);
00202
00203
00204 foreach ($this->answers as $key => $value)
00205 {
00206 $answer_obj = $this->answers[$key];
00207 $query = sprintf("INSERT INTO qpl_answer_ordering (answer_id, question_fi, answertext, points, aorder, solution_order) VALUES (NULL, %s, %s, %s, %s, %s)",
00208 $ilDB->quote($this->id),
00209 $ilDB->quote(ilRTE::_replaceMediaObjectImageSrc($answer_obj->getAnswertext(), 0)),
00210 $ilDB->quote($answer_obj->getPoints() . ""),
00211 $ilDB->quote($answer_obj->getOrder() . ""),
00212 $ilDB->quote($answer_obj->getSolutionOrder() . "")
00213 );
00214 $answer_result = $ilDB->query($query);
00215 }
00216 }
00217 parent::saveToDb($original_id);
00218 }
00219
00229 function loadFromDb($question_id)
00230 {
00231 global $ilDB;
00232
00233 $query = sprintf("SELECT qpl_questions.*, qpl_question_ordering.* FROM qpl_questions, qpl_question_ordering WHERE question_id = %s AND qpl_questions.question_id = qpl_question_ordering.question_fi",
00234 $ilDB->quote($question_id)
00235 );
00236 $result = $ilDB->query($query);
00237 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00238 {
00239 if ($result->numRows() == 1)
00240 {
00241 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00242 $this->id = $question_id;
00243 $this->title = $data->title;
00244 $this->obj_id = $data->obj_fi;
00245 $this->comment = $data->comment;
00246 $this->original_id = $data->original_id;
00247 $this->author = $data->author;
00248 $this->owner = $data->owner;
00249 include_once("./Services/RTE/classes/class.ilRTE.php");
00250 $this->question = ilRTE::_replaceMediaObjectImageSrc($data->question_text, 1);
00251 $this->solution_hint = $data->solution_hint;
00252 $this->ordering_type = $data->ordering_type;
00253 $this->points = $data->points;
00254 $this->setEstimatedWorkingTime(substr($data->working_time, 0, 2), substr($data->working_time, 3, 2), substr($data->working_time, 6, 2));
00255 }
00256
00257 $query = sprintf("SELECT * FROM qpl_answer_ordering WHERE question_fi = %s ORDER BY aorder ASC",
00258 $ilDB->quote($question_id)
00259 );
00260 $result = $ilDB->query($query);
00261 include_once "./Modules/TestQuestionPool/classes/class.assAnswerOrdering.php";
00262 if (strcmp(strtolower(get_class($result)), db_result) == 0)
00263 {
00264 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00265 {
00266 include_once("./Services/RTE/classes/class.ilRTE.php");
00267 $data->answertext = ilRTE::_replaceMediaObjectImageSrc($data->answertext, 1);
00268 array_push($this->answers, new ASS_AnswerOrdering($data->answertext, $data->points, $data->aorder, $data->solution_order));
00269 }
00270 }
00271 }
00272 parent::loadFromDb($question_id);
00273 }
00274
00282 function duplicate($for_test = true, $title = "", $author = "", $owner = "")
00283 {
00284 if ($this->id <= 0)
00285 {
00286
00287 return;
00288 }
00289
00290 $this_id = $this->getId();
00291 $clone = $this;
00292 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
00293 $original_id = assQuestion::_getOriginalId($this->id);
00294 $clone->id = -1;
00295 if ($title)
00296 {
00297 $clone->setTitle($title);
00298 }
00299 if ($author)
00300 {
00301 $clone->setAuthor($author);
00302 }
00303 if ($owner)
00304 {
00305 $clone->setOwner($owner);
00306 }
00307 if ($for_test)
00308 {
00309 $clone->saveToDb($original_id);
00310 }
00311 else
00312 {
00313 $clone->saveToDb();
00314 }
00315
00316
00317 $clone->copyPageOfQuestion($this_id);
00318
00319 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
00320
00321 $clone->duplicateFeedbackGeneric($this_id);
00322
00323
00324 $clone->duplicateImages($this_id);
00325 return $clone->id;
00326 }
00327
00335 function copyObject($target_questionpool, $title = "")
00336 {
00337 if ($this->id <= 0)
00338 {
00339
00340 return;
00341 }
00342
00343 $clone = $this;
00344 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
00345 $original_id = assQuestion::_getOriginalId($this->id);
00346 $clone->id = -1;
00347 $source_questionpool = $this->getObjId();
00348 $clone->setObjId($target_questionpool);
00349 if ($title)
00350 {
00351 $clone->setTitle($title);
00352 }
00353
00354 $clone->saveToDb();
00355
00356
00357 $clone->copyPageOfQuestion($original_id);
00358
00359 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
00360
00361 $clone->duplicateFeedbackGeneric($original_id);
00362
00363
00364 $clone->copyImages($original_id, $source_questionpool);
00365 return $clone->id;
00366 }
00367
00368 function duplicateImages($question_id)
00369 {
00370 if ($this->getOrderingType() == OQ_PICTURES)
00371 {
00372 $imagepath = $this->getImagePath();
00373 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00374 if (!file_exists($imagepath)) {
00375 ilUtil::makeDirParents($imagepath);
00376 }
00377 foreach ($this->answers as $answer)
00378 {
00379 $filename = $answer->getAnswertext();
00380 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
00381 print "image could not be duplicated!!!! ";
00382 }
00383 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg")) {
00384 print "image thumbnail could not be duplicated!!!! ";
00385 }
00386 }
00387 }
00388 }
00389
00390 function copyImages($question_id, $source_questionpool)
00391 {
00392 if ($this->getOrderingType() == OQ_PICTURES)
00393 {
00394 $imagepath = $this->getImagePath();
00395 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
00396 $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
00397 if (!file_exists($imagepath)) {
00398 ilUtil::makeDirParents($imagepath);
00399 }
00400 foreach ($this->answers as $answer)
00401 {
00402 $filename = $answer->getAnswertext();
00403 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
00404 print "image could not be copied!!!! ";
00405 }
00406 if (!copy($imagepath_original . $filename . ".thumb.jpg", $imagepath . $filename . ".thumb.jpg")) {
00407 print "image thumbnail could not be copied!!!! ";
00408 }
00409 }
00410 }
00411 }
00412
00422 function setOrderingType($ordering_type = OQ_TERMS)
00423 {
00424 $this->ordering_type = $ordering_type;
00425 }
00426
00436 function getOrderingType()
00437 {
00438 return $this->ordering_type;
00439 }
00440
00456 function addAnswer(
00457 $answertext = "",
00458 $points = 0.0,
00459 $order = 0,
00460 $solution_order = 0
00461 )
00462 {
00463 $found = -1;
00464 foreach ($this->answers as $key => $value)
00465 {
00466 if ($value->getOrder() == $order)
00467 {
00468 $found = $order;
00469 }
00470 }
00471 include_once "./Modules/TestQuestionPool/classes/class.assAnswerOrdering.php";
00472 if ($found >= 0)
00473 {
00474
00475 $answer = new ASS_AnswerOrdering($answertext, $points, $found, $solution_order);
00476 array_push($this->answers, $answer);
00477 for ($i = $found + 1; $i < count($this->answers); $i++)
00478 {
00479 $this->answers[$i] = $this->answers[$i-1];
00480 }
00481 $this->answers[$found] = $answer;
00482 }
00483 else
00484 {
00485
00486 $answer = new ASS_AnswerOrdering($answertext, $points,
00487 count($this->answers), $solution_order);
00488 array_push($this->answers, $answer);
00489 }
00490 }
00491
00503 function getAnswer($index = 0)
00504 {
00505 if ($index < 0) return NULL;
00506 if (count($this->answers) < 1) return NULL;
00507 if ($index >= count($this->answers)) return NULL;
00508 return $this->answers[$index];
00509 }
00510
00521 function deleteAnswer($index = 0)
00522 {
00523 if ($index < 0)
00524 {
00525 return;
00526 }
00527 if (count($this->answers) < 1)
00528 {
00529 return;
00530 }
00531 if ($index >= count($this->answers))
00532 {
00533 return;
00534 }
00535 unset($this->answers[$index]);
00536 $this->answers = array_values($this->answers);
00537 for ($i = 0; $i < count($this->answers); $i++)
00538 {
00539 if ($this->answers[$i]->getOrder() > $index)
00540 {
00541 $this->answers[$i]->setOrder($i);
00542 }
00543 }
00544 }
00545
00554 function flushAnswers()
00555 {
00556 $this->answers = array();
00557 }
00558
00568 function getAnswerCount()
00569 {
00570 return count($this->answers);
00571 }
00572
00581 function getMaxSolutionOrder()
00582 {
00583 if (count($this->answers) == 0)
00584 {
00585 $max = 0;
00586 }
00587 else
00588 {
00589 $max = $this->answers[0]->getSolutionOrder();
00590 }
00591 foreach ($this->answers as $key => $value)
00592 {
00593 if ($value->getSolutionOrder() > $max)
00594 {
00595 $max = $value->getSolutionOrder();
00596 }
00597 }
00598 return $max;
00599 }
00600
00612 function calculateReachedPoints($active_id, $pass = NULL)
00613 {
00614 global $ilDB;
00615
00616 $found_value1 = array();
00617 $found_value2 = array();
00618 if (is_null($pass))
00619 {
00620 $pass = $this->getSolutionMaxPass($active_id);
00621 }
00622 $query = sprintf("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
00623 $ilDB->quote($active_id . ""),
00624 $ilDB->quote($this->getId() . ""),
00625 $ilDB->quote($pass . "")
00626 );
00627 $result = $ilDB->query($query);
00628 $user_order = array();
00629 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
00630 {
00631 if ((strcmp($data->value1, "") != 0) && (strcmp($data->value2, "") != 0))
00632 {
00633 $user_order[$data->value2] = $data->value1;
00634 }
00635 }
00636 ksort($user_order);
00637 $user_order = array_values($user_order);
00638 $answer_order = array();
00639 foreach ($this->answers as $key => $answer)
00640 {
00641 $answer_order[$answer->getSolutionOrder()] = $key;
00642 }
00643 ksort($answer_order);
00644 $answer_order = array_values($answer_order);
00645 $points = 0;
00646 foreach ($answer_order as $index => $answer_id)
00647 {
00648 if (strcmp($user_order[$index], "") != 0)
00649 {
00650 if ($answer_id == $user_order[$index])
00651 {
00652 $points += $this->answers[$answer_id]->getPoints();
00653 }
00654 }
00655 }
00656
00657 $points = parent::calculateReachedPoints($active_id, $pass = NULL, $points);
00658 return $points;
00659 }
00660
00669 function getMaximumPoints()
00670 {
00671 $points = 0;
00672 foreach ($this->answers as $key => $value)
00673 {
00674 $points += $value->getPoints();
00675 }
00676 return $points;
00677 }
00678
00689 function setImageFile($image_filename, $image_tempfilename = "")
00690 {
00691 $result = 0;
00692 if (!empty($image_tempfilename))
00693 {
00694 $imagepath = $this->getImagePath();
00695 if (!file_exists($imagepath))
00696 {
00697 ilUtil::makeDirParents($imagepath);
00698 }
00699 if (!ilUtil::moveUploadedFile($image_tempfilename,$image_filename, $imagepath.$image_filename))
00700 {
00701 $result = 2;
00702 }
00703 else
00704 {
00705 include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
00706 $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
00707 if (!preg_match("/^image/", $mimetype))
00708 {
00709 unlink($imagepath . $image_filename);
00710 $result = 1;
00711 }
00712 else
00713 {
00714
00715 $thumbpath = $imagepath . $image_filename . "." . "thumb.jpg";
00716 ilUtil::convertImage($imagepath.$image_filename, $thumbpath, strtoupper($extension), 100);
00717 }
00718 }
00719 }
00720 return $result;
00721 }
00722
00732 function checkSaveData()
00733 {
00734 $result = true;
00735 if ($this->getOutputType() == OUTPUT_JAVASCRIPT)
00736 {
00737 if (strlen($_POST["orderresult"]))
00738 {
00739 return $result;
00740 }
00741 }
00742 $order_values = array();
00743 foreach ($_POST as $key => $value)
00744 {
00745 if (preg_match("/^order_(\d+)/", $key, $matches))
00746 {
00747 if (strcmp($value, "") != 0)
00748 {
00749 array_push($order_values, $value);
00750 }
00751 }
00752 }
00753 $check_order = array_flip($order_values);
00754 if (count($check_order) != count($order_values))
00755 {
00756
00757 $result = false;
00758 ilUtil::sendInfo($this->lng->txt("duplicate_order_values_entered"), TRUE);
00759 }
00760 return $result;
00761 }
00762
00773 function saveWorkingData($active_id, $pass = NULL)
00774 {
00775 global $ilDB;
00776 global $ilUser;
00777
00778 $saveWorkingDataResult = $this->checkSaveData();
00779 $entered_values = 0;
00780 if ($saveWorkingDataResult)
00781 {
00782 if (is_null($pass))
00783 {
00784 include_once "./Modules/Test/classes/class.ilObjTest.php";
00785 $pass = ilObjTest::_getPass($active_id);
00786 }
00787
00788 $query = sprintf("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
00789 $ilDB->quote($active_id . ""),
00790 $ilDB->quote($this->getId() . ""),
00791 $ilDB->quote($pass . "")
00792 );
00793 $result = $ilDB->query($query);
00794 if (array_key_exists("orderresult", $_POST))
00795 {
00796 $orderresult = $_POST["orderresult"];
00797 if (strlen($orderresult))
00798 {
00799 $orderarray = explode(":", $orderresult);
00800 $ordervalue = 1;
00801 foreach ($orderarray as $index)
00802 {
00803 $query = sprintf("INSERT INTO tst_solutions (solution_id, active_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
00804 $ilDB->quote($active_id . ""),
00805 $ilDB->quote($this->getId() . ""),
00806 $ilDB->quote(trim($index) . ""),
00807 $ilDB->quote(trim($ordervalue) . ""),
00808 $ilDB->quote($pass . "")
00809 );
00810 $result = $ilDB->query($query);
00811 $ordervalue++;
00812 $entered_values++;
00813 }
00814 }
00815 }
00816 else
00817 {
00818 foreach ($_POST as $key => $value)
00819 {
00820 if (preg_match("/^order_(\d+)/", $key, $matches))
00821 {
00822 if (!(preg_match("/initial_value_\d+/", $value)))
00823 {
00824 if (strlen($value))
00825 {
00826 $query = sprintf("INSERT INTO tst_solutions (solution_id, active_fi, question_fi, value1, value2, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
00827 $ilDB->quote($active_id . ""),
00828 $ilDB->quote($this->getId() . ""),
00829 $ilDB->quote($matches[1] . ""),
00830 $ilDB->quote($value . ""),
00831 $ilDB->quote($pass . "")
00832 );
00833 $result = $ilDB->query($query);
00834 $entered_values++;
00835 }
00836 }
00837 }
00838 }
00839 }
00840 }
00841 if ($entered_values)
00842 {
00843 include_once ("./classes/class.ilObjAssessmentFolder.php");
00844 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
00845 {
00846 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
00847 }
00848 }
00849 else
00850 {
00851 include_once ("./classes/class.ilObjAssessmentFolder.php");
00852 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
00853 {
00854 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
00855 }
00856 }
00857 parent::saveWorkingData($active_id, $pass);
00858 return $saveWorkingDataResult;
00859 }
00860
00861 function pc_array_shuffle($array) {
00862 mt_srand((double)microtime()*1000000);
00863 $i = count($array);
00864 while(--$i)
00865 {
00866 $j = mt_rand(0, $i);
00867 if ($i != $j)
00868 {
00869
00870 $tmp = $array[$j];
00871 $array[$j] = $array[$i];
00872 $array[$i] = $tmp;
00873 }
00874 }
00875 return $array;
00876 }
00877
00886 function getQuestionType()
00887 {
00888 return "assOrderingQuestion";
00889 }
00890
00899 function getAdditionalTableName()
00900 {
00901 return "qpl_question_ordering";
00902 }
00903
00912 function getAnswerTableName()
00913 {
00914 return "qpl_answer_ordering";
00915 }
00916
00921 function getRTETextWithMediaObjects()
00922 {
00923 $text = parent::getRTETextWithMediaObjects();
00924 foreach ($this->answers as $index => $answer)
00925 {
00926 $answer_obj = $this->answers[$index];
00927 $text .= $answer_obj->getAnswertext();
00928 }
00929 return $text;
00930 }
00931
00935 function &getAnswers()
00936 {
00937 return $this->answers;
00938 }
00939
00948 function supportsJavascriptOutput()
00949 {
00950 return TRUE;
00951 }
00952 }
00953
00954 ?>