Browse Source

Adding warning when clicking the "end test" button see BT#6525

Julio Montoya 11 years ago
parent
commit
2ab0dd64fc

+ 187 - 130
main/exercice/exercise.class.php

@@ -779,7 +779,7 @@ class Exercise
                 if (!empty($numberOfQuestions)) {
                     $elements = Testcategory::getNElementsFromArray($categoryQuestionList, $numberOfQuestions, $randomizeQuestions);
                 if (!empty($elements)) {
-                    $temp_question_list[$category_id] = $elements;
+                        $temp_question_list[$category_id] = $elements;
                         $categoryQuestionList = $elements;
                     }
                 }
@@ -947,10 +947,6 @@ class Exercise
                     break;
             }
 
-
-            if ($this->categories_grouping) {
-            }
-
             return $questionList;
         }
 
@@ -2544,7 +2540,7 @@ class Exercise
 
             $original_exercise->copy_exercise_categories($exercise_obj);
 
-            $question_list = $exercise_obj->selectQuestionList();
+            $question_list = $exercise_obj->selectQuestionList(true);
 
             if (!empty($question_list)) {
                 //Question creation
@@ -2738,15 +2734,19 @@ class Exercise
             $html .= '<br />';
         } else {
             // User
+            $showEndWarning = 0;
             if (api_is_allowed_to_session_edit()) {
                 if ($this->type == ALL_ON_ONE_PAGE || $nbrQuestions == $questionNum) {
                     if ($this->review_answers) {
-                        $label = get_lang('ReviewQuestions');
-                        $class = 'btn btn-success';
+                        //$label = get_lang('ReviewQuestions');
+                        //$class = 'btn btn-success';
+                        $label = get_lang('EndTest');
+                        $class = 'btn btn-warning';
                     } else {
                         $label = get_lang('EndTest');
                         $class = 'btn btn-warning';
                     }
+                    $showEndWarning = 1;
                 } else {
                     $label = get_lang('NextQuestion');
                     $class = 'btn btn-primary';
@@ -2758,13 +2758,14 @@ class Exercise
                         $all_button .= '<a href="javascript://" class="btn" onclick="previous_question_and_save('.$prev_question.', '.$question_id.' ); ">'.get_lang('PreviousQuestion').'</a>';
                     }
 
-                    //Next question
+                    // Next question
                     if (isset($questions_in_media) && !empty($questions_in_media) && is_array($questions_in_media)) {
                         $questions_in_media = "['".implode("','", $questions_in_media)."']";
-                        $all_button .= '&nbsp;<a href="javascript://" class="'.$class.'" onclick="save_question_list('.$questions_in_media.'); ">'.$label.'</a>';
+                        $all_button .= '&nbsp;<a href="javascript://" class="'.$class.'" onclick="save_question_list('.$questions_in_media.', '.$showEndWarning.'); ">'.$label.'</a>';
                     } else {
-                        $all_button .= '&nbsp;<a href="javascript://" class="'.$class.'" onclick="save_now('.$question_id.'); ">'.$label.'</a>';
+                        $all_button .= '&nbsp;<a href="javascript://" class="'.$class.'" onclick="save_now('.$question_id.', null, true, '.$showEndWarning.'); ">'.$label.'</a>';
                     }
+
                     $all_button .= '<span id="save_for_now_'.$question_id.'" class="exercise_save_mini_message"></span>&nbsp;';
                     $html .= $all_button;
                 } else {
@@ -2837,14 +2838,13 @@ class Exercise
                 }).bind('timer', function () {
                     send_form();
                 });
-
             }
 
             function send_form() {
                 if ($('#exercise_form').length) {
                     $('#exercise_form').submit();
                 } else {
-                    // In reminder
+                    // In reminder.
                     final_submit();
                 }
             }
