diff --git a/main/exercice/exercise.class.php b/main/exercice/exercise.class.php index 39dc9a572b..4de0b0a1ec 100644 --- a/main/exercice/exercise.class.php +++ b/main/exercice/exercise.class.php @@ -696,20 +696,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; } @@ -726,28 +724,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 @@ -776,13 +772,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']; @@ -840,12 +834,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']; } @@ -881,34 +880,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; } /** @@ -5206,9 +5197,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; @@ -5602,6 +5593,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) { @@ -5620,8 +5612,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); @@ -5668,7 +5660,6 @@ class Exercise $i++; } } else { - //var_dump($i, $questionId, $currentQuestion); // Normal question render. $this->renderQuestion($questionId, $attemptList, $remindList, $i, $currentQuestion, null, null, $questionList); } @@ -5713,6 +5704,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; diff --git a/main/exercice/exercise_submit.php b/main/exercice/exercise_submit.php index 0eed911abf..d3c3f66ad1 100644 --- a/main/exercice/exercise_submit.php +++ b/main/exercice/exercise_submit.php @@ -353,6 +353,7 @@ if (!isset($_SESSION['objExercise']) || $_SESSION['objExercise']->id != $_REQUES } } + // $objExercise = new Exercise(); $objExercise->read($exerciseId); //2. Checking if $objExercise is set @@ -482,6 +483,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; @@ -532,6 +534,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. @@ -587,7 +590,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(); /* @@ -821,6 +824,7 @@ if (api_is_course_admin() && $origin != 'learnpath') { } echo ''; } + if ($objExercise->type == ONE_PER_PAGE) { echo $objExercise->getProgressPagination( $exe_id, @@ -973,19 +977,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++; } @@ -993,6 +998,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') . "');\""; } @@ -1186,7 +1193,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']); } diff --git a/main/inc/ajax/exercise.ajax.php b/main/inc/ajax/exercise.ajax.php index a135f3c306..ccff137f88 100644 --- a/main/inc/ajax/exercise.ajax.php +++ b/main/inc/ajax/exercise.ajax.php @@ -338,7 +338,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. @@ -435,7 +435,7 @@ switch ($action) { if ($debug) error_log("Saving question_id = $my_question_id "); - $my_choice = $choice[$my_question_id]; + $my_choice = isset($choice[$my_question_id]) ? $choice[$my_question_id] : null; if ($debug) error_log("my_choice = ".print_r($my_choice, 1).""); diff --git a/main/install/1.10.0/db_course.sql b/main/install/1.10.0/db_course.sql index 0975bf6ceb..ba2648e73e 100644 --- a/main/install/1.10.0/db_course.sql +++ b/main/install/1.10.0/db_course.sql @@ -1332,6 +1332,7 @@ CREATE TABLE c_quiz_answer ( answer_code char(10) DEFAULT '', PRIMARY KEY (iid) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +ALTER TABLE c_quiz_answer ADD INDEX idx_cqa_qid (question_id); /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1455,6 +1456,7 @@ CREATE TABLE c_quiz_rel_question ( question_order int(10) unsigned NOT NULL DEFAULT '1', PRIMARY KEY (iid) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +ALTER TABLE c_quiz_rel_question ADD INDEX idx_cqrq_id (question_id); /*!40101 SET character_set_client = @saved_cs_client */; -- diff --git a/main/install/1.10.0/db_main.sql b/main/install/1.10.0/db_main.sql index c983eedd64..082e57e187 100644 --- a/main/install/1.10.0/db_main.sql +++ b/main/install/1.10.0/db_main.sql @@ -3528,4 +3528,4 @@ CREATE TABLE ext_log_entries ( ) DEFAULT CHARSET=utf8; -- Do not move this -UPDATE settings_current SET selected_value = '1.10.0.018' WHERE variable = 'chamilo_database_version'; +UPDATE settings_current SET selected_value = '1.10.0.020' WHERE variable = 'chamilo_database_version'; diff --git a/main/install/1.10.0/migrate-db-1.9.0-1.10.0-pre.sql b/main/install/1.10.0/migrate-db-1.9.0-1.10.0-pre.sql index 18ad5fa837..45f51cfe67 100755 --- a/main/install/1.10.0/migrate-db-1.9.0-1.10.0-pre.sql +++ b/main/install/1.10.0/migrate-db-1.9.0-1.10.0-pre.sql @@ -234,6 +234,7 @@ ALTER TABLE c_quiz_answer MODIFY c_id INT NOT NULL; ALTER TABLE c_quiz_answer MODIFY id_auto INT NOT NULL; ALTER TABLE c_quiz_answer DROP PRIMARY KEY; ALTER TABLE c_quiz_answer ADD COLUMN iid INT unsigned NOT NULL auto_increment PRIMARY KEY; +ALTER TABLE c_quiz_answer ADD INDEX idx_cqa_qid (question_id); ALTER TABLE c_quiz_question_option MODIFY id INT NOT NULL; ALTER TABLE c_quiz_question_option MODIFY c_id INT NOT NULL; @@ -245,6 +246,7 @@ ALTER TABLE c_quiz_rel_question MODIFY question_id INT NOT NULL; ALTER TABLE c_quiz_rel_question MODIFY exercice_id INT NOT NULL; ALTER TABLE c_quiz_rel_question DROP PRIMARY KEY; ALTER TABLE c_quiz_rel_question ADD COLUMN iid INT unsigned NOT NULL auto_increment PRIMARY KEY; +ALTER TABLE c_quiz_rel_question ADD INDEX idx_cqrq_id (question_id); ALTER TABLE c_quiz_category MODIFY id INT NOT NULL; ALTER TABLE c_quiz_category MODIFY c_id INT NOT NULL; @@ -300,4 +302,4 @@ ALTER TABLE c_quiz ADD COLUMN end_button int NOT NULL default 0; INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('template', NULL, 'text', 'stylesheets', 'default', 'DefaultTemplateTitle', 'DefaultTemplateComment', NULL, NULL, 1); -- Do not move this -UPDATE settings_current SET selected_value = '1.10.0.018' WHERE variable = 'chamilo_database_version'; +UPDATE settings_current SET selected_value = '1.10.0.019' WHERE variable = 'chamilo_database_version'; diff --git a/src/ChamiloLMS/Component/Editor/Toolbar/Message.php b/src/ChamiloLMS/Component/Editor/Toolbar/Message.php new file mode 100644 index 0000000000..91b5a026d7 --- /dev/null +++ b/src/ChamiloLMS/Component/Editor/Toolbar/Message.php @@ -0,0 +1,34 @@ + 'document', 'groups' =>array('mode', 'document', 'doctools')), +// array('name' => 'clipboard', 'groups' =>array('clipboard', 'undo', )), + //array('name' => 'editing', 'groups' =>array('clipboard', 'undo', )), + //array('name' => 'forms', 'groups' =>array('clipboard', 'undo', )), + '/', + array('name' => 'basicstyles', 'groups' =>array('basicstyles', 'cleanup', )), + array('name' => 'paragraph', 'groups' =>array('list', 'indent', 'blocks', 'align' )), + array('name' => 'links'), + array('name' => 'insert'), + '/', + array('name' => 'styles'), + array('name' => 'colors'), + array('name' => 'tools'), + array('name' => 'others') + ); + + $config['fullPage'] = 'true'; + //$config['height'] = '200'; + + return $config; + } +} + +