diff --git a/main/exercice/answer.class.php b/main/exercice/answer.class.php index 4f9e6652ce..d4fb7061d5 100755 --- a/main/exercice/answer.class.php +++ b/main/exercice/answer.class.php @@ -80,7 +80,15 @@ class Answer $this->cancel(); // fills arrays - $this->read(); + Exercise::read($_REQUEST['exerciseId']); + if($this->random_answers=='1') + { + $this->readOrderedBy('rand()', '');// randomize answers + } + else + { + $this->read(); // natural order + } } /** @@ -114,7 +122,7 @@ class Answer $questionId=$this->questionId; //$answerType=$this->selectType(); - $sql="SELECT id,answer,correct,comment,ponderation, position, hotspot_coordinates, hotspot_type, destination FROM + $sql="SELECT id,answer,correct,comment,ponderation, position, hotspot_coordinates, hotspot_type, destination, id_auto FROM $TBL_ANSWER WHERE question_id ='".Database::escape_string($questionId)."' ORDER BY position"; $result=Database::query($sql,__FILE__,__LINE__); @@ -133,6 +141,7 @@ class Answer $this->hotspot_coordinates[$i]=$object->hotspot_coordinates; $this->hotspot_type[$i]=$object->hotspot_type; $this->destination[$i]=$object->destination; + $this->autoId[$i]=$object->id_auto; $i++; } @@ -161,7 +170,7 @@ class Answer $questionId=$this->questionId; //$answerType=$this->selectType(); - $sql="SELECT answer,correct,comment,ponderation,position, hotspot_coordinates, hotspot_type,destination " . + $sql="SELECT answer,correct,comment,ponderation,position, hotspot_coordinates, hotspot_type, destination, id_auto " . "FROM $TBL_ANSWER WHERE question_id='".Database::escape_string($questionId)."' " . "ORDER BY $field $order"; @@ -178,13 +187,26 @@ class Answer $this->weighting[$i]=$object->ponderation; $this->position[$i]=$object->position; $this->destination[$i]=$object->destination; - + $this->autoId[$i]=$object->id_auto; $i++; } $this->nbrAnswers=$i-1; } + + /** + * returns the autoincrement id identificator + * + * @author - Juan Carlos Raņa + * @return - integer - answer num + */ + function selectAutoId($id) + { + return $this->autoId[$id]; + } + + /** * returns the number of answers in this question * diff --git a/main/exercice/exercise.class.php b/main/exercice/exercise.class.php index 2632451c83..2cab8f6caa 100755 --- a/main/exercice/exercise.class.php +++ b/main/exercice/exercise.class.php @@ -19,15 +19,16 @@ class Exercise var $sound; var $type; var $random; + var $random_answers; var $active; var $timeLimit; var $attempts; var $feedbacktype; var $end_time; - var $start_time; + var $start_time; var $questionList; // array with the list of this exercise's questions var $results_disabled; - var $expired_time; + var $expired_time; /** * constructor of the class * @@ -41,13 +42,14 @@ class Exercise $this->sound=''; $this->type=1; $this->random=0; + $this->random_answers=0; $this->active=1; $this->questionList=array(); $this->timeLimit = 0; $this->end_time = '0000-00-00 00:00:00'; - $this->start_time = '0000-00-00 00:00:00'; - $this->results_disabled =1; - $this->expired_time = '0000-00-00 00:00:00'; + $this->start_time = '0000-00-00 00:00:00'; + $this->results_disabled =1; + $this->expired_time = '0000-00-00 00:00:00'; } /** @@ -68,7 +70,7 @@ class Exercise $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION); #$TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER); - $sql="SELECT title,description,sound,type,random,active, results_disabled, max_attempt,start_time,end_time,feedback_type,expired_time FROM $TBL_EXERCICES WHERE id='".Database::escape_string($id)."'"; + $sql="SELECT title,description,sound,type,random, random_answers, active, results_disabled, max_attempt,start_time,end_time,feedback_type,expired_time FROM $TBL_EXERCICES WHERE id='".Database::escape_string($id)."'"; $result=Database::query($sql,__FILE__,__LINE__); // if the exercise has been found @@ -80,6 +82,7 @@ class Exercise $this->sound=$object->sound; $this->type=$object->type; $this->random=$object->random; + $this->random_answers=$object->random_answers; $this->active=$object->active; $this->results_disabled =$object->results_disabled; $this->attempts = $object->max_attempt; @@ -231,6 +234,21 @@ class Exercise return false; } } + + /** + * returns random answers status. + * + * @author - Juan Carlos Raņa + */ + function selectRandomAnswers() + { + + $this->random_answers; + + return $this->random_answers; + } + + /** * Same as isRandom() but has a name applied to values different than 0 or 1 */ @@ -366,7 +384,6 @@ class Exercise $this->feedbacktype=$feedback_type; } - /** * changes the exercise description * @@ -377,16 +394,18 @@ class Exercise { $this->description=$description; } - /** - * changes the exercise description - * - * @author - Isaac flores - * @param - int The expired time of the quiz - */ - function updateExpiredTime($expired_time) - { - $this->expired_time = $expired_time; - } + + /** + * changes the exercise expired_time + * + * @author - Isaac flores + * @param - int The expired time of the quiz + */ + function updateExpiredTime($expired_time) + { + $this->expired_time = $expired_time; + } + /** * changes the exercise sound file * @@ -460,6 +479,18 @@ class Exercise $this->random=$random; } + + /** + * sets to 0 if answers are not selected randomly + * if answers are selected randomly + * @author - Juan Carlos Raņa + * @param - integer $random_answers - random answers + */ + function updateRandomAnswers($random_answers) + { + $this->$random_answers = $random_answers; + } + /** * enables the exercise * @@ -520,6 +551,7 @@ class Exercise $attempts = $this->attempts; $feedbacktype = $this->feedbacktype; $random = $this->random; + $random_answers = $this->random_answers; $active = $this->active; $session_id = api_get_session_id(); $expired_time = $this->expired_time; @@ -545,6 +577,7 @@ class Exercise $sql .= ", sound='".Database::escape_string($sound)."', type='".Database::escape_string($type)."', random='".Database::escape_string($random)."', + random_answers='".Database::escape_string($random_answers)."', active='".Database::escape_string($active)."', feedback_type='".Database::escape_string($feedbacktype)."', start_time='$start_time',end_time='$end_time', @@ -576,7 +609,7 @@ class Exercise $cond1=Database::escape_string(Security::remove_XSS($exercise)); $cond2=Database::escape_string(Security::remove_XSS(api_html_entity_decode($description),COURSEMANAGERLOWSECURITY)); }*/ - $sql="INSERT INTO $TBL_EXERCICES (start_time, end_time, title, description, sound, type, random,active, results_disabled, max_attempt, feedback_type, expired_time, session_id) + $sql="INSERT INTO $TBL_EXERCICES (start_time, end_time, title, description, sound, type, random, random_answers,active, results_disabled, max_attempt, feedback_type, expired_time, session_id) VALUES( '$start_time','$end_time', '".Database::escape_string($exercise)."', @@ -584,6 +617,7 @@ class Exercise '".Database::escape_string($sound)."', '".Database::escape_string($type)."', '".Database::escape_string($random)."', + '".Database::escape_string($random_answers)."', '".Database::escape_string($active)."', '".Database::escape_string($results_disabled)."', '".Database::escape_string($attempts)."', @@ -949,59 +983,65 @@ class Exercise $random[] = FormValidator :: createElement ('static', 'help','help',''.get_lang('RandomQuestionsHelp').''); //$random[] = FormValidator :: createElement ('text', 'randomQuestions', null,null,'0'); $form -> addGroup($random,null,get_lang('RandomQuestions'),'
'); - + + //random answers + $radios_random_answers = array(); + $radios_random_answers[] = FormValidator :: createElement ('radio', 'randomAnswers', null, get_lang('Yes'),'1'); + $radios_random_answers[] = FormValidator :: createElement ('radio', 'randomAnswers', null, get_lang('No'),'0'); + $form -> addGroup($radios_random_answers, null, get_lang('RandomAnswers')); + + //Attempts $attempt_option=range(0,10); - $attempt_option[0]=get_lang('Infinite'); - - $form -> addElement('select', 'exerciseAttempts',get_lang('ExerciseAttempts'),$attempt_option); - - $form -> addElement('checkbox', 'enabletimelimit',get_lang('EnableTimeLimits'),null,'onclick = " return timelimit() "'); - $var= Exercise::selectTimeLimit(); + $attempt_option[0]=get_lang('Infinite'); + + $form -> addElement('select', 'exerciseAttempts',get_lang('ExerciseAttempts'),$attempt_option); + + $form -> addElement('checkbox', 'enabletimelimit',get_lang('EnableTimeLimits'),null,'onclick = " return timelimit() "'); + $var= Exercise::selectTimeLimit(); if(($this -> start_time!='0000-00-00 00:00:00')||($this -> end_time!='0000-00-00 00:00:00')) $form -> addElement('html','
'); else $form -> addElement('html',''); + + //$form -> addElement('select', 'enabletimercontroltotalminutes',get_lang('ExerciseTimerControlMinutes'),$time_minutes_option); + $form -> addElement('html','
'); - $check_option=$this -> selectType(); -// var_dump($check_option); + $check_option=$this -> selectType(); + // var_dump($check_option); - if ($check_option==1 && isset($_GET['exerciseId'])) { - $diplay = 'none'; - } else { - $diplay = 'block'; - } + if ($check_option==1 && isset($_GET['exerciseId'])) { + $diplay = 'none'; + } else { + $diplay = 'block'; + } - $form -> addElement('html','
'); + $form -> addElement('html','
'); - //Timer control - $time_hours_option = range(0,12); - $time_minutes_option = range(0,59); - $form -> addElement('checkbox', 'enabletimercontrol',get_lang('EnableTimerControl'),null,array('onclick' =>'option_time_expired()','id'=>'enabletimercontrol','onload'=>'check_load_time()')); - $expired_date = (int)$this->selectExpiredTime(); - - if(($expired_date!='0')) { - $form -> addElement('html','
'); - } else { - $form -> addElement('html',''); //End advanced setting - $form -> addElement('html','
'); + + $form -> addElement('html','
'); //End advanced setting + $form -> addElement('html','
'); $defaults = array(); @@ -1053,6 +1093,7 @@ class Exercise } else { $defaults['randomQuestions'] = $this -> random; } + $defaults['randomAnswers'] = $this ->selectRandomAnswers(); $defaults['exerciseType'] = $this -> selectType(); $defaults['exerciseTitle'] = $this -> selectTitle(); $defaults['exerciseDescription'] = $this -> selectDescription(); @@ -1064,20 +1105,21 @@ class Exercise $defaults['enabletimelimit'] = 1; $defaults['start_time'] = ($this->start_time!='0000-00-00 00:00:00')? $this -> start_time : date('Y-m-d 12:00:00'); - $defaults['end_time'] = ($this->end_time!='0000-00-00 00:00:00')?$this -> end_time : date('Y-m-d 12:00:00',time()+84600); + $defaults['end_time'] = ($this->end_time!='0000-00-00 00:00:00')?$this -> end_time : date('Y-m-d 12:00:00',time()+84600); - //Get expired time - if($this -> expired_time != '0') { - $defaults['enabletimercontrol'] = 1; - $defaults['enabletimercontroltotalminutes'] = $this -> expired_time; - } else { - $defaults['enabletimercontroltotalminutes'] = 0; - } + //Get expired time + if($this -> expired_time != '0') { + $defaults['enabletimercontrol'] = 1; + $defaults['enabletimercontroltotalminutes'] = $this -> expired_time; + } else { + $defaults['enabletimercontroltotalminutes'] = 0; + } } else { $defaults['exerciseType'] = 2; $defaults['exerciseAttempts'] = 0; $defaults['randomQuestions'] = 0; + $defaults['randomAnswers'] = 0; $defaults['exerciseDescription'] = ''; $defaults['exerciseFeedbackType'] = 0; $defaults['results_disabled'] = 0; @@ -1110,44 +1152,52 @@ class Exercise $this -> updateFeedbackType($form -> getSubmitValue('exerciseFeedbackType')); $this -> updateType($form -> getSubmitValue('exerciseType')); $this -> setRandom($form -> getSubmitValue('randomQuestions')); + $this -> updateRandomAnswers($form -> getSubmitValue('randomAnswers')); $this -> updateResultsDisabled($form -> getSubmitValue('results_disabled')); $this -> updateExpiredTime($form -> getSubmitValue('enabletimercontroltotalminutes')); + if($form -> getSubmitValue('enabletimelimit')==1) { $start_time = $form -> getSubmitValue('start_time'); $this->start_time = $start_time['Y'].'-'.$start_time['F'].'-'.$start_time['d'].' '.$start_time['H'].':'.$start_time['i'].':00'; $end_time = $form -> getSubmitValue('end_time'); $this->end_time = $end_time['Y'].'-'.$end_time['F'].'-'.$end_time['d'].' '.$end_time['H'].':'.$end_time['i'].':00'; - } else { + } else { $this->start_time = '0000-00-00 00:00:00'; $this->end_time = '0000-00-00 00:00:00'; } - if($form -> getSubmitValue('enabletimercontrol') == 1) { - $expired_total_time = $form -> getSubmitValue('enabletimercontroltotalminutes'); - if ($this->expired_time == 0) { - $this->expired_time = $expired_total_time; - } - - } else { - $this->expired_time = 0; + if($form -> getSubmitValue('enabletimercontrol') == 1) { + $expired_total_time = $form -> getSubmitValue('enabletimercontroltotalminutes'); + if ($this->expired_time == 0) { + $this->expired_time = $expired_total_time; + } + + } else { + $this->expired_time = 0; + } + + if($form -> getSubmitValue('randomAnswers') == 1) { + $this->random_answers=1; + } else { + $this->random_answers=0; } - - $this -> save($type); + + $this -> save($type); } - function search_engine_save() { - if ($_POST['index_document'] != 1) { - return; - } + function search_engine_save() { + if ($_POST['index_document'] != 1) { + return; + } - $course_id = api_get_course_id(); + $course_id = api_get_course_id(); - require_once(api_get_path(LIBRARY_PATH) . 'search/DokeosIndexer.class.php'); - require_once(api_get_path(LIBRARY_PATH) . 'search/IndexableChunk.class.php'); - require_once(api_get_path(LIBRARY_PATH) . 'specific_fields_manager.lib.php'); + require_once(api_get_path(LIBRARY_PATH) . 'search/DokeosIndexer.class.php'); + require_once(api_get_path(LIBRARY_PATH) . 'search/IndexableChunk.class.php'); + require_once(api_get_path(LIBRARY_PATH) . 'specific_fields_manager.lib.php'); - $specific_fields = get_specific_field_list(); - $ic_slide = new IndexableChunk(); + $specific_fields = get_specific_field_list(); + $ic_slide = new IndexableChunk(); $all_specific_terms = ''; foreach ($specific_fields as $specific_field) { diff --git a/main/exercice/exercise.lib.php b/main/exercice/exercise.lib.php index 2d60e3c36b..c9828df92c 100755 --- a/main/exercice/exercise.lib.php +++ b/main/exercice/exercise.lib.php @@ -134,7 +134,7 @@ function showQuestion($questionId, $onlyAnswers=false, $origin=false,$current_it for($answerId=1;$answerId <= $nbrAnswers;$answerId++) { $answer=$objAnswerTmp->selectAnswer($answerId); $answerCorrect=$objAnswerTmp->isCorrect($answerId); - + $numAnswer=$objAnswerTmp->selectAutoId($answerId); if($answerType == FILL_IN_BLANKS) { // splits text and weightings that are joined with the character '::' list($answer)=explode('::',$answer); @@ -209,10 +209,10 @@ function showQuestion($questionId, $onlyAnswers=false, $origin=false,$current_it