@@ -2886,119 +2886,118 @@ class Exercise
      */
     public function show_lp_javascript()
     {
-
         return "<script type=\"text/javascript\" src=\"../plugin/hotspot/JavaScriptFlashGateway.js\"></script>
-                    <script src=\"../plugin/hotspot/hotspot.js\" type=\"text/javascript\"></script>
-                    <script language=\"JavaScript\" type=\"text/javascript\">
-                    <!--
-                    // -----------------------------------------------------------------------------
-                    // Globals
-                    // Major version of Flash required
-                    var requiredMajorVersion = 7;
-                    // Minor version of Flash required
-                    var requiredMinorVersion = 0;
-                    // Minor version of Flash required
-                    var requiredRevision = 0;
-                    // the version of javascript supported
-                    var jsVersion = 1.0;
-                    // -----------------------------------------------------------------------------
-                    // -->
-                    </script>
-                    <script language=\"VBScript\" type=\"text/vbscript\">
-                    <!-- // Visual basic helper required to detect Flash Player ActiveX control version information
-                    Function VBGetSwfVer(i)
-                      on error resume next
-                      Dim swControl, swVersion
-                      swVersion = 0
-
-                      set swControl = CreateObject(\"ShockwaveFlash.ShockwaveFlash.\" + CStr(i))
-                      if (IsObject(swControl)) then
-                        swVersion = swControl.GetVariable(\"\$version\")
-                      end if
-                      VBGetSwfVer = swVersion
-                    End Function
-                    // -->
-                    </script>
-
-                    <script language=\"JavaScript1.1\" type=\"text/javascript\">
-                    <!-- // Detect Client Browser type
-                    var isIE  = (navigator.appVersion.indexOf(\"MSIE\") != -1) ? true : false;
-                    var isWin = (navigator.appVersion.toLowerCase().indexOf(\"win\") != -1) ? true : false;
-                    var isOpera = (navigator.userAgent.indexOf(\"Opera\") != -1) ? true : false;
-                    jsVersion = 1.1;
-                    // JavaScript helper required to detect Flash Player PlugIn version information
-                    function JSGetSwfVer(i){
-                        // NS/Opera version >= 3 check for Flash plugin in plugin array
-                        if (navigator.plugins != null && navigator.plugins.length > 0) {
-                            if (navigator.plugins[\"Shockwave Flash 2.0\"] || navigator.plugins[\"Shockwave Flash\"]) {
-                                var swVer2 = navigator.plugins[\"Shockwave Flash 2.0\"] ? \" 2.0\" : \"\";
-                                var flashDescription = navigator.plugins[\"Shockwave Flash\" + swVer2].description;
-                                descArray = flashDescription.split(\" \");
-                                tempArrayMajor = descArray[2].split(\".\");
-                                versionMajor = tempArrayMajor[0];
-                                versionMinor = tempArrayMajor[1];
-                                if ( descArray[3] != \"\" ) {
-                                    tempArrayMinor = descArray[3].split(\"r\");
-                                } else {
-                                    tempArrayMinor = descArray[4].split(\"r\");
-                                }
-                                versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
-                                flashVer = versionMajor + \".\" + versionMinor + \".\" + versionRevision;
+                <script src=\"../plugin/hotspot/hotspot.js\" type=\"text/javascript\"></script>
+                <script language=\"JavaScript\" type=\"text/javascript\">
+                <!--
+                // -----------------------------------------------------------------------------
+                // Globals
+                // Major version of Flash required
+                var requiredMajorVersion = 7;
+                // Minor version of Flash required
+                var requiredMinorVersion = 0;
+                // Minor version of Flash required
+                var requiredRevision = 0;
+                // the version of javascript supported
+                var jsVersion = 1.0;
+                // -----------------------------------------------------------------------------
+                // -->
+                </script>
+                <script language=\"VBScript\" type=\"text/vbscript\">
+                <!-- // Visual basic helper required to detect Flash Player ActiveX control version information
+                Function VBGetSwfVer(i)
+                  on error resume next
+                  Dim swControl, swVersion
+                  swVersion = 0
+
+                  set swControl = CreateObject(\"ShockwaveFlash.ShockwaveFlash.\" + CStr(i))
+                  if (IsObject(swControl)) then
+                    swVersion = swControl.GetVariable(\"\$version\")
+                  end if
+                  VBGetSwfVer = swVersion
+                End Function
+                // -->
+                </script>
+
+                <script language=\"JavaScript1.1\" type=\"text/javascript\">
+                <!-- // Detect Client Browser type
+                var isIE  = (navigator.appVersion.indexOf(\"MSIE\") != -1) ? true : false;
+                var isWin = (navigator.appVersion.toLowerCase().indexOf(\"win\") != -1) ? true : false;
+                var isOpera = (navigator.userAgent.indexOf(\"Opera\") != -1) ? true : false;
+                jsVersion = 1.1;
+                // JavaScript helper required to detect Flash Player PlugIn version information
+                function JSGetSwfVer(i){
+                    // NS/Opera version >= 3 check for Flash plugin in plugin array
+                    if (navigator.plugins != null && navigator.plugins.length > 0) {
+                        if (navigator.plugins[\"Shockwave Flash 2.0\"] || navigator.plugins[\"Shockwave Flash\"]) {
+                            var swVer2 = navigator.plugins[\"Shockwave Flash 2.0\"] ? \" 2.0\" : \"\";
+                            var flashDescription = navigator.plugins[\"Shockwave Flash\" + swVer2].description;
+                            descArray = flashDescription.split(\" \");
+                            tempArrayMajor = descArray[2].split(\".\");
+                            versionMajor = tempArrayMajor[0];
+                            versionMinor = tempArrayMajor[1];
+                            if ( descArray[3] != \"\" ) {
+                                tempArrayMinor = descArray[3].split(\"r\");
                             } else {
-                                flashVer = -1;
+                                tempArrayMinor = descArray[4].split(\"r\");
                             }
-                        }
-                        // MSN/WebTV 2.6 supports Flash 4
-                        else if (navigator.userAgent.toLowerCase().indexOf(\"webtv/2.6\") != -1) flashVer = 4;
-                        // WebTV 2.5 supports Flash 3
-                        else if (navigator.userAgent.toLowerCase().indexOf(\"webtv/2.5\") != -1) flashVer = 3;
-                        // older WebTV supports Flash 2
-                        else if (navigator.userAgent.toLowerCase().indexOf(\"webtv\") != -1) flashVer = 2;
-                        // Can't detect in all other cases
-                        else {
-
+                            versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
+                            flashVer = versionMajor + \".\" + versionMinor + \".\" + versionRevision;
+                        } else {
                             flashVer = -1;
                         }
-                        return flashVer;
                     }
-                    // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
-                    function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
-                    {
-                        reqVer = parseFloat(reqMajorVer + \".\" + reqRevision);
-                        // loop backwards through the versions until we find the newest version
-                        for (i=25;i>0;i--) {
-                            if (isIE && isWin && !isOpera) {
-                                versionStr = VBGetSwfVer(i);
+                    // MSN/WebTV 2.6 supports Flash 4
+                    else if (navigator.userAgent.toLowerCase().indexOf(\"webtv/2.6\") != -1) flashVer = 4;
+                    // WebTV 2.5 supports Flash 3
+                    else if (navigator.userAgent.toLowerCase().indexOf(\"webtv/2.5\") != -1) flashVer = 3;
+                    // older WebTV supports Flash 2
+                    else if (navigator.userAgent.toLowerCase().indexOf(\"webtv\") != -1) flashVer = 2;
+                    // Can't detect in all other cases
+                    else {
+
+                        flashVer = -1;
+                    }
+                    return flashVer;
+                }
+                // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
+                function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
+                {
+                    reqVer = parseFloat(reqMajorVer + \".\" + reqRevision);
+                    // loop backwards through the versions until we find the newest version
+                    for (i=25;i>0;i--) {
+                        if (isIE && isWin && !isOpera) {
+                            versionStr = VBGetSwfVer(i);
+                        } else {
+                            versionStr = JSGetSwfVer(i);
+                        }
+                        if (versionStr == -1 ) {
+                            return false;
+                        } else if (versionStr != 0) {
+                            if(isIE && isWin && !isOpera) {
+                                tempArray         = versionStr.split(\" \");
+                                tempString        = tempArray[1];
+                                versionArray      = tempString .split(\",\");
                             } else {
-                                versionStr = JSGetSwfVer(i);
+                                versionArray      = versionStr.split(\".\");
                             }
-                            if (versionStr == -1 ) {
-                                return false;
-                            } else if (versionStr != 0) {
-                                if(isIE && isWin && !isOpera) {
-                                    tempArray         = versionStr.split(\" \");
-                                    tempString        = tempArray[1];
-                                    versionArray      = tempString .split(\",\");
-                                } else {
-                                    versionArray      = versionStr.split(\".\");
-                                }
-                                versionMajor      = versionArray[0];
-                                versionMinor      = versionArray[1];
-                                versionRevision   = versionArray[2];
-
-                                versionString     = versionMajor + \".\" + versionRevision;   // 7.0r24 == 7.24
-                                versionNum        = parseFloat(versionString);
-                                // is the major.revision >= requested major.revision AND the minor version >= requested minor
-                                if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) {
-                                    return true;
-                                } else {
-                                    return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false );
-                                }
+                            versionMajor      = versionArray[0];
+                            versionMinor      = versionArray[1];
+                            versionRevision   = versionArray[2];
+
+                            versionString     = versionMajor + \".\" + versionRevision;   // 7.0r24 == 7.24
+                            versionNum        = parseFloat(versionString);
+                            // is the major.revision >= requested major.revision AND the minor version >= requested minor
+                            if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) {
+                                return true;
+                            } else {
+                                return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false );
                             }
                         }
                     }
-                    // -->
-                    </script>";
+                }
+                // -->
+                </script>";
     }
 
     /**
@@ -5465,6 +5464,62 @@ class Exercise
         return $html;
     }
 
+    public function returnWarningJs($url)
+    {
+        $condition = "
+            var dialog = $('#dialog-confirm');
+
+            if (dialog.data('question_list') != '') {
+                saveQuestionList(dialog.data('question_list'));
+            } else {
+                saveNow(dialog.data('question_id'), dialog.data('url_extra'), dialog.data('redirect'));
+            }
+
+            $(this).dialog('close');
+        ";
+
+        if (!empty($url)) {
+           $condition = 'window.location = "'.$url.'&" + lp_data;';
+        }
+
+        return '<script>
+            $(function() {
+                $("#dialog-confirm").dialog({
+                    autoOpen: false,
+                    resizable: false,
+                    height:200,
+                    width:550,
+                    modal: true,
+                    buttons: {
+                        "cancel": {
+                            click: function() {
+                                $(this).dialog("close");
+                            },
+                            text : "'.get_lang("NoIWantToTurnBack").'",
+                            class : "btn btn-danger"
+                        },
+                        "ok": {
+                            click : function() {
+                                '.$condition.'
+                            },
+                            text: "'.get_lang("YesImSure").'",
+                            class : "btn btn-success"
+                        }
+                    }
+                });
+            });
+        </script>';
+    }
+
+    function returnWarningHtml()
+    {
+        return  '<div id="dialog-confirm" title="'.get_lang('Exercise').'" style="display:none">
+          <p><span class="ui-icon ui-icon-alert" style="float: left; margin: 0 7px 20px 0;"></span>
+          '.get_lang('IfYouContinueYourAnswerWillBeSavedAnyChangeWillBeNotAllowed').'
+            </p>
+        </div>';
+    }
+
     /**
      * Get question list (including question ids of the media)
      * @return int
@@ -6216,7 +6271,7 @@ class Exercise
                     $exercise_actions .= $this->show_button($questionId, $current_question, null, $remindList);
                     break;
                 case ALL_ON_ONE_PAGE:
-                    $button  = '<a href="javascript://" class="btn" onclick="save_now(\''.$questionId.'\'); ">'.get_lang('SaveForNow').'</a>';
+                    $button  = '<a href="javascript://" class="btn" onclick="save_now(\''.$questionId.'\', null, true, 1); ">'.get_lang('SaveForNow').'</a>';
                     $button .= '<span id="save_for_now_'.$questionId.'" class="exercise_save_mini_message"></span>&nbsp;';
                     $exercise_actions .= Display::div($button, array('class'=>'exercise_save_now_button'));
                     break;
@@ -6225,7 +6280,7 @@ class Exercise
             if (!empty($questions_in_media)) {
                 $count_of_questions_inside_media = count($questions_in_media);
                 if ($count_of_questions_inside_media > 1) {
-                    $button  = '<a href="javascript://" class="btn" onclick="save_now(\''.$questionId.'\', false, false); ">'.get_lang('SaveForNow').'</a>';
+                    $button  = '<a href="javascript://" class="btn" onclick="save_now(\''.$questionId.'\', false, false, 0); ">'.get_lang('SaveForNow').'</a>';
                     $button .= '<span id="save_for_now_'.$questionId.'" class="exercise_save_mini_message"></span>&nbsp;';
                     $exercise_actions = Display::div($button, array('class'=>'exercise_save_now_button'));
                 }
@@ -6521,22 +6576,24 @@ class Exercise
                     $exercise_stat_info['exe_duration'],
                     '',
                     array()
-                  );
+                );
+
                 $log_transactions_settings = TransactionLog::getTransactionSettings();
                 if (isset($log_transactions_settings['exercise_attempt'])) {
-                  $transaction_controller = new TransactionLogController();
-                  $transaction = $transaction_controller->loadOne(array(
-                    'action' => 'exercise_attempt',
-                    'branch_id' => TransactionLog::BRANCH_LOCAL,
-                    'item_id' => $exercise_stat_info['exe_id'],
-                  ));
-                  if (!$transaction) {
-                    $transaction_data = array(
-                      'item_id' => $exercise_stat_info['exe_id'],
+                    $transaction_controller = new TransactionLogController();
+                    $transaction = $transaction_controller->loadOne(array(
+                        'action' => 'exercise_attempt',
+                        'branch_id' => TransactionLog::BRANCH_LOCAL,
+                        'item_id' => $exercise_stat_info['exe_id'],
+                        )
                     );
-                    $transaction = $transaction_controller->createTransaction('exercise_attempt', $transaction_data);
-                  }
-                  $transaction->save();
+                    if (!$transaction) {
+                        $transaction_data = array(
+                            'item_id' => $exercise_stat_info['exe_id'],
+                        );
+                        $transaction = $transaction_controller->createTransaction('exercise_attempt', $transaction_data);
+                    }
+                    $transaction->save();
                 }
             }
 

+ 14 - 6
main/exercice/exercise_result.php

@@ -53,6 +53,7 @@ if (empty($origin)) {
 if (empty($objExercise)) {
     $objExercise = $_SESSION['objExercise'];
 }
+
 if (empty($remind_list)) {
     $remind_list = isset($_REQUEST['remind_list']) ? $_REQUEST['remind_list'] : null;
 }
@@ -64,11 +65,17 @@ if (empty($objExercise)) {
     // Check if the exe_id exists
     $objExercise = new Exercise();
     $exercise_stat_info = $objExercise->getStatTrackExerciseInfoByExeId($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;
+        if ($exercise_stat_info['status'] == 'incomplete') {
+            $objExercise->read($exercise_stat_info['exe_exo_id']);
+        } else {
+            header("Location: overview.php?exerciseId=".$exercise_stat_info['exe_exo_id']);
+            exit;
+        }
+    } else {
+        api_not_allowed(true);
     }
-    api_not_allowed(true);
 }
 
 $gradebook = '';
@@ -129,7 +136,7 @@ if ($objExercise->selectAttempts() > 0) {
     if ($attempt_count >= $objExercise->selectAttempts()) {
         Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $objExercise->selectTitle(), $objExercise->selectAttempts()), false);
         if ($origin != 'learnpath') {
-            //we are not in learnpath tool
+            // We are not in learnpath tool
             Display::display_footer();
         }
         exit;
@@ -149,7 +156,7 @@ if (isset($session_control_key) && !ExerciseLib::exercise_time_control_is_valid(
     Database::query($sql_fraud);
 }
 
-//Unset session for clock time
+// Unset session for clock time.
 ExerciseLib::exercise_time_control_delete($objExercise->id, $learnpath_id, $learnpath_item_id);
 
 ExerciseLib::delete_chat_exercise_session($exe_id);
@@ -177,7 +184,8 @@ if ($origin != 'learnpath') {
         Session::erase('exe_id');
         Session::erase('categoryList');
     }
-    //record the results in the learning path, using the SCORM interface (API)
+
+    // Record the results in the learning path, using the SCORM interface (API)
     echo "<script>window.parent.API.void_save_asset('$total_score', '$total_weight', 0, 'completed');</script>";
     echo '<script type="text/javascript">'.$href.'</script>';
     echo '</body></html>';

+ 1 - 1
main/exercice/exercise_show.php

@@ -753,8 +753,8 @@ if ($is_allowedToEdit && $locked == false && !api_is_drh()) {
 
     echo '<input id="vals" type = "hidden" name="vals"       value="'.$strids.'">';
     echo '<input id="marksid" type = "hidden" name="marksid"       value="'.$marksid.'">';
-	if ($origin !='learnpath' && $origin!='student_progress') {
 
+	if ($origin !='learnpath' && $origin!='student_progress') {
         echo '<label><input type= "checkbox" name="send_notification"> '.get_lang('SendEmail').'</label>';
 		?>
         <input type="submit" class="btn btn-primary" value=" <?php echo get_lang('CorrectTest'); ?>">

+ 134 - 77
main/exercice/exercise_submit.php

@@ -47,13 +47,13 @@ $this_section = SECTION_COURSES;
 $debug = false;
 if ($debug) {
     error_log('--- Enter to the exercise_submit.php ---- ');
-    error_log('0. POST variables : '.print_r($_POST,1));
+    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);
+$is_allowedToEdit = api_is_allowed_to_edit(null, true);
 
 if (api_get_setting('show_glossary_in_extra_tools') == 'true') {
     $htmlHeadXtra[] = api_get_js('glossary.js'); //Glossary
@@ -257,14 +257,22 @@ var connectorType = "Straight";
                 sourceDestinationArray[count+1] = sourceEndPoint;
 
                 count++;
-                jsPlumb.addEndpoint(windowId, { anchor:[ "RightMiddle","RightMiddle","RightMiddle","RightMiddle" ] }, sourceEndPoint);
+                jsPlumb.addEndpoint(
+                    windowId,
+                    { anchor:[ "RightMiddle","RightMiddle","RightMiddle","RightMiddle" ] },
+                    sourceEndPoint
+                );
                 var destinationCount = 0;
                 $(windowQuestion).each(function( index ) {
                     var windowDestinationId = $(this).attr("id");
                     destinationEndPoint.scope = scope;
                     destinationEndPoint.paintStyle.fillStyle = colorArrayDestination[destinationCount].getHex();
                     destinationCount++;
-                    jsPlumb.addEndpoint(windowDestinationId+"_answer", { anchor:[ "LeftMiddle","LeftMiddle","LeftMiddle","LeftMiddle" ]  }, destinationEndPoint);
+                    jsPlumb.addEndpoint(
+                        windowDestinationId+"_answer",
+                        { anchor:[ "LeftMiddle","LeftMiddle","LeftMiddle","LeftMiddle" ] },
+                        destinationEndPoint
+                    );
                 });
             });
             //var divsWithWindowClass = jsPlumb.CurrentLibrary.getSelector("#"+questionId+" .window");
@@ -315,7 +323,6 @@ $(function(){
 
 // General parameters passed via POST/GET
 
-
 // @todo check get and posts
 $learnpath_id 			= isset($_GET['learnpath_id']) ? intval($_GET['learnpath_id']) : 0;
 $learnpath_item_id 		= isset($_GET['learnpath_item_id']) ? intval($_GET['learnpath_item_id']) : 0;
@@ -335,10 +342,11 @@ $current_question       = isset($_REQUEST['num']) ? intval($_REQUEST['num']) : n
 $error = '';
 
 /*  Teacher takes an exam and want to see a preview,
-we delete the objExercise from the session in order to get the latest changes in the exercise */
-if (api_is_allowed_to_edit(null,true) && isset($_GET['preview']) && $_GET['preview'] == 1) {
+    we delete the objExercise from the session in order to get the latest changes in the exercise */
+if (api_is_allowed_to_edit(null, true) && isset($_GET['preview']) && $_GET['preview'] == 1) {
     Session::erase('objExercise');
 }
+
 /** @var \Exercise $exerciseInSession */
 $exerciseInSession = Session::read('objExercise');
 
@@ -380,7 +388,7 @@ if (!isset($objExercise) && isset($exerciseInSession)) {
 
 //3. $objExercise is not set, then return to the exercise list
 if (!is_object($objExercise)) {
-	if ($debug) {
+    if ($debug) {
         error_log('3. $objExercise was not set, kill the script');
     }
     header('Location: '.$urlMainExercise.'exercice.php');
@@ -389,11 +397,22 @@ if (!is_object($objExercise)) {
 
 // If reminder ends we jump to the exercise_reminder
 if ($objExercise->review_answers) {
-	if ($remind_question_id == -1) {
+    if ($remind_question_id == -1) {
         $paramsReminder = "exerciseId=$exerciseId&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id&".api_get_cidreq();
         header('Location: '.$urlMainExercise.'exercise_reminder.php?'.$paramsReminder);
         exit;
-	}
+    }
+}
+
+$exeId = isset($_GET['exe_id']) ? $_GET['exe_id'] : null;
+// Blocking access if exe_id was already treated
+if (!empty($exeId)) {
+    $attemptInfo = $objExercise->getStatTrackExerciseInfoByExeId($exeId);
+
+    if (!empty($attemptInfo) && $attemptInfo['status'] == '') {
+        header("Location: ".$urlMainExercise."overview.php?exerciseId=".$exerciseId."&".api_get_cidreq());
+        exit;
+    }
 }
 
 $current_timestamp 	= time();
@@ -433,67 +452,67 @@ if ($objExercise->selectAttempts() > 0) {
     $warningMessage = Display::return_message(
         sprintf(
             get_lang('ReachedMaxAttempts'),
-        $exercise_title,
+            $exercise_title,
             $objExercise->selectAttempts()
         ),
         'warning',
         false
     );
 
-	if ($attempt_count >= $objExercise->selectAttempts()) {
-		$show_clock = false;
-		if (!api_is_allowed_to_edit(null,true)) {
+    if ($attempt_count >= $objExercise->selectAttempts()) {
+        $show_clock = false;
+        if (!api_is_allowed_to_edit(null, true)) {
 
-			if ($objExercise->results_disabled == 0 && $origin != 'learnpath') {
+            if ($objExercise->results_disabled == 0 && $origin != 'learnpath') {
 
-				// Showing latest attempt according with task BT#1628.
-				$exercise_stat_info = getExerciseResultsByUser(
+                // Showing latest attempt according with task BT#1628.
+                $exercise_stat_info = getExerciseResultsByUser(
                     $user_id,
                     $exerciseId,
                     api_get_course_int_id(),
                     api_get_session_id()
                 );
 
-				if (!empty($exercise_stat_info)) {
-					$max_exe_id = max(array_keys($exercise_stat_info));
-					$last_attempt_info = $exercise_stat_info[$max_exe_id];
-					$attempt_html .= Display::div(get_lang('Date').': '.api_get_local_time($last_attempt_info['exe_date']), array('id'=>''));
-					$attempt_html .= $warningMessage;
+                if (!empty($exercise_stat_info)) {
+                    $max_exe_id = max(array_keys($exercise_stat_info));
+                    $last_attempt_info = $exercise_stat_info[$max_exe_id];
+                    $attempt_html .= Display::div(get_lang('Date').': '.api_get_local_time($last_attempt_info['exe_date']), array('id'=>''));
+                    $attempt_html .= $warningMessage;
 
-					if (!empty($last_attempt_info['question_list'])) {
-						foreach($last_attempt_info['question_list'] as $question_data) {
-							$question_id = $question_data['question_id'];
-							$marks       = $question_data['marks'];
+                    if (!empty($last_attempt_info['question_list'])) {
+                        foreach ($last_attempt_info['question_list'] as $question_data) {
+                            $question_id = $question_data['question_id'];
+                            $marks       = $question_data['marks'];
 
-							$question_info = Question::read($question_id);
-							$attempt_html .= Display::div($question_info->question, array('class'=>'question_title'));
-							$attempt_html .= Display::div(get_lang('Score').' '.$marks, array('id'=>'question_score'));
-						}
-					}
-					$score = ExerciseLib::show_score($last_attempt_info['exe_result'], $last_attempt_info['exe_weighting']);
-					$attempt_html .= Display::div(get_lang('YourTotalScore').' '.$score, array('id'=>'question_score'));
-				} else {
-					$attempt_html .= $warningMessage;
-				}
-			} else {
-				$attempt_html .= $warningMessage;
-			}
-		} else {
-			$attempt_html .= $warningMessage;
-		}
+                            $question_info = Question::read($question_id);
+                            $attempt_html .= Display::div($question_info->question, array('class'=>'question_title'));
+                            $attempt_html .= Display::div(get_lang('Score').' '.$marks, array('id'=>'question_score'));
+                        }
+                    }
+                    $score = ExerciseLib::show_score($last_attempt_info['exe_result'], $last_attempt_info['exe_weighting']);
+                    $attempt_html .= Display::div(get_lang('YourTotalScore').' '.$score, array('id'=>'question_score'));
+                } else {
+                    $attempt_html .= $warningMessage;
+                }
+            } else {
+                $attempt_html .= $warningMessage;
+            }
+        } else {
+            $attempt_html .= $warningMessage;
+        }
 
-		if ($origin == 'learnpath') {
-			Display :: display_reduced_header();
-		} else {
-			Display :: display_header($nameTools,'Exercises');
-		}
+        if ($origin == 'learnpath') {
+            Display :: display_reduced_header();
+        } else {
+            Display :: display_header($nameTools, 'Exercises');
+        }
 
-		echo $attempt_html;
-		if ($origin != 'learnpath') {
-			Display :: display_footer();
+        echo $attempt_html;
+        if ($origin != 'learnpath') {
+            Display :: display_footer();
         }
-		exit;
-	}
+        exit;
+    }
 }
 
 // 5. Getting user exercise info (if the user took the exam before) - generating exe_id
@@ -517,12 +536,12 @@ if (!isset($questionListInSession)) {
         error_log('$_SESSION[questionList] was set');
     }
 } else {
-	if (isset($objExercise) && isset($exerciseInSession)) {
+    if (isset($objExercise) && isset($exerciseInSession)) {
         $questionList = Session::read('questionList');
 	}
 }
 
-//Fix in order to get the correct question list
+// Fix in order to get the correct question list.
 $questionListUncompressed = $objExercise->getQuestionListWithMediasUncompressed();
 
 Session::write('question_list_uncompressed', $questionListUncompressed);
@@ -530,20 +549,19 @@ Session::write('question_list_uncompressed', $questionListUncompressed);
 $clock_expired_time = null;
 
 if (empty($exercise_stat_info)) {
-    if ($debug)  {
+    if ($debug) {
         error_log('5  $exercise_stat_info is empty ');
     }
 	$total_weight = 0;
 
 	foreach ($questionListUncompressed as $question_id) {
-		$objQuestionTmp = Question::read($question_id);
-		$total_weight += floatval($objQuestionTmp->weighting);
+        $objQuestionTmp = Question::read($question_id);
+        $total_weight += floatval($objQuestionTmp->weighting);
 	}
 
 	if ($time_control) {
 		$expected_time = $current_timestamp + $total_seconds;
 
-
 		$clock_expired_time 	= api_get_utc_datetime($expected_time);
 
 		//Sessions  that contain the expired time
@@ -578,7 +596,10 @@ if (!empty($exercise_stat_info['questions_to_check'])) {
 	$my_remind_list = explode(',', $my_remind_list);
 	$my_remind_list = array_filter($my_remind_list);
 }
-if ($debug) { error_log("6.0 my_remind_list array: ".print_r($my_remind_list, 1)); }
+if ($debug) {
+    error_log("6.0 my_remind_list array: ".print_r($my_remind_list, 1));
+}
+//$now = time();
 $params = "exe_id=$exe_id&exerciseId=$exerciseId&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id&".api_get_cidreq();
 if ($debug) { error_log("6.1 params: $params"); };
 
@@ -727,11 +748,12 @@ if ($formSent && isset($_POST)) {
     }
 
     // the script "exercise_result.php" will take the variable $exerciseResult from the session
-    Session::write('exerciseResult',$exerciseResult);
+    Session::write('exerciseResult', $exerciseResult);
     //Session::write('remind_list', $remind_list);
-    Session::write('exerciseResultCoordinates',$exerciseResultCoordinates);
+    Session::write('exerciseResultCoordinates', $exerciseResultCoordinates);
 
     // if all questions on one page OR if it is the last question (only for an exercise with one question per page)
+
     if (($objExercise->type == ALL_ON_ONE_PAGE || $current_question >= $question_count)) {
 
         if (api_is_allowed_to_session_edit()) {
@@ -816,9 +838,9 @@ if ($question_count != 0) {
 	                }
 	            }
 	        } else {
-	            //Time control is only enabled for ONE PER PAGE
+	            // Time control is only enabled for ONE PER PAGE
 	            if (!empty($exe_id) && is_numeric($exe_id)) {
-	                //Verify if the current test is fraudulent
+	                // Verify if the current test is fraudulent
 	            	$check = ExerciseLib::exercise_time_control_is_valid($exerciseId, $learnpath_id, $learnpath_item_id);
 
 	                if ($check) {
@@ -830,7 +852,8 @@ if ($question_count != 0) {
 	                }
 	            }
 	            if ($objExercise->review_answers) {
-	            	header('Location: '.$urlMainExercise.'exercise_reminder.php?'.$params);
+	            	//header('Location: '.$urlMainExercise.'exercise_reminder.php?'.$params);
+                    header("Location: ".$urlMainExercise."exercise_result.php?".api_get_cidreq()."&exe_id=$exe_id&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
 	            	exit;
 	            } else {
 	            	header("Location: ".$urlMainExercise."exercise_result.php?".api_get_cidreq()."&exe_id=$exe_id&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
@@ -1013,7 +1036,7 @@ if ($reminder == 2)  {
         }
     } else {
     	if ($objExercise->review_answers) {
-            if ($debug) { error_log('. redirecting to exercise_reminder.php '); }
+            if ($debug) { error_log('Redirecting to exercise_reminder.php '); }
 	    	header("Location: ".$urlMainExercise."exercise_reminder.php?$params");
 	    	exit;
     	}
@@ -1066,6 +1089,8 @@ if (!empty($error)) {
         $onsubmit = "onsubmit=\"return validateFlashVar('" . $number_of_hotspot_questions . "', '" . get_lang('HotspotValidateError1') . "', '" . get_lang('HotspotValidateError2') . "');\"";
     }
 
+    echo $objExercise->returnWarningJs(null);
+
     echo '<script>
             $(function() {
     		    $(".main_question").mouseover(function() {
@@ -1088,14 +1113,30 @@ if (!empty($error)) {
 
             function previous_question_and_save(previous_question_id, question_id_to_save) {
                 url = "'.$urlMainExercise.'exercise_submit.php?'.$params.'&num="+previous_question_id;
-                //Save the current question
+                // Save the current question.
                 save_now(question_id_to_save, url);
             }
 
-            function save_question_list(question_list) {
+            function save_question_list(question_list, showWarning) {
+
+                if (showWarning == 1) {
+                    $("#dialog-confirm").data("question_list", question_list);
+                    $("#dialog-confirm").dialog("open");
+                } else {
+                    saveQuestionList(question_list);
+                }
+            }
+
+            function saveQuestionList(question_list) {
+                var redirect = true;
+
                 $.each(question_list, function(key, question_id) {
-                    save_now(question_id, null, false);
+                    result = save_now(question_id, null, false, 0);
+                    if (result == "answer_required") {
+                        redirect = false;
+                    }
                 });
+
                 var url = "";
                 if ('.$reminder.' == 1 ) {
                     url = "'.$urlMainExercise.'exercise_reminder.php?'.$params.'&num='.$current_question.'";
@@ -1105,14 +1146,31 @@ if (!empty($error)) {
                     url = "'.$urlMainExercise.'exercise_submit.php?'.$params.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'";
                 }
                 //$("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('save.png', get_lang('Saved'), array(), ICON_SIZE_SMALL)).'");
-                window.location = url;
+
+                if (redirect) {
+                    window.location = url;
+                }
             }
 
-            function save_now(question_id, url_extra, redirect) {
+            function save_now(question_id, url_extra, redirect, showWarning) {
                 if (redirect == undefined) {
                     redirect = true;
                 }
 
+                var result = false;
+                if (showWarning == 1) {
+                    $("#dialog-confirm").data("question_id", question_id);
+                    $("#dialog-confirm").data("url_extra", url_extra);
+                    $("#dialog-confirm").data("redirect", redirect);
+                    $("#dialog-confirm").dialog("open");
+                } else {
+                    result = saveNow(question_id, url_extra, redirect);
+                }
+                return result;
+            }
+
+            function saveNow(question_id, url_extra, redirect)
+            {
            		//1. Normal choice inputs
            		var my_choice = $(\'*[name*="choice[\'+question_id+\']"]\').serialize();
 
@@ -1140,17 +1198,15 @@ if (!empty($error)) {
            		// Only for the first time
 
           		$("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('loading1.gif')).'");
+          		var mainResult = false;
 
                 $.ajax({
                     type:"post",
                     async: false,
-                    beforeSend: function ( xhr ) {
-                         $("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('loading1.gif')).'");
-
-                    },
                     url: "'.api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?a=save_exercise_by_now",
                     data: "'.$params.'&type=simple&question_id="+question_id+"&"+my_choice+"&"+hotspot+"&"+remind_list,
                     success: function(return_value) {
+                        mainResult =  return_value;
                         if (return_value == "ok") {
                             $("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('save.png', get_lang('Saved'), array(), ICON_SIZE_SMALL)).'");
                         } else if (return_value == "error") {
@@ -1160,6 +1216,7 @@ if (!empty($error)) {
                             " ".get_lang('SelectAnAnswerToContinue')).'");
                         } else if (return_value == "one_per_page") {
                             var url = "";
+                            // Redirect to reminder
                             if ('.$reminder.' == 1 ) {
                                 url = "'.$urlMainExercise.'exercise_reminder.php?'.$params.'&num='.$current_question.'";
                             } else if ('.$reminder.' == 2 ) {
@@ -1173,7 +1230,6 @@ if (!empty($error)) {
                             }
 
                             $("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('save.png', get_lang('Saved'), array(), ICON_SIZE_SMALL)).'");
-
                             if (redirect) {
                                 window.location = url;
                             }
@@ -1183,7 +1239,8 @@ if (!empty($error)) {
                         $("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('error.png', get_lang('Error'), array(), ICON_SIZE_SMALL)).'");
                     }
                 });
-                return false;
+
+                return mainResult;
             }
 
             function save_now_all(validate) {
@@ -1266,8 +1323,8 @@ if (!empty($error)) {
      <input type="hidden" name="learnpath_item_id" 		value="'.$learnpath_item_id . '" />
      <input type="hidden" name="learnpath_item_view_id" value="'.$learnpath_item_view_id . '" />';
     $objExercise->renderQuestionList($questionList, $current_question, $exerciseResult, $attempt_list, $remind_list);
-
     echo '</form>';
+    echo $objExercise->returnWarningHtml();
 }
 
 if ($origin != 'learnpath') {

+ 31 - 19
main/exercice/overview.php

@@ -49,19 +49,31 @@ $time_control = false;
 $clock_expired_time = ExerciseLib::get_session_time_control_key($objExercise->id, $learnpath_id, $learnpath_item_id);
 
 if ($objExercise->expired_time != 0 && !empty($clock_expired_time)) {
-	$time_control = true;
+    $time_control = true;
 }
 
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
+
+$exercise_stat_info = $objExercise->getStatTrackExerciseInfo($learnpath_id, $learnpath_item_id, 0);
+
 if ($time_control) {
     // Get time left for expiring time
-    $time_left = api_strtotime($clock_expired_time,'UTC') - time();
+    $time_left = api_strtotime($clock_expired_time, 'UTC') - time();
 
-	$htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/stylesheet/jquery.epiclock.css');
+    $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/stylesheet/jquery.epiclock.css');
     $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/renderers/minute/epiclock.minute.css');
     $htmlHeadXtra[] = api_get_js('epiclock/javascript/jquery.dateformat.min.js');
     $htmlHeadXtra[] = api_get_js('epiclock/javascript/jquery.epiclock.min.js');
     $htmlHeadXtra[] = api_get_js('epiclock/renderers/minute/epiclock.minute.js');
-	$htmlHeadXtra[] = $objExercise->show_time_control_js($time_left);
+    $htmlHeadXtra[] = $objExercise->show_time_control_js($time_left);
+    $htmlHeadXtra[] = '<script>
+
+    function final_submit() {
+        var lp_data = $.param({"learnpath_id": '.intval($learnpath_id).', "learnpath_item_id" : '.intval($learnpath_item_id).', "learnpath_item_view_id": '.intval($learnpath_item_view_id).'});
+        var url = "'.$urlMainExercise.'exercise_result.php?'.api_get_cidreq().'&origin='.$origin.'&exe_id='.$exercise_stat_info['exe_id'].'&";
+        window.location = url ;
+    }
+    </script>';
 }
 
 if ($origin != 'learnpath') {
@@ -73,11 +85,11 @@ if ($origin != 'learnpath') {
 $html = '';
 $message = '';
 
-$is_allowed_to_edit = api_is_allowed_to_edit(null,true);
+$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
 $edit_link = '';
 if ($is_allowed_to_edit) {
     $url = api_get_path(WEB_CODE_PATH).'exercice/admin.php?'.api_get_cidreq().'&id_session='.api_get_session_id().'&exerciseId='.$objExercise->id;
-	$edit_link = Display::url(Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL), $url);
+    $edit_link = Display::url(Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL), $url);
 }
 
 //Exercise name
@@ -93,7 +105,6 @@ if (isset($_GET['preview'])) {
     $extra_params = '&preview=1';
 }
 
-$exercise_stat_info = $objExercise->getStatTrackExerciseInfo($learnpath_id, $learnpath_item_id, 0);
 $attempt_list = null;
 if (isset($exercise_stat_info['exe_id'])) {
     $attempt_list = getAllExerciseEventByExeId($exercise_stat_info['exe_id']);
@@ -103,11 +114,11 @@ if (isset($exercise_stat_info['exe_id'])) {
 $label = get_lang('StartTest');
 
 if ($time_control && !empty($clock_expired_time) || !empty($attempt_list)) {
-	$label = get_lang('ContinueTest');
+    $label = get_lang('ContinueTest');
 }
 
 if (!empty($attempt_list)) {
-	$message = Display::return_message(get_lang('YouTriedToResolveThisExerciseEarlier'));
+    $message = Display::return_message(get_lang('YouTriedToResolveThisExerciseEarlier'));
 }
 
 //2. Exercise button
@@ -159,9 +170,10 @@ if (!empty($attempts)) {
 		if ($attempt_result['attempt_revised'] == 0) {
 			$teacher_revised = Display::label(get_lang('NotValidated'), 'info');
 		}
-		$row = array('count'	 	=> $i,
-					 'date'	 		=> api_convert_and_format_date($attempt_result['start_date'], DATE_TIME_FORMAT_LONG)
-				);
+		$row = array(
+            'count'	 	=> $i,
+             'date'	 		=> api_convert_and_format_date($attempt_result['start_date'], DATE_TIME_FORMAT_LONG)
+        );
 		$attempt_link .= "&nbsp;&nbsp;&nbsp;".$teacher_revised;
 
 		if (in_array($objExercise->results_disabled, array(RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS, RESULT_DISABLE_SHOW_SCORE_ONLY, RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES))) {
@@ -191,13 +203,13 @@ if (!empty($attempts)) {
 			break;
 	}
 	$column = 0;
-	foreach ($header_names as $item) {
-		$table->setHeaderContents(0, $column, $item);
-		$column++;
-	}
+    foreach ($header_names as $item) {
+        $table->setHeaderContents(0, $column, $item);
+        $column++;
+    }
 	$row = 1;
-	if (!empty($my_attempt_array)) {
-		foreach ($my_attempt_array as $data) {
+    if (!empty($my_attempt_array)) {
+        foreach ($my_attempt_array as $data) {
 			$column = 0;
 			$table->setCellContents($row, $column, $data);
 			$class = 'class="row_odd"';
@@ -232,7 +244,7 @@ if ($time_control) {
     $html.= $objExercise->returnTimeLeftDiv();
 }
 
-$html .=  $message;
+$html .= $message;
 
 if (!empty($exercise_url_button)) {
     $html .=  Display::div(Display::div($exercise_url_button, array('class'=>'exercise_overview_options span12')), array('class'=>' row'));