MDL-37733 SCORM: Correct check for force new attempt
authorNiclas Tollstorff <niclastollstorff@gmail.com>
Fri, 31 Jan 2014 18:33:24 +0000 (19:33 +0100)
committerDan Marsden <dan@danmarsden.com>
Sat, 8 Mar 2014 08:22:38 +0000 (21:22 +1300)
mod/scorm/lib.php
mod/scorm/player.php

index 8d7eebe..9fa1994 100644 (file)
@@ -1401,27 +1401,49 @@ function scorm_validate_package($file) {
  * @param int $userid the userid of the user.
  * @param string $mode the current mode that has been selected.
  */
-function scorm_check_mode($scorm, $newattempt, &$attempt, $userid, &$mode) {
+function scorm_check_mode($scorm, &$newattempt, &$attempt, $userid, &$mode) {
     global $DB;
+
+    if (($mode == 'browse')) {
+        if ($scorm->hidebrowse == 1) {
+            // Prevent Browse mode if hidebrowse is set.
+            $mode = 'normal';
+        } else {
+            // We don't need to check attempts as browse mode is set.
+            return;
+        }
+    }
+    // Check if the scorm module is incomplete (used to validate user request to start a new attempt).
+    $incomplete = true;
+    $tracks = $DB->get_recordset('scorm_scoes_track', array('scormid' => $scorm->id, 'userid' => $userid,
+        'attempt' => $attempt, 'element' => 'cmi.core.lesson_status'));
+    foreach ($tracks as $track) {
+        if (($track->value == 'completed') || ($track->value == 'passed') || ($track->value == 'failed')) {
+            $incomplete = false;
+        } else {
+            $incomplete = true;
+            break; // Found an incomplete sco, so the result as a whole is incomplete.
+        }
+    }
+    $tracks->close();
+
+    // Validate user request to start a new attempt.
+    if ($incomplete === true) {
+        // The option to start a new attempt should never have been presented. Force false.
+        $newattempt = 'off';
+    } else if (($attempt !== '1') && !empty($scorm->forcenewattempt)) {
+        // A new attempt should be forced for already completed attempts.
+        $newattempt = 'on';
+    }
+
     if (($newattempt == 'on') && (($attempt < $scorm->maxattempt) || ($scorm->maxattempt == 0))) {
         $attempt++;
         $mode = 'normal';
-    } else if ($mode != 'browse') { // Check if review mode should be set.
-        $mode = 'normal'; // Set to normal mode by default.
-
-        // If all tracks == passed, failed or completed then use review mode.
-        $tracks = $DB->get_recordset('scorm_scoes_track', array('scormid' => $scorm->id, 'userid' => $userid,
-            'attempt' => $attempt, 'element' => 'cmi.core.lesson_status'));
-        foreach ($tracks as $track) {
-            if (($track->value == 'completed') || ($track->value == 'passed') || ($track->value == 'failed')) {
-                $mode = 'review';
-            } else { // Found an incomplete sco so exit and use normal mode.
-                $mode = 'normal';
-                break;
-            }
+    } else { // Check if review mode should be set.
+        if ($incomplete === true) {
+            $mode = 'normal';
+        } else {
+            $mode = 'review';
         }
-        $tracks->close();
-    } else if (($mode == 'browse') && ($scorm->hidebrowse == 1)) { // Prevent Browse mode if hidebrowse is set.
-        $mode = 'normal';
     }
 }
index abe9128..bc584a1 100644 (file)
@@ -54,7 +54,7 @@ if (!empty($id)) {
 // If new attempt is being triggered set normal mode and increment attempt number.
 $attempt = scorm_get_last_attempt($scorm->id, $USER->id);
 
-// Check mode is correct and set mode/attempt (uses pass by reference).
+// Check mode is correct and set/validate mode/attempt/newattempt (uses pass by reference).
 scorm_check_mode($scorm, $newattempt, $attempt, $USER->id, $mode);
 
 $url = new moodle_url('/mod/scorm/player.php', array('scoid'=>$scoid, 'cm'=>$cm->id));