diff --git a/main/css/base.css b/main/css/base.css index 94a162b46a..654fb48ef2 100644 --- a/main/css/base.css +++ b/main/css/base.css @@ -765,6 +765,29 @@ button:hover { } +/* blue */ +.blue { + color: #fff !important; + border: solid 1px #0076a3; + background: #0095cd; + background: -webkit-gradient(linear, left top, left bottom, from(#00adee), to(#0078a5)); + background: -moz-linear-gradient(top, #00adee, #0078a5); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00adee', endColorstr='#0078a5'); +} +.blue:hover { + background: #007ead; + background: -webkit-gradient(linear, left top, left bottom, from(#0095cc), to(#00678e)); + background: -moz-linear-gradient(top, #0095cc, #00678e); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0095cc', endColorstr='#00678e'); +} +.blue:active { + color: #80bed6; + background: -webkit-gradient(linear, left top, left bottom, from(#0078a5), to(#00adee)); + background: -moz-linear-gradient(top, #0078a5, #00adee); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0078a5', endColorstr='#00adee'); +} + + /* orange */ @@ -792,7 +815,7 @@ button:hover { /* green */ .green { - color: #e8f0de; + color: #fef4e9 !important; border: solid 1px #538312; background: #64991e; background: -webkit-gradient(linear, left top, left bottom, from(#7db72f), to(#4e7d0e)); @@ -2474,7 +2497,6 @@ div.admin_section h4 { width:33%; } - .exercise_overview_options .right_option { float:right; margin:12px 5px; @@ -2482,6 +2504,106 @@ div.admin_section h4 { font-size : 14px; } +.remind_highlight { + background-color: #FFF7C0; +} + +.main_question { + +} + +.exercise_header { + border-bottom: 1px dotted #ccc; + margin-bottom:20px; +} + +/* Table */ +.exercise_options { + width:720px; + border-collapse: collapse; + border-spacing: 0; +} + +.exercise_options th { + background-color: #F2F2F2; + border-bottom: 1px solid #DDDDDD; + line-height: normal; + padding: 8px 10px; + text-align: center; + vertical-align: middle; +} + +.question_options { + margin-left:14px; + min-height:150px; +} +.question_description { + padding:0px 0px 0px 16px; +} + +.exercise_description { + padding:0px 0px 10px 0px; +} +.exercise_title { + font-size: 1.6em; + font-weight: bold; + padding:10px 0px 10px 0px; +} +.question_title { + font-size: 1.2em; + font-weight: bold; + margin: 15px 0px; +} + +.question_no_answer { + background-color: #FFF7C0; + padding: 5px 0px 5px 0px; + margin: 5px 0px 5px 0px; +} + +.exercise_reminder_container { + +} + +.question_answer { + display: block; + float: left; + margin: 0; + width: 100%; + margin: 0 0 0 0px; +} +.question_answer label { + color: #222222; + display: block; + font-size: 100%; + line-height: 150%; + margin: -27px 0 0 23px; + padding: 0 0 5px; + width: 88%; +} + +.exercise_actions { + background: #f5f5f5; + margin-top: 18px; + margin-bottom: 18px; + padding: 17px 20px 18px 50px; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; +} + +.exercise_save_now_button img { + position: relative; + top: 4px; +} +.exercise_actions a, .exercise_actions div { + margin-right:10px; +} +.exercise_save_now_button, .exercise_button{ + /* padding:10px; */ +} + .red_alert { color:red; font-weight: bold; diff --git a/main/exercice/exercise.class.php b/main/exercice/exercise.class.php index a5c4ce2c80..0464a1f443 100755 --- a/main/exercice/exercise.class.php +++ b/main/exercice/exercise.class.php @@ -1509,8 +1509,12 @@ class Exercise { * @param array question list */ - public function save_stat_track_exercise_info($clock_expired_time = 0, $safe_lp_id = 0, $safe_lp_item_id = 0, $safe_lp_item_view_id = 0, $questionList = array(), $weight) { + public function save_stat_track_exercise_info($clock_expired_time = 0, $safe_lp_id = 0, $safe_lp_item_id = 0, $safe_lp_item_view_id = 0, $questionList = array(), $weight = 0) { $track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + $safe_lp_id = intval($safe_lp_id); + $safe_lp_item_id = intval($safe_lp_item_id); + $safe_lp_item_view_id = intval($safe_lp_item_view_id); + if (empty($safe_lp_id)) { $safe_lp_id = 0; } @@ -1528,63 +1532,72 @@ class Exercise { $sql_fields_values = ""; } array_map('intval', $questionList); + + $weight = Database::escape_string($weight); if ($this->type == ONE_PER_PAGE) { $sql = "INSERT INTO $track_exercises ($sql_fields exe_exo_id, exe_user_id, exe_cours_id, status,session_id, data_tracking, start_date, orig_lp_id, orig_lp_item_id, exe_weighting) VALUES($sql_fields_values '".$this->id."','" . api_get_user_id() . "','" . api_get_course_id() . "','incomplete','" . api_get_session_id() . "','" . implode(',', $questionList) . "', '" . api_get_utc_datetime() . "', '$safe_lp_id', '$safe_lp_item_id', '$weight' )"; } else { - $sql = "INSERT INTO $track_exercises ($sql_fields exe_exo_id,exe_user_id,exe_cours_id,status,session_id,start_date,orig_lp_id,orig_lp_item_id) - VALUES($sql_fields_values '".$this->id."','" . api_get_user_id() . "','" . api_get_course_id() . "','incomplete','" . api_get_session_id() . "','" . api_get_utc_datetime() . "', '$safe_lp_id', '$safe_lp_item_id' , '$weight' )"; + $sql = "INSERT INTO $track_exercises ($sql_fields exe_exo_id, exe_user_id, exe_cours_id, status, session_id, start_date, orig_lp_id, orig_lp_item_id) + VALUES($sql_fields_values '".$this->id."','".api_get_user_id()."','".api_get_course_id()."','incomplete','".api_get_session_id()."','".api_get_utc_datetime()."', '$safe_lp_id', '$safe_lp_item_id')"; } Database::query($sql); + $id = Database::insert_id(); + return $id; } - public function show_button($nbrQuestions, $questionNum, $exerciseId) { - global $origin, $learnpath_id,$learnpath_item_id; - $nbrQuestions = intval($nbrQuestions); - $exerciseId = intval($exerciseId); - - $html = ''; - $html = '
'; - $confirmation_alert = $this->type == 1? " onclick=\"javascript:if(!confirm('".get_lang("ConfirmYourChoice")."')) return false;\" ":""; - $submit_btn = ''; - if ($this->expired_time != 0) { - $html .= $submit_btn =''; + + /*if ($this->type == ALL_ON_ONE_PAGE && $nbrQuestions > 1) { + $all_button = ''.get_lang('SaveForNow').''; + $all_button .= ' '; + $html .= $all_button; + }*/ + + if ($this->type == ONE_PER_PAGE) { + $all_button = ''.$label.''; + //$all_button .= ' '; + $all_button .= ' '; + $html .= $all_button; } else { - $html .= $submit_btn; + $all_button = ''.get_lang('ValidateAnswer').''; + $all_button .= ' '; + $html .= $all_button; } + } - } - $html .= '
'; //margin top -10 + } + + $html = Display::span($html, array('class'=>'exercise_button')); return $html; + } /** @@ -1779,7 +1792,7 @@ class Exercise { if ($debug) error_log('manage_answer $from_database '.$from_database); if ($debug) error_log('manage_answer $show_result '.$show_result); if ($debug) error_log('manage_answer $propagate_neg '.$propagate_neg); - if ($debug) error_log('manage_answer $$hotspot_delineation_result '.print_r($hotspot_delineation_result, 1)); + if ($debug) error_log('manage_answer $hotspot_delineation_result '.print_r($hotspot_delineation_result, 1)); $extra_data = array(); $html = ''; @@ -1894,8 +1907,7 @@ class Exercise { $studentChoice =$choice[$numAnswer]; } else { $studentChoice =$choice[$numAnswer]; - } - + } if (!empty($studentChoice)) { if ($studentChoice == $answerCorrect ) { @@ -2242,12 +2254,14 @@ class Exercise { } // for hotspot with no order case HOT_SPOT : + if ($from_database) { + if ($show_result) { $TBL_TRACK_HOTSPOT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT); $query = "SELECT hotspot_correct FROM ".$TBL_TRACK_HOTSPOT." where hotspot_exe_id = '".$exeId."' and hotspot_question_id= '".$questionId."' AND hotspot_answer_id='".Database::escape_string($answerId)."'"; - $resq=Database::query($query); - $studentChoice = Database::result($resq,0,"hotspot_correct"); + $resq = Database::query($query); + $studentChoice = Database::result($resq,0,"hotspot_correct"); } } else { $studentChoice = $choice[$answerId]; @@ -2318,7 +2332,7 @@ class Exercise { //display answers (if not matching type, or if the answer is correct) if ($answerType != MATCHING || $answerCorrect) { if (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION))) { - if ($origin!='learnpath') { + if ($origin != 'learnpath') { ExerciseShowFunctions::display_unique_or_multiple_answer($answerType, $studentChoice, $answer, $answerComment, $answerCorrect,0,0,0); } } elseif($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { @@ -2743,7 +2757,7 @@ class Exercise { 'overlap_color' => $overlap_color, 'missing_color'=>$missing_color, 'excess_color'=> $excess_color, 'threadhold1' => $threadhold1, 'threadhold2'=>$threadhold2, 'threadhold3'=> $threadhold3, ); - + if ($from == 'exercise_result') { // if answer is hotspot. To the difference of exercise_show.php, we use the results from the session (from_db=0) // TODO Change this, because it is wrong to show the user some results that haven't been stored in the database yet @@ -2869,16 +2883,19 @@ class Exercise { if ($answerType == HOT_SPOT || $answerType == HOT_SPOT_ORDER) { // We made an extra table for the answers + if ($show_result) { + if ($origin != 'learnpath') { echo ''; echo ' '; echo ''.get_lang('HotSpot').'

'; - echo ''; - echo ' - - + + echo ' + + '; + echo ' '; } @@ -2908,7 +2925,7 @@ class Exercise { // For all in one page exercises, the results will be // stored by exercise_results.php (using the session) - if ($saved_results) { + if ($saved_results) { if (empty($choice)) { $choice = 0; } @@ -2956,14 +2973,14 @@ class Exercise { $answer = $choice; exercise_attempt($questionScore, $answer, $quesId, $exeId, 0, $this->id); // } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) { - } elseif ($answerType == HOT_SPOT) { + } elseif ($answerType == HOT_SPOT) { exercise_attempt($questionScore, $answer, $quesId, $exeId, 0, $this->id); if (isset($exerciseResultCoordinates[$questionId]) && !empty($exerciseResultCoordinates[$questionId])) { - foreach($exerciseResultCoordinates[$questionId] as $idx => $val) { + foreach($exerciseResultCoordinates[$questionId] as $idx => $val) { exercise_attempt_hotspot($exeId,$quesId,$idx,$choice[$idx],$val,$this->id); } } - } else { + } else { exercise_attempt($questionScore, $answer, $quesId, $exeId, 0,$this->id); } } @@ -3291,5 +3308,113 @@ class Exercise { return $is_visible; } + + function save_attempt() { + + } + + function added_in_lp() { + $TBL_LP_ITEM = Database::get_course_table(TABLE_LP_ITEM); + $sql = "SELECT max_score FROM $TBL_LP_ITEM WHERE item_type = '".TOOL_QUIZ."' AND path = '".$this->id."'"; + $result = Database::query($sql); + if (Database::num_rows($result) > 0) { + return true; + } + return false; + } + + function get_validated_question_list() { + return ($this->isRandom() ? $this->selectRandomList() : $this->selectQuestionList()); + } + + public function get_stat_track_exercise_info_by_exe_id($exe_id) { + $track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + $exe_id = intval($exe_id); + $sql_track = "SELECT * FROM $track_exercises WHERE exe_id = $exe_id "; + $result = Database::query($sql_track); + $new_array = array(); + if (Database::num_rows($result) > 0 ) { + $new_array = Database::fetch_array($result, 'ASSOC'); + } + return $new_array; + } + + public function edit_question_to_remind($exe_id, $question_id, $action = 'add') { + $exercise_info = self::get_stat_track_exercise_info_by_exe_id($exe_id); + $question_id = intval($question_id); + $exe_id = intval($exe_id); + $track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + if ($exercise_info) { + + if (empty($exercise_info['questions_to_check'])) { + if ($action == 'add') { + $sql = "UPDATE $track_exercises SET questions_to_check = '$question_id' WHERE exe_id = $exe_id "; + $result = Database::query($sql); + } + } else { + $remind_list = explode(',',$exercise_info['questions_to_check']); + + $remind_list_string = ''; + if ($action == 'add') { + if (!in_array($question_id, $remind_list)) { + $remind_list[] = $question_id; + if (!empty($remind_list)) { + sort($remind_list); + array_filter($remind_list); + } + $remind_list_string = implode(',', $remind_list); + } + } elseif ($action == 'delete') { + if (!empty($remind_list)) { + if (in_array($question_id, $remind_list)) { + $remind_list = array_flip($remind_list); + unset($remind_list[$question_id]); + $remind_list = array_flip($remind_list); + + if (!empty($remind_list)) { + sort($remind_list); + array_filter($remind_list); + $remind_list_string = implode(',', $remind_list); + } + } + } + } + $remind_list_string = Database::escape_string($remind_list_string); + $sql = "UPDATE $track_exercises SET questions_to_check = '$remind_list_string' WHERE exe_id = $exe_id "; + $result = Database::query($sql); + } + } + } + + public function fill_in_blank_answer_to_string($answer) { + + api_preg_match_all('/\[[^]]+\]/', $answer, $teacher_answer_list); + + + $result = ''; + + if (!empty($teacher_answer_list)) { + $teacher_answer_list = $teacher_answer_list[0]; + + + $i = 0; + foreach($teacher_answer_list as $teacher_item) { + $value = null; + //Cleaning student answer list + $value = strip_tags($teacher_item); + $value = api_substr($value,1, api_strlen($value)-2); + $value = explode('/', $value); + if (!empty($value[0])) { + $value = trim($value[0]); + $value = str_replace(' ', '', $value); + $result .= $value; + } + } + } + + return $result; + } + + } endif; \ No newline at end of file diff --git a/main/exercice/exercise.lib.php b/main/exercice/exercise.lib.php index a8e627539b..beff5e89d0 100755 --- a/main/exercice/exercise.lib.php +++ b/main/exercice/exercise.lib.php @@ -24,11 +24,12 @@ require_once dirname(__FILE__).'/../inc/lib/fckeditor/fckeditor.php'; * @param int current item from the list of questions * @param int number of total questions * */ -function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false) { +function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array()) { - $s = ''; // Text direction for the current language $is_ltr_text_direction = api_get_text_direction() != 'rtl'; + + $remind_question = 1; // Change false to true in the following line to enable answer hinting. $debug_mark_answer = api_is_allowed_to_edit() && false; @@ -41,56 +42,35 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu $answerType = $objQuestionTmp->selectType(); $pictureName = $objQuestionTmp->selectPicture(); - + + $html = ''; if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) { // Question is not a hotspot if (!$only_questions) { - - $questionName = $objQuestionTmp->selectTitle(); $questionDescription = $objQuestionTmp->selectDescription(); - $questionName = text_filter($questionName); - - if ($show_title) { - $s='
'.get_lang('Question').' '; - $s.=$current_item; - //@todo I need the get the feedback type - //if($answerType != 1) - //$s.=' / '.$total_item; - echo $s; - echo ' : '; - echo $questionName.'
'; - } - - $s=''; - $s.=' -
'; - $questionDescription=text_filter($questionDescription); - $s.=$questionDescription; - $s.='
'; - + + if ($show_title) { + echo Display::div($current_item.'. '.$objQuestionTmp->selectTitle(), array('class'=>'question_title')); + } + if (!empty($questionDescription)) { + echo Display::div($questionDescription, array('class'=>'question_description')); + } + //@deprecated if (!empty($pictureName)) { - $s.=" - - "; + //echo ""; } - $s.= ''; - } - - $s .= '
'; - $option_ie = ''; - /* - if (!ereg("MSIE",$_SERVER["HTTP_USER_AGENT"])) { - $s .= '
'; - } else { - $option_ie="margin-left:10px"; - }*/ + } + + echo '
'; if ($answerType == FREE_ANSWER && $freeze) { return ''; } - $s .= ''; + //$s .= '
'; + + $s .= '
'; // construction of the Answer object (also gets all answers details) $objAnswerTmp = new Answer($questionId); @@ -114,7 +94,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu $answer_matching = $cpt1 = array(); $answer_suggestions = $nbrAnswers; - for ($answerId=1;$answerId <= $nbrAnswers;$answerId++) { + for ($answerId=1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); $answer=$objAnswerTmp->selectAnswer($answerId); @@ -127,99 +107,60 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu } } $i = 1; + + $select_items[0]['id'] = 0; + $select_items[0]['letter'] = '--'; + $select_items[0]['answer'] = ''; + foreach ($answer_matching as $id => $value) { - $select_items[$i]['id'] = $value['id']; - $select_items[$i]['letter'] = $cpt1[$id]; + $select_items[$i]['id'] = $value['id']; + $select_items[$i]['letter'] = $cpt1[$id]; $select_items[$i]['answer'] = $value['answer']; $i ++; } $num_suggestions = ($nbrAnswers - $x) + 1; + } elseif ($answerType == FREE_ANSWER) { + $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer']:null; + $oFCKeditor = new FCKeditor("choice[".$questionId."]") ; + $oFCKeditor->ToolbarSet = 'TestFreeAnswer'; $oFCKeditor->Width = '100%'; $oFCKeditor->Height = '200'; - $oFCKeditor->Value = '' ; + $oFCKeditor->Value = $fck_content; $s .= ''; } - ?> - - - options as $key=>$item) { $header .= Display::tag('th', $item); } - $s.=Display::tag('tr',$header, array('style'=>'text-align:left;')); + $s.= Display::tag('tr',$header, array('style'=>'text-align:left;')); } - for ($answerId=1;$answerId <= $nbrAnswers;$answerId++) { + $matching_correct_answer = 0; + $user_choice_array = array(); + if (!empty($user_choice)) { + foreach($user_choice as $item) { + $user_choice_array[] = $item['answer']; + } + } + + + 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); - - //getting the matches - $answer = api_ereg_replace('\[[^]]+\]','',($answer)); - } - + // Unique answer if ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_NO_OPTION) { // set $debug_mark_answer to true at function start to @@ -232,16 +173,25 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu $selected = 'checked'; } } - $answer = text_filter($answer); + $input_id = 'choice-'.$questionId.'-'.$answerId; + if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer ) { + $attributes = array('id' =>$input_id, 'class'=>'checkbox','checked'=>1, 'selected'=>1); + } else { + $attributes = array('id' =>$input_id, 'class'=>'checkbox'); + } + $answer = Security::remove_XSS($answer, STUDENT); - $s .= Display::input('hidden','choice2['.$questionId.']','0'). - ''; - + $s .= Display::input('hidden','choice2['.$questionId.']','0'); + //@todo fix $is_ltr_text_direction + //

