• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

Modules/Test/classes/class.ilTestSequence.php

Go to the documentation of this file.
00001 <?php
00002  /*
00003    +----------------------------------------------------------------------------+
00004    | ILIAS open source                                                          |
00005    +----------------------------------------------------------------------------+
00006    | Copyright (c) 1998-2001 ILIAS open source, University of Cologne           |
00007    |                                                                            |
00008    | This program is free software; you can redistribute it and/or              |
00009    | modify it under the terms of the GNU General Public License                |
00010    | as published by the Free Software Foundation; either version 2             |
00011    | of the License, or (at your option) any later version.                     |
00012    |                                                                            |
00013    | This program is distributed in the hope that it will be useful,            |
00014    | but WITHOUT ANY WARRANTY; without even the implied warranty of             |
00015    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              |
00016    | GNU General Public License for more details.                               |
00017    |                                                                            |
00018    | You should have received a copy of the GNU General Public License          |
00019    | along with this program; if not, write to the Free Software                |
00020    | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
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                         // The following is a fix for random tests prior to ILIAS 3.8. If someone started a random test in ILIAS < 3.8, there
00142                         // is only one test pass (pass = 0) in tst_test_random_question while with ILIAS 3.8 there are questions for every test pass.
00143                         // To prevent problems with tests started in an older version and continued in ILIAS 3.8, the first pass should be taken if
00144                         // no questions are present for a newer pass.
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                                         // swap elements
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 ?>

Generated on Fri Dec 13 2013 17:56:53 for ILIAS Release_3_9_x_branch .rev 46835 by  doxygen 1.7.1