瀏覽代碼

Fixing random question list generation

Julio Montoya 11 年之前
父節點
當前提交
e9140f9887
共有 3 個文件被更改,包括 48 次插入49 次删除
  1. 37 45
      main/exercice/exercise.class.php
  2. 10 3
      main/exercice/exercise_submit.php
  3. 1 1
      main/inc/ajax/exercise.ajax.php

+ 37 - 45
main/exercice/exercise.class.php

@@ -697,20 +697,18 @@ class Exercise
         $categoriesAddedInExercise = array();
 
         // Order/random categories
+        $cat = new Testcategory();
 
         switch ($randomByCategory) {
             case EXERCISE_CATEGORY_RANDOM_DISABLED: // 0
                 break;
             case EXERCISE_CATEGORY_RANDOM_SHUFFLED: // 1
-                $cat = new Testcategory();
                 $categoriesAddedInExercise = $cat->getCategoryExerciseTree($this->id, $this->course['real_id']);
-
                 if (!empty($categoriesAddedInExercise)) {
                     shuffle($categoriesAddedInExercise);
                 }
                 break;
             case EXERCISE_CATEGORY_RANDOM_ORDERED: // 2
-                $cat = new Testcategory();
                 $categoriesAddedInExercise = $cat->getCategoryExerciseTree($this->id, $this->course['real_id'], 'title DESC');
                 break;
         }
