diff --git a/mod/scorm/README.txt b/mod/scorm/README.txt
index d27630a4058..25fe1dd8738 100644
--- a/mod/scorm/README.txt
+++ b/mod/scorm/README.txt
@@ -3,7 +3,7 @@ SCORM Module by Roberto "Bobo" Pinna
This module is a SCORM player that import SCORM packages in .zip or .pif format
(they are the same thing).
At this time the SCORM module import packages in SCORM1.2, SCORM1.3 (aka SCORM2004) and AICC.
-It plays SCORM1.2 and launch AICC packages.
+The SCORM 1.3 support still under development use it carefully.
Moodle SCORM Module is SCORM Version 1.2 Run-Time Environment Conformant -
Minimum with All Optional Data Model Elements (LMS-RTE3)
@@ -12,21 +12,30 @@ SCORM MODULE IS JAVA FREE.
================================================================
+FIX TO DO:
+Autocontinue & nav.event call
+
+================================================================
+
ROAD MAP
Moodle 1.6
-A popup window display mode. DONE (needs some javascript fixing)
-New Moodle course format: SCORM. DONE (needs to check CSS)
-Complete AICC conformance.
+A popup window display mode. DONE
+New Moodle course format: SCORM. DONE
Add prerequisites support to SCORM 1.2. DONE
+Customizable player page. DONE
+Multiple attempt management.
+Complete AICC conformance.
+
Moodle 1.7
+Customizable detailed report page.
Complete conformity to SCORM 2004 RTE.
Support of SCORM 2004's sequencing and navigation.
New package validation subsystem.
Moodle 2.0
-Many GREAT new features that NOW we can't think about.
+The BIG Boh?!
================================================================
@@ -72,4 +81,4 @@ loadSCO.php |
================================================================
-Updated to April 19 2005
+Updated January 9th 2006
diff --git a/mod/scorm/aicc.php b/mod/scorm/aicc.php
index 1a51feefd2d..6c61e6b525a 100755
--- a/mod/scorm/aicc.php
+++ b/mod/scorm/aicc.php
@@ -24,18 +24,8 @@
if (isset($SESSION->scorm_status)) {
$status = $SESSION->scorm_status;
}
- if (isset($SESSION->newattempt)) {
- $newattempt = $SESSION->newattempt;
- $SESSION->newattempt = '';
- } else {
- $newattempt = '';
- }
- if ($lastattempt = get_record('scorm_scoes_track', 'userid', $USER->id, 'scorm', $scorm->id, 'scoid', $scoid,'max(attempt) as a')) {
- if ($newattempt == 'new') {
- $attempt = $lastattempt->a + 1;
- } else {
- $attempt = $lastattempt->a;
- }
+ if (isset($SESSION->attempt)) {
+ $attempt = $SESSION->attempt;
} else {
$attempt = 1;
}
@@ -58,7 +48,7 @@
if ($status != 'Running') {
echo "error = 101\nerror_text = Terminated\n";
} else {
- if ($usertrack=scorm_get_tracks($scoid,$USER->id)) {
+ if ($usertrack=scorm_get_tracks($scoid,$USER->id,$attempt)) {
$userdata = $usertrack;
} else {
$userdata->status = '';
diff --git a/mod/scorm/api.php b/mod/scorm/api.php
index e416ba6c54f..c8afcb41edd 100644
--- a/mod/scorm/api.php
+++ b/mod/scorm/api.php
@@ -7,7 +7,7 @@
$a = optional_param('a', '', PARAM_INT); // scorm ID
$scoid = required_param('scoid', '', PARAM_INT); // sco ID
$mode = optional_param('mode', '', PARAM_ALPHA); // navigation mode
- $attempt = optional_param('attempt', '', PARAM_ALPHA); // new attempt
+ $attempt = required_param('attempt', '', PARAM_INT); // new attempt
if (!empty($id)) {
if (! $cm = get_record("course_modules", "id", $id)) {
@@ -35,7 +35,7 @@
require_login($course->id, false, $cm);
- if ($usertrack=scorm_get_tracks($scoid,$USER->id)) {
+ if ($usertrack=scorm_get_tracks($scoid,$USER->id,$attempt)) {
$userdata = $usertrack;
} else {
$userdata->status = '';
@@ -78,7 +78,6 @@
?>
var errorCode = "0";
-
function underscore(str) {
return str.replace(/\./g,"__");
}
diff --git a/mod/scorm/datamodel.php b/mod/scorm/datamodel.php
index 24f92cc910d..5e3b1f8f160 100755
--- a/mod/scorm/datamodel.php
+++ b/mod/scorm/datamodel.php
@@ -5,7 +5,7 @@
$id = optional_param('id', '', PARAM_INT); // Course Module ID, or
$a = optional_param('a', '', PARAM_INT); // scorm ID
$scoid = required_param('scoid', '', PARAM_INT); // sco ID
- $newattempt = optional_param('attempt', '', PARAM_ALPHA); // new attempt ?
+ $attempt = required_param('attempt', '', PARAM_INT); // attempt number
if (!empty($id)) {
if (! $cm = get_record("course_modules", "id", $id)) {
@@ -32,19 +32,10 @@
}
require_login($course->id, false, $cm);
-
+
if (confirm_sesskey() && (!empty($scoid))) {
$result = true;
if (isstudent($course->id) || (isteacher($course->id) && !isadmin())) {
- if ($lastattempt = get_record('scorm_scoes_track', 'userid', $USER->id, 'scorm', $scorm->id, 'scoid', $scoid,'max(attempt) as a')) {
- if ($newattempt == 'new') {
- $attempt = $lastattempt->a + 1;
- } else {
- $attempt = $lastattempt->a;
- }
- } else {
- $attempt = 1;
- }
foreach ($_POST as $element => $value) {
if (substr($element,0,3) == 'cmi') {
$element = str_replace('__','.',$element);
diff --git a/mod/scorm/datamodels/scorm1_2.js.php b/mod/scorm/datamodels/scorm1_2.js.php
index 790d0451f6b..baba1dea3f6 100644
--- a/mod/scorm/datamodels/scorm1_2.js.php
+++ b/mod/scorm/datamodels/scorm1_2.js.php
@@ -196,13 +196,13 @@ function SCORMapi1_2() {
result = StoreData(cmi,true);
if (nav.event != '') {
if (nav.event == 'continue') {
- setTimeout('top.nextSCO();',500);
+ setTimeout('top.document.location=top.next;',500);
} else {
- setTimeout('top.prevSCO();',500);
+ setTimeout('top.document.location=top.prev;',500);
}
} else {
if (auto ?> == 1) {
- setTimeout('top.nextSCO();',500);
+ setTimeout('top.document.location=top.next;',500);
}
}
return "true";
@@ -528,13 +528,9 @@ function SCORMapi1_2() {
} else {
datastring = CollectData(data,'cmi');
}
+ datastring += '&attempt=';
datastring += '&scoid=id ?>';
-
- //popupwin(datastring);
+
var myRequest = NewHttpReq();
result = DoRequest(myRequest,"wwwroot) ?>/mod/scorm/datamodel.php","id=&sesskey=sesskey) ?>"+datastring);
results = result.split('\n');
diff --git a/mod/scorm/locallib.php b/mod/scorm/locallib.php
index 38e25672c55..9468fe1c904 100755
--- a/mod/scorm/locallib.php
+++ b/mod/scorm/locallib.php
@@ -256,9 +256,9 @@ function scorm_eval_prerequisites($prerequisites,$usertracks) {
}
-function scorm_insert_track($userid,$scormid,$scoid,$element,$value) {
+function scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value) {
$id = null;
- if ($track = get_record_select('scorm_scoes_track',"userid='$userid' AND scormid='$scormid' AND scoid='$scoid' AND element='$element'")) {
+ if ($track = get_record_select('scorm_scoes_track',"userid='$userid' AND scormid='$scormid' AND scoid='$scoid' AND attempt='$attempt' AND element='$element'")) {
$track->value = $value;
$track->timemodified = time();
$id = update_record('scorm_scoes_track',$track);
@@ -266,6 +266,7 @@ function scorm_insert_track($userid,$scormid,$scoid,$element,$value) {
$track->userid = $userid;
$track->scormid = $scormid;
$track->scoid = $scoid;
+ $track->attempt = $attempt;
$track->element = $element;
$track->value = addslashes($value);
$track->timemodified = time();
@@ -348,8 +349,9 @@ function scorm_grade_user($scoes, $userid, $grademethod=VALUESCOES) {
return '';
}
+ $attempt = scorm_get_last_attempt(current($scoes)->scorm, $userid);
foreach ($scoes as $sco) {
- if ($userdata=scorm_get_tracks($sco->id, $userid)) {
+ if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {
if (($userdata->status == 'completed') || ($userdata->status == 'passed')) {
$scores->scoes++;
}
@@ -384,13 +386,14 @@ function scorm_count_launchable($scormid,$organization) {
return count_records_select('scorm_scoes',"scorm=$scormid AND organization='$organization' AND launch<>''");
}
-function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='normal',$play=false) {
+function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false) {
global $CFG;
$strexpand = get_string('expcoll','scorm');
$result = new stdClass();
$result->toc = "
\n";
+ $tocmenus = array();
$result->prerequisites = true;
$incomplete = false;
$organizationsql = '';
@@ -398,25 +401,26 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
if (!empty($currentorg)) {
if (($organizationtitle = get_field('scorm_scoes','title','scorm',$scorm->id,'identifier',$currentorg)) != '') {
$result->toc .= "\t- $organizationtitle
\n";
+ $tocmenus[] = $organizationtitle;
}
$organizationsql = "AND organization='$currentorg'";
}
+ if (empty($attempt)) {
+ $attempt = scorm_get_last_attempt($scorm->id, $user->id);
+ }
+ $result->attemptleft = $scorm->maxattempt - $attempt;
if ($scoes = get_records_select('scorm_scoes',"scorm='$scorm->id' $organizationsql order by id ASC")){
$usertracks = array();
- $maxattempt = 0;
foreach ($scoes as $sco) {
if (!empty($sco->launch)) {
- if ($usertrack=scorm_get_tracks($sco->id,$user->id)) {
+ if ($usertrack=scorm_get_tracks($sco->id,$user->id,$attempt)) {
if ($usertrack->status == '') {
$usertrack->status = 'notattempted';
}
- $attempt = scorm_get_last_attempt($sco->id, $user->id);
- $maxattempt = $attempt > $maxattempt ? $attempt : $maxattempt;
$usertracks[$sco->identifier] = $usertrack;
}
}
}
- $result->attemptleft = $scorm->maxattempt - $maxattempt;
$level=0;
$sublist=1;
@@ -508,7 +512,9 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
if ($sco->id == $scoid) {
$result->prerequisites = true;
}
- $result->toc .= ' '.$startbold.''.format_string($sco->title).''.$score.$endbold."\n";
+ $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'¤torg='.$currentorg.'&mode='.$mode.'&scoid='.$sco->id;
+ $result->toc .= ' '.$startbold.''.format_string($sco->title).''.$score.$endbold."\n";
+ $tocmenus[$sco->id] = scorm_repeater('−',$level) . '>' . format_string($sco->title);
} else {
if ($sco->id == $scoid) {
$result->prerequisites = false;
@@ -540,12 +546,15 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
}
$result->toc .= "\t
\n";
+ $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'¤torg='.$currentorg.'&mode='.$mode.'&scoid=';
+ $result->tocmenu = popup_form($url,$tocmenus, "tocmenu", $sco->id, '', '', '', true);
+
return $result;
}
-function scorm_get_last_attempt($scoid, $userid) {
-/// Find the last attempt number for the given user id and sco
- if ($lastattempt = get_record('scorm_scoes_track', 'userid', $userid, 'scoid', $scoid, '', '', 'max(attempt) as a')) {
+function scorm_get_last_attempt($scormid, $userid) {
+/// Find the last attempt number for the given user id and scorm id
+ if ($lastattempt = get_record('scorm_scoes_track', 'userid', $userid, 'scormid', $scormid, '', '', 'max(attempt) as a')) {
if (empty($lastattempt->a)) {
return '1';
} else {
@@ -554,11 +563,18 @@ function scorm_get_last_attempt($scoid, $userid) {
}
}
-function scorm_get_tracks($scoid,$userid) {
+function scorm_get_tracks($scoid,$userid,$attempt='') {
/// Gets all tracks of specified sco and user
global $CFG;
- $attemptsql = ' AND attempt=' . scorm_get_last_attempt($scoid, $userid);
+ if (empty($attempt)) {
+ if ($scormid = get_field('scorm_scoes','scorm','id',$scoid)) {
+ $attempt = scorm_get_last_attempt($scormid,$userid);
+ } else {
+ $attempt = 1;
+ }
+ }
+ $attemptsql = ' AND attempt=' . $attempt;
if ($tracks = get_records_select('scorm_scoes_track',"userid=$userid AND scoid=$scoid".$attemptsql,'element ASC')) {
$usertrack->userid = $userid;
$usertrack->scoid = $scoid;
@@ -1021,6 +1037,156 @@ function scorm_parse_scorm($pkgdir,$scormid) {
return $launch;
}
+function scorm_course_format_display($user,$course) {
+ global $CFG;
+
+ $strupdate = get_string('update');
+ $strmodule = get_string('modulename','scorm');
+
+ echo '';
+ if ($scorms = get_all_instances_in_course('scorm', $course)) {
+ // The module SCORM activity with the least id is the course
+ $scorm = current($scorms);
+ if (! $cm = get_coursemodule_from_instance('scorm', $scorm->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+ $colspan = '';
+ $headertext = '
'.get_string('name').': '.format_string($scorm->name).'';
+ if (isteacher($course->id, $user->id, true)) {
+ if (isediting($course->id)) {
+ // Display update icon
+ $path = $CFG->wwwroot.'/course';
+ $headertext .= ''.
+ ''.
+ ' ';
+ }
+ $headertext .= ' | ';
+ // Display report link
+ $trackedusers = get_record('scorm_scoes_track', 'scormid', $scorm->id, '', '', '', '', 'count(distinct(userid)) as c');
+ if ($trackedusers->c > 0) {
+ $headertext .= ''.
+ ''.
+ get_string('viewallreports','scorm',$trackedusers->c).'';
+ } else {
+ $headertext .= ' | '.get_string('noreports','scorm');
+ }
+ $colspan = ' colspan="2"';
+ }
+ $headertext .= ' |
'.format_text(get_string('summary').': '.$scorm->summary).' |
';
+ print_simple_box($headertext,'','100%');
+ scorm_view_display($user, $scorm, 'view.php?id='.$course->id, $cm);
+ } else {
+ if (isteacheredit($course->id, $user->id)) {
+ // Create a new activity
+ redirect('mod.php?id='.$course->id.'§ion=0&sesskey='.sesskey().'&add=scorm');
+ } else {
+ notify('Could not find a scorm course here');
+ }
+ }
+ echo '
';
+}
+
+function scorm_view_display ($user, $scorm, $action, $cm) {
+ global $CFG;
+
+ $organization = optional_param('organization', '', PARAM_INT);
+
+ print_simple_box_start('center','100%');
+?>
+
+launch;
+ }
+ if ($orgs = get_records_select_menu('scorm_scoes',"scorm='$scorm->id' AND organization='' AND launch=''",'id','id,title')) {
+ if (count($orgs) > 1) {
+ ?>
+
+
+
+
+organization == '') && ($org->launch == '')) {
+ $orgidentifier = $org->identifier;
+ } else {
+ $orgidentifier = $org->organization;
+ }
+ }
+ $result = scorm_get_toc($user,$scorm,'structlist',$orgidentifier);
+ $incomplete = $result->incomplete;
+ echo $result->toc;
+ print_simple_box_end();
+?>
+
+
+
+
+maxgrade)) {
$form->maxgrade = '';
}
+ if (empty($form->maxattempt)) {
+ $form->maxattempt = '1';
+ }
if (empty($form->grademethod)) {
$form->grademethod = '0';
}
@@ -229,6 +232,18 @@
?>
+
+ | : |
+
+ =1; $i--) {
+ $attempts[$i] = $i;
+ }
+ choose_from_menu($attempts, 'maxattempt', $form->maxattempt, '','','0',false);
+ helpbutton('maxattempt', get_string('maximumattempts'), 'scorm');
+ ?>
+ |
+
|
@@ -273,8 +288,9 @@
|
hidetoc, '');
?>
|
diff --git a/mod/scorm/player.php b/mod/scorm/player.php
index fd1cf629a2d..2f9108d909e 100755
--- a/mod/scorm/player.php
+++ b/mod/scorm/player.php
@@ -13,19 +13,7 @@
$scoid = required_param('scoid', '', PARAM_INT); // sco ID
$mode = optional_param('mode', '', PARAM_ALPHA); // navigation mode
$currentorg = optional_param('currentorg', '', PARAM_RAW); // selected organization
-
- $modestring = '';
- $scoidstring = '';
- $currentorgstring = '';
- if (!empty($mode)) {
- $modestring = '&mode='.$mode;
- }
- if (!empty($scoid)) {
- $scoidstring = '&scoid='.$scoid;
- }
- if (!empty($currentorg)) {
- $currentorgstring = '¤torg='.$currentorg;
- }
+ $newattempt = optional_param('newattempt', 'off', PARAM_ALPHA); // the user request to start a new attempt
if (!empty($id)) {
if (! $cm = get_record("course_modules", "id", $id)) {
@@ -77,16 +65,27 @@
//
// TOC processing
//
- $result = scorm_get_toc($USER,$scorm,'structurelist',$currentorg,$scoid,$mode,true);
+ $attempt = scorm_get_last_attempt($scorm->id, $USER->id);
+ if (($newattempt=='on') && ($attempt < $scorm->maxattempt)) {
+ $attempt++;
+ if ($mode == 'review') {
+ $mode = 'normal';
+ }
+ }
+ $attemptstr = '&attempt=' . $attempt;
+
+ $result = scorm_get_toc($USER,$scorm,'structurelist',$currentorg,$scoid,$mode,$attempt,true);
$sco = $result->sco;
if (($mode == 'browse') && ($scorm->hidebrowse == 1)) {
$mode = 'normal';
}
- if ($mode == 'normal') {
- if ($trackdata = scorm_get_tracks($USER->id,$sco->id)) {
+ if (($mode == 'normal') || ($mode == 'review')) {
+ if ($trackdata = scorm_get_tracks($sco->id,$USER->id,$attempt)) {
if (($trackdata->status == 'completed') || ($trackdata->status == 'passed') || ($trackdata->status == 'failed')) {
$mode = 'review';
+ } else {
+ $mode = 'normal';
}
}
}
@@ -97,14 +96,11 @@
$scoidpop = '&scoid='.$sco->id;
$modestr = '&mode='.$mode;
$modepop = '&mode='.$mode;
- $attemptstr = '';
- if ((!$result->incomplete) && ($result->attemptleft > 0)) {
- $attemptstr = '&attempt=new';
- }
$SESSION->scorm_scoid = $sco->id;
$SESSION->scorm_status = 'Not Initialized';
$SESSION->scorm_mode = $mode;
+ $SESSION->attempt = $attempt;
//
// Print the page header
@@ -149,6 +145,15 @@
?>
>
previd != 0) && ($sco->previous == 0)) {
+ $scostr = '&scoid='.$sco->previd;
+ echo '';
+ }
+ if (($sco->nextid != 0) && ($sco->next == 0)) {
+ $scostr = '&scoid='.$sco->nextid;
+ echo '';
+ }
// This very big test check if is necessary the "scormtop" div
if (
($mode != 'normal') || // We are not in normal mode so review or browse text will displayed
@@ -162,7 +167,8 @@
(
($sco->nextid != 0) && // This is not the last learning object of the package
($sco->next == 0) // Moodle must manage the next link
- )
+ ) ||
+ ($scorm->hidetoc == 2) // Teacher want to display toc in a small popup menu
)
)
) {
@@ -179,14 +185,17 @@
if (($sco->previd != 0) && ($sco->previous == 0)) {
/// Print the prev LO link
$scostr = '&scoid='.$sco->previd;
- $prevlink = $CFG->wwwroot.'/mod/scorm/player.php?id='.$cm->id.$orgstr.$modestr.$scostr;
- echo '
< '.get_string('prev','scorm').'';
+ $url = $CFG->wwwroot.'/mod/scorm/player.php?id='.$cm->id.$orgstr.$modestr.$scostr;
+ echo '
< '.get_string('prev','scorm').'';
+ }
+ if ($scorm->hidetoc == 2) {
+ echo $result->tocmenu;
}
if (($sco->nextid != 0) && ($sco->next == 0)) {
/// Print the next LO link
$scostr = '&scoid='.$sco->nextid;
- $nextlink = $CFG->wwwroot.'/mod/scorm/player.php?id='.$cm->id.$orgstr.$modestr.$scostr;
- echo '
'.get_string('next','scorm').' >';
+ $url = $CFG->wwwroot.'/mod/scorm/player.php?id='.$cm->id.$orgstr.$modestr.$scostr;
+ echo '
'.get_string('next','scorm').' >';
}
?>
diff --git a/mod/scorm/request.js b/mod/scorm/request.js
index 1d1f74fc17c..a087b2055ca 100644
--- a/mod/scorm/request.js
+++ b/mod/scorm/request.js
@@ -24,21 +24,22 @@ function NewHttpReq() {
function DoRequest(httpReq,url,param) {
// httpReq.open (Method("get","post"), URL(string), Asyncronous(true,false))
-
+ //popupwin(url+"\n"+param);
httpReq.open("POST", url,false);
httpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- httpReq.send(param);
+ httpReq.send(param)
if (httpReq.status == 200) {
+ //popupwin(url+"\n"+param+"\n"+httpReq.responseText);
return httpReq.responseText;
} else {
return httpReq.status;
}
}
-/*function popupwin(content) {
+function popupwin(content) {
var op = window.open();
op.document.open('text/plain');
op.document.write(content);
op.document.close();
-}*/
-//-->
\ No newline at end of file
+}
+//-->
diff --git a/mod/scorm/view.php b/mod/scorm/view.php
index d104163982b..414daa66106 100755
--- a/mod/scorm/view.php
+++ b/mod/scorm/view.php
@@ -8,7 +8,7 @@
$id = optional_param('id', '', PARAM_INT); // Course Module ID, or
$a = optional_param('a', '', PARAM_INT); // scorm ID
- $organization = optional_param('organization', '', PARAM_INT); // organization ID
+ //$organization = optional_param('organization', '', PARAM_INT); // organization ID
if (!empty($id)) {
if (! $cm = get_record("course_modules", "id", $id)) {
@@ -79,91 +79,7 @@
print_heading(format_string($scorm->name));
print_simple_box(format_text($scorm->summary), 'center', '70%', '', 5, 'generalbox', 'intro');
-
- print_simple_box_start('center');
-?>
-
-launch;
- }
- if ($orgs = get_records_select_menu('scorm_scoes',"scorm='$scorm->id' AND organization='' AND launch=''",'id','id,title')) {
- if (count($orgs) > 1) {
-?>
-
-
-
-
-organization == '') && ($org->launch == '')) {
- $orgidentifier = $org->identifier;
- } else {
- $orgidentifier = $org->organization;
- }
- }
- $result = scorm_get_toc($USER,$scorm,'structurelist',$orgidentifier);
- $incomplete = $result->incomplete;
- echo $result->toc;
- print_simple_box_end();
- ?>
-
-
-
-
-id, $cm);
print_footer($course);
}
?>