Browse Source

Fix wrong duration time when doing an exercise inside a LP see BT#14149

jmontoyaa 7 years ago
parent
commit
18bfe41a79
2 changed files with 116 additions and 89 deletions
  1. 19 15
      main/exercise/exercise_submit.php
  2. 97 74
      main/inc/ajax/exercise.ajax.php

+ 19 - 15
main/exercise/exercise_submit.php

@@ -1040,6 +1040,15 @@ if (!empty($error)) {
         $onsubmit = "onsubmit=\"return validateFlashVar('".$number_of_hotspot_questions."', '".get_lang('HotspotValidateError1')."', '".get_lang('HotspotValidateError2')."');\"";
     }
 
+    $saveIcon = Display::return_icon(
+        'save.png',
+        get_lang('Saved'),
+        [],
+        ICON_SIZE_SMALL,
+        false,
+        true
+    );
+
     echo '<script>
         function addExerciseEvent(elm, evType, fn, useCapture) {
             if (elm.addEventListener) {
@@ -1059,26 +1068,21 @@ if (!empty($error)) {
                 var saveDurationUrl = "'.$saveDurationUrl.'";
                 // Logout of course just in case
                 $.ajax({
+                    async: false, 
                     url: saveDurationUrl,
                     success: function (data) {
                         calledUpdateDuration = true;
                         return 1;
-                    }
+                    }, 
                 });
+                return 1;
             }
         }
         
         $(function() {
-            //This pre-load the save.png icon
+            // This pre-load the save.png icon
             var saveImage = new Image();
-            saveImage.src = \''.Display::return_icon(
-                'save.png',
-                get_lang('Saved'),
-                [],
-                ICON_SIZE_SMALL,
-                false,
-                true
-            ).'\';
+            saveImage.src = "'.$saveIcon.'";
 
             // Block form submition on enter
             $(".block_on_enter").keypress(function(event) {
@@ -1103,9 +1107,9 @@ if (!empty($error)) {
                 return false;
             });*/
 
-            $(\'form#exercise_form\').prepend($(\'#exercise-description\'));
+            $("form#exercise_form").prepend($("#exercise-description"));
         
-            $(\'button[name="previous_question_and_save"]\').on(\'click\', function (e) {
+            $(\'button[name="previous_question_and_save"]\').on("click", function (e) {
                 e.preventDefault();
                 e.stopPropagation();    
                 var
@@ -1119,8 +1123,8 @@ if (!empty($error)) {
             $(\'button[name="save_question_list"]\').on(\'click\', function (e) {
                 e.preventDefault();
                 e.stopPropagation();
-                var $this = $(this),
-                    questionList = $this.data(\'list\').split(",");
+                var $this = $(this);
+                var questionList = $this.data(\'list\').split(",");
 
                 save_question_list(questionList);
             });
@@ -1144,7 +1148,7 @@ if (!empty($error)) {
             
             // Save attempt duration
             addExerciseEvent(window, \'unload\', updateDuration , false);            
-            addExerciseEvent(window, \'beforeunload\', updateDuration , false);                        
+            addExerciseEvent(window, \'beforeunload\', updateDuration , false);                                    
         });
 
         function previous_question(question_num) {

+ 97 - 74
main/inc/ajax/exercise.ajax.php

@@ -12,9 +12,11 @@ api_protect_course_script(true);
 
 $action = $_REQUEST['a'];
 $course_id = api_get_course_int_id();
-
+$debug = false;
 if ($debug) {
+    error_log("-----------------");
     error_log("$action ajax call");
+    error_log("-----------------");
 }
 
 $session_id = isset($_REQUEST['session_id']) ? intval($_REQUEST['session_id']) : api_get_session_id();
@@ -22,7 +24,6 @@ $course_code = isset($_REQUEST['cidReq']) ? $_REQUEST['cidReq'] : api_get_course
 
 switch ($action) {
     case 'update_duration':
-        $debug = true;
         $exeId = isset($_REQUEST['exe_id']) ? $_REQUEST['exe_id'] : 0;
 
         if (Session::read('login_as')) {
@@ -49,83 +50,99 @@ switch ($action) {
             exit;
         }
 
-        if (!empty($exerciseInSession)) {
-            $em = Database::getManager();
-            /** @var \Chamilo\CoreBundle\Entity\TrackEExercises $attempt */
-            $attempt = $em->getRepository('ChamiloCoreBundle:TrackEExercises')->find($exeId);
-            $onlyUpdateValue = 10;
-            $nowObject = api_get_utc_datetime(null, false, true);
-            $now = $nowObject->getTimestamp();
-            $exerciseId = $attempt->getExeExoId();
-            $userId = $attempt->getExeUserId();
-            $currentUserId = api_get_user_id();
-
-            if ($exerciseInSession->id != $exerciseId) {
-                if ($debug) {
-                    error_log("Cannot update exercise are different.");
-                }
-                exit;
+        // If exercise was updated x seconds before, then don't updated duration.
+        $onlyUpdateValue = 10;
+
+        $em = Database::getManager();
+        /** @var \Chamilo\CoreBundle\Entity\TrackEExercises $attempt */
+        $attempt = $em->getRepository('ChamiloCoreBundle:TrackEExercises')->find($exeId);
+
+        if (empty($attempt)) {
+            if ($debug) {
+                error_log("Attempt #$exeId doesn't exists.");
             }
+            exit;
+        }
 
-            if ($attempt->getStatus() != 'incomplete') {
-                if ($debug) {
-                    error_log("Cannot update exercise is already completed.");
-                }
-                exit;
+        $nowObject = api_get_utc_datetime(null, false, true);
+        $now = $nowObject->getTimestamp();
+        $exerciseId = $attempt->getExeExoId();
+        $userId = $attempt->getExeUserId();
+        $currentUserId = api_get_user_id();
+
+        if ($userId != $currentUserId) {
+            if ($debug) {
+                error_log("User $currentUserId trying to change time for user $userId");
             }
+            exit;
+        }
 
-            // Check if we are dealing with the same exercise.
-            if ($attempt && $userId == $currentUserId) {
-                $timeWithOutUpdate = $now - $attempt->getExeDate()->getTimestamp();
-                if ($timeWithOutUpdate > $onlyUpdateValue) {
-                    $key = ExerciseLib::get_time_control_key(
-                        $exerciseId,
-                        $attempt->getOrigLpId(),
-                        $attempt->getOrigLpItemId()
-                    );
-                    $durationFromObject = $attempt->getExeDuration();
-                    $previousTime = Session::read('duration_time_previous');
-                    if (isset($previousTime[$key]) &&
-                        !empty($previousTime[$key])
-                    ) {
-                        $sessionTime = $previousTime[$key];
-                        $duration = $now - $sessionTime;
-                        if ($debug) {
-                            //error_log("Now in UTC: ".$nowObject->format('Y-m-d H:i:s'));
-                            //error_log("Session time in UTC: ".api_get_utc_datetime($sessionTime));
-                            error_log("Time spent in exercise: $duration just before an update");
-                        }
-                        if (!empty($durationFromObject)) {
-                            $duration += $durationFromObject;
-                        }
-                        $duration = (int) $duration;
-                        if (!empty($duration)) {
-                            if ($debug) {
-                                error_log("Exe_id: #".$exeId);
-                                error_log("Key: $key");
-                                error_log("Exercise to update: #$exerciseId for user: #$userId");
-                                error_log("Accumulate duration to save in DB: $duration");
-                                error_log("End date to save in DB: ".$nowObject->format('Y-m-d H:i:s'));
-                            }
-                            $attempt
-                                ->setExeDuration($duration)
-                                ->setExeDate($nowObject);
-                            $em->merge($attempt);
-                            $em->flush();
-                        }
-                    } else {
-                        if ($debug) {
-                            error_log("Nothing to update, 'duration_time_previous' session not set");
-                            error_log("Key: $key");
-                        }
-                    }
-                } else {
+        if ($exerciseInSession->id != $exerciseId) {
+            if ($debug) {
+                error_log("Cannot update, exercise are different.");
+            }
+            exit;
+        }
+
+        if ($attempt->getStatus() != 'incomplete') {
+            if ($debug) {
+                error_log("Cannot update exercise is already completed.");
+            }
+            exit;
+        }
+
+        // Check if we are dealing with the same exercise.
+        $timeWithOutUpdate = $now - $attempt->getExeDate()->getTimestamp();
+        if ($timeWithOutUpdate > $onlyUpdateValue) {
+            $key = ExerciseLib::get_time_control_key(
+                $exerciseId,
+                $attempt->getOrigLpId(),
+                $attempt->getOrigLpItemId()
+            );
+            $durationFromObject = $attempt->getExeDuration();
+            $previousTime = Session::read('duration_time_previous');
+            if (isset($previousTime[$key]) &&
+                !empty($previousTime[$key])
+            ) {
+                $sessionTime = $previousTime[$key];
+                $duration = $sessionTime = $now - $sessionTime;
+                /*if ($debug) {
+                    error_log("Now in UTC: ".$nowObject->format('Y-m-d H:i:s'));
+                    error_log("Session time in UTC: ".api_get_utc_datetime($sessionTime));
+                }*/
+                if (!empty($durationFromObject)) {
+                    $duration += $durationFromObject;
+                }
+                $duration = (int) $duration;
+                if (!empty($duration)) {
                     if ($debug) {
-                        error_log("Cannot update, latest time diff is just $timeWithOutUpdate seconds");
+                        error_log("Exe_id: #".$exeId);
+                        error_log("Key: $key");
+                        error_log("Exercise to update: #$exerciseId of user: #$userId");
+                        error_log("Duration time found in DB before update: $durationFromObject");
+                        error_log("Current spent time $sessionTime before an update");
+                        error_log("Accumulate duration to save in DB: $duration");
+                        error_log("End date (UTC) before update: ".$attempt->getExeDate()->format('Y-m-d H:i:s'));
+                        error_log("End date (UTC) to be save in DB: ".$nowObject->format('Y-m-d H:i:s'));
                     }
+                    $attempt
+                        ->setExeDuration($duration)
+                        ->setExeDate($nowObject);
+                    $em->merge($attempt);
+                    $em->flush();
                 }
+            } else {
+                if ($debug) {
+                    error_log("Nothing to update, 'duration_time_previous' session not set");
+                    error_log("Key: $key");
+                }
+            }
+        } else {
+            if ($debug) {
+                error_log("Can't update, time was already updated $timeWithOutUpdate seconds ago");
             }
         }
+
         break;
     case 'get_live_stats':
         if (!api_is_allowed_to_edit(null, true)) {
@@ -530,7 +547,7 @@ switch ($action) {
                 // Deleting old attempt
                 if (isset($attemptList) && !empty($attemptList[$my_question_id])) {
                     if ($debug) {
-                        error_log("delete_attempt  exe_id : $exe_id, my_question_id: $my_question_id");
+                        error_log("delete_attempt exe_id : $exe_id, my_question_id: $my_question_id");
                     }
                     Event::delete_attempt(
                         $exe_id,
@@ -592,20 +609,26 @@ switch ($action) {
                 );
 
                 $durationTime = Session::read('duration_time');
-
                 if (isset($durationTime[$key]) && !empty($durationTime[$key])) {
+                    if ($debug) {
+                        error_log('Session time :'.$durationTime[$key]);
+                    }
                     $duration = $now - $durationTime[$key];
                     if (!empty($exercise_stat_info['exe_duration'])) {
                         $duration += $exercise_stat_info['exe_duration'];
                     }
-                    $duration = intval($duration);
+                    $duration = (int) $duration;
                 } else {
                     if (!empty($exercise_stat_info['exe_duration'])) {
                         $duration = $exercise_stat_info['exe_duration'];
                     }
                 }
 
-                Session::write('duration_time', [$key => time()]);
+                if ($debug) {
+                    error_log('duration to save in DB:'.$duration);
+                }
+
+                Session::write('duration_time', [$key => $now]);
 
                 Event::updateEventExercise(
                     $exe_id,