示例#1
0
 /**
  * Start test
  *
  * This function is used to start a test. It gathers all the required information, creates
  * a new EfrontTest instance and stores it in the database.
  * <br/>Example:
  * <code>
  * $test = new EfrontTest(23);              //Instantiate object for test with id 23
  * $testInstance = $test -> start('jdoe);   //start() returns a new EfrontTest object, different that the initial, for the user 'jdoe'
  * $testInstance -> ...                     //Do whatever with the new object.
  * </code>
  *
  * @param string $login The user to start test for
  * @return EfrontCompletedTest a new EfrontCompletedTest instance, which represents the test (to be) completed
  * @since 3.5.2
  * @access public
  */
 public function start($login)
 {
     $completedTest = new EfrontCompletedTest($this, $login);
     $completedTest->time['start'] = time();
     //The time that this test has started
     $completedTest->time['resume'] = time();
     //Initialize time that this test has 'resumed'
     $completedTest->time['end'] = null;
     //The time that this test ends
     $completedTest->time['spent'] = 0;
     //Initialize the time spent
     $completedTest->completedTest['status'] = 'incomplete';
     //The test just started; So set its status to 'incomplete'
     //        $completedTest -> completedTest['archive'] = '0';                              //The test just started; So set its status to 'incomplete'
     $testQuestions = $this->getQuestions(true);
     // lines added for redo only wrong questions
     $resultCompleted = EfrontCompletedTest::retrieveCompletedTest("completed_tests ct join completed_tests_blob ctb on ct.id=ctb.completed_tests_ID", "ctb.test", "archive=1 AND users_LOGIN='******'s_login'] . "' AND tests_ID=" . $this->test['id'], "timestamp desc");
     $recentlyCompleted = unserialize($resultCompleted[0]['test']);
     //1. Get the random pool questions
     if ($this->options['random_pool']) {
         if ($recentlyCompleted->redoOnlyWrong == false) {
             sizeof($testQuestions) >= $this->options['random_pool'] ? $poolSize = $this->options['random_pool'] : ($poolSize = sizeof($testQuestions));
             shuffle($testQuestions);
             //shuffle available questions so that we don't take the same always
             if ($this->options['show_incomplete']) {
                 $alreadyCompletedQuestions = array();
                 foreach ($resultCompleted as $value) {
                     $previouslyCompletedTest = unserialize($value['test']);
                     if ($previouslyCompletedTest instanceof EfrontCompletedTest) {
                         $alreadyCompletedQuestions = array_merge($alreadyCompletedQuestions, array_keys($previouslyCompletedTest->questions));
                     }
                 }
                 $alreadyCompletedQuestions = array_unique($alreadyCompletedQuestions);
                 $incompleteQuestions = array_diff(array_keys($this->questions), $alreadyCompletedQuestions);
                 //Find out which questions haven't been answered yet
                 //Keep only incomplete questions
                 foreach ($testQuestions as $key => $value) {
                     if (!in_array($value->question['id'], $incompleteQuestions) && sizeof($testQuestions) > $poolSize) {
                         unset($testQuestions[$key]);
                     }
                 }
             }
             // Code for selecting questions depending on lessons_ID frequency
             $lesson_count = array();
             $questions_per_lesson = array();
             foreach ($testQuestions as $value) {
                 $lesson_count[$value->question['lessons_ID']] += 1;
                 $questions_per_lesson[$value->question['lessons_ID']][$value->question['id']] = $value;
             }
             $questionsTemp = array();
             $randomQuestions = array();
             foreach (array_keys($questions_per_lesson) as $key) {
                 $questionsTemp = $questions_per_lesson[$key];
                 shuffle($questionsTemp);
                 $questionsTemp = array_slice($questionsTemp, 0, floor($lesson_count[$key] * $poolSize / array_sum($lesson_count)), true);
                 $randomQuestions = array_merge($randomQuestions, $questionsTemp);
             }
             $temp = array();
             foreach ($randomQuestions as $value) {
                 //Shuffling reindexed array, so we need to put back the correct keys
                 $temp[$value->question['id']] = $value;
             }
             $randomQuestions = $temp;
             $temp2 = array();
             foreach ($testQuestions as $value) {
                 //Shuffling reindexed array, so we need to put back the correct keys
                 $temp2[$value->question['id']] = $value;
             }
             $testQuestions = $temp2;
             foreach ($randomQuestions as $key => $value) {
                 unset($testQuestions[$key]);
             }
             if (sizeof($randomQuestions) < $poolSize) {
                 $additionalQuestions = array_slice($testQuestions, 0, $poolSize - sizeof($randomQuestions));
             }
             $temp = array();
             foreach ($additionalQuestions as $value) {
                 //Shuffling reindexed array, so we need to put back the correct keys
                 $temp[$value->question['id']] = $value;
             }
             $additionalQuestions = $temp;
             if (!empty($additionalQuestions)) {
                 $randomQuestions = array_merge($randomQuestions, $additionalQuestions);
             }
             $temp = array();
             foreach ($randomQuestions as $value) {
                 //Shuffling reindexed array, so we need to put back the correct keys
                 $temp[$value->question['id']] = $value;
             }
             $randomQuestions = $temp;
             $completedTest->questions = $randomQuestions;
             //End of code for selecting questions depending on lessons_ID frequency
         } else {
             $completedTest->questions = $recentlyCompleted->questions;
             //when redoing wrong answered, same questions must be selected
         }
     } else {
         $completedTest->questions = $testQuestions;
     }
     //2. Shuffle answers inside questions
     foreach ($completedTest->questions as $key => $question) {
         if ($this->options['shuffle_answers']) {
             $question->shuffle();
         }
         $completedTest->questions[$key] = $question;
     }
     //3. Set questions in order
     if ($this->options['shuffle_questions']) {
         $completedTest->orderQuestions();
     }
     //4. Get additional information that might be useful
     $completedTest->getUnit();
     $completedTest->getLesson();
     //5. When redo only wrong, set it
     if ($recentlyCompleted->redoOnlyWrong == true) {
         $completedTest->correctPrevious = true;
     }
     //6. Store test
     $completedTest->save();
     try {
         $lesson = new EfrontLesson($this->test['lessons_ID']);
         $lesson_name = $lesson->lesson['name'];
     } catch (EfrontLessonException $e) {
         $lesson_name = _SKILLGAPTESTS;
     }
     EfrontEvent::triggerEvent(array("type" => EfrontEvent::TEST_START, "users_LOGIN" => $login, "lessons_ID" => $this->test['lessons_ID'], "lessons_name" => $lesson_name, "entity_ID" => $this->test['id'], "entity_name" => $this->test['name']));
     return $completedTest;
 }