+ //$s .= '

'. + + $s .= '
'; } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE) { // multiple answers @@ -253,37 +203,54 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu $help = 'x-'; $selected = 'checked="checked"'; } - } - $answer = text_filter($answer); + } + $input_id = 'choice-'.$questionId.'-'.$answerId; + + $answer = Security::remove_XSS($answer, STUDENT); + + if (in_array($numAnswer, $user_choice_array)) { + $attributes = array('id' =>$input_id, 'class'=>'checkbox','checked'=>1, 'selected'=>1); + } else { + $attributes = array('id' =>$input_id, 'class'=>'checkbox'); + } + $answer = Security::remove_XSS($answer, STUDENT); if ($answerType == MULTIPLE_ANSWER) { $s .= ''; - $s .= ''; - - } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { - $options = array('type'=>'radio','name'=>'choice['.$questionId.']['.$numAnswer.']', 'class'=>'checkbox'); - $s .= ''; - $s .=''; - $s .= Display::tag('td', $answer); - if (!empty($quiz_question_options)) { - foreach ($quiz_question_options as $id=>$item) { - $options['value'] = $id; - $s .= Display::tag('td', Display::tag('input','',$options )); + + $s .= Display::tag('span', Display::input('checkbox', 'choice['.$questionId.']['.$numAnswer.']', $numAnswer, $attributes)); + $s .= Display::tag('label', $answer, array('for'=>$input_id)).''; + + } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { + $my_choice = array(); + if (!empty($user_choice_array)) { + foreach ($user_choice_array as $item) { + $item = explode(':', $item); + $my_choice[$item[0]] = $item[1]; } } + $s .=''; + $s .= Display::tag('td', $answer); + if (!empty($quiz_question_options)) { + foreach ($quiz_question_options as $id=>$item) { + if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) { + $attributes = array('class'=>'checkbox','checked'=>1, 'selected'=>1); + } else { + $attributes = array('class'=>'checkbox'); + } + + $s .= Display::tag('td', Display::input('radio', 'choice['.$questionId.']['.$numAnswer.']', $id, $attributes)); + } + } $s.=''; } @@ -298,57 +265,123 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu $selected = 'checked="checked"'; } } - $answer = text_filter($answer); + $input_id = 'choice-'.$questionId.'-'.$answerId; + + if (in_array($numAnswer, $user_choice_array)) { + $attributes = array('id'=>$input_id, 'class'=>'checkbox','checked'=>1, 'selected'=>1); + } else { + $attributes = array('id'=>$input_id, 'class'=>'checkbox'); + } + $answer = Security::remove_XSS($answer, STUDENT); $s .= ''. - ''; + ''; + } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { // multiple answers // set $debug_mark_answer to true at function start to // show the correct answer with a suffix '-x' $s .= ''; - $help = $selected = ''; - if ($debug_mark_answer) { - if ($answerCorrect) { - $help = 'x-'; - $selected = 'checked="checked"'; - } - } - $answer = text_filter($answer); - $answer = Security::remove_XSS($answer, STUDENT); - $options = array('type'=>'radio','name'=>'choice['.$questionId.']['.$numAnswer.']', 'class'=>'checkbox'); - $s .=''; - $s .= Display::tag('td', $answer); - foreach ($objQuestionTmp->options as $key=>$item) { - $options['value'] = $key; - $s .= Display::tag('td', Display::tag('input','',$options )); - } - $s.=''; - + + $my_choice = array(); + if (!empty($user_choice_array)) { + foreach ($user_choice_array as $item) { + $item = explode(':', $item); + $my_choice[$item[0]] = $item[1]; + } + } + $answer = Security::remove_XSS($answer, STUDENT); + $s .=''; + $s .= Display::tag('td', $answer); + + foreach ($objQuestionTmp->options as $key => $item) { + //$options['value'] = $key; + if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) { + $attributes = array('class'=>'checkbox','checked'=>1, 'selected'=>1); + } else { + $attributes = array('class'=>'checkbox'); + } + $s .= Display::tag('td', Display::input('radio','choice['.$questionId.']['.$numAnswer.']', $key, $attributes)); + } + $s.=''; } elseif ($answerType == FILL_IN_BLANKS) { - // fill in blanks + + /* + // splits text and weightings that are joined with the character '::' + list($answer) = explode('::',$answer); + + //getting the matches + $answer = api_ereg_replace('\[[^]]+\]','',($answer)); + + + + $answer = api_preg_replace('/\[[^]]+\]/', Display::input('text', "choice[$questionId][]", '', $attributes), $answer); + + api_preg_match_all('/\[[^]]+\]/', $answer, $fill_list); + + + if (isset($user_choice[0]['answer'])) { + api_preg_match_all('/\[[^]]+\]/', $user_choice[0]['answer'], $user_fill_list); + $user_fill_list = $user_fill_list[0]; + }*/ + + list($answer) = explode('::',$answer); + + api_preg_match_all('/\[[^]]+\]/', $answer, $teacher_answer_list); + + if (isset($user_choice[0]['answer'])) { + api_preg_match_all('/\[[^]]+\]/', $user_choice[0]['answer'], $student_answer_list); + $student_answer_list = $student_answer_list[0]; + } + + //var_dump($teacher_answer_list, $student_answer_list); + + if (!empty($teacher_answer_list) && !empty($student_answer_list)) { + $teacher_answer_list = $teacher_answer_list[0]; + + $i = 0; + foreach($teacher_answer_list as $teacher_item) { + $value = null; + if (isset($student_answer_list[$i]) && !empty($student_answer_list[$i])) { + //Cleaning student answer list + $value = strip_tags($student_answer_list[$i]); + $value = api_substr($value,1, api_strlen($value)-2); + $value = explode('/', $value); + if (!empty($value[0])) { + $value = trim($value[0]); + $value = str_replace(' ', '', $value); + } + $answer = api_preg_replace('/\['.$teacher_item.'+\]/', Display::input('text', "choice[$questionId][]", $value), $answer); + } + $i++; + } + } else { + $answer = api_preg_replace('/\[[^]]+\]/', Display::input('text', "choice[$questionId][]", '', $attributes), $answer); + } + $s .= ''; - } else { + } elseif ($answerType == MATCHING) { // matching type, showing suggestions and answers // TODO: replace $answerId by $numAnswer + if ($answerCorrect != 0) { // only show elements to be answered (not the contents of // the select boxes, who are corrrect = 0) - $s .= ''; - //middle part (matches selects) + //middle part (matches selects) + $s .= ''; + $s .= ''; //print_r($select_items); //right part (answers) $s.=' - + @@ -390,35 +427,13 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu $lines_count++; } // end while() } // end if() + $matching_correct_answer++; } } } // end for() - - /* - //Adding divs for the new MATCHING interface - - if ($answerType == MATCHING && !$freeze) { - echo '
'; - echo Display::tag('h2','Questions'); - $i = 1; - foreach ($question_list as $key=>$val) { - echo Display::tag('div', Display::tag('p',$val), array('id'=>'question_'.$i, 'class'=>'question_item ui-widget-header')); - $i++; - } - echo '
'; - - - echo Display::tag('h2','Options'); - echo '
'; - foreach ($select_items as $key=>$val) { - echo Display::tag('div', Display::tag('p',$val['answer']), array('id'=>'option_'.$i, 'class'=>'option_item ui-widget-content')); - } - echo ''; - }*/ - - $s .= '
'; $s .= $oFCKeditor->CreateHtml(); $s .= '