@@ -727,28 +725,26 @@ class Exercise
         // "Category rel exercise" is empty we search now for the "category rel question" relationships
         if (empty($totalCategoriesRelExercise)) {
             switch ($randomByCategory) {
-                case EXERCISE_CATEGORY_RANDOM_DISABLED: // 0
-                    // No category order to apply check the random
-                    $question_list = $this->selectRandomList($question_list);
-                    break;
                 case EXERCISE_CATEGORY_RANDOM_SHUFFLED: // 1
                     // Getting questions by category in an exercise with shuffling mode ON
                     $questions_by_category = Testcategory::getQuestionsByCat($this->id, $question_list, null, true);
                     $question_list = $this->pickQuestionsPerCategory($question_list, $questions_by_category);
                     break;
+                case EXERCISE_CATEGORY_RANDOM_DISABLED: // 0
+                    // No category order to apply check the random
+                    $questions_by_category = Testcategory::getQuestionsByCat($this->id, $question_list);
+                    break;
                 case EXERCISE_CATEGORY_RANDOM_ORDERED: // 2
                     // Getting questions by category in an exercise ordered by category title
                     $questions_by_category = Testcategory::getQuestionsByCat($this->id, $question_list);
                     $question_list = $this->pickQuestionsPerCategory($question_list, $questions_by_category);
                     break;
             }
-
         } else {
             // Reorder questions depending of the category settings
             switch ($randomByCategory) {
                 case EXERCISE_CATEGORY_RANDOM_DISABLED: // 0
                     // No category order to apply check the random
-                    $question_list = $this->selectRandomList($question_list);
                     break;
                 case EXERCISE_CATEGORY_RANDOM_SHUFFLED: // 1
                     // Getting questions by category in an exercise with shuffling mode ON
@@ -777,13 +773,11 @@ class Exercise
 
             $questions_by_category = $this->pickQuestionsPerCategory($question_list, $questions_by_category, $categoryCountArray, false);
             $question_list = ArrayClass::array_flatten($questions_by_category);
-
         }
 
         $result['question_list'] = isset($question_list) ? $question_list : array();
         $result['category_with_questions_list'] = isset($questions_by_category) ? $questions_by_category : array();
 
-
         if (!empty($result['category_with_questions_list'])) {
             global $app;
             $em = $app['orm.em'];
@@ -841,12 +835,17 @@ class Exercise
     {
         if ($from_db && !empty($this->id)) {
 
-            // The question list is now ordered with the question_order parameter (normal behaviour)
-            $questionList = $this->getQuestionOrderedList();
+            $nbQuestions = $this->getQuestionCount();
+
+            // Not a random exercise, or if there are not at least 2 questions
+            if ($this->random == 0 || $nbQuestions < 2) {
+                $questionList = $this->getQuestionOrderedList();
+            } else {
+                $questionList = $this->selectRandomList();
+            }
 
             if ($this->categories_grouping) {
                 $result = $this->getQuestionListWithCategoryListFilteredByCategorySettings($questionList);
-
                 $this->categoryWithQuestionList = $result['category_with_questions_list'];
                 $questionList = $result['question_list'];
             }
@@ -882,34 +881,26 @@ class Exercise
      * @return array question list modified or unmodified
      *
      */
-    public function selectRandomList($question_list)
+    public function selectRandomList()
     {
-        $nbQuestions = $this->selectNbrQuestions();
-
-        // Not a random exercise, or if there are not at least 2 questions
-        if ($this->random == 0 || $nbQuestions < 2) {
-            return $question_list;
-        }
-
-        if ($nbQuestions != 0) {
-            shuffle($question_list);
-            $my_random_list = array_combine(range(1, $nbQuestions), $question_list);
-            $my_question_list = array();
-            if ($this->random > 0) {
-                $i = 0;
-                foreach ($my_random_list as $item) {
-                    if ($i < $this->random) {
-                        $my_question_list[$i] = $item;
-                    } else {
-                        break;
-                    }
-                    $i++;
-                }
-            } else {
-                $my_question_list = $my_random_list;
-            }
-            return $my_question_list;
+        $random = isset($this->random) && !empty($this->random) ? $this->random : 0;
+
+        $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
+        $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
+
+        // @todo improve this query
+        $sql = "SELECT e.question_id
+                FROM $TBL_EXERCICE_QUESTION e INNER JOIN $TBL_QUESTIONS q
+                    ON (e.question_id= q.iid)
+                WHERE e.c_id = {$this->course_id} AND e.exercice_id	= '".Database::escape_string($this->id)."'
+                ORDER BY RAND()
+                LIMIT $random ";
+        $result = Database::query($sql);
+        $questionList = array();
+        while ($row = Database::fetch_object($result)) {
+            $questionList[] = $row->question_id;
         }
+        return $questionList;
     }
 
     /**
@@ -5207,9 +5198,9 @@ class Exercise
     {
         //Real question count
         $question_count = 0;
-        $question_list = $this->getQuestionList();
-        if (!empty($question_list)) {
-            $question_count = count($question_list);
+        $questionList = $this->questionList;
+        if (!empty($questionList)) {
+            $question_count = count($questionList);
         }
 
         return $question_count;
@@ -5600,6 +5591,7 @@ class Exercise
         foreach ($questionList as $questionId) {
             $i++;
             // For sequential exercises
+
             if ($this->type == ONE_PER_PAGE) {
                 // If it is not the right question, goes to the next loop iteration
                 if ($currentQuestion != $i) {
@@ -5618,8 +5610,8 @@ class Exercise
             // The $questionList contains the media id we check if this questionId is a media question type
 
             if (isset($mediaQuestions[$questionId]) && $mediaQuestions[$questionId] != 999) {
-                // The question belongs to a media
 
+                // The question belongs to a media
                 $mediaQuestionList = $mediaQuestions[$questionId];
                 $objQuestionTmp = Question::read($questionId);
 
@@ -5666,7 +5658,6 @@ class Exercise
                     $i++;
                 }
             } else {
-                //var_dump($i, $questionId, $currentQuestion);
                 // Normal question render.
                 $this->renderQuestion($questionId, $attemptList, $remindList, $i, $currentQuestion, null, null, $questionList);
             }
@@ -5711,6 +5702,7 @@ class Exercise
 
         // With this option on the question is loaded via AJAX
         //$generateJS = true;
+        //$this->loadQuestionAJAX = true;
 
         if ($generateJS && $this->loadQuestionAJAX) {
             $url = api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?a=get_question&id='.$questionId;

+ 10 - 3
main/exercice/exercise_submit.php

@@ -352,6 +352,7 @@ if (!isset($_SESSION['objExercise']) || $_SESSION['objExercise']->id != $_REQUES
     }
 }
 
+
 // $objExercise = new Exercise(); $objExercise->read($exerciseId);
 
 //2. Checking if $objExercise is set
@@ -481,6 +482,7 @@ $questionListFlatten = $objExercise->transformQuestionListWithMedias($questionLi
 Session::write('question_list_flatten', $questionListFlatten);
 
 $clock_expired_time = null;
+
 if (empty($exercise_stat_info)) {
     if ($debug)  error_log('5  $exercise_stat_info is empty ');
 	$total_weight = 0;
@@ -531,6 +533,7 @@ if ($reminder == 2 && empty($my_remind_list)) {
 	exit;
 }
 
+
 /*
  * 7. Loading Time control parameters
  * If the expired time is major that zero(0) then the expired time is compute on this time.
@@ -586,7 +589,7 @@ if ($time_control) {
     if ($debug) { error_log("7. No time control"); };
 }
 
-// Get time left for exipiring time
+// Get time left for expiring time
 $time_left = api_strtotime($clock_expired_time,'UTC') - time();
 
 /*
@@ -820,6 +823,7 @@ if (api_is_course_admin() && $origin != 'learnpath') {
     }
     echo '</div>';
 }
+
 if ($objExercise->type == ONE_PER_PAGE) {
     echo $objExercise->getProgressPagination(
         $exe_id,
@@ -972,19 +976,20 @@ if (!empty($error)) {
     $i = 0;
     if (!empty($questionList)) {
         foreach ($questionList as $questionId) {
-            $objQuestionTmp = Question::read($questionId);
             // for sequential exercises
             if ($objExercise->type == ONE_PER_PAGE) {
                 // if it is not the right question, goes to the next loop iteration
                 if ($current_question != $i) {
                     continue;
                 } else {
+                    $objQuestionTmp = Question::read($questionId);
                     if ($objQuestionTmp->selectType() == HOT_SPOT || $objQuestionTmp->selectType() == HOT_SPOT_DELINEATION) {
                         $number_of_hotspot_questions++;
                     }
                     break;
                 }
             } else {
+                $objQuestionTmp = Question::read($questionId);
                 if ($objQuestionTmp->selectType() == HOT_SPOT || $objQuestionTmp->selectType() == HOT_SPOT_DELINEATION) {
                     $number_of_hotspot_questions++;
                 }
@@ -992,6 +997,8 @@ if (!empty($error)) {
             $i++;
         }
     }
+
+
     if ($number_of_hotspot_questions > 0) {
         $onsubmit = "onsubmit=\"return validateFlashVar('" . $number_of_hotspot_questions . "', '" . get_lang('HotspotValidateError1') . "', '" . get_lang('HotspotValidateError2') . "');\"";
     }
@@ -1185,7 +1192,7 @@ if (!empty($error)) {
         $attempt_list = getAllExerciseEventByExeId($exe_id);
     }
 
-    $remind_list  = array();
+    $remind_list = array();
     if (isset($exercise_stat_info['questions_to_check']) && !empty($exercise_stat_info['questions_to_check'])) {
         $remind_list = explode(',', $exercise_stat_info['questions_to_check']);
     }

+ 1 - 1
main/inc/ajax/exercise.ajax.php

@@ -335,7 +335,7 @@ switch ($action) {
             $objExercise             = isset($_SESSION['objExercise']) ? $_SESSION['objExercise'] : null;
 
             // Question info.
-            $question_id             = intval($_REQUEST['question_id']);
+            $question_id             = isset($_REQUEST['question_id']) ? intval($_REQUEST['question_id']) : null;
             $question_list           = Session::read('question_list_flatten');
 
             // If exercise or question is not set then exit.