-

"; - $answer=api_parse_tex($answer); - $s.=strip_tags($answer); - $s.="
"; +

"; + $answer=api_parse_tex($answer); + $s.=strip_tags($answer); + $s.=""; } elseif($answerType == MULTIPLE_ANSWER) { // multiple answers @@ -221,7 +221,7 @@ function showQuestion($questionId, $onlyAnswers=false, $origin=false,$current_it

-

"; +

"; $answer = api_parse_tex($answer); $s.=strip_tags($answer); $s.="
"; @@ -234,7 +234,7 @@ function showQuestion($questionId, $onlyAnswers=false, $origin=false,$current_it } // free answer - // matching + // matching // TODO: replace $answerId by $numAnswer else { if(!$answerCorrect) { // options (A, B, C, ...) that will be put into the list-box diff --git a/main/exercice/exercise_result.php b/main/exercice/exercise_result.php index 06070f519c..23406bd720 100755 --- a/main/exercice/exercise_result.php +++ b/main/exercice/exercise_result.php @@ -609,6 +609,8 @@ foreach ($questionList as $questionId) { $answerComment=$objAnswerTmp->selectComment($answerId); $answerCorrect=$objAnswerTmp->isCorrect($answerId); $answerWeighting=$objAnswerTmp->selectWeighting($answerId); + $numAnswer=$objAnswerTmp->selectAutoId($answerId); + switch ($answerType) { // for unique answer case UNIQUE_ANSWER : @@ -616,7 +618,7 @@ foreach ($questionList as $questionId) { // then give him the corresponding score // (maybe a negative score, positive score or 0) // Positive score should only be given when we are going over the right answer - $studentChoice=($choice == $answerId)?1:0; + $studentChoice=($choice == $numAnswer)?1:0; if($studentChoice) { $questionScore+=$answerWeighting; $totalScore+=$answerWeighting; @@ -624,7 +626,7 @@ foreach ($questionList as $questionId) { break; // for multiple answers case MULTIPLE_ANSWER : - $studentChoice=$choice[$answerId]; + $studentChoice=$choice[$numAnswer]; if($studentChoice) { $questionScore+=$answerWeighting; $totalScore+=$answerWeighting; @@ -794,7 +796,7 @@ foreach ($questionList as $questionId) { break; - // for matching + // for matching TODO: replace $answerId id by $numAnswer case MATCHING : if($answerCorrect) { diff --git a/main/inc/lib/add_course.lib.inc.php b/main/inc/lib/add_course.lib.inc.php index 680547caa9..64d9a231ed 100755 --- a/main/inc/lib/add_course.lib.inc.php +++ b/main/inc/lib/add_course.lib.inc.php @@ -636,6 +636,7 @@ function update_Db_course($courseDbName) sound varchar(50) default NULL, type tinyint unsigned NOT NULL default 1, random smallint(6) NOT NULL default 0, + random_answers tinyint unsigned NOT NULL default 0, active tinyint NOT NULL default 0, results_disabled TINYINT UNSIGNED NOT NULL DEFAULT 0, access_condition TEXT DEFAULT NULL, @@ -681,10 +682,14 @@ function update_Db_course($courseDbName) hotspot_coordinates text, hotspot_type enum('square','circle','poly','delineation') default NULL, destination text NOT NULL, - PRIMARY KEY (id, question_id) + id_auto int NOT NULL AUTO_INCREMENT, + PRIMARY KEY (id, question_id), + UNIQUE KEY id_auto (id_auto) )"; Database::query($sql, __FILE__, __LINE__); + + // Exercise tool - Test/question relations $sql = " CREATE TABLE `".$TABLEQUIZQUESTION . "` ( @@ -2251,12 +2256,12 @@ function fill_Db_course($courseDbName, $courseRepository, $language,$default_doc Exercise tool ----------------------------------------------------------- */ - Database::query("INSERT INTO `".$TABLEQUIZANSWERSLIST . "` VALUES ( '1', '1', '".lang2db(get_lang('Ridiculise')) . "', '0', '".lang2db(get_lang('NoPsychology')) . "', '-5', '1','','','')",__FILE__,__LINE__); - Database::query("INSERT INTO `".$TABLEQUIZANSWERSLIST . "` VALUES ( '2', '1', '".lang2db(get_lang('AdmitError')) . "', '0', '".lang2db(get_lang('NoSeduction')) . "', '-5', '2','','','')", __FILE__, __LINE__); - Database::query("INSERT INTO `".$TABLEQUIZANSWERSLIST . "` VALUES ( '3', '1', '".lang2db(get_lang('Force')) . "', '1', '".lang2db(get_lang('Indeed')) . "', '5', '3','','','')", __FILE__, __LINE__); - Database::query("INSERT INTO `".$TABLEQUIZANSWERSLIST . "` VALUES ( '4', '1', '".lang2db(get_lang('Contradiction')) . "', '1', '".lang2db(get_lang('NotFalse')) . "', '5', '4','','','')", __FILE__, __LINE__); + Database::query("INSERT INTO `".$TABLEQUIZANSWERSLIST . "` VALUES ( '1', '1', '".lang2db(get_lang('Ridiculise')) . "', '0', '".lang2db(get_lang('NoPsychology')) . "', '-5', '1','','','','')",__FILE__,__LINE__); + Database::query("INSERT INTO `".$TABLEQUIZANSWERSLIST . "` VALUES ( '2', '1', '".lang2db(get_lang('AdmitError')) . "', '0', '".lang2db(get_lang('NoSeduction')) . "', '-5', '2','','','','')", __FILE__, __LINE__); + Database::query("INSERT INTO `".$TABLEQUIZANSWERSLIST . "` VALUES ( '3', '1', '".lang2db(get_lang('Force')) . "', '1', '".lang2db(get_lang('Indeed')) . "', '5', '3','','','','')", __FILE__, __LINE__); + Database::query("INSERT INTO `".$TABLEQUIZANSWERSLIST . "` VALUES ( '4', '1', '".lang2db(get_lang('Contradiction')) . "', '1', '".lang2db(get_lang('NotFalse')) . "', '5', '4','','','','')", __FILE__, __LINE__); $html=addslashes('
'.lang2db(get_lang('Antique')).'
'); - Database::query('INSERT INTO `'.$TABLEQUIZ . '` (title, description, type, random, active, results_disabled ) VALUES ("'.lang2db(get_lang('ExerciceEx')) . '", "'.$html.'", "1", "0", "1", "0")', __FILE__, __LINE__); + Database::query('INSERT INTO `'.$TABLEQUIZ . '` (title, description, type, random, random_answers, active, results_disabled ) VALUES ("'.lang2db(get_lang('ExerciceEx')) . '", "'.$html.'", "1", "0", "0", "1", "0")', __FILE__, __LINE__); Database::query("INSERT INTO `".$TABLEQUIZQUESTIONLIST . "` (id, question, description, ponderation, position, type, picture, level) VALUES ( '1', '".lang2db(get_lang('SocraticIrony')) . "', '".lang2db(get_lang('ManyAnswers')) . "', '10', '1', '2','',1)", __FILE__, __LINE__); Database::query("INSERT INTO `".$TABLEQUIZQUESTION . "` (question_id, exercice_id, question_order) VALUES (1,1,1)", __FILE__, __LINE__); diff --git a/main/install/migrate-db-1.8.6.1-1.8.6.2-pre.sql b/main/install/migrate-db-1.8.6.1-1.8.6.2-pre.sql index 3c699529bc..93c148bdb0 100755 --- a/main/install/migrate-db-1.8.6.1-1.8.6.2-pre.sql +++ b/main/install/migrate-db-1.8.6.1-1.8.6.2-pre.sql @@ -93,3 +93,5 @@ ALTER TABLE group_category ADD COLUMN chat_state TINYINT DEFAULT 1, ADD INDEX (c ALTER TABLE student_publication ADD COLUMN weight float(6,2) UNSIGNED NOT NULL DEFAULT 0; ALTER TABLE course_description ADD COLUMN description_type TINYINT NOT NULL DEFAULT 0; ALTER TABLE dropbox_category ADD COLUMN session_id smallint NOT NULL DEFAULT 0, ADD INDEX (session_id); +ALTER TABLE quiz ADD COLUMN random_answers TINYINT UNSIGNED NOT NULL DEFAULT 0 AFTER random; +ALTER TABLE quiz_answer ADD COLUMN id_auto INT NOT NULL AUTO_INCREMENT, ADD UNIQUE INDEX (id_auto); \ No newline at end of file