00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00033 class ilTestSequence
00034 {
00042 var $sequencedata;
00043
00051 var $questions;
00052
00060 var $active_id;
00061
00069 var $pass;
00070
00078 var $isRandomTest;
00079
00089 function ilTestSequence($active_id, $pass, $randomtest)
00090 {
00091 $this->active_id = $active_id;
00092 $this->pass = $pass;
00093 $this->isRandomTest = $randomtest;
00094 $this->sequencedata = array(
00095 "sequence" => array(),
00096 "postponed" => array(),
00097 "hidden" => array()
00098 );
00099 $this->loadFromDb();
00100 $this->loadQuestions();
00101 }
00102
00103 function getActiveId()
00104 {
00105 return $this->active_id;
00106 }
00107
00108 function createNewSequence($max, $shuffle)
00109 {
00110 $newsequence = array();
00111 if ($max > 0)
00112 {
00113 for ($i = 1; $i <= $max; $i++)
00114 {
00115 array_push($newsequence, $i);
00116 }
00117 if ($shuffle) $newsequence = $this->pcArrayShuffle($newsequence);
00118 }
00119 $this->sequencedata["sequence"] = $newsequence;
00120 }
00121
00129 private function loadQuestions()
00130 {
00131 global $ilDB;
00132
00133 $this->questions = array();
00134 if ($this->isRandomTest)
00135 {
00136 $query = sprintf("SELECT tst_test_random_question.* FROM tst_test_random_question, qpl_questions WHERE tst_test_random_question.active_fi = %s AND qpl_questions.question_id = tst_test_random_question.question_fi AND tst_test_random_question.pass = %s ORDER BY sequence",
00137 $ilDB->quote($this->active_id . ""),
00138 $ilDB->quote($this->pass . "")
00139 );
00140 $result = $ilDB->query($query);
00141
00142
00143
00144
00145 if ($result->numRows() == 0)
00146 {
00147 $query = sprintf("SELECT tst_test_random_question.* FROM tst_test_random_question, qpl_questions WHERE tst_test_random_question.active_fi = %s AND qpl_questions.question_id = tst_test_random_question.question_fi AND tst_test_random_question.pass = 0 ORDER BY sequence",
00148 $ilDB->quote($this->active_id . "")
00149 );
00150 $result = $ilDB->query($query);
00151 }
00152 }
00153 else
00154 {
00155 $query = sprintf("SELECT tst_test_question.* FROM tst_test_question, qpl_questions, tst_active WHERE tst_active.active_id = %s AND tst_test_question.test_fi = tst_active.test_fi AND qpl_questions.question_id = tst_test_question.question_fi ORDER BY tst_test_question.sequence",
00156 $ilDB->quote($this->active_id . "")
00157 );
00158 $result = $ilDB->query($query);
00159 }
00160 $index = 1;
00161 while ($data = $result->fetchRow(DB_FETCHMODE_ASSOC))
00162 {
00163 $this->questions[$index++] = $data["question_fi"];
00164 }
00165 }
00166
00175 private function loadFromDb()
00176 {
00177 global $ilDB;
00178 $query = sprintf("SELECT * FROM tst_sequence WHERE active_fi = %s AND pass = %s",
00179 $ilDB->quote($this->active_id . ""),
00180 $ilDB->quote($this->pass . "")
00181 );
00182 $result = $ilDB->query($query);
00183 if ($result->numRows())
00184 {
00185 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00186 $this->sequencedata = array(
00187 "sequence" => unserialize($row["sequence"]),
00188 "postponed" => unserialize($row["postponed"]),
00189 "hidden" => unserialize($row["hidden"])
00190 );
00191 if (!is_array($this->sequencedata["sequence"])) $this->sequencedata["sequence"] = array();
00192 if (!is_array($this->sequencedata["postponed"])) $this->sequencedata["postponed"] = array();
00193 if (!is_array($this->sequencedata["hidden"])) $this->sequencedata["hidden"] = array();
00194 }
00195 }
00196
00204 public function saveToDb()
00205 {
00206 global $ilDB;
00207
00208 $postponed = "NULL";
00209 if ((is_array($this->sequencedata["postponed"])) && (count($this->sequencedata["postponed"])))
00210 {
00211 $postponed = $ilDB->quote(serialize($this->sequencedata["postponed"]));
00212 }
00213 $hidden = "NULL";
00214 if ((is_array($this->sequencedata["hidden"])) && (count($this->sequencedata["hidden"])))
00215 {
00216 $hidden = $ilDB->quote(serialize($this->sequencedata["hidden"]));
00217 }
00218
00219 $query = sprintf("REPLACE INTO tst_sequence (active_fi, pass, sequence, postponed, hidden) VALUES (%s, %s, %s, %s, %s)",
00220 $ilDB->quote($this->active_id . ""),
00221 $ilDB->quote($this->pass . ""),
00222 $ilDB->quote(serialize($this->sequencedata["sequence"])),
00223 $postponed,
00224 $hidden
00225 );
00226 $result = $ilDB->query($query);
00227 }
00228
00229 function postponeQuestion($question_id)
00230 {
00231 if (!$this->isPostponedQuestion($question_id))
00232 {
00233 array_push($this->sequencedata["postponed"], intval($question_id));
00234 }
00235 }
00236
00237 function hideQuestion($question_id)
00238 {
00239 if (!$this->isHiddenQuestion($question_id))
00240 {
00241 array_push($this->sequencedata["hidden"], intval($question_id));
00242 }
00243 }
00244
00245 function isPostponedQuestion($question_id)
00246 {
00247 if (!is_array($this->sequencedata["postponed"])) return FALSE;
00248 if (!in_array($question_id, $this->sequencedata["postponed"]))
00249 {
00250 return FALSE;
00251 }
00252 else
00253 {
00254 return TRUE;
00255 }
00256 }
00257
00258 function isHiddenQuestion($question_id)
00259 {
00260 if (!is_array($this->sequencedata["hidden"])) return FALSE;
00261 if (!in_array($question_id, $this->sequencedata["hidden"]))
00262 {
00263 return FALSE;
00264 }
00265 else
00266 {
00267 return TRUE;
00268 }
00269 }
00270
00271 function isPostponedSequence($sequence)
00272 {
00273 if (!array_key_exists($sequence, $this->questions)) return FALSE;
00274 if (!is_array($this->sequencedata["postponed"])) return FALSE;
00275 if (!in_array($this->questions[$sequence], $this->sequencedata["postponed"]))
00276 {
00277 return FALSE;
00278 }
00279 else
00280 {
00281 return TRUE;
00282 }
00283 }
00284
00285 function isHiddenSequence($sequence)
00286 {
00287 if (!array_key_exists($sequence, $this->questions)) return FALSE;
00288 if (!is_array($this->sequencedata["hidden"])) return FALSE;
00289 if (!in_array($this->questions[$sequence], $this->sequencedata["hidden"]))
00290 {
00291 return FALSE;
00292 }
00293 else
00294 {
00295 return TRUE;
00296 }
00297 }
00298
00299 function postponeSequence($sequence)
00300 {
00301 if (!$this->isPostponedSequence($sequence))
00302 {
00303 if (array_key_exists($sequence, $this->questions))
00304 {
00305 if (!is_array($this->sequencedata["postponed"])) $this->sequencedata["postponed"] = array();
00306 array_push($this->sequencedata["postponed"], intval($this->questions[$sequence]));
00307 }
00308 }
00309 }
00310
00311 function hideSequence($sequence)
00312 {
00313 if (!$this->isHiddenSequence($sequence))
00314 {
00315 if (array_key_exists($sequence, $this->questions))
00316 {
00317 if (!is_array($this->sequencedata["hidden"])) $this->sequencedata["hidden"] = array();
00318 array_push($this->sequencedata["hidden"], intval($this->questions[$sequence]));
00319 }
00320 }
00321 }
00322
00323 function getPositionOfSequence($sequence)
00324 {
00325 $correctedsequence = $this->getCorrectedSequence();
00326 $sequencekey = array_search($sequence, $correctedsequence);
00327 if ($sequencekey !== FALSE)
00328 {
00329 return $sequencekey + 1;
00330 }
00331 else
00332 {
00333 return "";
00334 }
00335 }
00336
00337 function getUserQuestionCount()
00338 {
00339 return count($this->getCorrectedSequence());
00340 }
00341
00342 function getOrderedSequence()
00343 {
00344 return array_keys($this->questions);
00345 }
00346
00347 function getUserSequence()
00348 {
00349 return $this->getCorrectedSequence(TRUE);
00350 }
00351
00352 protected function getCorrectedSequence($with_hidden_questions = FALSE)
00353 {
00354 $correctedsequence = $this->sequencedata["sequence"];
00355 if (!$with_hidden_questions)
00356 {
00357 if (is_array($this->sequencedata["hidden"]))
00358 {
00359 foreach ($this->sequencedata["hidden"] as $question_id)
00360 {
00361 $foundsequence = array_search($question_id, $this->questions);
00362 if ($foundsequence !== FALSE)
00363 {
00364 $sequencekey = array_search($foundsequence, $correctedsequence);
00365 if ($sequencekey !== FALSE)
00366 {
00367 unset($correctedsequence[$sequencekey]);
00368 }
00369 }
00370 }
00371 }
00372 }
00373 if (is_array($this->sequencedata["postponed"]))
00374 {
00375 foreach ($this->sequencedata["postponed"] as $question_id)
00376 {
00377 $foundsequence = array_search($question_id, $this->questions);
00378 if ($foundsequence !== FALSE)
00379 {
00380 $sequencekey = array_search($foundsequence, $correctedsequence);
00381 if ($sequencekey !== FALSE)
00382 {
00383 unset($correctedsequence[$sequencekey]);
00384 array_push($correctedsequence, $foundsequence);
00385 }
00386 }
00387 }
00388 }
00389 return array_values($correctedsequence);
00390 }
00391
00392 function getSequenceForQuestion($question_id)
00393 {
00394 return array_search($question_id, $this->questions);
00395 }
00396
00397 function getFirstSequence()
00398 {
00399 $correctedsequence = $this->getCorrectedSequence();
00400 if (count($correctedsequence))
00401 {
00402 return reset($correctedsequence);
00403 }
00404 else
00405 {
00406 return FALSE;
00407 }
00408 }
00409
00410 function getLastSequence()
00411 {
00412 $correctedsequence = $this->getCorrectedSequence();
00413 if (count($correctedsequence))
00414 {
00415 return end($correctedsequence);
00416 }
00417 else
00418 {
00419 return FALSE;
00420 }
00421 }
00422
00423 function getNextSequence($sequence)
00424 {
00425 $correctedsequence = $this->getCorrectedSequence();
00426 $sequencekey = array_search($sequence, $correctedsequence);
00427 if ($sequencekey !== FALSE)
00428 {
00429 $nextsequencekey = $sequencekey + 1;
00430 if (array_key_exists($nextsequencekey, $correctedsequence))
00431 {
00432 return $correctedsequence[$nextsequencekey];
00433 }
00434 }
00435 return FALSE;
00436 }
00437
00438 function getPreviousSequence($sequence)
00439 {
00440 $correctedsequence = $this->getCorrectedSequence();
00441 $sequencekey = array_search($sequence, $correctedsequence);
00442 if ($sequencekey !== FALSE)
00443 {
00444 $prevsequencekey = $sequencekey - 1;
00445 if (($prevsequencekey >= 0) && (array_key_exists($prevsequencekey, $correctedsequence)))
00446 {
00447 return $correctedsequence[$prevsequencekey];
00448 }
00449 }
00450 return FALSE;
00451 }
00452
00461 function pcArrayShuffle($array)
00462 {
00463 mt_srand((double)microtime()*1000000);
00464 $i = count($array);
00465 if ($i > 0)
00466 {
00467 while(--$i)
00468 {
00469 $j = mt_rand(0, $i);
00470 if ($i != $j)
00471 {
00472
00473 $tmp = $array[$j];
00474 $array[$j] = $array[$i];
00475 $array[$i] = $tmp;
00476 }
00477 }
00478 }
00479 return $array;
00480 }
00481
00482 function getQuestionForSequence($sequence)
00483 {
00484 if ($sequence < 1) return FALSE;
00485 if (array_key_exists($sequence, $this->questions))
00486 {
00487 return $this->questions[$sequence];
00488 }
00489 else
00490 {
00491 return FALSE;
00492 }
00493 }
00494
00495 function &getSequenceSummary()
00496 {
00497 $correctedsequence = $this->getCorrectedSequence();
00498 $result_array = array();
00499 include_once "./Modules/Test/classes/class.ilObjTest.php";
00500 $solved_questions = ilObjTest::_getSolvedQuestions($this->active_id);
00501 $key = 1;
00502 foreach ($correctedsequence as $sequence)
00503 {
00504 $question =& ilObjTest::_instanciateQuestion($this->getQuestionForSequence($sequence));
00505 if (is_object($question))
00506 {
00507 $worked_through = $question->_isWorkedThrough($this->active_id, $question->getId(), $this->pass);
00508 $solved = 0;
00509 if (array_key_exists($question->getId(), $solved_questions))
00510 {
00511 $solved = $solved_questions[$question->getId()]->solved;
00512 }
00513 $is_postponed = $this->isPostponedQuestion($question->getId());
00514
00515 $row = array(
00516 "nr" => "$key",
00517 "title" => $question->getTitle(),
00518 "qid" => $question->getId(),
00519 "visited" => $worked_through,
00520 "solved" => (($solved)?"1":"0"),
00521 "description" => $question->getComment(),
00522 "points" => $question->getMaximumPoints(),
00523 "worked_through" => $worked_through,
00524 "postponed" => $is_postponed,
00525 "sequence" => $sequence
00526 );
00527 array_push($result_array, $row);
00528 $key++;
00529 }
00530 }
00531 return $result_array;
00532 }
00533
00534 function getPass()
00535 {
00536 return $this->pass;
00537 }
00538
00539 function setPass($pass)
00540 {
00541 $this->pass = $pass;
00542 }
00543
00544 function hasSequence()
00545 {
00546 if ((is_array($this->sequencedata["sequence"])) && (count($this->sequencedata["sequence"]) > 0))
00547 {
00548 return TRUE;
00549 }
00550 else
00551 {
00552 return FALSE;
00553 }
00554 }
00555
00556 function hasHiddenQuestions()
00557 {
00558 if ((is_array($this->sequencedata["hidden"])) && (count($this->sequencedata["hidden"]) > 0))
00559 {
00560 return TRUE;
00561 }
00562 else
00563 {
00564 return FALSE;
00565 }
00566 }
00567
00568 function clearHiddenQuestions()
00569 {
00570 $this->sequencedata["hidden"] = array();
00571 }
00572 }
00573
00574 ?>