Added data store and reporting
authorbobopinna <bobopinna>
Thu, 28 Apr 2005 07:04:55 +0000 (07:04 +0000)
committerbobopinna <bobopinna>
Thu, 28 Apr 2005 07:04:55 +0000 (07:04 +0000)
mod/scorm/api.php
mod/scorm/datamodel.php
mod/scorm/datamodels/scorm1_2.js.php
mod/scorm/db/mysql.php
mod/scorm/db/postgres7.php
mod/scorm/lib.php
mod/scorm/playscorm.php
mod/scorm/report.php
mod/scorm/request.js
mod/scorm/version.php
mod/scorm/view.php

index a68e3b9..ed09758 100644 (file)
@@ -1,10 +1,12 @@
 <?php
 
     require_once("../../config.php");
+    require_once("lib.php");
 
     optional_variable($id);    // Course Module ID, or
     optional_variable($a);     // scorm ID
-    optional_variable($userid);  // user ID
+    //require_variable($scoid);  // sco ID
+    optional_variable($mode);  // navigation mode
 
     if ($id) {
         if (! $cm = get_record("course_modules", "id", $id)) {
     }
 
     require_login($course->id, false, $cm);
+    $scoid = $SESSION->scorm_scoid;
     
-    if (empty($userid) || !isteacher($course->id)) {
-       $user = $USER;
+    if ($usertrack=scorm_get_tracks($scoid,$USER->id)) {
+       $userdata = $usertrack;
     } else {
-       $user = get_complete_user_data('id', $userid);
+       $userdata->status = '';
+       $userdata->scorre_raw = '';
+    }
+    $userdata->student_id = $USER->username;
+    $userdata->student_name = $USER->lastname .', '. $USER->firstname;
+    $userdata->mode = 'normal';
+    if (isset($mode)) {
+       $userdata->mode = $mode;
+    }
+    if ($sco = get_record('scorm_scoes','id',$scoid)) {
+       $userdata->datafromlms = $sco->datafromlms;
+       $userdata->masteryscore = $sco->masteryscore;
+       $userdata->maxtimeallowed = $sco->maxtimeallowed;
+       $userdata->timelimitaction = $sco->timelimitaction;
+        if (!empty($sco->masteryscore)) {
+           $userdata->credit = 'credit';
+       } else {
+           $userdata->credit = 'no-credit';
+       }    
+    } else {
+       error('Sco not found');
     }
-?>
 
-function SCOFinish(){
-    /*if (typeof API != "undefined") {
-       API.SaveTotalTime();
-    } */
-}
+    switch ($scorm->version) {
+       case 'SCORM_1.2':
+           include_once ('datamodels/scorm1_2.js.php');
+       break;
+       case 'SCORM_1.3':
+           include_once ('datamodels/scorm1_3.js.php');
+       break;
+       case 'AICC':
+           include_once ('datamodels/aicc.js.php');
+       break;
+       default:
+           include_once ('datamodels/scorm1_2.js.php');
+       break;
+    }
+?>
 
-// 
-// SCORM Call Implementation
-//
 var errorCode = "0";
 
-function SCORM_Call (call,param) {
-    if (arguments.length < 2) {
-       alert ("Invalid SCORM_Call function call: too few arguments.\nYou need pass at least 2 parameters");
-    }
-    var myRequest = NewHttpReq();
-    result = DoRequest(myRequest,"<?php p($CFG->wwwroot) ?>/mod/scorm/datamodel.php","id=<?php p($id) ?>&sesskey=<?php p($USER->sesskey) ?>&call="+call+param);
-    //alert('Call: '+call+'\nParam: '+param+'\nResult: '+result);
-    results = result.split('\n');
-    
-    errorCode = results[1];
-    return results[0];
+function underscore(str) {
+    return str.replace(/\./g,"__");
 }
 
-//
-// SCORM 1.2 API Implementation
-//
-function SCORMapi1_2() {
-    
-    <?php include_once ('datamodels/scorm1_2.js.php'); ?>
-    
+function CollectData(apiname,data,parent) {
+    var datastring = '';
+    for (property in data) {
+       if (typeof data[property] == 'object') {
+           datastring += CollectData(apiname,data[property],parent+'.'+property);
+       } else {
+               element = parent+'.'+property;
+               expression = new RegExp(CMIIndex,'g');
+               elementmodel = element.replace(expression,'.n.');
+               if ((typeof eval(apiname+'.datamodel["'+elementmodel+'"]')) != "undefined") {
+                   if (eval(apiname+'.datamodel["'+elementmodel+'"].mod') != 'r') {
+                       if (eval(apiname+'.datamodel["'+elementmodel+'"].defaultvalue') != data[property]) {
+                           datastring += '&'+underscore(element)+'='+escape(data[property]);
+                           //alert(element+'='+data[property]);
+                       }
+                   }
+               }
+       }
+    }
+    return datastring;
 }
 
-var API = new SCORMapi1_2();
+function AddTime (first, second) {
+    var sFirst = first.split(":");
+    var sSecond = second.split(":");
+    var change = 0;
 
-//
-// SCORM 2004 API Implementation
-//
-function SCORMapi2004() {
+    var secs = (Math.round((parseFloat(sFirst[2],10)+parseFloat(sSecond[2],10))*100))/100;  //Seconds
+    change = Math.floor(secs / 60);
+    secs = secs - (change * 60);
+    if (Math.floor(secs) < 10) secs = "0" + secs.toString();
 
-    <?php include_once ('datamodels/scorm1_3.js.php'); ?>
-    
+    mins = parseInt(sFirst[1],10)+parseInt(sSecond[1],10)+change;   //Minutes
+    change = Math.floor(mins / 60);
+    mins = mins - (change * 60);
+    if (mins < 10) mins = "0" + mins.toString();
+
+    hours = parseInt(sFirst[0],10)+parseInt(sSecond[0],10)+change;  //Hours
+    if (hours < 10) hours = "0" + hours.toString();
+
+    return hours + ":" + mins + ":" + secs;
 }
 
-var API_1484_11 = new SCORMapi2004();
+function StoreData(apiname,data,storetotaltime) {
+    datastring = CollectData(apiname,data,'cmi');
+    if (storetotaltime) {
+       datastring += eval(apiname+'.TotalTime();');
+    }
+    //popupwin(datastring);
+    var myRequest = NewHttpReq();
+    result = DoRequest(myRequest,"<?php p($CFG->wwwroot) ?>/mod/scorm/datamodel.php","id=<?php p($id) ?>&sesskey=<?php p($USER->sesskey) ?>"+datastring);
+    results = result.split('\n');
+    //alert(results);
+    errorCode = results[1];
+    return results[0]; 
+}
index 910a4ea..b9c4abb 100755 (executable)
@@ -3,7 +3,7 @@
     require_once('lib.php');
     
     optional_variable($id);    // Course Module ID, or
-    optional_variable($a);     // scorm ID
+    optional_variable($a);     // scorm IDa
 
     if ($id) {
         if (! $cm = get_record('course_modules', 'id', $id)) {
 
     require_login($course->id, false, $cm);
     
-    
-    if (isset($_GET['call']) && confirm_sesskey()) {
-       if (strstr($_GET['call'],'LMS') !== false) {
-           // SCORM 1.2 Call
-           //require_once('datamodels/scorm1_2.php');
+    if (confirm_sesskey() && (isset($SESSION->scorm_scoid))) {
+       $scoid = $SESSION->scorm_scoid;
+       $result = true;
+       foreach ($_GET as $element => $value) {
+           if (substr($element,0,3) == 'cmi') {
+               $element = str_replace('__','.',$element);
+               $element = preg_replace('/_(\d+)/',".\$1",$element);
+               if ($track = get_record_select('scorm_scoes_track',"userid='$USER->id' AND scormid='$scorm->id' AND scoid='$scoid' AND element='$element'")) {
+                   $track->value = $value;
+                   $result = update_record('scorm_scoes_track',$track) && $result;
+               } else {
+                   $track->userid = $USER->id;
+                   $track->scormid = $scorm->id;
+                   $track->scoid = $scoid;
+                   $track->element = $element;
+                   $track->value = $value;
+                   $result = insert_record('scorm_scoes_track',$track) && $result;
+               }
+               //print_r($track);
+           }
+       }
+       if ($result) {
+           echo "true\n0";
        } else {
-           // SCORM 1.3 (aka SCORM 2004) Call
-           //require_once('datamodels/scorm1_3.php');
+           echo "false\n101";
        }
     }
 ?>
index d4dbea7..a5df0b5 100644 (file)
@@ -1,3 +1,20 @@
+<?php
+    if (isset($userdata->status)) {
+       if ($userdata->status == '') {
+           $userdata->entry = 'ab-initio';
+       } else {
+           if (isset($userdata->{'cmi.core.exit'}) && ($userdata->{'cmi.core.exit'} == 'suspend')) {
+               $userdata->entry = 'resume';
+           } else {
+               $userdata->entry = '';          
+           }
+       }
+    }
+?>
+//
+// SCORM 1.2 API Implementation
+//
+function SCORMapi1_2() {
     // Standard Data Type Definition
     CMIString255 = '^.{0,255}$';
     CMIString4096 = '^[.|\\n|\\r]{0,4096}$';
@@ -5,7 +22,8 @@
     CMITimespan = '^([0-9]{2,4}):([0-9]{2}):([0-9]{2})(\.[0-9]{1,2})?$';
     CMIInteger = '^\\d+$';
     CMISInteger = '^-?([0-9]+)$';
-    CMIDecimal = '^[0-9]?(\.[0-9]{1,2})?$';
+    //CMIDecimal = '^([0-9]{0,3})?(\.[0-9]{1,2})?$';
+    CMIDecimal = '^([0-9]{0,3})(\.[0-9]{1,2})?$';
     CMIIdentifier = '^\\w{0,255}$';
     CMIFeedback = CMIString255; // This must be redefined
     CMIIndex = '.\\d+.';
        'cmi._children':{'defaultvalue':cmi_children, 'mod':'r', 'writeerror':'402'},
        'cmi._version':{'defaultvalue':'3.4', 'mod':'r', 'writeerror':'402'},
        'cmi.core._children':{'defaultvalue':core_children, 'mod':'r', 'writeerror':'402'},
-       'cmi.core.student_id':{'defaultvalue':'<?php echo $user->username ?>', 'mod':'r', 'writeerror':'403'},
-       'cmi.core.student_name':{'defaultvalue':'<?php echo $user->lastname.', '.$user->firstname ?>', 'mod':'r', 'writeerror':'403'},
-       'cmi.core.lesson_location':{'format':CMIString255, 'mod':'rw', 'writeerror':'405'},
-       'cmi.core.credit':{'mod':'r', 'writeerror':'403'},
-       'cmi.core.lesson_status':{'format':CMIStatus, 'mod':'rw', 'writeerror':'405'},
-       'cmi.core.entry':{'mod':'r', 'writeerror':'403'},
+       'cmi.core.student_id':{'defaultvalue':'<?php echo $userdata->student_id ?>', 'mod':'r', 'writeerror':'403'},
+       'cmi.core.student_name':{'defaultvalue':'<?php echo $userdata->student_name ?>', 'mod':'r', 'writeerror':'403'},
+       'cmi.core.lesson_location':{'defaultvalue':'<?php echo isset($userdata->{'cmi.core.lesson_location'})?$userdata->{'cmi.core.lesson_location'}:'' ?>', 'format':CMIString255, 'mod':'rw', 'writeerror':'405'},
+       'cmi.core.credit':{'defaultvalue':'<?php echo $userdata->credit ?>', 'mod':'r', 'writeerror':'403'},
+       'cmi.core.lesson_status':{'defaultvalue':'<?php echo isset($userdata->{'cmi.core.lesson_status'})?$userdata->{'cmi.core.lesson_status'}:'' ?>', 'format':CMIStatus, 'mod':'rw', 'writeerror':'405'},
+       'cmi.core.entry':{'defaultvalue':'<?php echo $userdata->entry ?>', 'mod':'r', 'writeerror':'403'},
        'cmi.core.score._children':{'defaultvalue':score_children, 'mod':'r', 'writeerror':'402'},
-       'cmi.core.score.raw':{'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
-       'cmi.core.score.max':{'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
-       'cmi.core.score.min':{'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
-       'cmi.core.total_time':{'mod':'r', 'writeerror':'403'},
-       'cmi.core.lesson_mode':{'mod':'r', 'writeerror':'405'},
-       'cmi.core.exit':{'format':CMIExit, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
+       'cmi.core.score.raw':{'defaultvalue':'<?php echo isset($userdata->{'cmi.core.score.raw'})?$userdata->{'cmi.core.score.raw'}:'' ?>', 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
+       'cmi.core.score.max':{'defaultvalue':'<?php echo isset($userdata->{'cmi.core.score.max'})?$userdata->{'cmi.core.score.max'}:'' ?>', 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
+       'cmi.core.score.min':{'defaultvalue':'<?php echo isset($userdata->{'cmi.core.score.min'})?$userdata->{'cmi.core.score.min'}:'' ?>', 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
+       'cmi.core.total_time':{'defaultvalue':'<?php echo isset($userdata->{'cmi.core.total_time'})?$userdata->{'cmi.core.total_time'}:'00:00:00' ?>', 'mod':'r', 'writeerror':'403'},
+       'cmi.core.lesson_mode':{'defaultvalue':'<?php echo $userdata->mode ?>', 'mod':'r', 'writeerror':'405'},
+       'cmi.core.exit':{'defaultvalue':'<?php echo isset($userdata->{'cmi.core.exit'})?$userdata->{'cmi.core.exit'}:'' ?>', 'format':CMIExit, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
        'cmi.core.session_time':{'format':CMITimespan, 'mod':'w', 'defaultvalue':'00:00:00', 'readerror':'404', 'writeerror':'405'},
-       'cmi.suspend_data':{'format':CMIString4096, 'mod':'rw', 'writeerror':'405'},
-       'cmi.launch_data':{'mod':'r', 'writeerror':'403'},
-       'cmi.comments':{'format':CMIString4096, 'mod':'rw', 'writeerror':'405'},
+       'cmi.suspend_data':{'defaultvalue':'<?php echo isset($userdata->{'cmi.suspend_data'})?$userdata->{'cmi.suspend_data'}:'' ?>', 'format':CMIString4096, 'mod':'rw', 'writeerror':'405'},
+       'cmi.launch_data':{'defaultvalue':'<?php echo $userdata->datafromlms ?>', 'mod':'r', 'writeerror':'403'},
+       'cmi.comments':{'defaultvalue':'<?php echo isset($userdata->{'cmi.comments'})?$userdata->{'cmi.comments'}:'' ?>', 'format':CMIString4096, 'mod':'rw', 'writeerror':'405'},
        'cmi.comments_from_lms':{'mod':'r', 'writeerror':'403'},
        'cmi.objectives._children':{'defaultvalue':objectives_children, 'mod':'r', 'writeerror':'403'},
        'cmi.objectives._count':{'mod':'r', 'defaultvalue':'0', 'writeerror':'402'},
        'cmi.objectives.n.score.max':{'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
        'cmi.objectives.n.status':{'pattern':CMIIndex, 'format':CMIStatus, 'mod':'rw', 'writeerror':'405'},
        'cmi.student_data._children':{'defaultvalue':student_data_children, 'mod':'r', 'writeerror':'403'},
-       'cmi.student_data.mastery_score':{'mod':'r', 'writeerror':'403'},
-       'cmi.student_data.max_time_allowed':{'mod':'r', 'writeerror':'403'},
-       'cmi.student_data.time_limit_action':{'mod':'r', 'writeerror':'403'},
+       'cmi.student_data.mastery_score':{'defaultvalue':'<?php echo $userdata->masteryscore ?>', 'mod':'r', 'writeerror':'403'},
+       'cmi.student_data.max_time_allowed':{'defaultvalue':'<?php echo $userdata->maxtimeallowed ?>', 'mod':'r', 'writeerror':'403'},
+       'cmi.student_data.time_limit_action':{'defaultvalue':'<?php echo $userdata->timelimitaction ?>', 'mod':'r', 'writeerror':'403'},
        'cmi.student_preference._children':{'defaultvalue':student_preference_children, 'mod':'r', 'writeerror':'403'},
-       'cmi.student_preference.audio':{'format':CMISInteger, 'range':audio_range, 'mod':'rw', 'writeerror':'405'},
-       'cmi.student_preference.language':{'format':CMIString255, 'mod':'rw', 'writeerror':'405'},
-       'cmi.student_preference.speed':{'format':CMISInteger, 'range':speed_range, 'mod':'rw', 'writeerror':'405'},
-       'cmi.student_preference.text':{'format':CMISInteger, 'range':text_range, 'mod':'rw', 'writeerror':'405'},
+       'cmi.student_preference.audio':{'defaultvalue':'0', 'format':CMISInteger, 'range':audio_range, 'mod':'rw', 'writeerror':'405'},
+       'cmi.student_preference.language':{'defaultvalue':'', 'format':CMIString255, 'mod':'rw', 'writeerror':'405'},
+       'cmi.student_preference.speed':{'defaultvalue':'0', 'format':CMISInteger, 'range':speed_range, 'mod':'rw', 'writeerror':'405'},
+       'cmi.student_preference.text':{'defaultvalue':'0', 'format':CMISInteger, 'range':text_range, 'mod':'rw', 'writeerror':'405'},
        'cmi.interactions._children':{'defaultvalue':interactions_children, 'mod':'r', 'writeerror':'403'},
        'cmi.interactions._count':{'mod':'r', 'defaultvalue':'0', 'writeerror':'402'},
        'cmi.interactions.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
            }
            //alert (element+' = '+eval(element));
        }
+    }
+    if (cmi.core.lesson_status == '') {
+       cmi.core.lesson_status = 'not attempted';
     } 
     
     //
     function LMSFinish (param) {
        if (param == "") {
             if (Initialized) {
-               LMSCommit("");
                Initialized = false;
-               errorCode = "0";
-               return "true";
+               return StoreData('API',cmi,true);
             } else {
                errorCode = "301";
             }
                                    elementIndex = elementIndexes[i];
                                    //alert(elementIndex+' '+elementIndexes[i+1]);
                                    if (elementIndexes[i+1].match(/^\d+$/)) {
-                                       if ((typeof eval(subelement+'.'+elementIndex+'._count')) == "undefined") {
+                                       //alert('Matched: '+elementIndexes[i+1]);
+                                       //alert('Check: '+subelement+'.'+elementIndex);
+                                       if ((typeof eval(subelement+'.'+elementIndex)) == "undefined") {
                                            eval(subelement+'.'+elementIndex+' = new Object();');
                                            eval(subelement+'.'+elementIndex+'._count = 0;');
                                        }
                                    } else {
                                        subelement = subelement.concat('.'+elementIndex);
                                    }
-                                   alert(subelement);
+                                   //alert(subelement);
                                    if ((typeof eval(subelement)) == "undefined") {
                                        eval(subelement+' = new Object();');
                                    }
                                }
                                element = subelement.concat('.'+elementIndexes[elementIndexes.length-1]);
-                               alert('LMSSetValue: '+element+'\nModel: '+elementmodel+'\nValue: '+value+'\nMatches: '+matches);
+                               //alert('LMSSetValue: '+element+'\nModel: '+elementmodel+'\nValue: '+value+'\nMatches: '+matches);
                            }
                            //Store data
                            if ((typeof eval('datamodel["'+elementmodel+'"].range')) != "undefined") {
                                range = eval('datamodel["'+elementmodel+'"].range');
                                ranges = range.split('#');
-                               value = value+0.0;
+                               value = value*1.0;
                                if ((value >= ranges[0]) && (value <= ranges[1])) {
                                    eval(element+'="'+value+'";');
                                    errorCode = "0";
+                                   //alert('LMSSetValue: '+element+'\nModel: '+elementmodel+'\nValue: '+value);
                                    return "true";
                                } else {
                                    errorCode = eval('datamodel["'+elementmodel+'"].writeerror');
                            } else {
                                eval(element+'="'+value+'";');
                                errorCode = "0";
+                               //alert('LMSSetValue: '+element+'\nModel: '+elementmodel+'\nValue: '+value);
                                return "true";
                            }
                        } else {
        } else {
             errorCode = "301";
         }
-       alert('LMSSetValue: '+element+'\nValue: '+value+'\nPattern: '+expression+'\nMatches: '+matches+'\nError Code: '+errorCode);
+       //alert('LMSSetValue: '+element+'\nValue: '+value+'\nPattern: '+expression+'\nMatches: '+matches+'\nError Code: '+errorCode);
        return "false";
     }
     
     function LMSCommit (param) {
        if (param == "") {
             if (Initialized) {
-                
-               errorCode = "0";
-               return "true";
+               return StoreData('API',cmi,false);
             } else {
                errorCode = "301";
            }
        }
        return param;
     }
+
+    function TotalTime() {
+        total_time = AddTime(cmi.core.total_time, cmi.core.session_time);
+       //////////////alert (cmi.core.total_time+' '+cmi.core.session_time+' '+total_time);
+       return '&'+underscore('cmi.core.total_time')+'='+escape(total_time);
+    }
+
+    this.datamodel = datamodel;
+    this.TotalTime = TotalTime;
     
     this.LMSInitialize = LMSInitialize;
     this.LMSFinish = LMSFinish;
     this.LMSGetLastError = LMSGetLastError;
     this.LMSGetErrorString = LMSGetErrorString;
     this.LMSGetDiagnostic = LMSGetDiagnostic;
+}
+
+var API = new SCORMapi1_2();
index a83a9af..8f9ea0f 100755 (executable)
@@ -134,7 +134,21 @@ function scorm_upgrade($oldversion) {
     if ($oldversion < 2005041600) {
        table_column("scorm", "", "version", "VARCHAR", "9", "", "SCORM_1.2", "NOT NULL", "reference");
     }
-    
+
+    if ($oldversion < 2005042700) {
+       $trackingdata = get_records_select("scorm_scoes_track","1","id ASC");
+       if (!empty($trackingdata)) {
+           $oldelements = array ('cmi_core_lesson_location','cmi_core_lesson_status','cmi_core_exit','cmi_core_total_time','cmi_core_score_raw','cmi_suspend_data');
+           $newelements = array ('cmi.core.lesson_location','cmi.core.lesson_status','cmi.core.exit','cmi.core.total_time','cmi.core.score.raw','cmi.suspend_data');
+           foreach ($trackingdata as $track) {
+               if (($pos = array_search($track->element,$oldelements)) !== false) {
+                   $track->element = $newelements[$pos];
+                   update_record('scorm_scoes_track',$track);
+               }
+           }
+       }
+    }
+
     return true;
 }
 ?>
index 6957898..f68b579 100755 (executable)
@@ -132,6 +132,21 @@ function scorm_upgrade($oldversion) {
        table_column("scorm", "", "version", "VARCHAR", "9", "", "SCORM_1.2", "NOT NULL", "reference");
     }
 
+    if ($oldversion < 2005042700) {
+       $trackingdata = get_records_select("scorm_scoes_track","1","id ASC");
+       if (!empty($trackingdata)) {
+           $oldelements = array ('cmi_core_lesson_location','cmi_core_lesson_status','cmi_core_exit','cmi_core_total_time','cmi_core_score_raw','cmi_suspend_data');
+           $newelements = array ('cmi.core.lesson_location','cmi.core.lesson_status','cmi.core.exit','cmi.core.total_time','cmi.core.score.raw','cmi.suspend_data');
+           foreach ($trackingdata as $track) {
+               if (($pos = array_search($track->element,$oldelements)) !== false) {
+                   $track->element = $newelements[$pos];
+                   update_record('scorm_scoes_track',$track);
+               }
+           }
+       }
+    }
+
+
     return true;
 }
 
index 6a7bfbf..a94c14a 100755 (executable)
@@ -122,7 +122,7 @@ function scorm_user_outline($course, $user, $mod, $scorm) {
 /// $return->time = the time they did it
 /// $return->info = a short text description
 
-    return true;   // TO FIX
+    return NULL;   // TO FIX
 }
 
 function scorm_user_complete($course, $user, $mod, $scorm) {
@@ -760,27 +760,38 @@ function scorm_get_tracks($scoid,$userid) {
 /// Gets all tracks of specified sco and user 
     global $CFG;
     
-    if ($tracks = get_records_select('scorm_scoes_track',"userid=$userid AND scoid=$scoid")) {
+    if ($tracks = get_records_select('scorm_scoes_track',"userid=$userid AND scoid=$scoid",'element ASC')) {
+       //print_r($tracks);
        $usertrack->userid = $userid;
        $usertrack->scoid = $scoid;
        $usertrack->score_raw = '';
        $usertrack->status = '';
+       $usertrack->total_time = '00:00:00';
+       $usertrack->session_time = '00:00:00';
        foreach ($tracks as $track) {
-           $element = str_replace('.','_',$track->element);
+           //$element = str_replace('.','_',$track->element);
+           $element = $track->element;
+           $usertrack->{$element} = $track->value;
            switch ($element) {
-           case 'cmi_core_lesson_status':
-           case 'cmi_completition_status':
-               if ($track->value == 'not attempted') {
-                   $track->value = 'notattempted';
-               }
-               $usertrack->status = $track->value;
-           break;
-           case 'cmi_core_score_raw':
-           case 'cmi_score_raw':
-               $usertrack->score_raw = $track->value;
-           break;
-           default:
-               $usertrack->{$element} = $track->value;
+               case 'cmi.core.lesson_status':
+               case 'cmi.completition_status':
+                   if ($track->value == 'not attempted') {
+                       $track->value = 'notattempted';
+                   }
+                   $usertrack->status = $track->value;
+               break;
+               case 'cmi.core.score.raw':
+               case 'cmi.score.raw':
+                   $usertrack->score_raw = $track->value;
+               break;
+               case 'cmi.core.session_time':
+               case 'cmi.session_time':
+                   $usertrack->session_time = $track->value;
+               break;
+               case 'cmi.core.total_time':
+               case 'cmi.total_time':
+                   $usertrack->total_time = $track->value;
+               break;
            }
        }
        //print_r($usertrack);
@@ -790,18 +801,11 @@ function scorm_get_tracks($scoid,$userid) {
     }
 }
 
-function scorm_get_scoes_records($scouser) {
-/// Gets all info required to display the table of scorm results
+function scorm_get_user_data($userid) {
+/// Gets user info required to display the table of scorm results
 /// for report.php
-    global $CFG;
 
-    return get_records_sql("SELECT su.*, u.firstname, u.lastname, u.picture 
-                            FROM {$CFG->prefix}scorm_scoes_track su, 
-                                 {$CFG->prefix}user u
-                            WHERE su.scormid = '$scouser->scormid'
-                              AND su.userid = u.id
-                              AND su.userid = '$scouser->userid'
-                              ORDER BY scoid");
+    return get_record('user','id',$userid,'','','','','firstname, lastname, picture'); 
 }
 
 function scorm_remove_spaces($sourcestr) {
index 20dfa12..d91bfea 100755 (executable)
@@ -34,7 +34,6 @@
     }
 
     require_login($course->id, false, $cm);
-
     
     $strscorms = get_string('modulenameplural', 'scorm');
     $strscorm  = get_string('modulename', 'scorm');
     //
     // Print the page header
     //
-    $bodyscripts = "onUnload='SCOFinish();'";
+    //$bodyscripts = "onUnload='SCOFinish();'";
     print_header($pagetitle, "$course->fullname",
        "$navigation <a target='{$CFG->framename}' href='view.php?id=$cm->id'>".format_string($scorm->name,true)."</a>",
-       '', '', true, update_module_button($cm->id, $course->id, $strscorm), "", "", $bodyscripts);
+       '', '', true, update_module_button($cm->id, $course->id, $strscorm));
 ?>
     <style type="text/css">
         .scormlist { 
     -->
     </script>
 
-    <script language="JavaScript" type="text/javascript" src="request.js"></script>
-    <script language="JavaScript" type="text/javascript" src="api.php?id=<?php echo $cm->id ?>"></script>
     <table class="fullscreen" height="90%">
     <tr><td valign="top">
        <p><?php echo format_text($scorm->summary) ?></p>
                <th>
                    <div style='float: left;'><?php print_string('coursestruct','scorm') ?></div>
                    <div style='float:right;'>
-                       <a href='#' onClick='expandCollide(imgmain,0);'>
-                            <img id='imgmain' src="pix/minus.gif" alt="<?php echo $strexpand ?>" title="<?php echo $strexpand ?>"/>
-                       </a>
+                       <a href='#' onClick='expandCollide(imgmain,0);'><img id='imgmain' src="pix/minus.gif" alt="<?php echo $strexpand ?>" title="<?php echo $strexpand ?>"/></a>
                    </div>
                </th>
            </tr>
 <?php
     $sco = scorm_display_structure($scorm,'scormlist',$currentorg,$scoid,$mode,true);
     add_to_log($course->id, 'scorm', 'view', "playscorm.php?id=$cm->id&scoid=$sco->id", "$scorm->id");
+    $scoidstring = '&scoid='.$sco->id;
+
+    $SESSION->scorm_scoid = $sco->id;
 ?>
            </td></tr>
            <tr><td align="center">
                    <input name="currentorg" type="hidden" value="<?php echo $currentorg ?>" />
                    <input name="mode" type="hidden" value="<?php echo $mode ?>" />
                    <input name="prev" type="<?php if ($sco->prev == 0) { echo 'hidden'; } else { echo 'button'; } ?>" value="<?php print_string('prev','scorm') ?>" onClick="playSCO(<?php echo $sco->prev ?>);" />
-                   <input name="next" type="button" value="<?php if ($sco->next == 0) { print_string('exit','scorm'); } else { print_string('next','scorm'); } ?>" onClick="playSCO(<?php echo $sco->next ?>)" />
+                   <input name="next" type="<?php if ($sco->next == 0) { echo 'hidden'; } else { echo 'button'; } ?>" value="<?php print_string('next','scorm') ?>" onClick="playSCO(<?php echo $sco->next ?>);" /><br />
+                   <input name="exit" type="button" value="<?php print_string('exit','scorm') ?>" onClick="playSCO(0)" />
                </form>
            </td></tr>
        </table>
        <iframe name="main" class="fullscreen" height="640" src="loadSCO.php?id=<?php echo $cm->id.$scoidstring ?>"></iframe>
     </td></tr>
     </table>
+    <script language="JavaScript" type="text/javascript" src="request.js"></script>
+    <script language="JavaScript" type="text/javascript" src="api.php?id=<?php echo $cm->id.$scoidstring ?>"></script>
 </body>
 </html>
index 4c0c00e..5cab33c 100755 (executable)
@@ -6,6 +6,8 @@
     require_once("lib.php");
 
     optional_variable($id);    // Course Module ID, or
+    optional_variable($b);   // SCO ID 
+    optional_variable($user);
 
     if ($id) {
         if (! $cm = get_record("course_modules", "id", $id)) {
         if (! $scorm = get_record("scorm", "id", $cm->instance)) {
             error("Course module is incorrect");
         }
-
-    } else {
-        if (! $scorm = get_record("scorm", "id", $q)) {
+    } else if (isset($b)) {
+        if (! $sco = get_record("scorm_scoes", "id", $b)) {
+            error("Scorm activity is incorrect");
+        }
+        if (! $scorm = get_record("scorm", "id", $sco->scorm)) {
             error("Course module is incorrect");
         }
         if (! $course = get_record("course", "id", $scorm->course)) {
@@ -30,6 +34,7 @@
         if (! $cm = get_coursemodule_from_instance("scorm", $scorm->id, $course->id)) {
             error("Course Module ID was incorrect");
         }
+       
     }
 
     require_login($course->id, false, $cm);
         $strscorms = get_string("modulenameplural", "scorm");
         $strscorm  = get_string("modulename", "scorm");
         $strreport  = get_string("report", "scorm");
-
-        print_header("$course->shortname: ".format_string($scorm->name), "$course->fullname",
+        $strname  = get_string('name');
+       if (!empty($id)) {
+            print_header("$course->shortname: ".format_string($scorm->name), "$course->fullname",
                      "$navigation <a href=\"index.php?id=$course->id\">$strscorms</a>
                       -> <a href=\"view.php?id=$cm->id\">".format_string($scorm->name,true)."</a> -> $strreport",
                      "", "", true);
-
+       } else {
+            print_header("$course->shortname: ".format_string($scorm->name), "$course->fullname",
+                     "$navigation <a href=\"index.php?id=$course->id\">$strscorms</a>
+                      -> <a href=\"view.php?id=$cm->id\">".format_string($scorm->name,true)."</a>
+                     -> <a href=\"report.php?id=$cm->id\">$strreport</a> -> $sco->title",
+                     "", "", true);
+       }
         print_heading(format_string($scorm->name));
     }
-    if ($scoes =get_records_select("scorm_scoes","scorm='$scorm->id' ORDER BY id")) {
-        if ($sco_users=get_records_select("scorm_scoes_track", "scormid='$scorm->id' GROUP BY userid")) {
-
-            $strname  = get_string("name");
-
-            $table->head = array("&nbsp;", $strname);
-            $table->align = array("center", "left");
-            $table->wrap = array("nowrap", "nowrap");
-            $table->width = "100%";
-            $table->size = array(10, "*");
-            foreach ($scoes as $sco) {
-                if ($sco->launch!="") {
-                    $table->head[]=scorm_string_round($sco->title);
-                    $table->align[] = "center";
-                    $table->wrap[] = "nowrap";
-                    $table->size[] = "*";
-                }
-            }
-
-            foreach ($sco_users as $sco_user) {
-                $user_data = scorm_get_tracks($scorm->id,$sco_user->userid);
-
-                $row = array();
-                $data = current($user_data);
-                $row[] = print_user_picture($sco_user->userid, $course->id, $data->picture, false, true);
-                $row[] = "<a href=\"$CFG->wwwroot/user/view.php?id=$data->userid&course=$course->id\">".
-                         "$data->firstname $data->lastname</a>";
-                foreach ($user_data as $data) {
-                    $scoreview = "";
-                    if ($data->cmi_core_score_raw > 0)
-                        $scoreview = "<br />".get_string("score","scorm").":&nbsp;".$data->cmi_core_score_raw;
-                    if ( $data->cmi_core_lesson_status == "")
-                        $data->cmi_core_lesson_status = "not attempted";
-                    $row[]="<img src=\"pix/".scorm_remove_spaces($data->cmi_core_lesson_status).".gif\"
-                        alt=\"".get_string(scorm_remove_spaces($data->cmi_core_lesson_status),"scorm")."\"
-                        title=\"".get_string(scorm_remove_spaces($data->cmi_core_lesson_status),"scorm")."\">&nbsp;"
-                        .$data->cmi_core_total_time.$scoreview;
+    if (!empty($id)) {
+       if ($scoes = get_records_select("scorm_scoes","scorm='$scorm->id' ORDER BY id")) {
+            if ($scousers=get_records_select("scorm_scoes_track", "scormid='$scorm->id' GROUP BY userid")) {
+               $table->head = array('&nbsp;', $strname);
+               $table->align = array('center', 'left');
+               $table->wrap = array('nowrap', 'nowrap');
+               $table->width = '100%';
+               $table->size = array(10, '*');
+               foreach ($scoes as $sco) {
+                   if ($sco->launch!='') {
+                       $table->head[]=scorm_string_round($sco->title);
+                       $table->align[] = 'center';
+                       $table->wrap[] = 'nowrap';
+                       $table->size[] = '*';
+                   }
                 }
-                $table->data[] = $row;
-            }
 
-            print_table($table);
-
-        } else {
-            notice("No users to report");
-        }
+               foreach ($scousers as $scouser) {
+                   if ($userdata = scorm_get_user_data($scouser->userid)) {
+                       $row[] = print_user_picture($scouser->userid, $course->id, $userdata->picture, false, true);
+                       $row[] = "<a href=\"$CFG->wwwroot/user/view.php?id=$scouser->userid&course=$course->id\">".
+                            "$userdata->firstname $userdata->lastname</a>";
+                       foreach ($scoes as $sco) {
+                           if ($sco->launch!='') {
+                               $anchorstart = '';
+                               $anchorend = '';
+                               $scoreview = '';
+                               if ($trackdata = scorm_get_tracks($sco->id,$scouser->userid)) {
+                                   if ($trackdata->score_raw != '') {
+                                       $scoreview = '<br />'.get_string('score','scorm').':&nbsp;'.$trackdata->score_raw;
+                                   }
+                                   if ($trackdata->status == '') {
+                                       $trackdata->status = 'notattempted';
+                                   } else {
+                                       $anchorstart = '<a href="report.php?b='.$sco->id.'&user='.$scouser->userid.'" title="'.get_string('details','scorm').'">';
+                                       $anchorend = '</a>';
+                                   }
+                               } else {
+                                   $trackdata->status = 'notattempted';
+                                   $trackdata->total_time = '';
+                               }
+                               $strstatus = get_string($trackdata->status,'scorm');
+                               $row[] = $anchorstart.'<img src="pix/'.$trackdata->status.'.gif" alt="'.$strstatus.'" title="'.
+                                       $strstatus.'">&nbsp;'.$trackdata->total_time.$scoreview.$anchorend;
+                           }
+                       }
+                       $table->data[] = $row;
+                   }
+               }
+               print_table($table);
+            } else {
+                       notice('No users to report');
+           }
+       }
+    } else {
+       if (!empty($user)) {
+           if ($userdata = scorm_get_user_data($user)) {
+               print_simple_box_start('center');
+               print_heading(format_string($sco->title));
+               echo '<div align="center">'."\n";
+               print_user_picture($user, $course->id, $userdata->picture, false, false);
+               echo "<a href=\"$CFG->wwwroot/user/view.php?id=$user&course=$course->id\">".
+                    "$userdata->firstname $userdata->lastname</a><br />";
+               $scoreview = '';
+               if ($trackdata = scorm_get_tracks($sco->id,$user)) {
+                   if ($trackdata->score_raw != '') {
+                       $scoreview = get_string('score','scorm').':&nbsp;'.$trackdata->score_raw;
+                   }
+                   if ($trackdata->status == '') {
+                       $trackdata->status = 'notattempted';
+                   }
+               } else {
+                   $trackdata->status = 'notattempted';
+                   $trackdata->total_time = '';
+               }
+               $strstatus = get_string($trackdata->status,'scorm');
+               echo '<img src="pix/'.$trackdata->status.'.gif" alt="'.$strstatus.'" title="'.
+                       $strstatus.'">&nbsp;'.$trackdata->total_time.'<br />'.$scoreview.'<br />';
+               echo '</div>'."\n";
+               //print_r($trackdata);
+               foreach($trackdata as $element => $value) {
+                   if (substr($element,0,3) == 'cmi') {
+                       echo $element.' => '.$value.'<br />';
+                   }
+               }
+               print_simple_box_end();
+           }
+       } else {
+           error('Missing script parameter');
+       }
     }
     if (empty($noheader)) {
         print_footer($course);
index 321c931..9001b0f 100644 (file)
@@ -32,4 +32,11 @@ function DoRequest(httpReq,url,param) {
     } else {
        return httpReq.status;
     }
-}
\ No newline at end of file
+}
+
+function popupwin(content) {
+    op = window.open();
+    op.document.open('text/plain');
+    op.document.write(content);
+    op.document.close();
+}
index ad0cd21..f229576 100755 (executable)
@@ -5,7 +5,7 @@
 ///  This fragment is called by moodle_needs_upgrading() and /admin/index.php
 /////////////////////////////////////////////////////////////////////////////////
 
-$module->version  = 2005041600;   // The (date) version of this module
+$module->version  = 2005042700;   // The (date) version of this module
 $module->requires = 2005021600;   // The version of Moodle that is required
 $module->cron     = 0;            // How often should cron check this module (seconds)?
 
index 52973d3..6ef60e3 100755 (executable)
     }
 
     require_login($course->id, false, $cm);
-
+    
+    if (isset($SESSION->scorm_scoid)) {
+       unset($SESSION->scorm_scoid);
+    }
     
     $strscorms = get_string("modulenameplural", "scorm");
     $strscorm  = get_string("modulename", "scorm");