'. - ''.Display::input('radio','choice['.$questionId.']', $numAnswer, array('class'=>'checkbox','selected'=>$selected)).'

'. - '
'. - $answer. - '
'; + $s .= ''; + $s .= Display::input('radio', 'choice['.$questionId.']', $numAnswer, $attributes); + $s .= Display::tag('label', $answer, array('for'=>$input_id)).''; + $s .= '

'; - - $options = array('type'=>'checkbox','name'=>'choice['.$questionId.']['.$numAnswer.']', 'class'=>'checkbox'); + $s .= '

'; + $s .= ''; + if ($debug_mark_answer) { if ($answerCorrect) { - $options['checked'] = 'checked'; + //$options['checked'] = 'checked'; } } - $s .= Display::tag('span', Display::tag('input','',$options )); - $s .= '

'; - $s .= '
'. - $answer. - '

'. - '

'. - '
'. - $answer. - '
'; + $s .= ''; + $s .= Display::tag('span', Display::input('checkbox', 'choice['.$questionId.']['.$numAnswer.']', 1, $attributes)); + $s .= Display::tag('label', $answer, array('for'=>$input_id)).'
'.$answer.'
'; - $parsed_answer = text_filter($answer); - $question_list[] = $parsed_answer; + $s .= '
'; + $parsed_answer = $answer; + //$question_list[] = $parsed_answer; //left part questions $s .= ' '.$lines_count.' '.$parsed_answer.'   - '; + // fills the list-box foreach ($select_items as $key=>$val) { // set $debug_mark_answer to true at function start to @@ -357,13 +390,17 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $help = '-x'; - $selected = 'selected="selected"'; + //$selected = 'selected="selected"'; } + } + if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { + $selected = 'selected="selected"'; } - $s.=''; + $s .= ''; + } // end foreach() - $s .= '  '; @@ -382,7 +419,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu // if it remains answers to shown at the right side while (isset($select_items[$lines_count])) { $s .= '
  '; $s.=''.$select_items[$lines_count]['letter'].'. '.$select_items[$lines_count]['answer']; $s.="
'; + $s .= ''; + $s .= '
'; - $s .= '

'; // destruction of the Answer object unset($objAnswerTmp); @@ -429,7 +444,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu if ($origin != 'export') { echo $s; } else { - return($s); + return $s; } } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) { // Question is a HOT_SPOT @@ -486,16 +501,14 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu if (!$only_questions) { if ($show_title) { - echo '
'.get_lang('Question').' '.$current_item.' : '.$questionName.'
'; + echo '
'.$current_item.'. '.$questionName.'
'; } //@todo I need to the get the feedback type - //if($answerType == 2) - // $s.=' / '.$total_item; echo ''; echo ''; } $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1'); @@ -638,7 +651,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu '; echo $s; } - echo '
'; - echo $questionDescription=text_filter($questionDescription); + echo $questionDescription; echo '

'; + echo ''; return $nbrAnswers; } diff --git a/main/exercice/exercise_reminder.php b/main/exercice/exercise_reminder.php new file mode 100755 index 0000000000..8a7fb40b17 --- /dev/null +++ b/main/exercice/exercise_reminder.php @@ -0,0 +1,223 @@ +0){error_log('Entered exercise_result.php: '.print_r($_POST,1));} + +// general parameters passed via POST/GET +if ( empty ( $origin ) ) { $origin = Security::remove_XSS($_REQUEST['origin']);} +if ( empty ( $learnpath_id ) ) { $learnpath_id = intval($_REQUEST['learnpath_id']);} +if ( empty ( $learnpath_item_id ) ) { $learnpath_item_id = intval($_REQUEST['learnpath_item_id']);} +if ( empty ( $learnpath_item_view_id ) ) { $learnpath_item_view_id = intval($_REQUEST['learnpath_item_view_id']);} + +if ( empty ($exerciseId)) { $exerciseId = intval($_REQUEST['exerciseId']);} + +if ( empty ($objExercise)) { $objExercise = $_SESSION['objExercise'];} + +if (!$objExercise) { + //Redirect to the exercise overview + //Check if the exe_id exists + header("Location: overview.php?exerciseId=".$exerciseId); + exit; +} + +if (isset($_SESSION['exe_id'])) { + $exe_id = intval($_SESSION['exe_id']); +} +$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id); +if (!empty($exercise_stat_info['data_tracking'])) { + $question_list = explode(',', $exercise_stat_info['data_tracking']); +} + +if (empty($exercise_stat_info) || empty($question_list)) { + api_not_allowed(); +} + +$nameTools = get_lang('Exercice'); +$interbreadcrumb[] = array("url" => "exercice.php?gradebook=$gradebook","name" => get_lang('Exercices')); + +if ($origin != 'learnpath') { + //so we are not in learnpath tool + Display::display_header($nameTools,get_lang('Exercise')); +} else { + Display::display_reduced_header(); +} + +/* DISPLAY AND MAIN PROCESS */ + +// I'm in a preview mode as course admin. Display the action menu. +if (api_is_course_admin() && $origin != 'learnpath') { + echo '
'; + echo ''.Display::return_icon('back.png', get_lang('GoBackToQuestionList'), array(), 32).''; + echo ''.Display::return_icon('edit.png', get_lang('ModifyExercise'), array(), 32).''; + echo '
'; +} + + +$user_info = api_get_user_info(api_get_user_id()); +echo $exercise_header = $objExercise->show_exercise_result_header(api_get_person_name($user_info['firstName'], $user_info['lastName']), null, 'review'); +echo Display::div(get_lang('QuestionsToReview'), array('class'=>'question_title')); +echo Display::div('', array('id'=>'message')); + +echo ''; + +$attempt_list = get_all_exercise_event_by_exe_id($exe_id); + +$remind_list = $exercise_stat_info['questions_to_check']; +$remind_list = explode(',', $remind_list); + +$exercise_result = array(); + +foreach ($attempt_list as $question_id => $options) { + //echo $question_id.'
'; + foreach($options as $item) { + + $question_obj = Question::read($item['question_id']); + + switch($question_obj->type) { + case FILL_IN_BLANKS: + $item['answer'] = $objExercise->fill_in_blank_answer_to_string($item['answer']); + break; + case HOT_SPOT: + //var_dump($item['answer']); + break; + } + + if ($item['answer'] != '0' && !empty($item['answer'])) { + $exercise_result[] = $question_id; + break; + } + } +} +$rows = array(Display::div('', array('class'=>'question_no_answer', 'style'=>'width:20px;height:10px;')), get_lang('QuestionWithNoAnswer')); +echo Display::table(array() , $rows, array('class'=>'t')); + +$table = ''; +$counter = 0; +// Loop over all question to show results for each of them, one by one + +foreach ($question_list as $questionId) { + // destruction of the Question object + unset($objQuestionTmp); + + // creates a temporary Question object + $objQuestionTmp = Question :: read($questionId); + // initialize question information + + $quesId = $objQuestionTmp->selectId(); + $check_id = 'remind_list['.$questionId.']'; + $attributes = array('id'=>$check_id, 'onclick'=>"save_remind_item(this, '$questionId');"); + + if (in_array($questionId, $remind_list)) { + $attributes['checked'] = 1; + } + $label_attributes = array(); + $label_attributes['class'] = ''; + $label_attributes['for'] = $check_id; + + //Check if the question doesn't have an answer + if (!in_array($questionId, $exercise_result)) { + $label_attributes['class'] = "question_no_answer"; + } + + $checkbox = Display::input('checkbox', 'remind_list['.$questionId.']', '', $attributes); + $url = 'exercise_submit.php?exerciseId='.$objExercise->id.'&num='.$counter.'&reminder=1'; + + $counter++; + if ($objExercise->type == ONE_PER_PAGE) { + $question_title = Display::url($counter.'. '.cut($objQuestionTmp->selectTitle(), 40), $url); + $question_title = $counter.'. '.cut($objQuestionTmp->selectTitle(), 40); + } else { + $question_title = $counter.'. '.cut($objQuestionTmp->selectTitle(), 40); + } + $question_title = Display::tag('label', $question_title, $label_attributes); + $table .= Display::div($checkbox.$question_title, array('class'=>'exercise_reminder_item')); +} // end foreach() block that loops over all questions + +echo Display::div($table, array('class'=>'exercise_reminder_container')); + +$exercise_actions = Display::url(get_lang('ValidateAnswers'), 'javascript://', array('onclick'=>'final_submit();', 'class'=>'a_button green')); +$exercise_actions .= Display::url(get_lang('ReviewQuestions'), 'javascript://', array('onclick'=>'review_questions();','class'=>'a_button white medium ')); + +echo Display::div('', array('class'=>'clear')); + +echo Display::div($exercise_actions, array('class'=>'exercise_actions')); + + +if ($origin != 'learnpath') { + //we are not in learnpath tool + Display::display_footer(); +} \ No newline at end of file diff --git a/main/exercice/exercise_result.php b/main/exercice/exercise_result.php index 8f7f776e12..e626ff829d 100755 --- a/main/exercice/exercise_result.php +++ b/main/exercice/exercise_result.php @@ -37,50 +37,36 @@ if ($_GET['origin']=='learnpath') { require_once api_get_path(LIBRARY_PATH).'exercise_show_functions.lib.php'; require_once api_get_path(LIBRARY_PATH).'mail.lib.inc.php'; -$this_section=SECTION_COURSES; +$this_section = SECTION_COURSES; /* ACCESS RIGHTS */ // notice for unauthorized people. api_protect_course_script(true); // Database table definitions -$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION); -$TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST); -$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION); -$TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER); -$TBL_TRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); -$TBL_TRACK_ATTEMPT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); -$main_user_table = Database::get_main_table(TABLE_MAIN_USER); $main_admin_table = Database::get_main_table(TABLE_MAIN_ADMIN); -$main_course_user_table = Database::get_main_table(TABLE_MAIN_COURSE_USER); if($debug>0){error_log('Entered exercise_result.php: '.print_r($_POST,1));} // general parameters passed via POST/GET if ( empty ( $origin ) ) { $origin = Security::remove_XSS($_REQUEST['origin']);} -if ( empty ( $learnpath_id ) ) { $learnpath_id = intval($_REQUEST['learnpath_id']);} -if ( empty ( $learnpath_item_id ) ) { $learnpath_item_id = intval($_REQUEST['learnpath_item_id']);} -if ( empty ( $learnpath_item_view_id ) ) { $learnpath_item_view_id = intval($_REQUEST['learnpath_item_view_id']);} -if ( empty ( $formSent ) ) { $formSent = $_REQUEST['formSent'];} -if ( empty ( $exerciseResult ) ) { $exerciseResult = $_SESSION['exerciseResult'];} -if ( empty ( $exerciseResultCoordinates)){ $exerciseResultCoordinates = $_SESSION['exerciseResultCoordinates'];} -if ( empty ( $questionId ) ) { $questionId = $_REQUEST['questionId'];} -if ( empty ( $choice ) ) { $choice = $_REQUEST['choice'];} -if ( empty ( $questionNum ) ) { $questionNum = $_REQUEST['questionNum'];} -if ( empty ( $nbrQuestions ) ) { $nbrQuestions = $_REQUEST['nbrQuestions'];} -if ( empty ( $questionList ) ) { $questionList = $_SESSION['questionList'];} if ( empty ( $objExercise ) ) { $objExercise = $_SESSION['objExercise'];} -if ( empty ( $exerciseType ) ) { $exerciseType = $_REQUEST['exerciseType'];} +if ( empty ( $remind_list ) ) { $remind_list = $_REQUEST['remind_list'];} -//@todo There should be some doc about this settings -$_configuration['live_exercise_tracking'] = false; -if ($_configuration['live_exercise_tracking']) define('ENABLED_LIVE_EXERCISE_TRACKING',1); +$exe_id = isset($_REQUEST['exe_id']) ? intval($_REQUEST['exe_id']) : 0; -if ($_configuration['live_exercise_tracking'] && $exerciseType == 1){ - $_configuration['live_exercise_tracking'] = false; +if (empty($objExercise)) { + + //Redirect to the exercise overview + //Check if the exe_id exists + $objExercise = new Exercise(); + $exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id); + if (!empty($exercise_stat_info) && isset($exercise_stat_info['exe_exo_id'])) { + header("Location: overview.php?exerciseId=".$exercise_stat_info['exe_exo_id']); + exit; + } + api_not_allowed(); } -$arrques = array(); -$arrans = array(); // set admin name as person who sends the results e-mail (lacks policy about whom should really send the results) @@ -92,13 +78,6 @@ $from_name = api_get_person_name($uinfo['firstname'], $uinfo['lastname'], null, $str = $_SERVER['REQUEST_URI']; $url = api_get_path(WEB_CODE_PATH).'exercice/exercice.php?'.api_get_cidreq().'&show=result'; -// if the above variables are empty or incorrect, we don't have any result to show, so stop the script -if (!is_array($exerciseResult) || !is_array($questionList) || !is_object($objExercise)) { - if ($debug) {error_log('Exit exercise result'); error_log('$exerciseResult: '.print_r($exerciseResult,1)); error_log('$questionList:'.print_r($questionList,1));error_log('$objExercise:'.print_r($objExercise,1));} - header('Location: exercice.php'); - exit(); -} - $gradebook = ''; if (isset($_SESSION['gradebook'])) { $gradebook= $_SESSION['gradebook']; @@ -107,31 +86,17 @@ if (!empty($gradebook) && $gradebook=='view') { $interbreadcrumb[]= array ('url' => '../gradebook/'.$_SESSION['gradebook_dest'], 'name' => get_lang('ToolGradebook')); } -$nameTools = get_lang('Result'); +$nameTools = get_lang('Exercice'); -$interbreadcrumb[]=array("url" => "exercice.php?gradebook=$gradebook","name" => get_lang('Exercices')); -//$htmlHeadXtra[] = $objExercise->show_lp_javascript(); +$interbreadcrumb[]= array("url" => "exercice.php?gradebook=$gradebook","name" => get_lang('Exercices')); if ($origin != 'learnpath') { //so we are not in learnpath tool Display::display_header($nameTools,get_lang('Exercise')); } else { - header('Content-Type: text/html; charset='.api_get_system_encoding()); - $document_language = api_get_language_isocode(); - /* HTML HEADER */ -?> - - - - - - - - -'; } -$exerciseTitle = $objExercise->selectTitle(); -$feedback_type = $objExercise->feedbacktype; +$feedback_type = $objExercise->feedbacktype; + +$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id); +if (!empty($exercise_stat_info['data_tracking'])) { + $question_list = explode(',', $exercise_stat_info['data_tracking']); +} + -//show exercise title -if($origin == 'learnpath') { ?> +$safe_lp_id = $exercise_stat_info['orig_lp_id']; +$safe_lp_item_id = $exercise_stat_info['orig_lp_item_id']; +$safe_lp_item_view_id = $exercise_stat_info['orig_lp_item_view_id']; + +if ($origin == 'learnpath') { + + ?>
- - - - + + + + 0){error_log ("ExerciseResult: ".print_r($exerciseResult,1)); error_log("QuestionList: ".print_r($questionList,1));} - -$safe_lp_id = $learnpath_id==''?0:(int)$learnpath_id; -$safe_lp_item_id = $learnpath_item_id==''?0:(int)$learnpath_item_id; -$safe_lp_item_view_id = $learnpath_item_view_id==''?0:(int)$learnpath_item_view_id; +$i = $total_score = $total_weight = 0; //We check if the user attempts before sending to the exercise_result.php if ($objExercise->selectAttempts() > 0) { $attempt_count = get_attempt_count(api_get_user_id(), $objExercise->id, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id); if ($attempt_count >= $objExercise->selectAttempts()) { - Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false); + Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $objExercise->selectTitle(), $objExercise->selectAttempts()), false); if ($origin != 'learnpath') { //we are not in learnpath tool Display::display_footer(); @@ -187,18 +157,17 @@ if ($objExercise->selectAttempts() > 0) { } } -// Create an empty exercise -if (api_is_allowed_to_session_edit()) { - $exeId = create_event_exercice($objExercise->selectId()); -} $user_info = api_get_user_info(api_get_user_id()); if ($show_results || $show_only_score) { echo $exercise_header = $objExercise->show_exercise_result_header(api_get_person_name($user_info['firstName'], $user_info['lastName'])); } + +Display :: display_confirmation_message(get_lang('Saved').'

