Browse Source

Fixing media + categories exercise submit page (works when the "exercise-category" table is empty)

Julio Montoya 11 years ago
parent
commit
51b2fecba7

File diff suppressed because it is too large
+ 323 - 327
main/exercice/exercise.class.php


+ 4 - 4
main/exercice/exercise_reminder.php

@@ -255,18 +255,18 @@ $exercise_actions = Display::url(get_lang('EndTest'), 'javascript://', array('on
 $questionList = explode(',', $exercise_stat_info['data_tracking']);
 
 $questionListFlatten = $objExercise->transform_question_list_with_medias($questionList, true);
-$mediaQuestions = $objExercise->get_media_list();
+$mediaQuestions = $objExercise->getMediaList($questionList);
 
 $params = "exe_id=$exe_id&exerciseId=$exerciseId&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id&".api_get_cidreq();
 $url = api_get_path(WEB_CODE_PATH).'exercice/exercise_submit.php?'.$params;
 
-echo $objExercise->getProgressPagination($exe_id,
+echo $objExercise->getProgressPagination(
+    $exe_id,
     $questionList,
+    $questionListFlatten,
     $remind_list,
     2,
     null,
-    $questionListFlatten,
-    $mediaQuestions,
     $url,
     null
 );

+ 30 - 67
main/exercice/exercise_submit.php

@@ -13,8 +13,6 @@
 * 	When the user has answered all questions and clicks on the button "Ok",
 * 	it goes to exercise_result.php
 *
-* 	Notice : This script is also used to show a question before modifying it by
-* 	the administrator
 *	@package chamilo.exercise
 * 	@author Olivier Brouckaert
 * 	@author Julio Montoya <gugli100@gmail.com>
@@ -22,6 +20,7 @@
 * 			Cleaning exercises (2010),
 * 			Adding hotspot delineation support (2011)
 * 			Adding reminder + ajax support (2011)
+ * 			Adding adding medias, local and global categories (2013)
 *   Modified by hubert.borderiou (2011-10-21 question category)
 */
 /**
@@ -55,10 +54,10 @@ if (api_get_setting('show_glossary_in_extra_tools') == 'true') {
     $htmlHeadXtra[] = api_get_js('glossary.js'); //Glossary
     $htmlHeadXtra[] = api_get_js('jquery.   highlight.js'); //highlight
 }
-
+// Matching question
 $htmlHeadXtra[] = api_get_js('jquery.jsPlumb.all.js');
 
-//This library is necessary for the time control feature
+// This library is necessary for the time control feature
 $htmlHeadXtra[]= api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/stylesheet/jquery.epiclock.css');
 $htmlHeadXtra[]= api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/renderers/minute/epiclock.minute.css');
 $htmlHeadXtra[]= api_get_js('epiclock/javascript/jquery.dateformat.min.js');
@@ -77,9 +76,6 @@ function deleteItem($item, $insertHere) {
     }
 
     $item.fadeOut(function() {
-        /*var $list = $( "ul", $trash ).length ?
-          $( "ul", $trash ) :
-          $( "<ul class=\'gallery ui-helper-reset\'/>" ).appendTo( $trash );*/
 
         $list =  $( "<div class=\'gallery ui-helper-reset\'/>" ).appendTo($insertHere);
         $item.find( "a.ui-icon-trash" ).remove();
@@ -120,18 +116,7 @@ $(function() {
     $trash.droppable({
         accept: ".drag_question > li",
         hoverClass: "ui-state-active",
-        //activeClass: "ui-state-highlight",
         drop: function(event, ui) {
-                /*
-            var dropped = ui.draggable;
-            var droppedId = dropped.attr("id");
-
-            var droppedOn = $(this);
-            var droppedOnId = droppedOn.attr("id");
-
-            $(this).html(dropped.html());
-            $( this ).addClass("ui-state-highlight");
-            */
             deleteItem(ui.draggable,  $(this));
         }
     });
@@ -179,7 +164,6 @@ $(function() {
         }
         return false;
     });
-
 });
 
 // Matching js script in order to use jsplumb
@@ -290,25 +274,6 @@ var connectorType = "Straight";
 
     jsPlumbDemo.attachBehaviour = function() {
         if (!_initialised) {
-            /*$(".hide").click(function() {
-                jsPlumb.toggle($(this).attr("rel"));
-            });
-
-            $(".drag").click(function() {
-                var s = jsPlumb.toggleDraggable($(this).attr("rel"));
-                $(this).html(s ? "disable dragging" : "enable dragging");
-                if (!s) $("#" + $(this).attr("rel")).addClass("drag-locked"); else $("#" + $(this).attr("rel")).removeClass("drag-locked");
-                $("#" + $(this).attr("rel")).css("cursor", s ? "pointer" : "default");
-            });
-
-            $(".detach").click(function() {
-                jsPlumb.detachAllConnections($(this).attr("rel"));
-            });
-
-            $("#clear").click(function() {
-                jsPlumb.detachEveryConnection(); jsPlumbDemo.showConnectionInfo("");
-            });*/
-
             _initialised = true;
         }
     };
@@ -363,7 +328,7 @@ $current_question       = isset($_REQUEST['num']) ? intval($_REQUEST['num']) : n
 $error = '';
 
 /*  Teacher takes an exam and want to see a preview, we delete the objExercise from the session in order to get the latest changes in the exercise */
-if (api_is_allowed_to_edit(null,true) && isset($_GET['preview']) && $_GET['preview'] == 1 ) {
+if (api_is_allowed_to_edit(null,true) && isset($_GET['preview']) && $_GET['preview'] == 1) {
     Session::erase('objExercise');
 }
 
@@ -377,16 +342,18 @@ if (!isset($_SESSION['objExercise']) || $_SESSION['objExercise']->id != $_REQUES
 
     // if the specified exercise doesn't exist or is disabled
     if (!$objExercise->read($exerciseId) || (!$objExercise->selectStatus() && !$is_allowedToEdit && ($origin != 'learnpath'))) {
-    	if ($debug) {error_log('1.1. Error while reading the exercise'); };
+    	if ($debug) { error_log('1.1. Error while reading the exercise'); };
         unset ($objExercise);
         $error = get_lang('ExerciseNotFound');
     } else {
         // Saves the object into the session
-        Session::write('objExercise',$objExercise);
-        if ($debug) {error_log('1.1. $_SESSION[objExercise] was unset - set now - end'); };
+        Session::write('objExercise', $objExercise);
+        if ($debug) { error_log('1.1. $_SESSION[objExercise] was unset - set now - end'); };
     }
 }
 
+// $objExercise = new Exercise(); $objExercise->read($exerciseId);
+
 //2. Checking if $objExercise is set
 if (!isset($objExercise) && isset($_SESSION['objExercise'])) {
 	if ($debug) { error_log('2. Loading $objExercise from session'); };
@@ -414,18 +381,18 @@ $my_remind_list 	= array();
 
 $time_control = false;
 if ($objExercise->expired_time != 0) {
-	$time_control = true;
+    $time_control = true;
 }
 
 //Generating the time control key for the user
 $current_expired_time_key = ExerciseLib::get_time_control_key($objExercise->id, $learnpath_id, $learnpath_item_id);
-if ($debug)  error_log("4. current_expired_time_key: $current_expired_time_key ");
+if ($debug) error_log("4. current_expired_time_key: $current_expired_time_key ");
 
 $_SESSION['duration_time'][$current_expired_time_key] = $current_timestamp;
 
 if ($time_control) {
 	//Get the expired time of the current exercice in track_e_exercices
-	$total_seconds = $objExercise->expired_time*60;
+	$total_seconds = $objExercise->expired_time * 60;
 }
 
 $show_clock = true;
@@ -486,18 +453,16 @@ if ($objExercise->selectAttempts() > 0) {
 	}
 }
 
-//5. Getting user exercise info (if the user took the exam before) - generating exe_id
+// 5. Getting user exercise info (if the user took the exam before) - generating exe_id
 $exercise_stat_info = $objExercise->get_stat_track_exercise_info($learnpath_id, $learnpath_item_id, $learnpath_item_view_id);
 
-//Media questions
-$mediaQuestions = $objExercise->get_media_list();
-$media_is_activated = $objExercise->media_is_activated($mediaQuestions);
-
-//In LP's is enabled the "remember question" feature?
-
+//if (1) {
 if (!isset($_SESSION['questionList'])) {
     // Selects the list of question ID
-    $questionList = $objExercise->get_question_list(false);
+    $questionList = $objExercise->getQuestionList();
+
+    // Media questions.
+    $media_is_activated = $objExercise->media_is_activated();
 
     //Getting order from random
     if ($media_is_activated == false && $objExercise->isRandom() && isset($exercise_stat_info) && !empty($exercise_stat_info['data_tracking'])) {
@@ -511,8 +476,11 @@ if (!isset($_SESSION['questionList'])) {
 	}
 }
 
+//var_dump($questionList);
 //Fix in order to get the correct question list
 $questionListFlatten = $objExercise->transform_question_list_with_medias($questionList, true);
+//var_dump($questionListFlatten);
+
 Session::write('question_list_flatten', $questionListFlatten);
 
 $clock_expired_time = null;
@@ -636,7 +604,6 @@ $exercise_title	= $objExercise->selectTitle();
 $exercise_sound = $objExercise->selectSound();
 
 if ($debug) error_log('8. Question list loaded '.print_r($questionList, 1));
-if ($debug) error_log('8.1. Media list loaded '.print_r($mediaQuestions, 1));
 
 $question_count = $objExercise->get_count_question_list();
 
@@ -649,7 +616,7 @@ if ($formSent && isset($_POST)) {
         $exerciseResultCoordinates = array();
     }
 
-    //Only for hotspot
+    // Only for hotspot
     if (!isset($choice) && isset($_REQUEST['hidden_hotspot_id'])) {
         $hotspot_id = (int)($_REQUEST['hidden_hotspot_id']);
         $choice     = array($hotspot_id => '');
@@ -680,7 +647,6 @@ if ($formSent && isset($_POST)) {
                 $exerciseResult[$key] = $choice[$key];
                 //saving each question
                 if ($objExercise->feedback_type != EXERCISE_FEEDBACK_TYPE_DIRECT) {
-                    //$nro_question = $current_question; // - 1;
                  	$questionId   = $key;
                     // gets the student choice for this question
                     $choice = $exerciseResult[$questionId];
@@ -857,16 +823,15 @@ if (api_is_course_admin() && $origin != 'learnpath') {
     }
     echo '</div>';
 }
-
+//var_dump($questionList);var_dump($questionListFlatten);
 if ($objExercise->type == ONE_PER_PAGE) {
     echo $objExercise->getProgressPagination(
         $exe_id,
         $questionList,
+        $questionListFlatten,
         $my_remind_list,
         $reminder,
         $remind_question_id,
-        $questionListFlatten,
-        $mediaQuestions,
         api_get_self().'?'.$params,
         $current_question
     );
@@ -956,7 +921,8 @@ if ($reminder == 2)  {
     $data_tracking  = $exercise_stat_info['data_tracking'];
     $data_tracking  = explode(',', $data_tracking);
 
-    $current_question = 1; //set by default the 1st question
+    // Set by default the 1st question
+    $current_question = 1;
 
     if (!empty($my_remind_list)) {
     	//Checking which questions we are going to call from the remind list
@@ -1011,14 +977,13 @@ if (!empty($error)) {
     if (!empty($exercise_sound)) {
         echo "<a href=\"../document/download.php?doc_url=%2Faudio%2F".Security::remove_XSS($exercise_sound)."\" target=\"_blank\">", "<img src=\"../img/sound.gif\" border=\"0\" align=\"absmiddle\" alt=", get_lang('Sound') . "\" /></a>";
     }
+
     // Get number of hotspot questions for javascript validation
     $number_of_hotspot_questions = 0;
     $onsubmit = '';
     $i = 0;
-
     if (!empty($questionList)) {
         foreach ($questionList as $questionId) {
-            $i++;
             $objQuestionTmp = Question::read($questionId);
             // for sequential exercises
             if ($objExercise->type == ONE_PER_PAGE) {
@@ -1036,9 +1001,9 @@ if (!empty($error)) {
                     $number_of_hotspot_questions++;
                 }
             }
+            $i++;
         }
     }
-
     if ($number_of_hotspot_questions > 0) {
         $onsubmit = "onsubmit=\"return validateFlashVar('" . $number_of_hotspot_questions . "', '" . get_lang('HotspotValidateError1') . "', '" . get_lang('HotspotValidateError2') . "');\"";
     }
@@ -1073,7 +1038,6 @@ if (!empty($error)) {
                 $.each(question_list, function(key, question_id) {
                     save_now(question_id, null, false);
                 });
-
                 var url = "";
                 if ('.$reminder.' == 1 ) {
                     url = "exercise_reminder.php?'.$params.'&num='.$current_question.'";
@@ -1157,7 +1121,7 @@ if (!empty($error)) {
                     error: function() {
                         $("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('error.png', get_lang('Error'), array(), ICON_SIZE_SMALL)).'");
                     }
-                    });
+                });
                 return false;
             }
 
@@ -1241,12 +1205,11 @@ if (!empty($error)) {
         $remind_list = explode(',', $exercise_stat_info['questions_to_check']);
     }
 
-    ExerciseLib::render_question_list($objExercise, $questionList, $current_question, $exerciseResult, $attempt_list, $remind_list, $mediaQuestions);
+    ExerciseLib::render_question_list($objExercise, $questionListFlatten, $questionList, $current_question, $exerciseResult, $attempt_list, $remind_list);
 
     echo '</form>';
 }
 
-
 if ($origin != 'learnpath') {
     //so we are not in learnpath tool
     echo '</div>'; //End glossary div

+ 9 - 16
main/exercice/question.class.php

@@ -1351,8 +1351,6 @@ abstract class Question
                         $("#parent_id option:selected").each(function() {
                             var questionId = $(this).val();
                             if (questionId != 0) {
-                                //console.log(counter);
-                                //console.log(questionId);
                                 if (counter >= 1) {
                                     alert("'.addslashes(get_lang('YouCantAddAnotherCategory')).'");
                                     $("#category_id").trigger("removeItem",[{ "value" : id}]);
@@ -1369,7 +1367,7 @@ abstract class Question
                                 if (return_value == 0 ) {
                                     alert("'.addslashes(get_lang('CategoryDoesNotExists')).'");
                                     // Deleting select option tag
-                                    // $("#parent_id").find("option").remove();
+                                    $("#category_id").find("option").remove();
 
                                     $(".holder li").each(function () {
                                         if ($(this).attr("rel") == id) {
@@ -1727,11 +1725,7 @@ abstract class Question
     public static function updateQuestionOption($id, $params, $course_id)
     {
         $TBL_EXERCICE_QUESTION_OPTION = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
-        $result                       = Database::update(
-            $TBL_EXERCICE_QUESTION_OPTION,
-            $params,
-            array('c_id = ? AND id = ?' => array($course_id, $id))
-        );
+        $result = Database::update($TBL_EXERCICE_QUESTION_OPTION, $params, array('c_id = ? AND id = ?' => array($course_id, $id)));
 
         return $result;
     }
@@ -1739,11 +1733,9 @@ abstract class Question
     public static function readQuestionOption($question_id, $course_id)
     {
         $TBL_EXERCICE_QUESTION_OPTION = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
-        $result                       = Database::select(
-            '*',
-            $TBL_EXERCICE_QUESTION_OPTION,
-            array(
-                'where' => array('c_id = ? AND question_id = ?' => array($course_id, $question_id)),
+        $result = Database::select('*', $TBL_EXERCICE_QUESTION_OPTION, array(
+            'where' => array(
+                'c_id = ? AND question_id = ?' => array($course_id, $question_id)),
                 'order' => 'iid ASC'
             )
         );
@@ -1762,9 +1754,10 @@ abstract class Question
     /**
      * Shows question title an description
      *
-     * @param type $feedback_type
-     * @param type $counter
+     * @param int $feedback_type
+     * @param int $counter
      * @param type $score
+     * @param bool $show_media
      *
      * @return string
      */
@@ -2072,7 +2065,7 @@ abstract class Question
             ),
             'question_category_id' => array(
                 'innerjoin' => " INNER JOIN ".Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY)." as quiz_rel_cat ON (quiz_rel_cat.question_id = s.iid)
-                                 INNER JOIN ".Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY)." as cat ON (cat.iid = quiz_rel_cat.category_id)
+                                 INNER JOIN ".Database::get_course_table(TABLE_QUIZ_CATEGORY)." as cat ON (cat.iid = quiz_rel_cat.category_id)
                 ",
                 'where' =>  'quiz_rel_cat.category_id',
                 'inject_fields' => 'cat.title as question_category_id, ',

+ 1 - 1
main/exercice/stats.php

@@ -26,7 +26,7 @@ if (empty($session_id)) {
 }
 $count_students = count($students);
 
-$question_list = $objExercise->get_validated_question_list();
+$question_list = $objExercise->selectQuestionList();
 
 $data = array();
 //Question title 	# of students who tool it 	Lowest score 	Average 	Highest score 	Maximum score

+ 68 - 159
main/exercice/testcategory.class.php

@@ -70,7 +70,7 @@ class Testcategory
     */
     public function getCategory($id)
     {
-        $t_cattable = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
+        $t_cattable = Database::get_course_table(TABLE_QUIZ_CATEGORY);
         $id = Database::escape_string($id);
         $sql = "SELECT * FROM $t_cattable WHERE iid = $id ";
         $res = Database::query($sql);
@@ -93,7 +93,7 @@ class Testcategory
     */
     public function addCategoryInBDD()
     {
-        $t_cattable = Database :: get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
+        $t_cattable = Database :: get_course_table(TABLE_QUIZ_CATEGORY);
         $v_name = Database::escape_string($this->name);
         $parent_id = intval($this->parent_id);
         $course_id = $this->course_id;
@@ -222,7 +222,7 @@ class Testcategory
      */
     public function get_category_by_title($title , $course_id = 0)
     {
-        $table = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
+        $table = Database::get_course_table(TABLE_QUIZ_CATEGORY);
         $course_id = intval($course_id);
         $title = Database::escape_string($title);
 
@@ -248,7 +248,7 @@ class Testcategory
         if (empty($tag)) {
             return false;
         }
-        $table = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
+        $table = Database::get_course_table(TABLE_QUIZ_CATEGORY);
         $sql = "SELECT iid, title, c_id FROM $table WHERE 1=1 ";
         $tag = Database::escape_string($tag);
 
@@ -317,7 +317,7 @@ class Testcategory
 	public static function getCategoryListInfo($in_field = "", $courseId = null)
     {
         $courseId = intval($courseId);
-		$t_cattable = Database :: get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
+		$t_cattable = Database :: get_course_table(TABLE_QUIZ_CATEGORY);
 		$in_field = Database::escape_string($in_field);
 		$tabres = array();
 		if ($in_field=="") {
@@ -372,7 +372,7 @@ class Testcategory
         $courseId = intval($courseId);
 
 		$t_cattable = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
-        $table_category = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
+        $table_category = Database::get_course_table(TABLE_QUIZ_CATEGORY);
         $question_id = Database::escape_string($question_id);
         $sql = "SELECT * FROM $t_cattable qc INNER JOIN $table_category c ON (category_id = c.iid) WHERE question_id = '$question_id' AND qc.c_id = $courseId";
         $res = Database::query($sql);
@@ -397,7 +397,7 @@ class Testcategory
             $course_id = api_get_course_int_id();
         }
         $t_cattable = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
-        $table_category = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
+        $table_category = Database::get_course_table(TABLE_QUIZ_CATEGORY);
         $question_id = intval($question_id);
         $course_id = intval($course_id);
 
@@ -449,7 +449,7 @@ class Testcategory
         $course_id = intval($course_id);
 
         $result = array();
-		$t_cattable = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
+		$t_cattable = Database::get_course_table(TABLE_QUIZ_CATEGORY);
 		$catid = Database::escape_string($catid);
         $sql = "SELECT title FROM $t_cattable WHERE iid = '$catid' AND c_id = $course_id";
 		$res = Database::query($sql);
@@ -507,68 +507,6 @@ class Testcategory
 		return $categories_in_exercise;
 	}
 
-    /**
-     * @param Exercise $exercise_obj
-     * @return array question list (flatten not grouped by Medias)
-     */
-    public static function getListOfCategoriesWithQuestionForTestObject($exercise_obj, $questionList, $mediaQuestions)
-    {
-        $categoriesWithQuestion = array();
-        $parentsLoaded = array();
-        global $app;
-        $em = $app['orm.em'];
-        $repo = $em->getRepository('Entity\CQuizCategory');
-
-        $newMediaList = array();
-        foreach ($mediaQuestions as $mediaId => $questionMediaList) {
-            foreach ($questionMediaList as $questionId) {
-                $newMediaList[$questionId] = $mediaId;
-            }
-        }
-
-        foreach ($questionList as $question_id) {
-            $categoryList = Testcategory::getCategoryForQuestion($question_id);
-
-            foreach ($categoryList as $categoryId) {
-                if (!isset($categoriesWithQuestion[$categoryId])) {
-                    $cat = new Testcategory($categoryId);
-                    $cat = (array)$cat;
-                    $cat['iid'] = $cat['id'];
-                    $cat['name'] = $cat['title'];
-
-                    if (!empty($cat['parent_id'])) {
-                        if (!isset($parentsLoaded[$cat['parent_id']])) {
-                            $categoryEntity = $em->find('Entity\CQuizCategory', $cat['parent_id']);
-                            $parentsLoaded[$cat['parent_id']] = $categoryEntity;
-                        } else {
-                            $categoryEntity = $parentsLoaded[$cat['parent_id']];
-                        }
-                        $path = $repo->getPath($categoryEntity);
-
-                        if (isset($path) && isset($path[0])) {
-                            $categoryId = $path[0]->getIid();
-                            $cat['id'] = $categoryId;
-                            $cat['iid'] = $categoryId;
-                            $cat['parent_path'] = null;
-                            $cat['title'] = $path[0]->getTitle();
-                            $cat['name'] = $path[0]->getTitle();
-                            $cat['parent_id'] = null;
-                        }
-                        $temp = isset($categoriesWithQuestion[$categoryId]) ? $categoriesWithQuestion[$categoryId]['question_list'] : array();
-                        $categoriesWithQuestion[$categoryId] = $cat;
-                        $categoriesWithQuestion[$categoryId]['question_list'] = $temp;
-                        $categoriesWithQuestion[$categoryId]['media_question'] = isset($newMediaList[$question_id]) ? $newMediaList[$question_id] : 999;
-                    } else {
-                        $categoriesWithQuestion[$categoryId] = $cat;
-                        $categoriesWithQuestion[$categoryId]['media_question'] = isset($newMediaList[$question_id]) ? $newMediaList[$question_id] : 999;
-                    }
-                }
-
-                $categoriesWithQuestion[$categoryId]['question_list'][] = (int)$question_id;
-            }
-        }
-        return $categoriesWithQuestion;
-    }
 
 
     /**
@@ -691,23 +629,35 @@ class Testcategory
      * Returns an array of question ids for each category
      * $categories[1][30] = 10, array with category id = 1 and question_id = 10
      * A question has "n" categories
+     * @param int exercise
+     * @param array check question list
+     * @param string order by
+     * @return array
 	 */
-    static function getQuestionsByCat($exerciseId, $check_in_question_list = array())
+    static function getQuestionsByCat($exerciseId, $check_in_question_list = array(), $orderBy = null, $shuffleResult = false)
     {
-        $categories = array();
 		$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
 		$TBL_QUESTION_REL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
+        $categoryTable = Database::get_course_table(TABLE_QUIZ_CATEGORY);
         $exerciseId = intval($exerciseId);
 
+        if (empty($orderBy)) {
+            $orderBy = "c.title, category_id, question_id";
+        } else {
+            $orderBy = Database::escape_string($orderBy);
+        }
         $sql = "SELECT DISTINCT qrc.question_id, qrc.category_id
-                FROM $TBL_QUESTION_REL_CATEGORY qrc, $TBL_EXERCICE_QUESTION eq
+                FROM $TBL_QUESTION_REL_CATEGORY qrc INNER JOIN $TBL_EXERCICE_QUESTION eq
+                ON (eq.question_id = qrc.question_id)
+                INNER JOIN $categoryTable c
+                ON (c.iid = qrc.category_id)
                 WHERE   exercice_id = $exerciseId AND
-                        eq.question_id = qrc.question_id AND
-                        eq.c_id =".api_get_course_int_id()." AND
-                        eq.c_id = qrc.c_id
-                ORDER BY category_id, question_id";
+                        qrc.c_id = ".api_get_course_int_id()."
+                ORDER BY $orderBy ";
 
 		$res = Database::query($sql);
+
+        $categories = array();
 		while ($data = Database::fetch_array($res)) {
             if (!empty($check_in_question_list)) {
                 if (!in_array($data['question_id'], $check_in_question_list)) {
@@ -721,18 +671,32 @@ class Testcategory
 
             $categories[$data['category_id']][] = $data['question_id'];
         }
+
+        if ($shuffleResult) {
+            if (!empty($categories)) {
+                ArrayClass::shuffle_assoc($categories);
+            }
+        }
         return $categories;
     }
 
-	/**
+    /**
      * Return an array of X elements of an array
-	 */
-    public static function getNElementsFromArray($array, $random_number)
+     * @param array $array
+     * @param int $numberOfElements
+     * @param bool $randomize
+     * @return array
+     */
+    public static function getNElementsFromArray($array, $numberOfElements, $randomize)
     {
-        shuffle($array);
-        if ($random_number < count($array)) {
-            $array = array_slice($array, 0, $random_number);
-		}
+        if (!empty($array)) {
+            if ($randomize) {
+                shuffle($array);
+            }
+            if ($numberOfElements < count($array)) {
+                $array = array_slice($array, 0, $numberOfElements);
+            }
+        }
         return $array;
 	}
 
@@ -1009,7 +973,7 @@ class Testcategory
      * @return array
      */
     function get_all_categories() {
-        $table = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
+        $table = Database::get_course_table(TABLE_QUIZ_CATEGORY);
         $sql = "SELECT * FROM $table ORDER BY title ASC";
         $res = Database::query($sql);
         while ($row = Database::fetch_array($res,'ASSOC')) {
@@ -1022,83 +986,50 @@ class Testcategory
      * @param int $exercise_id
      * @param int $course_id
      * @param string $order
-     * @return bool
+     * @return array
      */
-    public function get_category_exercise_tree($exercise_id, $course_id, $order = null)
+    public function getCategoryExerciseTree($exercise_id, $course_id, $order = null)
     {
         $table = Database::get_course_table(TABLE_QUIZ_REL_CATEGORY);
-        $table_category = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
+        $table_category = Database::get_course_table(TABLE_QUIZ_CATEGORY);
         $sql = "SELECT * FROM $table qc INNER JOIN $table_category c ON (category_id = c.iid)
-                WHERE exercise_id = {$exercise_id} AND qc.c_id = {$course_id} ";
+                WHERE exercise_id = {$exercise_id} ";
 
         if (!empty($order)) {
             $sql .= "ORDER BY $order";
         }
+        $categories = array();
 
         $result = Database::query($sql);
         if (Database::num_rows($result)) {
+            $list = array();
              while ($row = Database::fetch_array($result, 'ASSOC')) {
                 $list[$row['category_id']] = $row;
             }
+
             if (!empty($list)) {
-                $array = $this->sort_tree_array($list);
-                $this->create_tree_array($array);
+                $categories = $this->sort_tree_array($list);
             }
-            return $this->category_array_tree;
-        }
-        return false;
-    }
-
-    /**
-     * @param $type
-     * @return mixed
-     */
-    public function get_category_tree_by_type($type) {
-        $course_id = api_get_course_int_id();
-        if ($type == 'global') {
-            $course_condition = 'c_id = 0';
-        } else {
-            $course_condition = " c_id IN ('$course_id', '0') ";
-        }
-        $t_cattable = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
-
-        $sql = "SELECT * FROM $t_cattable WHERE $course_condition";
-        $res = Database::query($sql);
-        $categories = array();
-        while ($row = Database::fetch_array($res, 'ASSOC')) {
-            $row['id'] = $row['iid'];
-            $categories[] = $row;
-        }
-        if (!empty($categories)) {
-            $array = $this->sort_tree_array($categories);
-            $this->create_tree_array($array);
         }
-        return $this->category_array_tree;
+        return $categories;
     }
 
     /**
      * @param $exercise_obj
      * @return string
      */
-    public function return_category_form($exercise_obj) {
+    public function return_category_form($exercise_obj)
+    {
 
         $categories = $this->getListOfCategoriesForTest($exercise_obj);
 
-        if (!empty($categories)) {
-            $array = $this->sort_tree_array($categories);
-
-            $this->create_tree_array($array);
-        }
-
         $saved_categories = $exercise_obj->get_categories_in_exercise();
         $return = null;
 
-        if (!empty($this->category_array_tree)) {
+        if (!empty($categories)) {
             $nbQuestionsTotal = $exercise_obj->getNumberQuestionExerciseCategory();
-            $original_grouping = $exercise_obj->categories_grouping;
             $exercise_obj->setCategoriesGrouping(true);
             $real_question_count = count($exercise_obj->selectQuestionList(true));
-            $exercise_obj->setCategoriesGrouping($original_grouping);
 
             $warning = null;
             if ($nbQuestionsTotal != $real_question_count) {
@@ -1110,12 +1041,12 @@ class Testcategory
             $return .= '<tr>';
             $return .= '<th height="24">' . get_lang('Categories') . '</th>';
             $return .= '<th width="70" height="24">' . get_lang('Number') . '</th></tr>';
-            for ($i = 0; $i < count($this->category_array_tree); $i++) {
-                $cat_id = $this->category_array_tree[$i]['id'];
+
+            foreach($categories as $category) {
+                $cat_id = $category['iid'];
                 $return .= '<tr>';
                 $return .= '<td>';
-                $style = 'margin-left:' . $this->category_array_tree[$i]['depth'] * 20 . 'px; margin-right:10px;';
-                $return .= Display::div($this->category_array_tree[$i]['title'], array('style' => $style));
+                $return .= Display::div($category['parent_path']);
                 $return .= '</td>';
                 $return .= '<td>';
                 $value = isset($saved_categories) && isset($saved_categories[$cat_id]) ? $saved_categories[$cat_id]['count_questions'] : 0;
@@ -1129,10 +1060,12 @@ class Testcategory
     }
 
     /**
+     * Sorts an array
      * @param $array
      * @return mixed
      */
-    public function sort_tree_array($array) {
+    public function sort_tree_array($array)
+    {
       foreach ($array as $key => $row) {
             $parent[$key] = $row['parent_id'];
         }
@@ -1142,30 +1075,6 @@ class Testcategory
         return $array;
     }
 
-    /**
-     * @param $array
-     * @param int $parent
-     * @param $depth
-     * @param array $tmp
-     */
-    public function create_tree_array($array, $parent = 0, $depth = -1, $tmp = array()) {
-        if (is_array($array)) {
-            for ($i = 0; $i < count($array); $i++) {
-                if ($array[$i]['parent_id'] == $parent) {
-                    if (!in_array($array[$i]['parent_id'], $tmp)) {
-                        $tmp[] = $array[$i]['parent_id'];
-                        $depth++;
-                    }
-                    $row = $array[$i];
-                    $row['id'] = $array[$i]['iid'];
-                    $row['depth'] = $depth;
-                    $this->category_array_tree[] = $row;
-                    $this->create_tree_array($array, $array[$i]['iid'], $depth, $tmp);
-                }
-            }
-        }
-    }
-
     public function getForm(& $form, $action = 'new') {
 
         switch($action) {

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

@@ -317,7 +317,7 @@ switch ($action) {
     case 'get_question_list':
         if (isset($exercise) && !empty($exercise)) {
             $columns = array('question', 'type', 'category', 'level', 'score', 'actions');
-            $result = $exercise->getQuestionList($start, $limit, $sidx, $sord, $where_condition);
+            $result = $exercise->getQuestionListPagination($start, $limit, $sidx, $sord, $where_condition);
         }
         break;
     case 'get_group_reporting':

+ 15 - 10
main/inc/lib/display.lib.php

@@ -1749,30 +1749,31 @@ class Display
      * @param string $link
      * @return string
      */
-    public static function progress_pagination_bar($list, $current, $conditions = array(), $link = null, $counter = null, $addLetters = false, $fixValue = null)
+    public static function progress_pagination_bar($questionList, $current, $conditions = array(), $link = null, $counter = null, $addLetters = false, $fixValue = null)
     {
         if (empty($counter)) {
             $counter = 1;
         }
+
         $fixedCounter = $counter;
         $pagination_size = 'pagination-mini';
         $html = '<div class="exercise_pagination pagination '.$pagination_size.'"><ul>';
         $cleanCounter = 1;
-
         $defaultClass = "before";
 
         $affectAllItems = false;
+
         if ($addLetters && $fixValue) {
             if ($current == $fixValue) {
                 $affectAllItems = true;
             }
         }
 
-        foreach ($list as $item_id) {
+        foreach ($questionList as $item_id) {
             $class = $defaultClass;
 
             foreach ($conditions as $condition) {
-                $array = $condition['items'];
+                $array = isset($condition['items']) ? $condition['items'] : array();
                 $class_to_applied = $condition['class'];
                 $type = isset($condition['type']) ? $condition['type'] : 'positive';
                 $mode = isset($condition['mode']) ? $condition['mode'] : 'add';
@@ -1806,8 +1807,6 @@ class Display
                             $class = "before current";
                         //}
                     }
-                } else {
-
                 }
             } else {
                 // Default behaviour
@@ -1830,7 +1829,7 @@ class Display
                 $link_to_show = $link.($fixedCounter - 1);
             }
 
-            $html .= '<li class = "'.$class.'"><a href="'.$link_to_show.'">'.$label.'</a></li>';
+            $html .= '<li class = "'.$class.'"><a href="'.$link_to_show.'">'.$label.' '.$item_id.' </a></li>';
             $counter++;
             $cleanCounter++;
         }
@@ -1849,12 +1848,12 @@ class Display
      * @param string $link
      * @return string
      */
-    public static function progress_pagination_bar_with_categories($unflattenQuestionList, $categories, $current, $conditions = array(), $link = null)
+    public static function progress_pagination_bar_with_categories($flattenQuestionList, $categories, $current, $conditions = array(), $link = null)
     {
         $counter = 1;
         $html = null;
         $mediaUsedCounter = 0;
-        //var_dump($categories);
+
         if (!empty($categories)) {
             foreach ($categories as $category) {
                 //var_dump($counter);
@@ -1871,8 +1870,14 @@ class Display
                     $mediaUsedCounter++;
                 }
 
+                $categoryName = $category['name'];
+
+                if (isset($category['parent_info'])) {
+                    $categoryName  = $category['parent_info']['title'];
+                }
+
                 $html .= '<div class="row">';
-                $html .= '<div class="span2">'.$category['name'].'</div>';
+                $html .= '<div class="span2">'.$categoryName.'</div>';
                 $html .= '<div class="span8">';
                 $html .= self::progress_pagination_bar(
                     $questionList,

+ 216 - 156
main/inc/lib/exercise.lib.php

@@ -25,8 +25,18 @@ class ExerciseLib
      * @param int   current item from the list of questions
      * @param int   number of total questions
      * */
-    public static function showQuestion($objQuestionTmp, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false)
-    {
+    public static function showQuestion(
+        $objQuestionTmp,
+        $only_questions = false,
+        $origin = false,
+        $current_item = '',
+        $show_title = true,
+        $freeze = false,
+        $user_choice = array(),
+        $show_comment = false,
+        $exercise_feedback = null,
+        $show_answers = false
+    ) {
         // Text direction for the current language
         //$is_ltr_text_direction = api_get_text_direction() != 'rtl';
         // Change false to true in the following line to enable answer hinting
@@ -136,7 +146,7 @@ class ExerciseLib
                 $oFCKeditor->Value = $fck_content;
                 $s .= $oFCKeditor->CreateHtml();
             } elseif ($answerType == ORAL_EXPRESSION) {
-                //Add nanog
+                // Add nanogong
                 if (api_get_setting('enable_nanogong') == 'true') {
 
                     //@todo pass this as a parameter
@@ -204,8 +214,6 @@ class ExerciseLib
                 }
             }
 
-            //for ($answerId=1; $answerId <= $nbrAnswers; $answerId++) {
-
             foreach ($objAnswerTmp->answer as $answerId => $answer_item) {
                 $answer = $objAnswerTmp->selectAnswer($answerId);
                 $answerCorrect = $objAnswerTmp->isCorrect($answerId);
@@ -217,6 +225,7 @@ class ExerciseLib
                 $attributes = array();
                 // Unique answer
                 if (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION))) {
+
                     $input_id = 'choice-'.$questionId.'-'.$answerId;
                     if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) {
                         $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
@@ -261,6 +270,7 @@ class ExerciseLib
                     } else {
                         $s .= $answer_input;
                     }
+
                 } elseif (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_TRUE_FALSE, GLOBAL_MULTIPLE_ANSWER))) {
                     $input_id = 'choice-'.$questionId.'-'.$answerId;
                     $answer = Security::remove_XSS($answer, STUDENT);
@@ -336,6 +346,7 @@ class ExerciseLib
                         }
                         $s.='</tr>';
                     }
+
                 } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) {
 
                     // multiple answers
@@ -723,140 +734,140 @@ class ExerciseLib
                 $html .=  $questionDescription;
                 $html .=  '</td></tr>';
             }
+
             $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1');
 
-            $s .= '<script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script>
-                            <script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script>
-                            <script type="text/javascript">
-                            <!--
-                            // Globals
-                            // Major version of Flash required
-                            var requiredMajorVersion = 7;
-                            // Minor version of Flash required
-                            var requiredMinorVersion = 0;
-                            // Minor version of Flash required
-                            var requiredRevision = 0;
-                            // the version of javascript supported
-                            var jsVersion = 1.0;
-                            // -->
-                            </script>
-                            <script language="VBScript" type="text/vbscript">
-                            <!-- // Visual basic helper required to detect Flash Player ActiveX control version information
-                            Function VBGetSwfVer(i)
-                              on error resume next
-                              Dim swControl, swVersion
-                              swVersion = 0
-
-                              set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i))
-                              if (IsObject(swControl)) then
-                                swVersion = swControl.GetVariable("$version")
-                              end if
-                              VBGetSwfVer = swVersion
-                            End Function
-                            // -->
-                            </script>
-
-                            <script language="JavaScript1.1" type="text/javascript">
-                            <!-- // Detect Client Browser type
-                            var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
-                            var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
-                            var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
-                            jsVersion = 1.1;
-                            // JavaScript helper required to detect Flash Player PlugIn version information
-                            function JSGetSwfVer(i) {
-                                // NS/Opera version >= 3 check for Flash plugin in plugin array
-                                if (navigator.plugins != null && navigator.plugins.length > 0) {
-                                    if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
-                                        var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
-                                        var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
-                                        descArray = flashDescription.split(" ");
-                                        tempArrayMajor = descArray[2].split(".");
-                                        versionMajor = tempArrayMajor[0];
-                                        versionMinor = tempArrayMajor[1];
-                                        if ( descArray[3] != "" ) {
-                                            tempArrayMinor = descArray[3].split("r");
-                                        } else {
-                                            tempArrayMinor = descArray[4].split("r");
-                                        }
-                                        versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
-                                        flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
-                                    } else {
-                                        flashVer = -1;
-                                    }
-                                }
-                                // MSN/WebTV 2.6 supports Flash 4
-                                else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
-                                // WebTV 2.5 supports Flash 3
-                                else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
-                                // older WebTV supports Flash 2
-                                else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
-                                // Can\'t detect in all other cases
-                                else
-                                {
-                                    flashVer = -1;
+            $s .= ' <script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script>
+                    <script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script>
+                    <script type="text/javascript">
+                    <!--
+                    // Globals
+                    // Major version of Flash required
+                    var requiredMajorVersion = 7;
+                    // Minor version of Flash required
+                    var requiredMinorVersion = 0;
+                    // Minor version of Flash required
+                    var requiredRevision = 0;
+                    // the version of javascript supported
+                    var jsVersion = 1.0;
+                    // -->
+                    </script>
+                    <script language="VBScript" type="text/vbscript">
+                    <!-- // Visual basic helper required to detect Flash Player ActiveX control version information
+                    Function VBGetSwfVer(i)
+                      on error resume next
+                      Dim swControl, swVersion
+                      swVersion = 0
+
+                      set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i))
+                      if (IsObject(swControl)) then
+                        swVersion = swControl.GetVariable("$version")
+                      end if
+                      VBGetSwfVer = swVersion
+                    End Function
+                    // -->
+                    </script>
+
+                    <script language="JavaScript1.1" type="text/javascript">
+                    <!-- // Detect Client Browser type
+                    var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
+                    var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
+                    var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
+                    jsVersion = 1.1;
+                    // JavaScript helper required to detect Flash Player PlugIn version information
+                    function JSGetSwfVer(i) {
+                        // NS/Opera version >= 3 check for Flash plugin in plugin array
+                        if (navigator.plugins != null && navigator.plugins.length > 0) {
+                            if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
+                                var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
+                                var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
+                                descArray = flashDescription.split(" ");
+                                tempArrayMajor = descArray[2].split(".");
+                                versionMajor = tempArrayMajor[0];
+                                versionMinor = tempArrayMajor[1];
+                                if ( descArray[3] != "" ) {
+                                    tempArrayMinor = descArray[3].split("r");
+                                } else {
+                                    tempArrayMinor = descArray[4].split("r");
                                 }
-                                return flashVer;
+                                versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
+                                flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
+                            } else {
+                                flashVer = -1;
                             }
-                            // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
-
-                            function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) {
-                                reqVer = parseFloat(reqMajorVer + "." + reqRevision);
-                                // loop backwards through the versions until we find the newest version
-                                for (i=25;i>0;i--) {
-                                    if (isIE && isWin && !isOpera) {
-                                        versionStr = VBGetSwfVer(i);
-                                    } else {
-                                        versionStr = JSGetSwfVer(i);
-                                    }
-                                    if (versionStr == -1 ) {
-                                        return false;
-                                    } else if (versionStr != 0) {
-                                        if(isIE && isWin && !isOpera) {
-                                            tempArray         = versionStr.split(" ");
-                                            tempString        = tempArray[1];
-                                            versionArray      = tempString .split(",");
-                                        } else {
-                                            versionArray      = versionStr.split(".");
-                                        }
-                                        versionMajor      = versionArray[0];
-                                        versionMinor      = versionArray[1];
-                                        versionRevision   = versionArray[2];
-
-                                        versionString     = versionMajor + "." + versionRevision;   // 7.0r24 == 7.24
-                                        versionNum        = parseFloat(versionString);
-                                        // is the major.revision >= requested major.revision AND the minor version >= requested minor
-                                        if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) {
-                                            return true;
-                                        } else {
-                                            return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false );
-                                        }
-                                    }
+                        }
+                        // MSN/WebTV 2.6 supports Flash 4
+                        else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
+                        // WebTV 2.5 supports Flash 3
+                        else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
+                        // older WebTV supports Flash 2
+                        else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
+                        // Can\'t detect in all other cases
+                        else {
+                            flashVer = -1;
+                        }
+                        return flashVer;
+                    }
+                    // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
+
+                    function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) {
+                        reqVer = parseFloat(reqMajorVer + "." + reqRevision);
+                        // loop backwards through the versions until we find the newest version
+                        for (i=25;i>0;i--) {
+                            if (isIE && isWin && !isOpera) {
+                                versionStr = VBGetSwfVer(i);
+                            } else {
+                                versionStr = JSGetSwfVer(i);
+                            }
+                            if (versionStr == -1 ) {
+                                return false;
+                            } else if (versionStr != 0) {
+                                if(isIE && isWin && !isOpera) {
+                                    tempArray         = versionStr.split(" ");
+                                    tempString        = tempArray[1];
+                                    versionArray      = tempString .split(",");
+                                } else {
+                                    versionArray      = versionStr.split(".");
+                                }
+                                versionMajor      = versionArray[0];
+                                versionMinor      = versionArray[1];
+                                versionRevision   = versionArray[2];
+
+                                versionString     = versionMajor + "." + versionRevision;   // 7.0r24 == 7.24
+                                versionNum        = parseFloat(versionString);
+                                // is the major.revision >= requested major.revision AND the minor version >= requested minor
+                                if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) {
+                                    return true;
+                                } else {
+                                    return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false );
                                 }
                             }
-                            // -->
-                            </script>';
+                        }
+                    }
+                    // -->
+                    </script>';
             $s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520">
-                        <script>
-                            // Version check based upon the values entered above in "Globals"
-                            var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
-
-                            // Check to see if the version meets the requirements for playback
-                            if (hasReqestedVersion) {  // if we\'ve detected an acceptable version
-                                var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/'.$swf_file.'.swf?modifyAnswers='.$questionId.'&amp;canClick:'.$canClick.'" width="600" height="'.$swf_height.'">\'
-                                            + \'<param name="wmode" value="transparent">\'
-                                            + \'<param name="movie" value="../plugin/hotspot/'.$swf_file.'.swf?modifyAnswers='.$questionId.'&amp;canClick:'.$canClick.'" />\'
-                                            + \'<\/object>\';
-                                document.write(oeTags);   // embed the Flash Content SWF when all tests are passed
-                            } else {  // flash is too old or we can\'t detect the plugin
-                                var alternateContent = "Error<br \/>"
-                                    + "Hotspots requires Macromedia Flash 7.<br \/>"
-                                    + "<a href=\"http://www.macromedia.com/go/getflash/\">Get Flash<\/a>";
-                                document.write(alternateContent);  // insert non-flash content
-                            }
-                        </script>
-                        </td>
-                        <td valign="top" align="left">'.$answer_list.'</td></tr>
-                        </table>
+                    <script>
+                        // Version check based upon the values entered above in "Globals"
+                        var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
+
+                        // Check to see if the version meets the requirements for playback
+                        if (hasReqestedVersion) {  // if we\'ve detected an acceptable version
+                            var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/'.$swf_file.'.swf?modifyAnswers='.$questionId.'&amp;canClick:'.$canClick.'" width="600" height="'.$swf_height.'">\'
+                                        + \'<param name="wmode" value="transparent">\'
+                                        + \'<param name="movie" value="../plugin/hotspot/'.$swf_file.'.swf?modifyAnswers='.$questionId.'&amp;canClick:'.$canClick.'" />\'
+                                        + \'<\/object>\';
+                            document.write(oeTags);   // embed the Flash Content SWF when all tests are passed
+                        } else {  // flash is too old or we can\'t detect the plugin
+                            var alternateContent = "Error<br \/>"
+                                + "Hotspots requires Macromedia Flash 7.<br \/>"
+                                + "<a href=\"http://www.macromedia.com/go/getflash/\">Get Flash<\/a>";
+                            document.write(alternateContent);  // insert non-flash content
+                        }
+                    </script>
+                    </td>
+                    <td valign="top" align="left">'.$answer_list.'</td></tr>
+                    </table>
             </td></tr>';
             $html .= $s;
             $html .= '</table>';
@@ -2293,7 +2304,7 @@ class ExerciseLib
         } else {
             //Try getting the question list only if save result is off
             if ($save_user_result == false) {
-                $question_list = $objExercise->get_validated_question_list();
+                $question_list = $objExercise->selectQuestionList();
             }
             error_log("Data tracking is empty! exe_id: $exe_id");
         }
@@ -2342,7 +2353,7 @@ class ExerciseLib
                 error_log('Looping question_list '.print_r($question_list, 1));
             }
 
-            $media_questions = $objExercise->get_media_list();
+            $media_questions = $objExercise->getMediaList();
             $media_is_activated = $objExercise->media_is_activated($media_questions);
 
             $medias_showed = array();
@@ -2551,27 +2562,42 @@ class ExerciseLib
     }
 
 
-    public static function render_question_list($objExercise, $questionList, $current_question, $exerciseResult, $attempt_list, $remind_list, $media_questions = array()) {
+    /**
+     * @param \Exercise $objExercise
+     * @param array $questionListFlatten
+     * @param array $questionList
+     * @param int $current_question
+     * @param array $exerciseResult
+     * @param array $attempt_list
+     * @param array $remind_list
+     */
+    public static function render_question_list($objExercise, $questionListFlatten, $questionList, $current_question, $exerciseResult, $attempt_list, $remind_list)
+    {
+        $mediaQuestions = $objExercise->getMediaList();
+        /* $newMediaList = array();
+        if (!empty($mediaQuestions)) {
+            foreach ($mediaQuestions as $mediaId => $questionMediaList) {
+                foreach ($questionMediaList as $questionId) {
+                    $newMediaList[$questionId] = $mediaId;
+                }
+            }
+        }*/
 
-        $i = 1;
-        //Normal question list render
+        $i = 0;
+
+        // Normal question list render
         foreach ($questionList as $questionId) {
-            // for sequential exercises
+            $i++;
+            // For sequential exercises
             if ($objExercise->type == ONE_PER_PAGE) {
-                // if it is not the right question, goes to the next loop iteration
+                // If it is not the right question, goes to the next loop iteration
                 if ($current_question != $i) {
-                    $i++;
                     continue;
                 } else {
                     if ($objExercise->feedback_type != EXERCISE_FEEDBACK_TYPE_DIRECT) {
                         // if the user has already answered this question
                         if (isset($exerciseResult[$questionId])) {
-                            // construction of the Question object
-                            $objQuestionTmp = Question::read($questionId);
-                            // destruction of the Question object
-                            unset ($objQuestionTmp);
                             Display::display_normal_message(get_lang('AlreadyAnswered'));
-                            $i++;
                             break;
                         }
                     }
@@ -2579,8 +2605,10 @@ class ExerciseLib
             }
 
             // Media question render
-            if (isset($media_questions) && !empty($media_questions) && isset($media_questions[$questionId])) {
-                $media_question_list = $media_questions[$questionId];
+
+            if (isset($mediaQuestions[$questionId]) && $mediaQuestions[$questionId] != 999) {
+
+                $media_question_list = $mediaQuestions[$questionId];
                 $objQuestionTmp = Question::read($questionId);
 
                 $counter = 1;
@@ -2597,19 +2625,49 @@ class ExerciseLib
                             if ($counter == $count_of_questions_inside_media) {
                                 $last_question_in_media = true;
                             }
-                            self::render_question($objExercise, $my_question_id, $attempt_list, $remind_list, chr($letterCounter), $current_question, $media_question_list, $last_question_in_media, $questionList, $current_question);
+                            self::render_question(
+                                $objExercise,
+                                $my_question_id,
+                                $attempt_list,
+                                $remind_list,
+                                chr($letterCounter),
+                                $current_question,
+                                $media_question_list,
+                                $last_question_in_media,
+                                $questionList
+                            );
                             $letterCounter++;
                             $counter++;
                         }
                     }
                 } else {
-                    self::render_question($objExercise, $questionId, $attempt_list, $remind_list, $i, $current_question, null, null, $questionList, $current_question);
+                    self::render_question(
+                        $objExercise,
+                        $questionId,
+                        $attempt_list,
+                        $remind_list,
+                        $i,
+                        $current_question,
+                        null,
+                        null,
+                        $questionList
+                    );
                     $i++;
                 }
             } else {
+                //var_dump($i, $questionId, $current_question);
                 // Normal question render.
-                self::render_question($objExercise, $questionId, $attempt_list, $remind_list, $i, $current_question, null, null, $questionList, $current_question);
-                $i++;
+                self::render_question(
+                    $objExercise,
+                    $questionId,
+                    $attempt_list,
+                    $remind_list,
+                    $i,
+                    $current_question,
+                    null,
+                    null,
+                    $questionList
+                );
             }
 
             // For sequential exercises.
@@ -2635,10 +2693,11 @@ class ExerciseLib
         $current_question,
         $questions_in_media = array(),
         $last_question_in_media = false,
-        $realQuestionList,
-        $realCurrentQuestion
+        $realQuestionList
     ) {
+
         global $origin;
+
         $question_obj = Question::read($questionId);
         $user_choice = isset($attempt_list[$questionId]) ? $attempt_list[$questionId] : null;
 
@@ -2706,10 +2765,10 @@ class ExerciseLib
         $paginator = null;
         if ($objExercise->type == ONE_PER_PAGE) {
             if (empty($questions_in_media)) {
-                $paginator = Display::paginationIndicator($realCurrentQuestion, count($realQuestionList));
+                $paginator = Display::paginationIndicator($current_question, count($realQuestionList));
             } else {
                 if ($last_question_in_media) {
-                    $paginator = Display::paginationIndicator($realCurrentQuestion, count($realQuestionList));
+                    $paginator = Display::paginationIndicator($current_question, count($realQuestionList));
                 }
             }
         }
@@ -2725,7 +2784,8 @@ class ExerciseLib
      * @param int $exeId
      * @param Datetime $last_attempt_date
      */
-    function update_attempt_date($exeId, $last_attempt_date) {
+    public static function update_attempt_date($exeId, $last_attempt_date)
+    {
         $exercice_attemp_table = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
         $exeId = intval($exeId);
         $last_attempt_date = Database::escape_string($last_attempt_date);

Some files were not shown because too many files changed in this diff