',false); + $counter = 1; // Loop over all question to show results for each of them, one by one -foreach ($questionList as $questionId) { +foreach ($question_list as $questionId) { // destruction of the Question object unset($objQuestionTmp); @@ -207,94 +176,61 @@ foreach ($questionList as $questionId) { // creates a temporary Question object $objQuestionTmp = Question :: read($questionId); - // initialize question information - $questionName = $objQuestionTmp->selectTitle(); - $questionDescription = $objQuestionTmp->selectDescription(); - $questionWeighting = $objQuestionTmp->selectWeighting(); - $answerType = $objQuestionTmp->selectType(); - $quesId = $objQuestionTmp->selectId(); - - //this variable commes from exercise_submit_modal.php - $hotspot_delineation_result = $_SESSION['hotspot_delineation_result'][$objExercise->selectId()][$quesId]; + + //this variable commes from exercise_submit_modal.php + + //$hotspot_delineation_result = $_SESSION['hotspot_delineation_result'][$objExercise->selectId()][$quesId]; if ($show_results) { - // show titles - if ($origin != 'learnpath') { - echo $objQuestionTmp->return_header($objExercise->feedbacktype, $counter ); - $counter++; - if ($answerType == HOT_SPOT) { - ?> - - - - - - - feedbacktype != EXERCISE_FEEDBACK_TYPE_EXAM) { ?> - - - - - - manage_answer($exeId, $questionId, $choice,'exercise_result', $exerciseResultCoordinates, true, false, $show_results, $objExercise->selectPropagateNeg(), $hotspot_delineation_result); - $totalScore += $result['score']; - $totalWeighting += $result['weight']; + // show titles + echo $objQuestionTmp->return_header($objExercise->feedback_type, $counter); + $counter++; + // We're inside *one* question. Go through each possible answer for this question + $result = $objExercise->manage_answer($exercise_stat_info['exe_id'], $questionId, null ,'exercise_result', array(), false, true, $show_results, $objExercise->selectPropagateNeg(), $hotspot_delineation_result); + } + $total_score += $result['score']; + $total_weight += $result['weight']; } // end foreach() block that loops over all questions - - -if ($show_results || $show_only_score) { - echo '
'; - echo get_lang('YourTotalScore')." "; - if ($objExercise->selectPropagateNeg() == 0 && $totalScore < 0) { - $totalScore = 0; - } - echo show_score($totalScore, $totalWeighting, false); - echo '
'; +if ($origin != 'learnpath') { + if ($show_results || $show_only_score) { + echo '
'; + echo get_lang('YourTotalScore')." "; + if ($objExercise->selectPropagateNeg() == 0 && $total_score < 0) { + $total_score = 0; + } + echo show_score($total_score, $total_weight, false); + echo '
'; + } + /* */ } - // Tracking of results // Updates the empty exercise $quizDuration = (!empty($_SESSION['quizStartTime']) ? time() - $_SESSION['quizStartTime'] : 0); -if (api_is_allowed_to_session_edit() ) { - update_event_exercice($exeId, $objExercise->selectId(), $totalScore, $totalWeighting, api_get_session_id(), $safe_lp_id,$safe_lp_item_id,$safe_lp_item_view_id, $quizDuration, $questionList); +$feed = $objExercise->feedbacktype; +if (api_is_allowed_to_session_edit()) { + update_event_exercice($exercise_stat_info['exe_id'], $objExercise->selectId(), $total_score, $total_weight, api_get_session_id(), $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id, $quiz_duration, $question_list, ''); + api_session_unregister('objExercise'); + api_session_unregister('exe_id'); } -if ($origin != 'learnpath') { - Display :: display_normal_message(get_lang('ExerciseFinished').'
'.get_lang('Back').'',false); +if ($origin != 'learnpath') { + Display::display_footer(); } else { - Display :: display_normal_message(get_lang('ExerciseFinished').'

',false); - $lp_mode = $_SESSION['lp_mode']; - $url = '../newscorm/lp_controller.php?cidReq='.api_get_course_id().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exeId.'&fb_type='.$objExercise->feedbacktype; + $url = '../newscorm/lp_controller.php?cidReq='.api_get_course_id().'&action=view&lp_id='.$safe_lp_id.'&lp_item_id='.$safe_lp_item_id.'&exeId='.$exercise_stat_info['exe_id'].'&fb_type='.$feed; + //echo $total_score.','.$total_weight; exit; $href = ($lp_mode == 'fullscreen')?' window.opener.location.href="'.$url.'" ':' top.location.href="'.$url.'" '; echo ''."\n"; //record the results in the learning path, using the SCORM interface (API) - echo ''."\n"; + echo ''."\n"; echo ''; } -if ($origin != 'learnpath') { - //we are not in learnpath tool - Display::display_footer(); -} - // Send notification.. if (!api_is_allowed_to_edit(null,true)) { $objExercise->send_notification($arrques, $arrans, $origin); diff --git a/main/exercice/exercise_show.php b/main/exercice/exercise_show.php index afc41a3e28..c6418e4ff8 100755 --- a/main/exercice/exercise_show.php +++ b/main/exercice/exercise_show.php @@ -276,7 +276,7 @@ foreach ($questionList as $questionId) { $quesId = $objQuestionTmp->selectId(); if ($show_results) { - echo $objQuestionTmp->return_header($feedback_type, $counter); + echo $objQuestionTmp->return_header($counter); } $counter++; diff --git a/main/exercice/exercise_submit.php b/main/exercice/exercise_submit.php index 0b2d61dcbf..985a0a4de6 100644 --- a/main/exercice/exercise_submit.php +++ b/main/exercice/exercise_submit.php @@ -17,7 +17,11 @@ * the administrator * @package chamilo.exercise * @author Olivier Brouckaert -* @author Julio Montoya multiple fill in blank option added (2008) and Cleaning exercises (2010), Adding hotspot delineation support (2011) +* @author Julio Montoya +* Fill in blank option added (2008) +* Cleaning exercises (2010), +* Adding hotspot delineation support (2011) +* Adding reminder + ajax support (2011) */ /** * Code @@ -27,7 +31,7 @@ require_once 'question.class.php'; require_once 'answer.class.php'; require_once 'exercise.lib.php'; -//$debug = 1; //debug value is set in the exercise.class.php file +$debug = 1; //debug value is set in the exercise.class.php file // name of the language file that needs to be included $language_file = 'exercice'; @@ -36,34 +40,28 @@ require_once '../inc/global.inc.php'; $this_section = SECTION_COURSES; -if($debug) { error_log('Entered exercise_submit.php: '.print_r($_POST,1)); } +if ($debug) { error_log('--- Enter to the exercise_submit.php ---- '); error_log('0. POST variables : '.print_r($_POST,1)); } // Notice for unauthorized people. api_protect_course_script(true); + $is_allowedToEdit = api_is_allowed_to_edit(null,true); +$htmlHeadXtra[] = api_get_jquery_js(); + if (api_get_setting('show_glossary_in_extra_tools') == 'true') { $htmlHeadXtra[] = ''; //Glossary $htmlHeadXtra[] = ''; } -//@todo we should only enable this when there is a time control - //This library is necessary for the time control feature $htmlHeadXtra[] = ''; //jQuery -$_configuration['live_exercise_tracking'] = true; - +//Table calls $stat_table = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); $exercice_attemp_table = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); -$TBL_EXERCICE_QUESTION = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION); -$TBL_EXERCICES = Database :: get_course_table(TABLE_QUIZ_TEST); -$TBL_QUESTIONS = Database :: get_course_table(TABLE_QUIZ_QUESTION); -$TBL_REPONSES = Database :: get_course_table(TABLE_QUIZ_ANSWER); - // General parameters passed via POST/GET - if (empty ($origin)) { $origin = Security::remove_XSS($_REQUEST['origin']); } @@ -79,15 +77,12 @@ if (empty ($learnpath_item_view_id)) { if (empty ($formSent)) { $formSent = $_REQUEST['formSent']; } -if (empty ($exerciseResult)) { +if (empty($exerciseResult)) { $exerciseResult = $_REQUEST['exerciseResult']; } if (empty ($exerciseResultCoordinates)) { $exerciseResultCoordinates = $_REQUEST['exerciseResultCoordinates']; } -if (empty ($exerciseType)) { - $exerciseType = $_REQUEST['exerciseType']; -} if (empty ($exerciseId)) { $exerciseId = intval($_REQUEST['exerciseId']); } @@ -100,15 +95,24 @@ if (empty($_REQUEST['choice'])) { if (empty ($questionNum)) { $questionNum = intval($_REQUEST['questionNum']); } -if (empty ($nbrQuestions)) { - $nbrQuestions = intval($_REQUEST['nbrQuestions']); +if (empty ($current_question)) { + $current_question = intval($_REQUEST['num']); } if (empty ($buttonCancel)) { $buttonCancel = $_REQUEST['buttonCancel']; } + +$reminder = isset($_GET['reminder']) ? intval($_GET['reminder']) : 0; +$remind_question_id = isset($_GET['remind_question_id']) ? intval($_GET['remind_question_id']) : 0; + +if ($remind_question_id == -1) { + header('Location: exercise_reminder.php?origin='.$origin.'&exerciseId='.$exerciseId); + exit; +} + $error = ''; -// if the user has clicked on the "Cancel" button +// If the user has clicked on the "Cancel" button if ($buttonCancel) { // returns to the exercise list header("Location: exercice.php?origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id"); @@ -127,63 +131,86 @@ if (api_is_allowed_to_edit(null,true) && $_GET['preview'] == 1 ) { api_session_unregister('objExercise'); } -// Loading the $objExercise variable +// 1. Loading the $objExercise variable if (!isset ($_SESSION['objExercise']) || $_SESSION['objExercise']->id != $_REQUEST['exerciseId']) { // Construction of Exercise $objExercise = new Exercise(); - if ($debug) {error_log('Setting the $objExercise variable'); }; + if ($debug) {error_log('1. Setting the $objExercise variable'); }; unset($_SESSION['questionList']); // if the specified exercise doesn't exist or is disabled if (!$objExercise->read($exerciseId) || (!$objExercise->selectStatus() && !$is_allowedToEdit && ($origin != 'learnpath'))) { - if ($debug) {error_log('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 + // Saves the object into the session api_session_register('objExercise'); - if ($debug) {error_log('$_SESSION[objExercise] was unset - set now - end'); }; + if ($debug) {error_log('1.1. $_SESSION[objExercise] was unset - set now - end'); }; } } -if (!isset ($objExercise) && isset($_SESSION['objExercise'])) { - if ($debug) {error_log('Loading $objExercise from session'); }; - +//2. Checking if $objExercise is set +if (!isset($objExercise) && isset($_SESSION['objExercise'])) { + if ($debug) { error_log('2. Loading $objExercise from session'); }; $objExercise = $_SESSION['objExercise']; } +//3. $objExercise is not set, then return to the exercise list if (!is_object($objExercise)) { - if ($debug) {error_log('$objExercise was not set, kill the script'); }; + if ($debug) {error_log('3. $objExercise was not set, kill the script'); }; header('Location: exercice.php'); exit; } -$exerciseType = $objExercise->type; -$current_timestamp = time(); +$current_timestamp = time(); + +//4. Setting the exe_id (attempt id) +$exe_id = null; +if (isset($_SESSION['exe_id'])) { + $exe_id = $_SESSION['exe_id']; +} + -//Getting track exercise info +//4. Getting user exercise info (if the user took the exam before) $exercise_stat_info = $objExercise->get_stat_track_exercise_info($safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id); +//$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id); +$my_remind_list = array(); + +if ($debug) { error_log('5. $objExercise->get_stat_track_exercise_info function called:: '.print_r($exercise_stat_info, 1)); }; -if ($debug) {error_log('$objExercise->get_stat_track_exercise_info function called:: '.print_r($exercise_stat_info, 1)); }; +if (!empty($exercise_stat_info['questions_to_check'])) { + $my_remind_list = $exercise_stat_info['questions_to_check']; + $my_remind_list = explode(',', $my_remind_list); + $my_remind_list = array_filter($my_remind_list); +} +$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; + +if ($reminder == 2 && empty($my_remind_list)) { + header('Location: exercise_reminder.php?'.$params); + exit; +} /* - * Time control feature - * if the expired time is major that zero(0) then the expired time is compute on this time. Disable for learning path + * 6. Loading Time control parameters + * If the expired time is major that zero(0) then the expired time is compute on this time. Disable for learning path */ + $time_control = false; if ($objExercise->expired_time != 0 && $origin != 'learnpath') { $time_control = true; } if ($time_control) { + if ($debug) error_log('6.1. Time control is enabled'); //Get the expired time of the current exercice in track_e_exercices $total_seconds = $objExercise->expired_time*60; //Generating the time control key $current_expired_time_key = generate_time_control_key($objExercise->id); - if ($debug) {error_log('$current_expired_time_key '.$current_expired_time_key); }; + if ($debug) {error_log('6.2. $current_expired_time_key '.$current_expired_time_key); }; if (!isset($_SESSION['expired_time'][$current_expired_time_key])) { //Timer - Get expired_time for a student if (!empty($exercise_stat_info)) { - if ($debug) {error_log('Seems that the session ends and the user want to retake the exam'); }; + if ($debug) {error_log('6.3 Seems that the session ends and the user want to retake the exam'); }; $expired_time_of_this_attempt = $exercise_stat_info['expired_time_control']; if ($debug) {error_log('$expired_time_of_this_attempt: '.$expired_time_of_this_attempt); } //Get the last attempt of an exercice @@ -198,64 +225,47 @@ if ($time_control) { $diff = $current_timestamp - api_strtotime($last_attempt_date,'UTC'); $last_attempt_date = api_get_utc_datetime(api_strtotime($last_attempt_date,'UTC') + $diff); } - if ($debug) {error_log('$last_attempt_date: '.$last_attempt_date); } + if ($debug) {error_log('6.4. $last_attempt_date: '.$last_attempt_date); } //New expired time - it is due to the possible closure of session $new_expired_time_in_seconds = api_strtotime($expired_time_of_this_attempt, 'UTC') - api_strtotime($last_attempt_date,'UTC'); - if ($debug) {error_log('$new_expired_time_in_seconds: '.$new_expired_time_in_seconds); } + if ($debug) {error_log('6.5. $new_expired_time_in_seconds: '.$new_expired_time_in_seconds); } $expected_time = $current_timestamp + $new_expired_time_in_seconds; - if ($debug) {error_log('$expected_time1: '.$expected_time); } + if ($debug) {error_log('6.6. $expected_time1: '.$expected_time); } - //$plugin_expired_time = date('M d, Y H:i:s', $expected_time); $clock_expired_time = api_get_utc_datetime($expected_time); - if ($debug) {error_log('$clock_expired_time: '.$clock_expired_time); } - - //@todo check this validation with Fasa: With this change the user can log out and login from the system and the counter will not work - /* - //We modify the "expired_time_control" field in track_e_exercices for this attempt - $sql_track_e_exe = "UPDATE $stat_table SET expired_time_control = '".$clock_expired_time."' WHERE exe_id = '".$exercise_stat_info['exe_id']."'"; - if ($debug) {error_log('$sql_track_e_exe1: '.$sql_track_e_exe); } - Database::query($sql_track_e_exe); - */ + if ($debug) {error_log('6.7. $clock_expired_time: '.$clock_expired_time); } - //First we update the attempt to today + // First we update the attempt to today // How the expired time is changed into "track_e_exercices" table,then the last attempt for this student should be changed too,so $sql_track_e_exe = "UPDATE $exercice_attemp_table SET tms = '".api_get_utc_datetime()."' WHERE exe_id = '".$exercise_stat_info['exe_id']."' AND tms = '".$last_attempt_date."' "; - if ($debug) {error_log('$sql_track_e_exe2: '.$sql_track_e_exe); } + if ($debug) {error_log('6.8. $sql_track_e_exe2: '.$sql_track_e_exe); } Database::query($sql_track_e_exe); //Sessions that contain the expired time $_SESSION['expired_time'][$current_expired_time_key] = $clock_expired_time; - if ($debug) {error_log('1. Setting the $_SESSION[expired_time]: '.$_SESSION['expired_time'][$current_expired_time_key] ); }; + if ($debug) {error_log('6.9. Setting the $_SESSION[expired_time]: '.$_SESSION['expired_time'][$current_expired_time_key] ); }; } else { $expected_time = $current_timestamp + $total_seconds; - if ($debug) error_log('$current_timestamp '.$current_timestamp); - if ($debug) error_log('$expected_time '.$expected_time); - //$expected_time = api_strtotime(api_get_utc_datetime($expected_time)); - - //$plugin_expired_time = date('M d, Y H:i:s', $expected_time); - //$clock_expired_time = date('Y-m-d H:i:s', $expected_time); + if ($debug) error_log('6.3. $current_timestamp '.$current_timestamp); + if ($debug) error_log('6.4. $expected_time '.$expected_time); + $clock_expired_time = api_get_utc_datetime($expected_time); - if ($debug) error_log('$expected_time '.$clock_expired_time); + if ($debug) error_log('6.5. $expected_time '.$clock_expired_time); //Sessions that contain the expired time - $_SESSION['expired_time'][$current_expired_time_key] = $clock_expired_time; - // $_SESSION['end_expired_time'][$current_expired_time_key] = $plugin_expired_time; - if ($debug) {error_log('2. Setting the $_SESSION[expired_time]: '.$_SESSION['expired_time'][$current_expired_time_key] ); }; - //if ($debug) {error_log('2. Setting the $_SESSION[end_expired_time]: '.$_SESSION['end_expired_time'][$current_expired_time_key] ); }; + $_SESSION['expired_time'][$current_expired_time_key] = $clock_expired_time; + if ($debug) {error_log('6.6. Setting the $_SESSION[expired_time]: '.$_SESSION['expired_time'][$current_expired_time_key] ); }; } } else { - // $plugin_expired_time = $_SESSION['end_expired_time'][$current_expired_time_key]; $clock_expired_time = $_SESSION['expired_time'][$current_expired_time_key]; - if ($debug) {error_log('Getting the $_SESSION[end_expired_time]: '.$_SESSION['end_expired_time'][$current_expired_time_key] ); }; + if ($debug) {error_log('6.2. Getting the $_SESSION[end_expired_time]: '.$_SESSION['end_expired_time'][$current_expired_time_key] ); }; } } -// get time left for exipiring time -//$time_left = api_strtotime($plugin_expired_time) - api_strtotime(api_get_utc_datetime()); -// get time left for exipiring time +// Get time left for exipiring time $time_left = api_strtotime($clock_expired_time,'UTC') - time(); /* @@ -266,11 +276,11 @@ if ($time_control) { //Sends the exercice form when the expired time is finished $htmlHeadXtra[] = $objExercise->show_time_control_js($time_left); } -if ($_configuration['live_exercise_tracking'] && $objExercise->type == ONE_PER_PAGE && $objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) { +/* +if ($objExercise->type == ONE_PER_PAGE && $objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) { if (!empty($exercise_stat_info)) { $exe_id = $exercise_stat_info['exe_id']; - if ($_SERVER['REQUEST_METHOD'] != 'POST') { - define('QUESTION_LIST_ALREADY_LOGGED', 1); + if ($_SERVER['REQUEST_METHOD'] != 'POST') { $recorded['questionList'] = explode(',', $exercise_stat_info['data_tracking']); $query = 'SELECT * FROM ' . $exercice_attemp_table . ' WHERE exe_id = ' . $exercise_stat_info['exe_id'] . ' ORDER BY tms ASC'; $result = Database::query($query); @@ -278,41 +288,67 @@ if ($_configuration['live_exercise_tracking'] && $objExercise->type == ONE_PER_P $recorded['exerciseResult'][$row['question_id']] = 1; } $exerciseResult = $_SESSION['exerciseResult'] = $recorded['exerciseResult']; - $questionNum = count($recorded['exerciseResult']); - $questionNum++; + $current_question = count($recorded['exerciseResult']); + $current_question++; $questionList = $_SESSION['questionList'] = $recorded['questionList']; } } +}*/ +// if the user has submitted the form + +$exercise_title = $objExercise->selectTitle(); +$exercise_description = $objExercise->selectDescription(); +$exercise_sound = $objExercise->selectSound(); + +//if (!isset($_SESSION['questionList']) || $origin == 'learnpath') { +//in LP's is enabled the "remember question" feature? +if (!isset($_SESSION['questionList'])) { + // selects the list of question ID + $questionList = $objExercise->get_validated_question_list(); + api_session_register('questionList'); + if ($debug > 0) { error_log('$_SESSION[questionList] was set'); } +} +if (!isset($objExercise) && isset($_SESSION['objExercise'])) { + $questionList = $_SESSION['questionList']; } -// if the user has submitted the form +if ($debug) error_log('7 Question list loaded '.print_r($questionList, 1)); + +$quizStartTime = time(); +api_session_register('quizStartTime'); + +//Real question count +$question_count = 0; +if (!empty($questionList)) { + $question_count = count($questionList); +} if ($formSent && isset($_POST)) { - if ($debug > 0) { error_log('$formSent was set'); } + if ($debug > 0) { error_log('8. $formSent was set'); } // Initializing if (!is_array($exerciseResult)) { - $exerciseResult = array (); + $exerciseResult = array(); $exerciseResultCoordinates = array(); - } + } //Only for hotspot if (!isset($choice) && isset($_REQUEST['hidden_hotspot_id'])) { $hotspot_id = (int)($_REQUEST['hidden_hotspot_id']); $choice = array($hotspot_id => ''); } - // if the user has answered at least one question + + // if the user has answered at least one question if (is_array($choice)) { - - if ($debug) { error_log('$choice is an array '.print_r($choice, 1)); } + if ($debug) { error_log('8.1. $choice is an array '.print_r($choice, 1)); } // Also store hotspot spots in the session ($exerciseResultCoordinates // will be stored in the session at the end of this script) - if (isset ($_POST['hotspot'])) { + if (isset($_POST['hotspot'])) { $exerciseResultCoordinates = $_POST['hotspot']; - if ($debug) { error_log('$_POST[hotspot] data '.print_r($exerciseResultCoordinates, 1)); } + if ($debug) { error_log('8.2. $_POST[hotspot] data '.print_r($exerciseResultCoordinates, 1)); } } - if ($exerciseType == ALL_ON_ONE_PAGE) { + if ($objExercise->type == ALL_ON_ONE_PAGE) { // $exerciseResult receives the content of the form. // Each choice of the student is stored into the array $choice $exerciseResult = $choice; @@ -324,42 +360,43 @@ if ($formSent && isset($_POST)) { // stores the user answer into the array $exerciseResult[$key] = $choice[$key]; //saving each question - if ($_configuration['live_exercise_tracking'] && $objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) { - $nro_question = $questionNum; // - 1; - //START of saving and qualifying each question submitted - define('ENABLED_LIVE_EXERCISE_TRACKING', 1); - $questionId = $key; + if ($objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) { + $nro_question = $current_question; // - 1; + $questionId = $key; // gets the student choice for this question $choice = $exerciseResult[$questionId]; if (isset($exe_id)) { //Manage the question and answer attempts - if ($debug > 0) { error_log('manage_answer exe_id: '.$exe_id.' - $questionId: '.$questionId.' Choice'.print_r($choice,1)); } + if ($debug > 0) { error_log('8.3. manage_answer exe_id: '.$exe_id.' - $questionId: '.$questionId.' Choice'.print_r($choice,1)); } $objExercise->manage_answer($exe_id, $questionId, $choice,'exercise_show',$exerciseResultCoordinates, true, false,false, $objExercise->propagate_neg); } //END of saving and qualifying } } } - if ($debug > 0) { error_log('$choice is an array - end'); } + if ($debug > 0) { error_log('8.3. $choice is an array - end'); } + if ($debug > 0) { error_log('8.4. $exerciseResult '.print_r($exerciseResult,1)); } } - + + // the script "exercise_result.php" will take the variable $exerciseResult from the session api_session_register('exerciseResult'); + api_session_register('remind_list'); api_session_register('exerciseResultCoordinates'); // if all questions on one page OR if it is the last question (only for an exercise with one question per page) - - if ($exerciseType == ALL_ON_ONE_PAGE || $questionNum >= $nbrQuestions) { + + if (($objExercise->type == ALL_ON_ONE_PAGE || $current_question >= $question_count)) { if (api_is_allowed_to_session_edit()) { // goes to the script that will show the result of the exercise - if ($exerciseType == ALL_ON_ONE_PAGE) { + if ($objExercise->type == ALL_ON_ONE_PAGE) { if ($debug) { error_log('Exercise ALL_ON_ONE_PAGE -> Redirecting to exercise_result.php'); } //We check if the user attempts before sending to the exercise_result.php if ($objExercise->selectAttempts() > 0) { $attempt_count = get_attempt_count(api_get_user_id(), $exerciseId, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id); if ($attempt_count >= $objExercise->selectAttempts()) { - Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false); + Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), false); if ($origin != 'learnpath') { //so we are not in learnpath tool echo ''; //End glossary div @@ -369,7 +406,7 @@ if ($formSent && isset($_POST)) { } } } - header("Location: exercise_result.php?exerciseType=$exerciseType&origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id"); + header("Location: exercise_result.php?origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id"); exit; } else { //Time control is only enabled for ONE PER PAGE @@ -382,54 +419,91 @@ if ($formSent && isset($_POST)) { $sql_exe_result = ", exe_result = 0"; if ($debug) { error_log('exercise_time_control_is_valid is NOT valid then exe_result = 0 '); } } + /* //Clean incomplete - @todo why setting to blank the status? $update_query = "UPDATE $stat_table SET status = '', exe_date = '".api_get_utc_datetime() ."' , orig_lp_item_view_id = '$safe_lp_item_view_id' $sql_exe_result WHERE exe_id = ".$exe_id; if ($debug) { error_log('Updating track_e_exercises '.$update_query); } - Database::query($update_query); + Database::query($update_query);*/ } if ($debug) { error_log('Redirecting to exercise_show.php'); } - header("Location: exercise_show.php?id=$exe_id&exerciseType=$exerciseType&origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id"); + header("Location: exercise_show.php?id=$exe_id&origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id"); exit; } } else { if ($debug) { error_log('Redirecting to exercise_submit.php'); } - header("Location: exercise_submit.php?exerciseId=$exerciseId"); + header("Location: exercise_submit.php?exerciseId=$exerciseId&origin=$origin"); exit; } } + + if (!empty($remind_list)) { + //header("Location: exercise_reminder.php?origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id"); + exit; + } if ($debug > 0) { error_log('$formSent was set - end'); } } -$exerciseTitle = $objExercise->selectTitle(); -$exerciseDescription = $objExercise->selectDescription(); -$exerciseSound = $objExercise->selectSound(); -$exerciseType = $objExercise->selectType(); +// if questionNum comes from POST and not from GET -//if (!isset($_SESSION['questionList']) || $origin == 'learnpath') { -//in LP's is enabled the "remember question" feature? -if (!isset($_SESSION['questionList'])) { - // selects the list of question ID - $questionList = ($objExercise->isRandom() ? $objExercise->selectRandomList() : $objExercise->selectQuestionList()); - api_session_register('questionList'); - if ($debug > 0) { error_log('$_SESSION[questionList] was set'); } -} -if (!isset ($objExercise) && isset ($_SESSION['objExercise'])) { - $questionList = $_SESSION['questionList']; +if (!$current_question || $_REQUEST['num']) { + if (!$current_question) { + $current_question = 1; + } else { + $current_question++; + } } -$quizStartTime = time(); -api_session_register('quizStartTime'); -//Real question count -$nbrQuestions = count($questionList); - -// if questionNum comes from POST and not from GET -if (!$questionNum || $_POST['questionNum']) { - // only used for sequential exercises (see $exerciseType) - if (!$questionNum) { - $questionNum = 1; +if (($objExercise->type == ALL_ON_ONE_PAGE || $current_question > $question_count)) { + if (api_is_allowed_to_session_edit()) { + // goes to the script that will show the result of the exercise + if ($objExercise->type == ALL_ON_ONE_PAGE) { + if ($debug) { error_log('Exercise ALL_ON_ONE_PAGE -> Redirecting to exercise_result.php'); } + + //We check if the user attempts before sending to the exercise_result.php + if ($objExercise->selectAttempts() > 0) { + $attempt_count = get_attempt_count(api_get_user_id(), $exerciseId, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id); + if ($attempt_count >= $objExercise->selectAttempts()) { + Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), false); + if ($origin != 'learnpath') { + //so we are not in learnpath tool + echo ''; //End glossary div + Display :: display_footer(); + } else { + echo ''; + } + exit; + } + } + //header("Location: exercise_result.php?origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id"); + //exit; + } else { + //Time control is only enabled for ONE PER PAGE + + if (!empty($exe_id) && is_numeric($exe_id)) { + //Verify if the current test is fraudulent + if (exercise_time_control_is_valid($exerciseId)) { + $sql_exe_result = ""; + if ($debug) { error_log('exercise_time_control_is_valid is valid'); } + } else { + $sql_exe_result = ", exe_result = 0"; + if ($debug) { error_log('exercise_time_control_is_valid is NOT valid then exe_result = 0 '); } + } + /* + //Clean incomplete - @todo why setting to blank the status? + $update_query = "UPDATE $stat_table SET status = '', exe_date = '".api_get_utc_datetime() ."' , orig_lp_item_view_id = '$safe_lp_item_view_id' $sql_exe_result WHERE exe_id = ".$exe_id; + + //if ($debug) { error_log('Updating track_e_exercises '.$update_query); } + Database::query($update_query);*/ + } + //if ($debug) { error_log('Redirecting to exercise_show.php'); } + header('Location: exercise_reminder.php?'.$params); + exit; + } } else { - $questionNum++; + if ($debug) { error_log('Redirecting to exercise_submit.php'); } + //header("Location: exercise_submit.php?exerciseId=$exerciseId"); + exit; } } @@ -448,8 +522,7 @@ if (!empty ($gradebook) && $gradebook == 'view') { $interbreadcrumb[] = array ("url" => "exercice.php?gradebook=$gradebook", "name" => get_lang('Exercices')); $interbreadcrumb[] = array ("url" => "#","name" => $objExercise->name); -if ($origin != 'learnpath') { //so we are not in learnpath tool - //$htmlHeadXtra[] = $objExercise->show_lp_javascript(); +if ($origin != 'learnpath') { //so we are not in learnpath tool Display :: display_header($nameTools,'Exercises'); if (!api_is_allowed_to_session_edit() ) { Display :: display_warning_message(get_lang('SessionIsReadOnly')); @@ -459,30 +532,27 @@ if ($origin != 'learnpath') { //so we are not in learnpath tool echo '
 
'; } -$show_quiz_edition = true; -if (isset($exerciseId) && !empty($exerciseId)) { - $TBL_LP_ITEM = Database::get_course_table(TABLE_LP_ITEM); - $sql="SELECT max_score FROM $TBL_LP_ITEM WHERE item_type = '".TOOL_QUIZ."' AND path ='".$exerciseId."'"; - $result = Database::query($sql); - if (Database::num_rows($result) > 0) { - $show_quiz_edition = false; - } -} +$show_quiz_edition = $objExercise->added_in_lp(); // I'm in a preview mode if (api_is_course_admin() && $origin != 'learnpath') { echo '
'; echo '' . Display :: return_icon('back.png', get_lang('BackToExercisesList'),'','32').''; - if ($show_quiz_edition) { + if ($show_quiz_edition == false) { echo ''.Display :: return_icon('settings.png', get_lang('ModifyExercise'),'','32').''; + //echo Display :: return_icon('wizard.gif', get_lang('QuestionList')) . '' . get_lang('QuestionList') . ''; } else { echo ''.Display::return_icon('settings_na.png', get_lang('ModifyExercise'),'','32').''; } echo '
'; } +/* +$exercise_header = Display::div($exercise_title, array('class'=>'exercise_title')); +if (!empty($exercise_description)) { + $exercise_header .= Display::div($exercise_description, array('class'=>'exercise_description')); +} +echo Display::div($exercise_header, array('class'=>'exercise_header'));*/ -$exerciseTitle = $objExercise->selectTitle(); -echo Display::tag('h1', $exerciseTitle); $show_clock = true; $user_id = api_get_user_id(); if ($objExercise->selectAttempts() > 0) { @@ -497,12 +567,12 @@ if ($objExercise->selectAttempts() > 0) { //Showing latest attempt according with task BT#1628 $exercise_stat_info = get_exercise_results_by_user($user_id, $exerciseId, api_get_course_id(), api_get_session_id()); - if (!empty($exercise_stat_info)) { + if (!empty($exercise_stat_info)) { $max_exe_id = max(array_keys($exercise_stat_info)); $last_attempt_info = $exercise_stat_info[$max_exe_id]; echo Display::div(get_lang('Date').': '.api_get_local_time($last_attempt_info['exe_date']), array('id'=>'')); - Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false); + Display::display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), false); if (!empty($last_attempt_info['question_list'])) { foreach($last_attempt_info['question_list'] as $question_data) { @@ -510,29 +580,27 @@ if ($objExercise->selectAttempts() > 0) { $marks = $question_data['marks']; $question_info = Question::read($question_id); - echo Display::div($question_info->question, array('id'=>'question_title','class'=>'sectiontitle')); + echo Display::div($question_info->question, array('class'=>'question_title')); echo Display::div(get_lang('Score').' '.$marks, array('id'=>'question_score')); } } $score = show_score($last_attempt_info['exe_result'], $last_attempt_info['exe_weighting']); - echo Display::div(get_lang('YourTotalScore').' '.$score, array('id'=>'question_score')); - + echo Display::div(get_lang('YourTotalScore').' '.$score, array('id'=>'question_score')); } else { - Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false); + Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), false); } } else { - Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false); + Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), false); } if ($origin != 'learnpath') Display :: display_footer(); exit; } else { - Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttemptsAdmin'), $exerciseTitle, $objExercise->selectAttempts()), false); + Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttemptsAdmin'), $exercise_title, $objExercise->selectAttempts()), false); } } } -//@todo create a function and move to the exercise class $limit_time_exists = (($objExercise->start_time != '0000-00-00 00:00:00') || ($objExercise->end_time != '0000-00-00 00:00:00')) ? true : false; if ($limit_time_exists) { @@ -556,14 +624,14 @@ if ($limit_time_exists) { if (!$permission_to_start || $exercise_timeover) { if (!api_is_allowed_to_edit(null,true)) { $message_warning = $permission_to_start ? get_lang('ReachedTimeLimit') : get_lang('ExerciseNoStartedYet'); - Display :: display_warning_message(sprintf($message_warning, $exerciseTitle, $objExercise->selectAttempts())); + Display :: display_warning_message(sprintf($message_warning, $exercise_title, $objExercise->selectAttempts())); if ($origin != 'learnpath') { Display :: display_footer(); } exit; } else { $message_warning = $permission_to_start ? get_lang('ReachedTimeLimitAdmin') : get_lang('ExerciseNoStartedAdmin'); - Display :: display_warning_message(sprintf($message_warning, $exerciseTitle, $objExercise->selectAttempts())); + Display :: display_warning_message(sprintf($message_warning, $exercise_title, $objExercise->selectAttempts())); exit; } } @@ -573,7 +641,7 @@ if ($limit_time_exists) { global $_custom; if (isset($_custom['exercises_hidden_when_no_start_date']) && $_custom['exercises_hidden_when_no_start_date']) { if (empty($objExercise->start_time) || $objExercise->start_time == '0000-00-00 00:00:00') { - Display :: display_warning_message(sprintf(get_lang('ExerciseNoStartedYet'), $exerciseTitle, $objExercise->selectAttempts())); + Display :: display_warning_message(sprintf(get_lang('ExerciseNoStartedYet'), $exercise_title, $objExercise->selectAttempts())); if ($origin != 'learnpath') { Display :: display_footer(); } @@ -590,106 +658,336 @@ if ($origin != 'learnpath') { echo '
'; } -if (!empty ($error)) { +//var_dump('$remind_question_id . '.$remind_question_id); + +if ($reminder == 2) { + + $data_tracking = $exercise_stat_info['data_tracking']; + $data_tracking = explode(',', $data_tracking); + + $current_question = 1; //set by default the 1st question + + if (!empty($my_remind_list)) { + //Checking which questions we are going to call from the remind list + for ($i = 0; $i < count($data_tracking); $i++) { + for($j = 0; $j < count($my_remind_list); $j++) { + + if (!empty($remind_question_id)) { + if ($remind_question_id == $my_remind_list[$j]) { + + if ($remind_question_id == $data_tracking[$i]) { + if (isset($my_remind_list[$j+1])) { + $remind_question_id = $my_remind_list[$j+1]; + $current_question = $i + 1; + } else { + $remind_question_id = -1; //We end the remind list we go to the exercise_reminder.php please + $current_question = $i + 1; // last question + } + break 2; + } + } + } else { + if ($my_remind_list[$j] == $data_tracking[$i]) { + if (isset($my_remind_list[$j+1])) { + $remind_question_id = $my_remind_list[$j+1]; + $current_question = $i + 1; // last question + } else { + $remind_question_id = -1; //We end the remind list we go to the exercise_reminder.php please + $current_question = $i + 1; // last question + } + break 2; + } + } + } + } + } else { + header("Location: exercise_reminder.php?$params"); + exit; + } + //var_dump($remind_question_id, $my_remind_list, $data_tracking, $current_question); +} + + +if (!empty($error)) { Display :: display_error_message($error, false); } else { - if (!empty ($exerciseSound)) { - echo "", ", get_lang('Sound') . "; + if (!empty ($exercise_sound)) { + echo "", ", get_lang('Sound') . "; } // Get number of hotspot questions for javascript validation $number_of_hotspot_questions = 0; $onsubmit = ''; $i = 0; - if (!empty($questionList) && is_array($questionList)) { + //i have a doubt in this line cvargas + //var_dump($questionList); + if (!strcmp($questionList[0], '') === 0) { foreach ($questionList as $questionId) { $i++; $objQuestionTmp = Question::read($questionId); // for sequential exercises - if (!empty($objQuestionTmp)) { - if ($exerciseType == ONE_PER_PAGE) { - // if it is not the right question, goes to the next loop iteration - if ($questionNum != $i) { - continue; - } else { - if ($objQuestionTmp->selectType() == HOT_SPOT || $objQuestionTmp->selectType() == HOT_SPOT_DELINEATION) { - $number_of_hotspot_questions++; - } - break; - } - } else { - if ($objQuestionTmp->selectType() == HOT_SPOT || $objQuestionTmp->selectType() == HOT_SPOT_DELINEATION) { - $number_of_hotspot_questions++; - } - } + 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 { + if ($objQuestionTmp->selectType() == HOT_SPOT || $objQuestionTmp->selectType() == HOT_SPOT_DELINEATION) { + $number_of_hotspot_questions++; + } + break; + } + } else { + if ($objQuestionTmp->selectType() == HOT_SPOT || $objQuestionTmp->selectType() == HOT_SPOT_DELINEATION) { + $number_of_hotspot_questions++; + } } } } + if ($number_of_hotspot_questions > 0) { $onsubmit = "onsubmit=\"return validateFlashVar('" . $number_of_hotspot_questions . "', '" . get_lang('HotspotValidateError1') . "', '" . get_lang('HotspotValidateError2') . "');\""; } - echo "

$exerciseDescription

"; - $exercise_condition = ''; - if ($exerciseType == ONE_PER_PAGE) { - $exercise_condition = "&exerciseId=" . $exerciseId; - } - echo ' - - - - - - - - -
-

-
-

-
-

-
 
- - - -
- '; + + echo ''; + + echo ' + + + + + + + '; - //Show list of questions - $i = 1; - if (is_array($questionList)) { - foreach ($questionList as $questionId) { - - // for sequential exercises - if ($exerciseType == ONE_PER_PAGE) { - // if it is not the right question, goes to the next loop iteration - if ($questionNum != $i) { - $i++; - continue; - } else { - if ($objExercise->feedbacktype != 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); - $questionName = $objQuestionTmp->selectTitle(); - // destruction of the Question object - unset ($objQuestionTmp); - Display :: display_normal_message(get_lang('AlreadyAnswered')); - $i++; - break; - } - } - } - } - // shows the question and its answers - showQuestion($questionId, false, $origin, $i); - $i++; - // for sequential exercises - if ($exerciseType == ONE_PER_PAGE) { - // quits the loop - break; - } - } - } - // end foreach() - echo $objExercise->show_button($nbrQuestions, $questionNum, $exerciseId); - echo '
-
'; + //Show list of questions + $i = 1; + + $attempt_list = array(); + + if (isset($exe_id)) { + $attempt_list = get_all_exercise_event_by_exe_id($exe_id); + } + + if (!empty($attempt_list) && $current_question == 1) { + Display::display_normal_message(get_lang('YouTriedToResolveThisExerciseEarlier')); + } + + $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']); + } + + foreach ($questionList as $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) { + $i++; + continue; + } else { + if ($objExercise->feedbacktype != 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); + $questionName = $objQuestionTmp->selectTitle(); + // destruction of the Question object + unset ($objQuestionTmp); + Display :: display_normal_message(get_lang('AlreadyAnswered')); + $i++; + break; + } + } + } + } + + $user_choice = $attempt_list[$questionId]; + + $remind_highlight = ''; + $exercise_actions = ''; + $is_remind_on = false; + + $attributes = array('id' =>'remind_list['.$questionId.']'); + if (in_array($questionId, $remind_list)) { + $is_remind_on = true; + $attributes['checked'] = 1; + $remind_question = true; + $remind_highlight = ' remind_highlight '; + } + + //Showing the question + + echo '
'; + + // shows the question and its answers + showQuestion($questionId, false, $origin, $i, true, false, $user_choice); + + if ($objExercise->type == ONE_PER_PAGE) { + $exercise_actions .= $objExercise->show_button($questionId, $current_question); + } + + if ($objExercise->type == ALL_ON_ONE_PAGE) { + $button = ''.get_lang('SaveForNow').''; + $button .= ' '; + $exercise_actions .= Display::span($button, array('class'=>'exercise_save_now_button')); + } + + $remind_question_div = Display::input('checkbox', 'remind_list['.$questionId.']', '', $attributes); + $remind_question_div .= Display::tag('label', get_lang('RemindQuestion'), array('for' =>'remind_list['.$questionId.']')); + $exercise_actions .= Display::span($remind_question_div, array('class'=>'exercise_save_now_button')); + + echo Display::div($exercise_actions, array('class'=>'exercise_actions')); + + echo '
'; + + $i++; + // for sequential exercises + if ($objExercise->type == ONE_PER_PAGE) { + // quits the loop + break; + } + } + // end foreach() + if ($objExercise->type == ALL_ON_ONE_PAGE) { + $exercise_actions = $objExercise->show_button($questionId, $current_question); + echo Display::div($exercise_actions, array('class'=>'exercise_actions')); + } + echo ''; } +/* if ($objExercise->type == ONE_PER_PAGE) { if (empty($exercise_stat_info)) { $total_weight = 0; @@ -699,7 +997,7 @@ if ($objExercise->type == ONE_PER_PAGE) { } $objExercise->save_stat_track_exercise_info($clock_expired_time, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id, $questionList, $total_weight); } -} +}*/ if ($origin != 'learnpath') { //so we are not in learnpath tool echo '
'; //End glossary div diff --git a/main/exercice/question.class.php b/main/exercice/question.class.php index 2200621196..06c171db40 100755 --- a/main/exercice/question.class.php +++ b/main/exercice/question.class.php @@ -1254,7 +1254,7 @@ abstract class Question return $result; } - function return_header($feedback_type, $counter = null) { + function return_header($feedback_type = null, $counter = null) { $counter_label = ''; if (!empty($counter)) { $counter_label = intval($counter); diff --git a/main/exercice/result.php b/main/exercice/result.php index 07eb87d6c1..0313bc9a6b 100644 --- a/main/exercice/result.php +++ b/main/exercice/result.php @@ -162,7 +162,8 @@ if (!empty($question_list)) { $question_result = $objExercise->manage_answer($id, $questionId, $choice,'exercise_show', array(), false, true, $show_results, $objExercise->selectPropagateNeg()); $questionScore = $question_result['score']; $totalScore += $question_result['score']; - } elseif ($answerType == HOT_SPOT) { + } elseif ($answerType == HOT_SPOT) { + //@todo move this in the manage_answer function if ($show_results) { echo '
@@ -183,6 +184,7 @@ if (!empty($question_list)) {

'; } + } else if($answerType == HOT_SPOT_DELINEATION) { $question_result = $objExercise->manage_answer($id, $questionId, $choice,'exercise_show', array(), false, true, $show_results, $objExercise->selectPropagateNeg(), 'database'); diff --git a/main/inc/ajax/exercise.ajax.php b/main/inc/ajax/exercise.ajax.php index fe9ee6c056..27e33fc442 100644 --- a/main/inc/ajax/exercise.ajax.php +++ b/main/inc/ajax/exercise.ajax.php @@ -4,6 +4,10 @@ * Responses to AJAX calls */ +require_once '../../exercice/exercise.class.php'; +require_once '../../exercice/question.class.php'; +require_once '../../exercice/answer.class.php'; +require_once '../../exercice/exercise.lib.php'; require_once '../global.inc.php'; api_protect_course_script(true); $action = $_REQUEST['a']; @@ -21,6 +25,177 @@ switch ($action) { Display::display_confirmation_message(get_lang('Saved')); } break; + case 'add_question_to_reminder': + $objExercise = $_SESSION['objExercise']; + if (empty($objExercise)) { + echo 0; + exit; + } else { + $objExercise->edit_question_to_remind($_REQUEST['exe_id'], $_REQUEST['question_id'], $_REQUEST['action']); + } + break; + case 'save_exercise_by_now': + //Use have permissions? + if (api_is_allowed_to_session_edit()) { + + //"all" or "simple" strings means that there's one or all questions + $type = $_REQUEST['type']; + + //Normal questions choices + $choice = $_REQUEST['choice']; + + //All Hotspot coordinates from all questions + $hot_spot_coordinates = $_REQUEST['hotspot']; + + + //There is a reminder? + $remind_list = isset($_REQUEST['remind_list']) && !empty($_REQUEST['remind_list'])? array_keys($_REQUEST['remind_list']) : null; + + //Lp ids + $safe_lp_id = $_REQUEST['learnpath_id']; + $safe_lp_item_id = $_REQUEST['learnpath_item_id']; + $safe_lp_item_view_id = $_REQUEST['learnpath_item_view_id']; + + //Exercise information + $question_id = intval($_REQUEST['question_id']); + $question_list = $_SESSION['questionList']; + $objExercise = $_SESSION['objExercise']; + + if (empty($question_list) || empty($objExercise)) { + echo 0; + exit; + } + + $exe_id = null; + if (isset($_SESSION['exe_id'])) { + $exe_id = $_SESSION['exe_id']; + } + + //Getting information of the current exercise + $exercise_stat_info = $objExercise->get_stat_track_exercise_info($safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id); + //$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id); + + + $attempt_list = array(); + + //First time here we create an attempt (getting the exe_id) + if (empty($exercise_stat_info)) { + //$exe_id = create_event_exercice($objExercise->selectId()); + $current_expired_time_key = get_time_control_key($objExercise->id); + if (isset($_SESSION['expired_time'][$current_expired_time_key])) { //Only for exercice of type "One page" + $expired_date = $_SESSION['expired_time'][$current_expired_time_key]; + } else { + $expired_date = '0000-00-00 00:00:00'; + } + $exe_id = $objExercise->save_stat_track_exercise_info($expired_date, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id, $question_list, 0); //total weight 0 by now + + $total_score = $total_weight = 0; + } else { + //We know the user we get the exe_id + $exe_id = $exercise_stat_info['exe_id']; + $total_score = $exercise_stat_info['exe_result']; + + //Getting the list of attempts + $attempt_list = get_all_exercise_event_by_exe_id($exe_id); + } + + + //Updating Reminder algorythm + if ($objExercise->type == ONE_PER_PAGE) { + $bd_reminder_list = explode(',', $exercise_stat_info['questions_to_check']); + + if (empty($remind_list)) { + $remind_list = $bd_reminder_list; + + $new_list = array(); + foreach($bd_reminder_list as $item) { + if ($item != $question_id) { + $new_list[] = $item; + } + } + $remind_list = $new_list; + } else { + if (isset($remind_list[0])) { + if (!in_array($remind_list[0], $bd_reminder_list)) { + array_push($bd_reminder_list, $remind_list[0]); + } + $remind_list = $bd_reminder_list; + } + } + } + + + //No exe id? Can't save answer + if (empty($exe_id)) { + //Fires an error + echo 'error'; + exit; + } else { + $_SESSION['exe_id'] = $exe_id; + } + + // Getting the total weight if the request is simple + $total_weight = 0; + if ($type == 'simple') { + foreach($question_list as $my_question_id) { + $objQuestionTmp = Question :: read($my_question_id); + $total_weight += $objQuestionTmp->selectWeighting(); + } + } + + unset($objQuestionTmp); + + //Looping the question list + + foreach($question_list as $my_question_id) { + if ($type == 'simple' && $question_id != $my_question_id) { + continue; + } + + $my_choice = $choice[$my_question_id]; + + // creates a temporary Question object + $objQuestionTmp = Question::read($my_question_id); + + //Getting free choice data + if ($objQuestionTmp->type == FREE_ANSWER && $type == 'all') { + $my_choice = isset($_REQUEST['free_choice'][$my_question_id]) && !empty($_REQUEST['free_choice'][$my_question_id])? $_REQUEST['free_choice'][$my_question_id]: null; + } + + if ($type == 'all') { + $total_weight += $objQuestionTmp->selectWeighting(); + } + + //this variable commes from exercise_submit_modal.php + $hotspot_delineation_result = $_SESSION['hotspot_delineation_result'][$objExercise->selectId()][$my_question_id]; + + // Deleting old attempt + if (isset($attempt_list) && !empty($attempt_list[$my_question_id])) { + delete_attempt($exe_id, api_get_user_id() , api_get_course_id(), api_get_session_id(), $my_question_id); + if ($objQuestionTmp->type == HOT_SPOT) { + delete_attempt_hotspot($exe_id, api_get_user_id() , api_get_course_id(), $my_question_id); + } + $total_score -= $attempt_list[$my_question_id]['marks']; + } + + // We're inside *one* question. Go through each possible answer for this question + $result = $objExercise->manage_answer($exe_id, $my_question_id, $my_choice,'exercise_result', $hot_spot_coordinates, true, false, $show_results, $objExercise->selectPropagateNeg(), $hotspot_delineation_result, true); + + $total_score += $result['score']; + + update_event_exercice($exe_id, $objExercise->selectId(), $total_score, $total_weight, api_get_session_id(), $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id, $quizDuration, $question_list, 'incomplete', $remind_list); + + // Destruction of the Question object + unset($objQuestionTmp); + } + } + + if ($objExercise->type == ONE_PER_PAGE) { + echo 'one_per_page'; + exit; + } + echo 'ok'; + break; default: echo ''; } diff --git a/main/inc/lib/display.lib.php b/main/inc/lib/display.lib.php index 643450500e..48df457097 100755 --- a/main/inc/lib/display.lib.php +++ b/main/inc/lib/display.lib.php @@ -964,25 +964,33 @@ class Display { }); */ } - public static function table($headers, $rows) { - /* - require_once api_get_path(LIBRARY_PATH).'pear/HTML/Table.php'; - $table = new HTML_Table(array('class' => 'data_table')); + public static function table($headers, $rows, $attributes = array()) { + + if (empty($attributes)) { + $attributes['class'] = 'data_table'; + } + //require_once api_get_path(LIBRARY_PATH).'pear/HTML/Table.php'; + $table = new HTML_Table($attributes); $row = 0; $column = 0; //Course headers - foreach ($headers as $item) { - $table->setHeaderContents($row, $column, $item); - $column++; - } - $row = 1; - $column = 0; - foreach($rows as $content) { - $table->setCellContents($row, $column, $content); - $column++; - } - return $table->toHtml();*/ + if (!empty($headers)) { + foreach ($headers as $item) { + $table->setHeaderContents($row, $column, $item); + $column++; + } + $row = 1; + $column = 0; + } + + if (!empty($rows)) { + foreach($rows as $content) { + $table->setCellContents($row, $column, $content); + $column++; + } + } + return $table->toHtml(); } /** diff --git a/main/inc/lib/events.lib.inc.php b/main/inc/lib/events.lib.inc.php index 461b6c536f..6388d436fa 100755 --- a/main/inc/lib/events.lib.inc.php +++ b/main/inc/lib/events.lib.inc.php @@ -305,9 +305,9 @@ function event_link($link_id) { * @author Julio Montoya Armas Reworked 2010 * @desc Record result of user when an exercice was done */ -function update_event_exercice($exeid, $exo_id, $score, $weighting,$session_id,$learnpath_id=0, $learnpath_item_id=0, $learnpath_item_view_id = 0, $duration , $question_list) { +function update_event_exercice($exeid, $exo_id, $score, $weighting,$session_id,$learnpath_id=0, $learnpath_item_id=0, $learnpath_item_view_id = 0, $duration, $question_list, $status = '', $remind_list = array()) { require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.lib.php'; - if ($exeid!='') { + if ($exeid != '') { // Validation in case of fraud with actived control time if (!exercise_time_control_is_valid($exo_id)) { $score = 0; @@ -321,25 +321,41 @@ function update_event_exercice($exeid, $exo_id, $score, $weighting,$session_id,$ $start_date = $now - 1800; // Now - 30min } } + + if (!isset($status) || empty($status)) { + $status = ''; + } else { + $status = Database::escape_string($status); + } + $TABLETRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); array_map('intval', $question_list); + + if (!empty($remind_list)) { + array_map('intval', $remind_list); + $remind_list = array_filter($remind_list); + $remind_list = implode(",", $remind_list); + } else { + $remind_list = ''; + } $sql = "UPDATE $TABLETRACK_EXERCICES SET - exe_exo_id = '".Database::escape_string($exo_id)."', - exe_result = '".Database::escape_string($score)."', - exe_weighting = '".Database::escape_string($weighting)."', - session_id = '".Database::escape_string($session_id)."', - orig_lp_id = '".Database::escape_string($learnpath_id)."', - orig_lp_item_id = '".Database::escape_string($learnpath_item_id)."', - orig_lp_item_view_id = '".Database::escape_string($learnpath_item_view_id)."', - exe_duration = '".Database::escape_string($duration)."', - exe_date = '".api_get_utc_datetime()."', - status = '', - start_date = '".api_get_utc_datetime($start_date)."', - data_tracking = '".implode(',', $question_list)."' + exe_exo_id = '".Database::escape_string($exo_id)."', + exe_result = '".Database::escape_string($score)."', + exe_weighting = '".Database::escape_string($weighting)."', + session_id = '".Database::escape_string($session_id)."', + orig_lp_id = '".Database::escape_string($learnpath_id)."', + orig_lp_item_id = '".Database::escape_string($learnpath_item_id)."', + orig_lp_item_view_id = '".Database::escape_string($learnpath_item_view_id)."', + exe_duration = '".Database::escape_string($duration)."', + exe_date = '".api_get_utc_datetime()."', + status = '".$status."', + questions_to_check = '".$remind_list."', + start_date = '".api_get_utc_datetime($start_date)."', + data_tracking = '".implode(',', $question_list)."' WHERE exe_id = '".Database::escape_string($exeid)."'"; - $res = @Database::query($sql); + $res = Database::query($sql); //Deleting control time session track exercise_time_control_delete($exo_id); @@ -1020,3 +1036,47 @@ function get_comments($id,$question_id) { return $comm; } + + +function get_all_exercise_event_by_exe_id($exe_id) { + $table_track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); + $exe_id = intval($exe_id); + $list = array(); + + $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = $exe_id ORDER BY position"; + $res_question = Database::query($sql); + if (Database::num_rows($res_question)) + while($row_q = Database::fetch_array($res_question,'ASSOC')) { + $list[$row_q['question_id']][] = $row_q; + } + return $list; +} + + + +function delete_attempt($exe_id, $user_id, $course_code, $session_id, $question_id) { + $table_track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); + + $exe_id = intval($exe_id); + $user_id = intval($user_id); + $course_code = Database::escape_string($course_code); + $session_id = intval($session_id); + $question_id = intval($question_id); + + $sql = "DELETE FROM $table_track_attempt WHERE exe_id = $exe_id AND user_id = $user_id AND course_code = '$course_code' AND session_id = $session_id AND question_id = $question_id "; + Database::query($sql); +} + +function delete_attempt_hotspot($exe_id, $user_id, $course_code, $question_id) { + $table_track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT); + + $exe_id = intval($exe_id); + $user_id = intval($user_id); + $course_code = Database::escape_string($course_code); + //$session_id = intval($session_id); + $question_id = intval($question_id); + + $sql = "DELETE FROM $table_track_attempt WHERE hotspot_exe_id = $exe_id AND hotspot_user_id = $user_id AND hotspot_course_code = '$course_code' AND hotspot_question_id = $question_id "; + Database::query($sql); +} + diff --git a/main/inc/lib/exercise_show_functions.lib.php b/main/inc/lib/exercise_show_functions.lib.php index a762088021..6e41fb5142 100755 --- a/main/inc/lib/exercise_show_functions.lib.php +++ b/main/inc/lib/exercise_show_functions.lib.php @@ -60,9 +60,11 @@ class ExerciseShowFunctions { function display_free_answer($answer,$id,$questionId) { global $feedback_type; if (empty($id)) { - echo ''; - echo Display::tag('td',nl2br(Security::remove_XSS($answer,COURSEMANAGERLOWSECURITY)), array('width'=>'55%')); - echo ''; + if (!empty($answer)) { + echo ''; + echo Display::tag('td',nl2br(Security::remove_XSS($answer,COURSEMANAGERLOWSECURITY)), array('width'=>'55%')); + echo ''; + } if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { echo ''; echo Display::tag('td',get_lang('notCorrectedYet'), array('width'=>'45%')); @@ -72,12 +74,11 @@ class ExerciseShowFunctions { } } else { echo ''; - echo ''; if (!empty($answer)) { + echo ''; echo nl2br(Security::remove_XSS($answer,COURSEMANAGERLOWSECURITY)); + echo ''; } - echo ''; - if(!api_is_allowed_to_edit(null,true) && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { echo ''; $comm = get_comments($id,$questionId); @@ -112,6 +113,7 @@ class ExerciseShowFunctions { "#3B3B3B", "#F7BDE2"); ?> +
@@ -132,8 +134,7 @@ class ExerciseShowFunctions {
- '.nl2br(make_clickable($answerComment)).''; } else { diff --git a/main/install/db_stats.sql b/main/install/db_stats.sql index 34bd169a81..ca2be64c75 100755 --- a/main/install/db_stats.sql +++ b/main/install/db_stats.sql @@ -117,6 +117,8 @@ ALTER TABLE track_e_exercices ADD orig_lp_item_id int NOT NULL default 0; ALTER TABLE track_e_exercices ADD exe_duration int UNSIGNED NOT NULL default 0; ALTER TABLE track_e_exercices ADD COLUMN expired_time_control datetime NOT NULL DEFAULT '0000-00-00 00:00:00'; ALTER TABLE track_e_exercices ADD COLUMN orig_lp_item_view_id INT NOT NULL DEFAULT 0; +ALTER TABLE track_e_exercices ADD COLUMN questions_to_check TEXT NOT NULL DEFAULT ''; + CREATE TABLE track_e_attempt ( exe_id int default NULL,