MDL-46397 mod_scorm : binding cmi values with scoid

This commit is contained in:
Nobelium 2014-07-28 05:37:21 +00:00
parent ec36fafc0f
commit bf4f65fbb6
9 changed files with 497 additions and 401 deletions

View file

@ -60,105 +60,114 @@ function AICCapi(def, cmiobj, scormauto, cfgwwwroot, scormid, scoid, attempt, vi
text_range = '-1#1'; text_range = '-1#1';
// The AICC data model // The AICC data model
var datamodel = { var datamodel = {};
'cmi._children':{'defaultvalue':cmi_children, 'mod':'r', 'writeerror':'402'}, for(scoid in def){
'cmi._version':{'defaultvalue':'3.4', 'mod':'r', 'writeerror':'402'}, datamodel[scoid] = {
'cmi.core._children':{'defaultvalue':core_children, 'mod':'r', 'writeerror':'402'}, 'cmi._children':{'defaultvalue':cmi_children, 'mod':'r', 'writeerror':'402'},
'cmi.core.student_id':{'defaultvalue':def['cmi.core.student_id'], 'mod':'r', 'writeerror':'403'}, 'cmi._version':{'defaultvalue':'3.4', 'mod':'r', 'writeerror':'402'},
'cmi.core.student_name':{'defaultvalue':def['cmi.core.student_name'], 'mod':'r', 'writeerror':'403'}, 'cmi.core._children':{'defaultvalue':core_children, 'mod':'r', 'writeerror':'402'},
'cmi.core.lesson_location':{'defaultvalue':def['cmi.core.lesson_location'], 'format':CMIString256, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.student_id':{'defaultvalue':def[scoid]['cmi.core.student_id'], 'mod':'r', 'writeerror':'403'},
'cmi.core.credit':{'defaultvalue':def['cmi.core.credit'], 'mod':'r', 'writeerror':'403'}, 'cmi.core.student_name':{'defaultvalue':def[scoid]['cmi.core.student_name'], 'mod':'r', 'writeerror':'403'},
'cmi.core.lesson_status':{'defaultvalue':def['cmi.core.lesson_status'], 'format':CMIStatus, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.lesson_location':{'defaultvalue':def[scoid]['cmi.core.lesson_location'], 'format':CMIString256, 'mod':'rw', 'writeerror':'405'},
'cmi.core.exit':{'defaultvalue':def['cmi.core.exit'], 'format':CMIExit, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.core.credit':{'defaultvalue':def[scoid]['cmi.core.credit'], 'mod':'r', 'writeerror':'403'},
'cmi.core.entry':{'defaultvalue':def['cmi.core.entry'], 'mod':'r', 'writeerror':'403'}, 'cmi.core.lesson_status':{'defaultvalue':def[scoid]['cmi.core.lesson_status'], 'format':CMIStatus, 'mod':'rw', 'writeerror':'405'},
'cmi.core.score._children':{'defaultvalue':score_children, 'mod':'r', 'writeerror':'402'}, 'cmi.core.exit':{'defaultvalue':def[scoid]['cmi.core.exit'], 'format':CMIExit, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.core.score.raw':{'defaultvalue':def['cmi.core.score.raw'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.entry':{'defaultvalue':def[scoid]['cmi.core.entry'], 'mod':'r', 'writeerror':'403'},
'cmi.core.score.max':{'defaultvalue':def['cmi.core.score.max'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.score._children':{'defaultvalue':score_children, 'mod':'r', 'writeerror':'402'},
'cmi.core.score.min':{'defaultvalue':def['cmi.core.score.min'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.score.raw':{'defaultvalue':def[scoid]['cmi.core.score.raw'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.core.session_time':{'format':CMITimespan, 'mod':'w', 'defaultvalue':'00:00:00', 'readerror':'404', 'writeerror':'405'}, 'cmi.core.score.max':{'defaultvalue':def[scoid]['cmi.core.score.max'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.core.total_time':{'defaultvalue':def['cmi.core.total_time'], 'mod':'r', 'writeerror':'403'}, 'cmi.core.score.min':{'defaultvalue':def[scoid]['cmi.core.score.min'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.core.lesson_mode':{'defaultvalue':def['cmi.core.lesson_mode'], 'mod':'r', 'writeerror':'403'}, 'cmi.core.session_time':{'format':CMITimespan, 'mod':'w', 'defaultvalue':'00:00:00', 'readerror':'404', 'writeerror':'405'},
'cmi.suspend_data':{'defaultvalue':def['cmi.suspend_data'], 'format':CMIString4096, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.total_time':{'defaultvalue':def[scoid]['cmi.core.total_time'], 'mod':'r', 'writeerror':'403'},
'cmi.launch_data':{'defaultvalue':def['cmi.launch_data'], 'mod':'r', 'writeerror':'403'}, 'cmi.core.lesson_mode':{'defaultvalue':def[scoid]['cmi.core.lesson_mode'], 'mod':'r', 'writeerror':'403'},
'cmi.comments':{'defaultvalue':def['cmi.comments'], 'format':CMIString4096, 'mod':'rw', 'writeerror':'405'}, 'cmi.suspend_data':{'defaultvalue':def[scoid]['cmi.suspend_data'], 'format':CMIString4096, 'mod':'rw', 'writeerror':'405'},
// deprecated evaluation attributes 'cmi.launch_data':{'defaultvalue':def[scoid]['cmi.launch_data'], 'mod':'r', 'writeerror':'403'},
'cmi.evaluation.comments._count':{'defaultvalue':'0', 'mod':'r', 'writeerror':'402'}, 'cmi.comments':{'defaultvalue':def[scoid]['cmi.comments'], 'format':CMIString4096, 'mod':'rw', 'writeerror':'405'},
'cmi.evaluation.comments._children':{'defaultvalue':comments_children, 'mod':'r', 'writeerror':'402'}, // deprecated evaluation attributes
'cmi.evaluation.comments.n.content':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIString256, 'mod':'rw', 'writeerror':'405'}, 'cmi.evaluation.comments._count':{'defaultvalue':'0', 'mod':'r', 'writeerror':'402'},
'cmi.evaluation.comments.n.location':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIString256, 'mod':'rw', 'writeerror':'405'}, 'cmi.evaluation.comments._children':{'defaultvalue':comments_children, 'mod':'r', 'writeerror':'402'},
'cmi.evaluation.comments.n.time':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMITime, 'mod':'rw', 'writeerror':'405'}, 'cmi.evaluation.comments.n.content':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIString256, 'mod':'rw', 'writeerror':'405'},
'cmi.comments_from_lms':{'mod':'r', 'writeerror':'403'}, 'cmi.evaluation.comments.n.location':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIString256, 'mod':'rw', 'writeerror':'405'},
'cmi.objectives._children':{'defaultvalue':objectives_children, 'mod':'r', 'writeerror':'402'}, 'cmi.evaluation.comments.n.time':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMITime, 'mod':'rw', 'writeerror':'405'},
'cmi.objectives._count':{'mod':'r', 'defaultvalue':'0', 'writeerror':'402'}, 'cmi.comments_from_lms':{'mod':'r', 'writeerror':'403'},
'cmi.objectives.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'rw', 'writeerror':'405'}, 'cmi.objectives._children':{'defaultvalue':objectives_children, 'mod':'r', 'writeerror':'402'},
'cmi.objectives.n.score._children':{'pattern':CMIIndex, 'mod':'r', 'writeerror':'402'}, 'cmi.objectives._count':{'mod':'r', 'defaultvalue':'0', 'writeerror':'402'},
'cmi.objectives.n.score.raw':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.objectives.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'rw', 'writeerror':'405'},
'cmi.objectives.n.score.min':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.objectives.n.score._children':{'pattern':CMIIndex, 'mod':'r', 'writeerror':'402'},
'cmi.objectives.n.score.max':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.objectives.n.score.raw':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.objectives.n.status':{'pattern':CMIIndex, 'format':CMIStatus2, 'mod':'rw', 'writeerror':'405'}, 'cmi.objectives.n.score.min':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data._children':{'defaultvalue':student_data_children, 'mod':'r', 'writeerror':'402'}, 'cmi.objectives.n.score.max':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data.attempt_number':{'defaultvalue':def['cmi.student_data.attempt_number'], 'mod':'r', 'writeerror':'402'}, 'cmi.objectives.n.status':{'pattern':CMIIndex, 'format':CMIStatus2, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data.tries.n.score.raw':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_data._children':{'defaultvalue':student_data_children, 'mod':'r', 'writeerror':'402'},
'cmi.student_data.tries.n.score.min':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_data.attempt_number':{'defaultvalue':def[scoid]['cmi.student_data.attempt_number'], 'mod':'r', 'writeerror':'402'},
'cmi.student_data.tries.n.score.max':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_data.tries.n.score.raw':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data.tries.n.status':{'pattern':CMIIndex, 'format':CMIStatus2, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_data.tries.n.score.min':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data.tries.n.time':{'pattern':CMIIndex, 'format':CMITime, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_data.tries.n.score.max':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data.mastery_score':{'defaultvalue':def['cmi.student_data.mastery_score'], 'mod':'r', 'writeerror':'403'}, 'cmi.student_data.tries.n.status':{'pattern':CMIIndex, 'format':CMIStatus2, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data.max_time_allowed':{'defaultvalue':def['cmi.student_data.max_time_allowed'], 'mod':'r', 'writeerror':'403'}, 'cmi.student_data.tries.n.time':{'pattern':CMIIndex, 'format':CMITime, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data.time_limit_action':{'defaultvalue':def['cmi.student_data.time_limit_action'], 'mod':'r', 'writeerror':'403'}, 'cmi.student_data.mastery_score':{'defaultvalue':def[scoid]['cmi.student_data.mastery_score'], 'mod':'r', 'writeerror':'403'},
'cmi.student_data.tries_during_lesson':{'defaultvalue':def['cmi.student_data.tries_during_lesson'], 'mod':'r', 'writeerror':'402'}, 'cmi.student_data.max_time_allowed':{'defaultvalue':def[scoid]['cmi.student_data.max_time_allowed'], 'mod':'r', 'writeerror':'403'},
'cmi.student_preference._children':{'defaultvalue':student_preference_children, 'mod':'r', 'writeerror':'402'}, 'cmi.student_data.time_limit_action':{'defaultvalue':def[scoid]['cmi.student_data.time_limit_action'], 'mod':'r', 'writeerror':'403'},
'cmi.student_preference.audio':{'defaultvalue':'0', 'format':CMISInteger, 'range':audio_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_data.tries_during_lesson':{'defaultvalue':def[scoid]['cmi.student_data.tries_during_lesson'], 'mod':'r', 'writeerror':'402'},
'cmi.student_preference.language':{'defaultvalue':'', 'format':CMIString256, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_preference._children':{'defaultvalue':student_preference_children, 'mod':'r', 'writeerror':'402'},
'cmi.student_preference.speed':{'defaultvalue':'0', 'format':CMISInteger, 'range':speed_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_preference.audio':{'defaultvalue':'0', 'format':CMISInteger, 'range':audio_range, 'mod':'rw', 'writeerror':'405'},
'cmi.student_preference.text':{'defaultvalue':'0', 'format':CMISInteger, 'range':text_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_preference.language':{'defaultvalue':'', 'format':CMIString256, 'mod':'rw', 'writeerror':'405'},
'cmi.interactions._children':{'defaultvalue':interactions_children, 'mod':'r', 'writeerror':'402'}, 'cmi.student_preference.speed':{'defaultvalue':'0', 'format':CMISInteger, 'range':speed_range, 'mod':'rw', 'writeerror':'405'},
'cmi.interactions._count':{'mod':'r', 'defaultvalue':'0', 'writeerror':'402'}, 'cmi.student_preference.text':{'defaultvalue':'0', 'format':CMISInteger, 'range':text_range, 'mod':'rw', 'writeerror':'405'},
'cmi.interactions.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions._children':{'defaultvalue':interactions_children, 'mod':'r', 'writeerror':'402'},
'cmi.interactions.n.objectives._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0', 'writeerror':'402'}, 'cmi.interactions._count':{'mod':'r', 'defaultvalue':'0', 'writeerror':'402'},
'cmi.interactions.n.objectives.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.time':{'pattern':CMIIndex, 'format':CMITime, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.objectives._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0', 'writeerror':'402'},
'cmi.interactions.n.type':{'pattern':CMIIndex, 'format':CMIType, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.objectives.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.correct_responses._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0', 'writeerror':'402'}, 'cmi.interactions.n.time':{'pattern':CMIIndex, 'format':CMITime, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.correct_responses.n.pattern':{'pattern':CMIIndex, 'format':CMIFeedback, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.type':{'pattern':CMIIndex, 'format':CMIType, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.weighting':{'pattern':CMIIndex, 'format':CMIDecimal, 'range':weighting_range, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.correct_responses._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0', 'writeerror':'402'},
'cmi.interactions.n.student_response':{'pattern':CMIIndex, 'format':CMIFeedback, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.correct_responses.n.pattern':{'pattern':CMIIndex, 'format':CMIFeedback, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.result':{'pattern':CMIIndex, 'format':CMIResult, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.weighting':{'pattern':CMIIndex, 'format':CMIDecimal, 'range':weighting_range, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.latency':{'pattern':CMIIndex, 'format':CMITimespan, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.student_response':{'pattern':CMIIndex, 'format':CMIFeedback, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'nav.event':{'defaultvalue':'', 'format':NAVEvent, 'mod':'w', 'readerror':'404', 'writeerror':'405'} 'cmi.interactions.n.result':{'pattern':CMIIndex, 'format':CMIResult, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
}; 'cmi.interactions.n.latency':{'pattern':CMIIndex, 'format':CMITimespan, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'nav.event':{'defaultvalue':'', 'format':NAVEvent, 'mod':'w', 'readerror':'404', 'writeerror':'405'}
// };
// Datamodel inizialization
//
var cmi = new Object();
cmi.core = new Object();
cmi.core.score = new Object();
cmi.objectives = new Object();
cmi.student_data = new Object();
cmi.student_preference = new Object();
cmi.interactions = new Object();
// deprecated evaluation attributes
cmi.evaluation = new Object();
cmi.evaluation.comments = new Object();
// Navigation Object
var nav = new Object();
for (element in datamodel) {
if (element.match(/\.n\./) == null) {
if ((typeof eval('datamodel["'+element+'"].defaultvalue')) != 'undefined') {
eval(element+' = datamodel["'+element+'"].defaultvalue;');
} else {
eval(element+' = "";');
}
}
} }
eval(cmiobj); var cmi, nav;
function initdatamodel(scoid){
prerequrl = cfgwwwroot + "/mod/scorm/prereqs.php?a="+scormid+"&scoid="+scoid+"&attempt="+attempt+"&mode="+viewmode+"&currentorg="+currentorg+"&sesskey="+sesskey;
datamodelurlparams = "id="+cmid+"&a="+scormid+"&sesskey="+sesskey+"&attempt="+attempt+"&scoid="+scoid;
if (cmi.core.lesson_status == '') { //
cmi.core.lesson_status = 'not attempted'; // Datamodel inizialization
//
cmi = new Object();
cmi.core = new Object();
cmi.core.score = new Object();
cmi.objectives = new Object();
cmi.student_data = new Object();
cmi.student_preference = new Object();
cmi.interactions = new Object();
// deprecated evaluation attributes
cmi.evaluation = new Object();
cmi.evaluation.comments = new Object();
// Navigation Object
nav = new Object();
for (element in datamodel[scoid]) {
if (element.match(/\.n\./) == null) {
if ((typeof eval('datamodel["'+scoid+'"]["'+element+'"].defaultvalue')) != 'undefined') {
eval(element+' = datamodel["'+scoid+'"]["'+element+'"].defaultvalue;');
} else {
eval(element+' = "";');
}
}
}
eval(cmiobj[scoid]);
if (cmi.core.lesson_status == '') {
cmi.core.lesson_status = 'not attempted';
}
} }
// //
@ -167,6 +176,9 @@ function AICCapi(def, cmiobj, scormauto, cfgwwwroot, scormid, scoid, attempt, vi
var Initialized = false; var Initialized = false;
function LMSInitialize (param) { function LMSInitialize (param) {
scoid = scorm_current_node ? scorm_current_node.scoid : scoid ;
initdatamodel(scoid);
errorCode = "0"; errorCode = "0";
if (param == "") { if (param == "") {
if (!Initialized) { if (!Initialized) {
@ -221,8 +233,8 @@ function AICCapi(def, cmiobj, scormauto, cfgwwwroot, scormid, scoid, attempt, vi
if (element !="") { if (element !="") {
expression = new RegExp(CMIIndex,'g'); expression = new RegExp(CMIIndex,'g');
elementmodel = String(element).replace(expression,'.n.'); elementmodel = String(element).replace(expression,'.n.');
if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"]')) != "undefined") {
if (eval('datamodel["'+elementmodel+'"].mod') != 'w') { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].mod') != 'w') {
element = String(element).replace(expression, "_$1."); element = String(element).replace(expression, "_$1.");
elementIndexes = element.split('.'); elementIndexes = element.split('.');
subelement = 'cmi'; subelement = 'cmi';
@ -237,21 +249,21 @@ function AICCapi(def, cmiobj, scormauto, cfgwwwroot, scormid, scoid, attempt, vi
errorCode = "0"; // Need to check if it is the right errorCode errorCode = "0"; // Need to check if it is the right errorCode
} }
} else { } else {
errorCode = eval('datamodel["'+elementmodel+'"].readerror'); errorCode = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].readerror');
} }
} else { } else {
childrenstr = '._children'; childrenstr = '._children';
countstr = '._count'; countstr = '._count';
if (elementmodel.substr(elementmodel.length-childrenstr.length,elementmodel.length) == childrenstr) { if (elementmodel.substr(elementmodel.length-childrenstr.length,elementmodel.length) == childrenstr) {
parentmodel = elementmodel.substr(0,elementmodel.length-childrenstr.length); parentmodel = elementmodel.substr(0,elementmodel.length-childrenstr.length);
if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+parentmodel+'"]')) != "undefined") {
errorCode = "202"; errorCode = "202";
} else { } else {
errorCode = "201"; errorCode = "201";
} }
} else if (elementmodel.substr(elementmodel.length-countstr.length,elementmodel.length) == countstr) { } else if (elementmodel.substr(elementmodel.length-countstr.length,elementmodel.length) == countstr) {
parentmodel = elementmodel.substr(0,elementmodel.length-countstr.length); parentmodel = elementmodel.substr(0,elementmodel.length-countstr.length);
if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+parentmodel+'"]')) != "undefined") {
errorCode = "203"; errorCode = "203";
} else { } else {
errorCode = "201"; errorCode = "201";
@ -275,9 +287,9 @@ function AICCapi(def, cmiobj, scormauto, cfgwwwroot, scormid, scoid, attempt, vi
if (element != "") { if (element != "") {
expression = new RegExp(CMIIndex,'g'); expression = new RegExp(CMIIndex,'g');
elementmodel = String(element).replace(expression,'.n.'); elementmodel = String(element).replace(expression,'.n.');
if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"]')) != "undefined") {
if (eval('datamodel["'+elementmodel+'"].mod') != 'r') { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].mod') != 'r') {
expression = new RegExp(eval('datamodel["'+elementmodel+'"].format')); expression = new RegExp(eval('datamodel["'+scoid+'"]["'+elementmodel+'"].format'));
value = value+''; value = value+'';
matches = value.match(expression); matches = value.match(expression);
if (matches != null) { if (matches != null) {
@ -324,8 +336,8 @@ function AICCapi(def, cmiobj, scormauto, cfgwwwroot, scormid, scoid, attempt, vi
} }
//Store data //Store data
if (errorCode == "0") { if (errorCode == "0") {
if ((typeof eval('datamodel["'+elementmodel+'"].range')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"].range')) != "undefined") {
range = eval('datamodel["'+elementmodel+'"].range'); range = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].range');
ranges = range.split('#'); ranges = range.split('#');
value = value*1.0; value = value*1.0;
if ((value >= ranges[0]) && (value <= ranges[1])) { if ((value >= ranges[0]) && (value <= ranges[1])) {
@ -333,7 +345,7 @@ function AICCapi(def, cmiobj, scormauto, cfgwwwroot, scormid, scoid, attempt, vi
errorCode = "0"; errorCode = "0";
return "true"; return "true";
} else { } else {
errorCode = eval('datamodel["'+elementmodel+'"].writeerror'); errorCode = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].writeerror');
} }
} else { } else {
if (element == 'cmi.comments') { if (element == 'cmi.comments') {
@ -346,10 +358,10 @@ function AICCapi(def, cmiobj, scormauto, cfgwwwroot, scormid, scoid, attempt, vi
} }
} }
} else { } else {
errorCode = eval('datamodel["'+elementmodel+'"].writeerror'); errorCode = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].writeerror');
} }
} else { } else {
errorCode = eval('datamodel["'+elementmodel+'"].writeerror'); errorCode = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].writeerror');
} }
} else { } else {
errorCode = "201" errorCode = "201"
@ -471,11 +483,11 @@ function AICCapi(def, cmiobj, scormauto, cfgwwwroot, scormid, scoid, attempt, vi
element = parent+'.'+property; element = parent+'.'+property;
expression = new RegExp(CMIIndex,'g'); expression = new RegExp(CMIIndex,'g');
elementmodel = String(element).replace(expression,'.n.'); elementmodel = String(element).replace(expression,'.n.');
if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"]')) != "undefined") {
if (eval('datamodel["'+elementmodel+'"].mod') != 'r') { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].mod') != 'r') {
elementstring = '&'+underscore(element)+'='+escape(data[property]); elementstring = '&'+underscore(element)+'='+escape(data[property]);
if ((typeof eval('datamodel["'+elementmodel+'"].defaultvalue')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"].defaultvalue')) != "undefined") {
if (eval('datamodel["'+elementmodel+'"].defaultvalue') != data[property]) { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].defaultvalue') != data[property]) {
datastring += elementstring; datastring += elementstring;
} }
} else { } else {
@ -502,7 +514,7 @@ function AICCapi(def, cmiobj, scormauto, cfgwwwroot, scormid, scoid, attempt, vi
} }
} }
if (cmi.core.lesson_mode == 'browse') { if (cmi.core.lesson_mode == 'browse') {
if (datamodel['cmi.core.lesson_status'].defaultvalue == '' && cmi.core.lesson_status == 'not attempted') { if (datamodel[scoid]['cmi.core.lesson_status'].defaultvalue == '' && cmi.core.lesson_status == 'not attempted') {
cmi.core.lesson_status = 'browsed'; cmi.core.lesson_status = 'browsed';
} }
} }

View file

@ -17,37 +17,50 @@
require_once($CFG->dirroot.'/mod/scorm/locallib.php'); require_once($CFG->dirroot.'/mod/scorm/locallib.php');
$userdata = new stdClass(); $userdata = new stdClass();
$def = get_scorm_default($userdata, $scorm, $scoid, $attempt, $mode); $def = new stdClass();
$cmiobj = new stdClass();
if (!isset($currentorg)) { if (!isset($currentorg)) {
$currentorg = ''; $currentorg = '';
} }
$cmiobj = ''; if ($scoes = $DB->get_records('scorm_scoes', array('scorm' => $scorm->id), 'sortorder, id')) {
$currentobj = ''; // Drop keys so that it is a simple array.
$count = 0; $scoes = array_values($scoes);
foreach ($userdata as $element => $value) { foreach ($scoes as $sco) {
if (substr($element, 0, 14) == 'cmi.objectives') { $def->{($sco->id)} = new stdClass();
$element = preg_replace('/\.(\d+)\./', "_\$1.", $element); $userdata->{($sco->id)} = new stdClass();
preg_match('/\_(\d+)\./', $element, $matches); $def->{($sco->id)} = get_scorm_default($userdata->{($sco->id)}, $scorm, $sco->id, $attempt, $mode);
if (count($matches) > 0 && $currentobj != $matches[1]) {
$currentobj = $matches[1]; // Reconstitute objectives, comments_from_learner and comments_from_lms.
$count++; $cmiobj->{($sco->id)} = '';
$end = strpos($element, $matches[1])+strlen($matches[1]); $currentobj = '';
$subelement = substr($element, 0, $end); $count = 0;
$cmiobj .= ' '.$subelement." = new Object();\n"; foreach ($userdata as $element => $value) {
$cmiobj .= ' '.$subelement.".score = new Object();\n"; if (substr($element, 0, 14) == 'cmi.objectives') {
$cmiobj .= ' '.$subelement.".score._children = score_children;\n"; $element = preg_replace('/\.(\d+)\./', "_\$1.", $element);
$cmiobj .= ' '.$subelement.".score.raw = '';\n"; preg_match('/\_(\d+)\./', $element, $matches);
$cmiobj .= ' '.$subelement.".score.min = '';\n"; if (count($matches) > 0 && $currentobj != $matches[1]) {
$cmiobj .= ' '.$subelement.".score.max = '';\n"; $currentobj = $matches[1];
$count++;
$end = strpos($element, $matches[1]) + strlen($matches[1]);
$subelement = substr($element, 0, $end);
$cmiobj->{($sco->id)} .= ' '.$subelement." = new Object();\n";
$cmiobj->{($sco->id)} .= ' '.$subelement.".score = new Object();\n";
$cmiobj->{($sco->id)} .= ' '.$subelement.".score._children = score_children;\n";
$cmiobj->{($sco->id)} .= ' '.$subelement.".score.raw = '';\n";
$cmiobj->{($sco->id)} .= ' '.$subelement.".score.min = '';\n";
$cmiobj->{($sco->id)} .= ' '.$subelement.".score.max = '';\n";
}
$cmiobj->{($sco->id)} .= ' '.$element.' = \''.$value."';\n";
}
}
if ($count > 0) {
$cmiobj->{($sco->id)} .= ' cmi.objectives._count = '.$count.";\n";
} }
$cmiobj .= ' '.$element.' = \''.$value."';\n";
} }
} }
if ($count > 0) {
$cmiobj .= ' cmi.objectives._count = '.$count.";\n";
}
$PAGE->requires->js_init_call('M.scorm_api.init', array($def, $cmiobj, $scorm->auto, $CFG->wwwroot, $scorm->id, $scoid, $attempt, $PAGE->requires->js_init_call('M.scorm_api.init', array($def, $cmiobj, $scorm->auto, $CFG->wwwroot, $scorm->id, $scoid, $attempt,
$mode, $currentorg, sesskey(), $id)); $mode, $currentorg, sesskey(), $id));

View file

@ -736,7 +736,7 @@ function LogAPICall(func, nam, val, rc) {
if (func.match(/GetValue/)) { if (func.match(/GetValue/)) {
s += ' - ' + val; s += ' - ' + val;
} }
s += ' => ' + String(rc); s += ' => ' + String(rc) + " scoid = " + scorm_current_node.scoid;
AppendToLog(s, rc); AppendToLog(s, rc);
<?php <?php
if (scorm_debugging($scorm) && ($sco->scormtype == 'asset')) { if (scorm_debugging($scorm) && ($sco->scormtype == 'asset')) {

View file

@ -56,99 +56,111 @@ function SCORMapi1_2(def, cmiobj, cmiint, cmistring256, cmistring4096, scormdebu
speed_range = '-100#100'; speed_range = '-100#100';
weighting_range = '-100#100'; weighting_range = '-100#100';
text_range = '-1#1'; text_range = '-1#1';
// The SCORM 1.2 data model // The SCORM 1.2 data model
var datamodel = { // Set up data model for each sco
'cmi._children':{'defaultvalue':cmi_children, 'mod':'r', 'writeerror':'402'}, var datamodel = {};
'cmi._version':{'defaultvalue':'3.4', 'mod':'r', 'writeerror':'402'}, for(scoid in def){
'cmi.core._children':{'defaultvalue':core_children, 'mod':'r', 'writeerror':'402'}, datamodel[scoid] = {
'cmi.core.student_id':{'defaultvalue':def['cmi.core.student_id'], 'mod':'r', 'writeerror':'403'}, 'cmi._children':{'defaultvalue':cmi_children, 'mod':'r', 'writeerror':'402'},
'cmi.core.student_name':{'defaultvalue':def['cmi.core.student_name'], 'mod':'r', 'writeerror':'403'}, 'cmi._version':{'defaultvalue':'3.4', 'mod':'r', 'writeerror':'402'},
'cmi.core.lesson_location':{'defaultvalue':def['cmi.core.lesson_location'], 'format':CMIString256, 'mod':'rw', 'writeerror':'405'}, 'cmi.core._children':{'defaultvalue':core_children, 'mod':'r', 'writeerror':'402'},
'cmi.core.credit':{'defaultvalue':def['cmi.core.credit'], 'mod':'r', 'writeerror':'403'}, 'cmi.core.student_id':{'defaultvalue':def[scoid]['cmi.core.student_id'], 'mod':'r', 'writeerror':'403'},
'cmi.core.lesson_status':{'defaultvalue':def['cmi.core.lesson_status'], 'format':CMIStatus, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.student_name':{'defaultvalue':def[scoid]['cmi.core.student_name'], 'mod':'r', 'writeerror':'403'},
'cmi.core.entry':{'defaultvalue':def['cmi.core.entry'], 'mod':'r', 'writeerror':'403'}, 'cmi.core.lesson_location':{'defaultvalue':def[scoid]['cmi.core.lesson_location'], 'format':CMIString256, 'mod':'rw', 'writeerror':'405'},
'cmi.core.score._children':{'defaultvalue':score_children, 'mod':'r', 'writeerror':'402'}, 'cmi.core.credit':{'defaultvalue':def[scoid]['cmi.core.credit'], 'mod':'r', 'writeerror':'403'},
'cmi.core.score.raw':{'defaultvalue':def['cmi.core.score.raw'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.lesson_status':{'defaultvalue':def[scoid]['cmi.core.lesson_status'], 'format':CMIStatus, 'mod':'rw', 'writeerror':'405'},
'cmi.core.score.max':{'defaultvalue':def['cmi.core.score.max'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.entry':{'defaultvalue':def[scoid]['cmi.core.entry'], 'mod':'r', 'writeerror':'403'},
'cmi.core.score.min':{'defaultvalue':def['cmi.core.score.min'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.score._children':{'defaultvalue':score_children, 'mod':'r', 'writeerror':'402'},
'cmi.core.total_time':{'defaultvalue':def['cmi.core.total_time'], 'mod':'r', 'writeerror':'403'}, 'cmi.core.score.raw':{'defaultvalue':def[scoid]['cmi.core.score.raw'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.core.lesson_mode':{'defaultvalue':def['cmi.core.lesson_mode'], 'mod':'r', 'writeerror':'403'}, 'cmi.core.score.max':{'defaultvalue':def[scoid]['cmi.core.score.max'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.core.exit':{'defaultvalue':def['cmi.core.exit'], 'format':CMIExit, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.core.score.min':{'defaultvalue':def[scoid]['cmi.core.score.min'], 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.core.session_time':{'format':CMITimespan, 'mod':'w', 'defaultvalue':'00:00:00', 'readerror':'404', 'writeerror':'405'}, 'cmi.core.total_time':{'defaultvalue':def[scoid]['cmi.core.total_time'], 'mod':'r', 'writeerror':'403'},
'cmi.suspend_data':{'defaultvalue':def['cmi.suspend_data'], 'format':CMIString4096, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.lesson_mode':{'defaultvalue':def[scoid]['cmi.core.lesson_mode'], 'mod':'r', 'writeerror':'403'},
'cmi.launch_data':{'defaultvalue':def['cmi.launch_data'], 'mod':'r', 'writeerror':'403'}, 'cmi.core.exit':{'defaultvalue':def[scoid]['cmi.core.exit'], 'format':CMIExit, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.comments':{'defaultvalue':def['cmi.comments'], 'format':CMIString4096, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.session_time':{'format':CMITimespan, 'mod':'w', 'defaultvalue':'00:00:00', 'readerror':'404', 'writeerror':'405'},
// deprecated evaluation attributes 'cmi.suspend_data':{'defaultvalue':def[scoid]['cmi.suspend_data'], 'format':CMIString4096, 'mod':'rw', 'writeerror':'405'},
'cmi.evaluation.comments._count':{'defaultvalue':'0', 'mod':'r', 'writeerror':'402'}, 'cmi.launch_data':{'defaultvalue':def[scoid]['cmi.launch_data'], 'mod':'r', 'writeerror':'403'},
'cmi.evaluation.comments._children':{'defaultvalue':comments_children, 'mod':'r', 'writeerror':'402'}, 'cmi.comments':{'defaultvalue':def[scoid]['cmi.comments'], 'format':CMIString4096, 'mod':'rw', 'writeerror':'405'},
'cmi.evaluation.comments.n.content':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIString256, 'mod':'rw', 'writeerror':'405'}, // deprecated evaluation attributes
'cmi.evaluation.comments.n.location':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIString256, 'mod':'rw', 'writeerror':'405'}, 'cmi.evaluation.comments._count':{'defaultvalue':'0', 'mod':'r', 'writeerror':'402'},
'cmi.evaluation.comments.n.time':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMITime, 'mod':'rw', 'writeerror':'405'}, 'cmi.evaluation.comments._children':{'defaultvalue':comments_children, 'mod':'r', 'writeerror':'402'},
'cmi.comments_from_lms':{'mod':'r', 'writeerror':'403'}, 'cmi.evaluation.comments.n.content':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIString256, 'mod':'rw', 'writeerror':'405'},
'cmi.objectives._children':{'defaultvalue':objectives_children, 'mod':'r', 'writeerror':'402'}, 'cmi.evaluation.comments.n.location':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIString256, 'mod':'rw', 'writeerror':'405'},
'cmi.objectives._count':{'mod':'r', 'defaultvalue':'0', 'writeerror':'402'}, 'cmi.evaluation.comments.n.time':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMITime, 'mod':'rw', 'writeerror':'405'},
'cmi.objectives.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'rw', 'writeerror':'405'}, 'cmi.comments_from_lms':{'mod':'r', 'writeerror':'403'},
'cmi.objectives.n.score._children':{'pattern':CMIIndex, 'mod':'r', 'writeerror':'402'}, 'cmi.objectives._children':{'defaultvalue':objectives_children, 'mod':'r', 'writeerror':'402'},
'cmi.objectives.n.score.raw':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.objectives._count':{'mod':'r', 'defaultvalue':'0', 'writeerror':'402'},
'cmi.objectives.n.score.min':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.objectives.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'rw', 'writeerror':'405'},
'cmi.objectives.n.score.max':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.objectives.n.score._children':{'pattern':CMIIndex, 'mod':'r', 'writeerror':'402'},
'cmi.objectives.n.status':{'pattern':CMIIndex, 'format':CMIStatus2, 'mod':'rw', 'writeerror':'405'}, 'cmi.objectives.n.score.raw':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data._children':{'defaultvalue':student_data_children, 'mod':'r', 'writeerror':'402'}, 'cmi.objectives.n.score.min':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data.mastery_score':{'defaultvalue':def['cmi.student_data.mastery_score'], 'mod':'r', 'writeerror':'403'}, 'cmi.objectives.n.score.max':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data.max_time_allowed':{'defaultvalue':def['cmi.student_data.max_time_allowed'], 'mod':'r', 'writeerror':'403'}, 'cmi.objectives.n.status':{'pattern':CMIIndex, 'format':CMIStatus2, 'mod':'rw', 'writeerror':'405'},
'cmi.student_data.time_limit_action':{'defaultvalue':def['cmi.student_data.time_limit_action'], 'mod':'r', 'writeerror':'403'}, 'cmi.student_data._children':{'defaultvalue':student_data_children, 'mod':'r', 'writeerror':'402'},
'cmi.student_preference._children':{'defaultvalue':student_preference_children, 'mod':'r', 'writeerror':'402'}, 'cmi.student_data.mastery_score':{'defaultvalue':def[scoid]['cmi.student_data.mastery_score'], 'mod':'r', 'writeerror':'403'},
'cmi.student_preference.audio':{'defaultvalue':'0', 'format':CMISInteger, 'range':audio_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_data.max_time_allowed':{'defaultvalue':def[scoid]['cmi.student_data.max_time_allowed'], 'mod':'r', 'writeerror':'403'},
'cmi.student_preference.language':{'defaultvalue':'', 'format':CMIString256, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_data.time_limit_action':{'defaultvalue':def[scoid]['cmi.student_data.time_limit_action'], 'mod':'r', 'writeerror':'403'},
'cmi.student_preference.speed':{'defaultvalue':'0', 'format':CMISInteger, 'range':speed_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_preference._children':{'defaultvalue':student_preference_children, 'mod':'r', 'writeerror':'402'},
'cmi.student_preference.text':{'defaultvalue':'0', '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.interactions._children':{'defaultvalue':interactions_children, 'mod':'r', 'writeerror':'402'}, 'cmi.student_preference.language':{'defaultvalue':'', 'format':CMIString256, 'mod':'rw', 'writeerror':'405'},
'cmi.interactions._count':{'mod':'r', 'defaultvalue':'0', 'writeerror':'402'}, 'cmi.student_preference.speed':{'defaultvalue':'0', 'format':CMISInteger, 'range':speed_range, 'mod':'rw', 'writeerror':'405'},
'cmi.interactions.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.student_preference.text':{'defaultvalue':'0', 'format':CMISInteger, 'range':text_range, 'mod':'rw', 'writeerror':'405'},
'cmi.interactions.n.objectives._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0', 'writeerror':'402'}, 'cmi.interactions._children':{'defaultvalue':interactions_children, 'mod':'r', 'writeerror':'402'},
'cmi.interactions.n.objectives.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions._count':{'mod':'r', 'defaultvalue':'0', 'writeerror':'402'},
'cmi.interactions.n.time':{'pattern':CMIIndex, 'format':CMITime, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.type':{'pattern':CMIIndex, 'format':CMIType, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.objectives._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0', 'writeerror':'402'},
'cmi.interactions.n.correct_responses._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0', 'writeerror':'402'}, 'cmi.interactions.n.objectives.n.id':{'pattern':CMIIndex, 'format':CMIIdentifier, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.correct_responses.n.pattern':{'pattern':CMIIndex, 'format':CMIFeedback, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.time':{'pattern':CMIIndex, 'format':CMITime, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.weighting':{'pattern':CMIIndex, 'format':CMIDecimal, 'range':weighting_range, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.type':{'pattern':CMIIndex, 'format':CMIType, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.student_response':{'pattern':CMIIndex, 'format':CMIFeedback, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.correct_responses._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0', 'writeerror':'402'},
'cmi.interactions.n.result':{'pattern':CMIIndex, 'format':CMIResult, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.correct_responses.n.pattern':{'pattern':CMIIndex, 'format':CMIFeedback, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'cmi.interactions.n.latency':{'pattern':CMIIndex, 'format':CMITimespan, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.interactions.n.weighting':{'pattern':CMIIndex, 'format':CMIDecimal, 'range':weighting_range, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
'nav.event':{'defaultvalue':'', 'format':NAVEvent, 'mod':'w', 'readerror':'404', 'writeerror':'405'} 'cmi.interactions.n.student_response':{'pattern':CMIIndex, 'format':CMIFeedback, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
}; 'cmi.interactions.n.result':{'pattern':CMIIndex, 'format':CMIResult, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
// 'cmi.interactions.n.latency':{'pattern':CMIIndex, 'format':CMITimespan, 'mod':'w', 'readerror':'404', 'writeerror':'405'},
// Datamodel inizialization 'nav.event':{'defaultvalue':'', 'format':NAVEvent, 'mod':'w', 'readerror':'404', 'writeerror':'405'}
// };
var cmi = new Object();
cmi.core = new Object();
cmi.core.score = new Object();
cmi.objectives = new Object();
cmi.student_data = new Object();
cmi.student_preference = new Object();
cmi.interactions = new Object();
// deprecated evaluation attributes
cmi.evaluation = new Object();
cmi.evaluation.comments = new Object();
// Navigation Object
var nav = new Object();
for (element in datamodel) {
if (element.match(/\.n\./) == null) {
if ((typeof eval('datamodel["'+element+'"].defaultvalue')) != 'undefined') {
eval(element+' = datamodel["'+element+'"].defaultvalue;');
} else {
eval(element+' = "";');
}
}
} }
eval(cmiobj); var cmi, nav;
eval(cmiint); function initdatamodel(scoid){
prerequrl = cfgwwwroot + "/mod/scorm/prereqs.php?a="+scormid+"&scoid="+scoid+"&attempt="+attempt+"&mode="+viewmode+"&currentorg="+currentorg+"&sesskey="+sesskey;
datamodelurlparams = "id="+cmid+"&a="+scormid+"&sesskey="+sesskey+"&attempt="+attempt+"&scoid="+scoid;
if (cmi.core.lesson_status == '') { //
cmi.core.lesson_status = 'not attempted'; // Datamodel inizialization
//
cmi = new Object();
cmi.core = new Object();
cmi.core.score = new Object();
cmi.objectives = new Object();
cmi.student_data = new Object();
cmi.student_preference = new Object();
cmi.interactions = new Object();
// deprecated evaluation attributes
cmi.evaluation = new Object();
cmi.evaluation.comments = new Object();
// Navigation Object
nav = new Object();
for (element in datamodel[scoid]) {
if (element.match(/\.n\./) == null) {
if ((typeof eval('datamodel["'+scoid+'"]["'+element+'"].defaultvalue')) != 'undefined') {
eval(element+' = datamodel["'+scoid+'"]["'+element+'"].defaultvalue;');
} else {
eval(element+' = "";');
}
}
}
eval(cmiobj[scoid]);
eval(cmiint[scoid]);
if (cmi.core.lesson_status == '') {
cmi.core.lesson_status = 'not attempted';
}
} }
// //
@ -157,6 +169,9 @@ function SCORMapi1_2(def, cmiobj, cmiint, cmistring256, cmistring4096, scormdebu
var Initialized = false; var Initialized = false;
function LMSInitialize (param) { function LMSInitialize (param) {
scoid = scorm_current_node ? scorm_current_node.scoid : scoid ;
initdatamodel(scoid);
errorCode = "0"; errorCode = "0";
if (param == "") { if (param == "") {
if (!Initialized) { if (!Initialized) {
@ -229,8 +244,8 @@ function SCORMapi1_2(def, cmiobj, cmiint, cmistring256, cmistring4096, scormdebu
if (element !="") { if (element !="") {
expression = new RegExp(CMIIndex,'g'); expression = new RegExp(CMIIndex,'g');
elementmodel = String(element).replace(expression,'.n.'); elementmodel = String(element).replace(expression,'.n.');
if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"]')) != "undefined") {
if (eval('datamodel["'+elementmodel+'"].mod') != 'w') { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].mod') != 'w') {
element = String(element).replace(expression, "_$1."); element = String(element).replace(expression, "_$1.");
elementIndexes = element.split('.'); elementIndexes = element.split('.');
subelement = 'cmi'; subelement = 'cmi';
@ -248,21 +263,21 @@ function SCORMapi1_2(def, cmiobj, cmiint, cmistring256, cmistring4096, scormdebu
errorCode = "0"; // Need to check if it is the right errorCode errorCode = "0"; // Need to check if it is the right errorCode
} }
} else { } else {
errorCode = eval('datamodel["'+elementmodel+'"].readerror'); errorCode = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].readerror');
} }
} else { } else {
childrenstr = '._children'; childrenstr = '._children';
countstr = '._count'; countstr = '._count';
if (elementmodel.substr(elementmodel.length-childrenstr.length,elementmodel.length) == childrenstr) { if (elementmodel.substr(elementmodel.length-childrenstr.length,elementmodel.length) == childrenstr) {
parentmodel = elementmodel.substr(0,elementmodel.length-childrenstr.length); parentmodel = elementmodel.substr(0,elementmodel.length-childrenstr.length);
if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+parentmodel+'"]')) != "undefined") {
errorCode = "202"; errorCode = "202";
} else { } else {
errorCode = "201"; errorCode = "201";
} }
} else if (elementmodel.substr(elementmodel.length-countstr.length,elementmodel.length) == countstr) { } else if (elementmodel.substr(elementmodel.length-countstr.length,elementmodel.length) == countstr) {
parentmodel = elementmodel.substr(0,elementmodel.length-countstr.length); parentmodel = elementmodel.substr(0,elementmodel.length-countstr.length);
if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+parentmodel+'"]')) != "undefined") {
errorCode = "203"; errorCode = "203";
} else { } else {
errorCode = "201"; errorCode = "201";
@ -289,9 +304,9 @@ function SCORMapi1_2(def, cmiobj, cmiint, cmistring256, cmistring4096, scormdebu
if (element != "") { if (element != "") {
expression = new RegExp(CMIIndex,'g'); expression = new RegExp(CMIIndex,'g');
elementmodel = String(element).replace(expression,'.n.'); elementmodel = String(element).replace(expression,'.n.');
if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"]')) != "undefined") {
if (eval('datamodel["'+elementmodel+'"].mod') != 'r') { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].mod') != 'r') {
expression = new RegExp(eval('datamodel["'+elementmodel+'"].format')); expression = new RegExp(eval('datamodel["'+scoid+'"]["'+elementmodel+'"].format'));
value = value+''; value = value+'';
matches = value.match(expression); matches = value.match(expression);
if (matches != null) { if (matches != null) {
@ -338,8 +353,8 @@ function SCORMapi1_2(def, cmiobj, cmiint, cmistring256, cmistring4096, scormdebu
} }
//Store data //Store data
if (errorCode == "0") { if (errorCode == "0") {
if ((typeof eval('datamodel["'+elementmodel+'"].range')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"].range')) != "undefined") {
range = eval('datamodel["'+elementmodel+'"].range'); range = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].range');
ranges = range.split('#'); ranges = range.split('#');
value = value*1.0; value = value*1.0;
if ((value >= ranges[0]) && (value <= ranges[1])) { if ((value >= ranges[0]) && (value <= ranges[1])) {
@ -350,7 +365,7 @@ function SCORMapi1_2(def, cmiobj, cmiint, cmistring256, cmistring4096, scormdebu
} }
return "true"; return "true";
} else { } else {
errorCode = eval('datamodel["'+elementmodel+'"].writeerror'); errorCode = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].writeerror');
} }
} else { } else {
if (element == 'cmi.comments') { if (element == 'cmi.comments') {
@ -366,10 +381,10 @@ function SCORMapi1_2(def, cmiobj, cmiint, cmistring256, cmistring4096, scormdebu
} }
} }
} else { } else {
errorCode = eval('datamodel["'+elementmodel+'"].writeerror'); errorCode = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].writeerror');
} }
} else { } else {
errorCode = eval('datamodel["'+elementmodel+'"].writeerror'); errorCode = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].writeerror');
} }
} else { } else {
errorCode = "201" errorCode = "201"
@ -535,40 +550,40 @@ function SCORMapi1_2(def, cmiobj, cmiint, cmistring256, cmistring4096, scormdebu
// check if this specific element is not defined in the datamodel, // check if this specific element is not defined in the datamodel,
// but the generic element name is // but the generic element name is
if ((eval('typeof datamodel["'+element+'"]')) == "undefined" if ((eval('typeof datamodel["'+scoid+'"]["'+element+'"]')) == "undefined"
&& (eval('typeof datamodel["'+elementmodel+'"]')) != "undefined") { && (eval('typeof datamodel["'+scoid+'"]["'+elementmodel+'"]')) != "undefined") {
// add this specific element to the data model (by cloning // add this specific element to the data model (by cloning
// the generic element) so we can track changes to it // the generic element) so we can track changes to it
eval('datamodel["'+element+'"]=CloneObj(datamodel["'+elementmodel+'"]);'); eval('datamodel["'+scoid+'"]["'+element+'"]=CloneObj(datamodel["'+scoid+'"]["'+elementmodel+'"]);');
} }
// check if the current element exists in the datamodel // check if the current element exists in the datamodel
if ((typeof eval('datamodel["'+element+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+element+'"]')) != "undefined") {
// make sure this is not a read only element // make sure this is not a read only element
if (eval('datamodel["'+element+'"].mod') != 'r') { if (eval('datamodel["'+scoid+'"]["'+element+'"].mod') != 'r') {
elementstring = '&'+underscore(element)+'='+encodeURIComponent(data[property]); elementstring = '&'+underscore(element)+'='+encodeURIComponent(data[property]);
// check if the element has a default value // check if the element has a default value
if ((typeof eval('datamodel["'+element+'"].defaultvalue')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+element+'"].defaultvalue')) != "undefined") {
// check if the default value is different from the current value // check if the default value is different from the current value
if (eval('datamodel["'+element+'"].defaultvalue') != data[property] if (eval('datamodel["'+scoid+'"]["'+element+'"].defaultvalue') != data[property]
|| eval('typeof(datamodel["'+element+'"].defaultvalue)') != typeof(data[property])) { || eval('typeof(datamodel["'+scoid+'"]["'+element+'"].defaultvalue)') != typeof(data[property])) {
// append the URI fragment to the string we plan to commit // append the URI fragment to the string we plan to commit
datastring += elementstring; datastring += elementstring;
// update the element default to reflect the current committed value // update the element default to reflect the current committed value
eval('datamodel["'+element+'"].defaultvalue=data[property];'); eval('datamodel["'+scoid+'"]["'+element+'"].defaultvalue=data[property];');
} }
} else { } else {
// append the URI fragment to the string we plan to commit // append the URI fragment to the string we plan to commit
datastring += elementstring; datastring += elementstring;
// no default value for the element, so set it now // no default value for the element, so set it now
eval('datamodel["'+element+'"].defaultvalue=data[property];'); eval('datamodel["'+scoid+'"]["'+element+'"].defaultvalue=data[property];');
} }
} }
} }
@ -608,7 +623,7 @@ function SCORMapi1_2(def, cmiobj, cmiint, cmistring256, cmistring4096, scormdebu
} }
} }
if (cmi.core.lesson_mode == 'browse') { if (cmi.core.lesson_mode == 'browse') {
if (datamodel['cmi.core.lesson_status'].defaultvalue == '' && cmi.core.lesson_status == 'not attempted') { if (datamodel[scoid]['cmi.core.lesson_status'].defaultvalue == '' && cmi.core.lesson_status == 'not attempted') {
cmi.core.lesson_status = 'browsed'; cmi.core.lesson_status = 'browsed';
} }
} }

View file

@ -18,12 +18,30 @@ require_once($CFG->dirroot.'/mod/scorm/locallib.php');
// Set some vars to use as default values. // Set some vars to use as default values.
$userdata = new stdClass(); $userdata = new stdClass();
$def = get_scorm_default($userdata, $scorm, $scoid, $attempt, $mode); $def = new stdClass();
$cmiobj = new stdClass();
$cmiint = new stdClass();
if (!isset($currentorg)) { if (!isset($currentorg)) {
$currentorg = ''; $currentorg = '';
} }
if ($scoes = $DB->get_records('scorm_scoes', array('scorm' => $scorm->id), 'sortorder, id')) {
// Drop keys so that it is a simple array.
$scoes = array_values($scoes);
foreach ($scoes as $sco) {
$def->{($sco->id)} = new stdClass();
$userdata->{($sco->id)} = new stdClass();
$def->{($sco->id)} = get_scorm_default($userdata->{($sco->id)}, $scorm, $sco->id, $attempt, $mode);
// Reconstitute objectives.
$cmiobj->{($sco->id)} = scorm_reconstitute_array_element($scorm->version, $userdata->{($sco->id)},
'cmi.objectives', array('score'));
$cmiint->{($sco->id)} = scorm_reconstitute_array_element($scorm->version, $userdata->{($sco->id)},
'cmi.interactions', array('objectives', 'correct_responses'));
}
}
// If SCORM 1.2 standard mode is disabled allow higher datamodel limits. // If SCORM 1.2 standard mode is disabled allow higher datamodel limits.
if (intval(get_config("scorm", "scorm12standard"))) { if (intval(get_config("scorm", "scorm12standard"))) {
$cmistring256 = '^[\\u0000-\\uFFFF]{0,255}$'; $cmistring256 = '^[\\u0000-\\uFFFF]{0,255}$';
@ -33,10 +51,6 @@ if (intval(get_config("scorm", "scorm12standard"))) {
$cmistring4096 = $cmistring256; $cmistring4096 = $cmistring256;
} }
// reconstitute objectives
$cmiobj = scorm_reconstitute_array_element($scorm->version, $userdata, 'cmi.objectives', array('score'));
$cmiint = scorm_reconstitute_array_element($scorm->version, $userdata, 'cmi.interactions', array('objectives', 'correct_responses'));
$PAGE->requires->js_init_call('M.scorm_api.init', array($def, $cmiobj, $cmiint, $cmistring256, $cmistring4096, $PAGE->requires->js_init_call('M.scorm_api.init', array($def, $cmiobj, $cmiint, $cmistring256, $cmistring4096,
scorm_debugging($scorm), $scorm->auto, $scorm->id, $CFG->wwwroot, scorm_debugging($scorm), $scorm->auto, $scorm->id, $CFG->wwwroot,
sesskey(), $scoid, $attempt, $mode, $id, $currentorg)); sesskey(), $scoid, $attempt, $mode, $id, $currentorg));

View file

@ -150,112 +150,123 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
} }
// The SCORM 1.3 data model // The SCORM 1.3 data model
var datamodel = { // Set up data model for each sco
'cmi._children':{'defaultvalue':cmi_children, 'mod':'r'}, var datamodel = {};
'cmi._version':{'defaultvalue':'1.0', 'mod':'r'}, for(scoid in def){
'cmi.comments_from_learner._children':{'defaultvalue':comments_children, 'mod':'r'}, datamodel[scoid] = {
'cmi.comments_from_learner._count':{'mod':'r', 'defaultvalue':'0'}, 'cmi._children':{'defaultvalue':cmi_children, 'mod':'r'},
'cmi.comments_from_learner.n.comment':{'format':CMILangString4000, 'mod':'rw'}, 'cmi._version':{'defaultvalue':'1.0', 'mod':'r'},
'cmi.comments_from_learner.n.location':{'format':CMIString250, 'mod':'rw'}, 'cmi.comments_from_learner._children':{'defaultvalue':comments_children, 'mod':'r'},
'cmi.comments_from_learner.n.timestamp':{'format':CMITime, 'mod':'rw'}, 'cmi.comments_from_learner._count':{'mod':'r', 'defaultvalue':'0'},
'cmi.comments_from_lms._children':{'defaultvalue':comments_children, 'mod':'r'}, 'cmi.comments_from_learner.n.comment':{'format':CMILangString4000, 'mod':'rw'},
'cmi.comments_from_lms._count':{'mod':'r', 'defaultvalue':'0'}, 'cmi.comments_from_learner.n.location':{'format':CMIString250, 'mod':'rw'},
'cmi.comments_from_lms.n.comment':{'format':CMILangString4000, 'mod':'r'}, 'cmi.comments_from_learner.n.timestamp':{'format':CMITime, 'mod':'rw'},
'cmi.comments_from_lms.n.location':{'format':CMIString250, 'mod':'r'}, 'cmi.comments_from_lms._children':{'defaultvalue':comments_children, 'mod':'r'},
'cmi.comments_from_lms.n.timestamp':{'format':CMITime, 'mod':'r'}, 'cmi.comments_from_lms._count':{'mod':'r', 'defaultvalue':'0'},
'cmi.completion_status':{'defaultvalue':def['cmi.completion_status'], 'format':CMICStatus, 'mod':'rw'}, 'cmi.comments_from_lms.n.comment':{'format':CMILangString4000, 'mod':'r'},
'cmi.completion_threshold':{'defaultvalue':def['cmi.completion_threshold'], 'mod':'r'}, 'cmi.comments_from_lms.n.location':{'format':CMIString250, 'mod':'r'},
'cmi.credit':{'defaultvalue':def['cmi.credit'], 'mod':'r'}, 'cmi.comments_from_lms.n.timestamp':{'format':CMITime, 'mod':'r'},
'cmi.entry':{'defaultvalue':def['cmi.entry'], 'mod':'r'}, 'cmi.completion_status':{'defaultvalue':def[scoid]['cmi.completion_status'], 'format':CMICStatus, 'mod':'rw'},
'cmi.exit':{'defaultvalue':def['cmi.exit'], 'format':CMIExit, 'mod':'w'}, 'cmi.completion_threshold':{'defaultvalue':def[scoid]['cmi.completion_threshold'], 'mod':'r'},
'cmi.interactions._children':{'defaultvalue':interactions_children, 'mod':'r'}, 'cmi.credit':{'defaultvalue':def[scoid]['cmi.credit'], 'mod':'r'},
'cmi.interactions._count':{'mod':'r', 'defaultvalue':'0'}, 'cmi.entry':{'defaultvalue':def[scoid]['cmi.entry'], 'mod':'r'},
'cmi.interactions.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'}, 'cmi.exit':{'defaultvalue':def[scoid]['cmi.exit'], 'format':CMIExit, 'mod':'w'},
'cmi.interactions.n.type':{'pattern':CMIIndex, 'format':CMIType, 'mod':'rw'}, 'cmi.interactions._children':{'defaultvalue':interactions_children, 'mod':'r'},
'cmi.interactions.n.objectives._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0'}, 'cmi.interactions._count':{'mod':'r', 'defaultvalue':'0'},
'cmi.interactions.n.objectives.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'}, 'cmi.interactions.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'},
'cmi.interactions.n.timestamp':{'pattern':CMIIndex, 'format':CMITime, 'mod':'rw'}, 'cmi.interactions.n.type':{'pattern':CMIIndex, 'format':CMIType, 'mod':'rw'},
'cmi.interactions.n.correct_responses._count':{'defaultvalue':'0', 'pattern':CMIIndex, 'mod':'r'}, 'cmi.interactions.n.objectives._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0'},
'cmi.interactions.n.correct_responses.n.pattern':{'pattern':CMIIndex, 'format':'CMIFeedback', 'mod':'rw'}, 'cmi.interactions.n.objectives.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'},
'cmi.interactions.n.weighting':{'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'}, 'cmi.interactions.n.timestamp':{'pattern':CMIIndex, 'format':CMITime, 'mod':'rw'},
'cmi.interactions.n.learner_response':{'pattern':CMIIndex, 'format':'CMIFeedback', 'mod':'rw'}, 'cmi.interactions.n.correct_responses._count':{'defaultvalue':'0', 'pattern':CMIIndex, 'mod':'r'},
'cmi.interactions.n.result':{'pattern':CMIIndex, 'format':CMIResult, 'mod':'rw'}, 'cmi.interactions.n.correct_responses.n.pattern':{'pattern':CMIIndex, 'format':'CMIFeedback', 'mod':'rw'},
'cmi.interactions.n.latency':{'pattern':CMIIndex, 'format':CMITimespan, 'mod':'rw'}, 'cmi.interactions.n.weighting':{'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'},
'cmi.interactions.n.description':{'pattern':CMIIndex, 'format':CMILangString250, 'mod':'rw'}, 'cmi.interactions.n.learner_response':{'pattern':CMIIndex, 'format':'CMIFeedback', 'mod':'rw'},
'cmi.launch_data':{'defaultvalue':def['cmi.exit'], 'mod':'r'}, 'cmi.interactions.n.result':{'pattern':CMIIndex, 'format':CMIResult, 'mod':'rw'},
'cmi.learner_id':{'defaultvalue':def['cmi.learner_id'], 'mod':'r'}, 'cmi.interactions.n.latency':{'pattern':CMIIndex, 'format':CMITimespan, 'mod':'rw'},
'cmi.learner_name':{'defaultvalue':def['cmi.learner_name'], 'mod':'r'}, 'cmi.interactions.n.description':{'pattern':CMIIndex, 'format':CMILangString250, 'mod':'rw'},
'cmi.learner_preference._children':{'defaultvalue':student_preference_children, 'mod':'r'}, 'cmi.launch_data':{'defaultvalue':def[scoid]['cmi.exit'], 'mod':'r'},
'cmi.learner_preference.audio_level':{'defaultvalue':def['cmi.learner_preference.audio_level'], 'format':CMIDecimal, 'range':audio_range, 'mod':'rw'}, 'cmi.learner_id':{'defaultvalue':def[scoid]['cmi.learner_id'], 'mod':'r'},
'cmi.learner_preference.language':{'defaultvalue':def['cmi.learner_preference.language'], 'format':CMILang, 'mod':'rw'}, 'cmi.learner_name':{'defaultvalue':def[scoid]['cmi.learner_name'], 'mod':'r'},
'cmi.learner_preference.delivery_speed':{'defaultvalue':def['cmi.learner_preference.delivery_speed'], 'format':CMIDecimal, 'range':speed_range, 'mod':'rw'}, 'cmi.learner_preference._children':{'defaultvalue':student_preference_children, 'mod':'r'},
'cmi.learner_preference.audio_captioning':{'defaultvalue':def['cmi.learner_preference.audio_captioning'], 'format':CMISInteger, 'range':text_range, 'mod':'rw'}, 'cmi.learner_preference.audio_level':{'defaultvalue':def[scoid]['cmi.learner_preference.audio_level'], 'format':CMIDecimal, 'range':audio_range, 'mod':'rw'},
'cmi.location':{'defaultvalue':def['cmi.location'], 'format':CMIString1000, 'mod':'rw'}, 'cmi.learner_preference.language':{'defaultvalue':def[scoid]['cmi.learner_preference.language'], 'format':CMILang, 'mod':'rw'},
'cmi.max_time_allowed':{'defaultvalue':def['cmi.max_time_allowed'], 'mod':'r'}, 'cmi.learner_preference.delivery_speed':{'defaultvalue':def[scoid]['cmi.learner_preference.delivery_speed'], 'format':CMIDecimal, 'range':speed_range, 'mod':'rw'},
'cmi.mode':{'defaultvalue':def['cmi.mode'], 'mod':'r'}, 'cmi.learner_preference.audio_captioning':{'defaultvalue':def[scoid]['cmi.learner_preference.audio_captioning'], 'format':CMISInteger, 'range':text_range, 'mod':'rw'},
'cmi.objectives._children':{'defaultvalue':objectives_children, 'mod':'r'}, 'cmi.location':{'defaultvalue':def[scoid]['cmi.location'], 'format':CMIString1000, 'mod':'rw'},
'cmi.objectives._count':{'mod':'r', 'defaultvalue':'0'}, 'cmi.max_time_allowed':{'defaultvalue':def[scoid]['cmi.max_time_allowed'], 'mod':'r'},
'cmi.objectives.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'}, 'cmi.mode':{'defaultvalue':def[scoid]['cmi.mode'], 'mod':'r'},
'cmi.objectives.n.score._children':{'defaultvalue':score_children, 'pattern':CMIIndex, 'mod':'r'}, 'cmi.objectives._children':{'defaultvalue':objectives_children, 'mod':'r'},
'cmi.objectives.n.score.scaled':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'range':scaled_range, 'mod':'rw'}, 'cmi.objectives._count':{'mod':'r', 'defaultvalue':'0'},
'cmi.objectives.n.score.raw':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'}, 'cmi.objectives.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'},
'cmi.objectives.n.score.min':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'}, 'cmi.objectives.n.score._children':{'defaultvalue':score_children, 'pattern':CMIIndex, 'mod':'r'},
'cmi.objectives.n.score.max':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'}, 'cmi.objectives.n.score.scaled':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'range':scaled_range, 'mod':'rw'},
'cmi.objectives.n.success_status':{'defaultvalue':'unknown', 'pattern':CMIIndex, 'format':CMISStatus, 'mod':'rw'}, 'cmi.objectives.n.score.raw':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'},
'cmi.objectives.n.completion_status':{'defaultvalue':'unknown', 'pattern':CMIIndex, 'format':CMICStatus, 'mod':'rw'}, 'cmi.objectives.n.score.min':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'},
'cmi.objectives.n.progress_measure':{'defaultvalue':null, 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'}, 'cmi.objectives.n.score.max':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'},
'cmi.objectives.n.description':{'pattern':CMIIndex, 'format':CMILangString250, 'mod':'rw'}, 'cmi.objectives.n.success_status':{'defaultvalue':'unknown', 'pattern':CMIIndex, 'format':CMISStatus, 'mod':'rw'},
'cmi.progress_measure':{'defaultvalue':def['cmi.progress_measure'], 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'}, 'cmi.objectives.n.completion_status':{'defaultvalue':'unknown', 'pattern':CMIIndex, 'format':CMICStatus, 'mod':'rw'},
'cmi.scaled_passing_score':{'defaultvalue':def['cmi.scaled_passing_score'], 'format':CMIDecimal, 'range':scaled_range, 'mod':'r'}, 'cmi.objectives.n.progress_measure':{'defaultvalue':null, 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'},
'cmi.score._children':{'defaultvalue':score_children, 'mod':'r'}, 'cmi.objectives.n.description':{'pattern':CMIIndex, 'format':CMILangString250, 'mod':'rw'},
'cmi.score.scaled':{'defaultvalue':def['cmi.score.scaled'], 'format':CMIDecimal, 'range':scaled_range, 'mod':'rw'}, 'cmi.progress_measure':{'defaultvalue':def[scoid]['cmi.progress_measure'], 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'},
'cmi.score.raw':{'defaultvalue':def['cmi.score.raw'], 'format':CMIDecimal, 'mod':'rw'}, 'cmi.scaled_passing_score':{'defaultvalue':def[scoid]['cmi.scaled_passing_score'], 'format':CMIDecimal, 'range':scaled_range, 'mod':'r'},
'cmi.score.min':{'defaultvalue':def['cmi.score.min'], 'format':CMIDecimal, 'mod':'rw'}, 'cmi.score._children':{'defaultvalue':score_children, 'mod':'r'},
'cmi.score.max':{'defaultvalue':def['cmi.score.max'], 'format':CMIDecimal, 'mod':'rw'}, 'cmi.score.scaled':{'defaultvalue':def[scoid]['cmi.score.scaled'], 'format':CMIDecimal, 'range':scaled_range, 'mod':'rw'},
'cmi.session_time':{'format':CMITimespan, 'mod':'w', 'defaultvalue':'PT0H0M0S'}, 'cmi.score.raw':{'defaultvalue':def[scoid]['cmi.score.raw'], 'format':CMIDecimal, 'mod':'rw'},
'cmi.success_status':{'defaultvalue':def['cmi.success_status'], 'format':CMISStatus, 'mod':'rw'}, 'cmi.score.min':{'defaultvalue':def[scoid]['cmi.score.min'], 'format':CMIDecimal, 'mod':'rw'},
'cmi.suspend_data':{'defaultvalue':def['cmi.suspend_data'], 'format':CMIString64000, 'mod':'rw'}, 'cmi.score.max':{'defaultvalue':def[scoid]['cmi.score.max'], 'format':CMIDecimal, 'mod':'rw'},
'cmi.time_limit_action':{'defaultvalue':def['cmi.time_limit_action'], 'mod':'r'}, 'cmi.session_time':{'format':CMITimespan, 'mod':'w', 'defaultvalue':'PT0H0M0S'},
'cmi.total_time':{'defaultvalue':def['cmi.total_time'], 'mod':'r'}, 'cmi.success_status':{'defaultvalue':def[scoid]['cmi.success_status'], 'format':CMISStatus, 'mod':'rw'},
'adl.nav.request':{'defaultvalue':'_none_', 'format':NAVEvent, 'mod':'rw'} 'cmi.suspend_data':{'defaultvalue':def[scoid]['cmi.suspend_data'], 'format':CMIString64000, 'mod':'rw'},
}; 'cmi.time_limit_action':{'defaultvalue':def[scoid]['cmi.time_limit_action'], 'mod':'r'},
// 'cmi.total_time':{'defaultvalue':def[scoid]['cmi.total_time'], 'mod':'r'},
// Datamodel inizialization 'adl.nav.request':{'defaultvalue':'_none_', 'format':NAVEvent, 'mod':'rw'}
// };
var cmi = new Object();
cmi.comments_from_learner = new Object();
cmi.comments_from_learner._count = 0;
cmi.comments_from_lms = new Object();
cmi.comments_from_lms._count = 0;
cmi.interactions = new Object();
cmi.interactions._count = 0;
cmi.learner_preference = new Object();
cmi.objectives = new Object();
cmi.objectives._count = 0;
cmi.score = new Object();
// Navigation Object
var adl = new Object();
adl.nav = new Object();
adl.nav.request_valid = new Array();
for (element in datamodel) {
if (element.match(/\.n\./) == null) {
if ((typeof eval('datamodel["'+element+'"].defaultvalue')) != 'undefined') {
eval(element+' = datamodel["'+element+'"].defaultvalue;');
} else {
eval(element+' = "";');
}
}
} }
eval(cmiobj); var cmi, adl;
eval(cmiint); function initdatamodel(scoid){
eval(cmicommentsuser); prerequrl = cfgwwwroot + "/mod/scorm/prereqs.php?a="+scormid+"&scoid="+scoid+"&attempt="+attempt+"&mode="+viewmode+"&currentorg="+currentorg+"&sesskey="+sesskey;
eval(cmicommentslms); datamodelurlparams = "id="+cmid+"&a="+scormid+"&sesskey="+sesskey+"&attempt="+attempt+"&scoid="+scoid;
if (cmi.completion_status == '') { //
cmi.completion_status = 'not attempted'; // Datamodel inizialization
//
cmi = new Object();
cmi.comments_from_learner = new Object();
cmi.comments_from_learner._count = 0;
cmi.comments_from_lms = new Object();
cmi.comments_from_lms._count = 0;
cmi.interactions = new Object();
cmi.interactions._count = 0;
cmi.learner_preference = new Object();
cmi.objectives = new Object();
cmi.objectives._count = 0;
cmi.score = new Object();
// Navigation Object
adl = new Object();
adl.nav = new Object();
adl.nav.request_valid = new Array();
for (element in datamodel[scoid]) {
if (element.match(/\.n\./) == null) {
if ((typeof eval('datamodel["'+scoid+'"]["'+element+'"].defaultvalue')) != 'undefined') {
eval(element+' = datamodel["'+scoid+'"]["'+element+'"].defaultvalue;');
} else {
eval(element+' = "";');
}
}
}
eval(cmiobj[scoid]);
eval(cmiint[scoid]);
eval(cmicommentsuser[scoid]);
eval(cmicommentslms[scoid]);
if (cmi.completion_status == '') {
cmi.completion_status = 'not attempted';
}
} }
// //
@ -267,6 +278,9 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
var errorCode = "0"; var errorCode = "0";
function Initialize (param) { function Initialize (param) {
scoid = scorm_current_node ? scorm_current_node.scoid : scoid ;
initdatamodel(scoid);
errorCode = "0"; errorCode = "0";
if (param == "") { if (param == "") {
if ((!Initialized) && (!Terminated)) { if ((!Initialized) && (!Terminated)) {
@ -365,8 +379,8 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
if (element !="") { if (element !="") {
var expression = new RegExp(CMIIndex,'g'); var expression = new RegExp(CMIIndex,'g');
var elementmodel = String(element).replace(expression,'.n.'); var elementmodel = String(element).replace(expression,'.n.');
if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"]')) != "undefined") {
if (eval('datamodel["'+elementmodel+'"].mod') != 'w') { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].mod') != 'w') {
element = String(element).replace(/\.(\d+)\./, ".N$1."); element = String(element).replace(/\.(\d+)\./, ".N$1.");
element = element.replace(/\.(\d+)\./, ".N$1."); element = element.replace(/\.(\d+)\./, ".N$1.");
@ -393,7 +407,7 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
errorCode = "301"; errorCode = "301";
} }
} else { } else {
//errorCode = eval('datamodel["'+elementmodel+'"].readerror'); //errorCode = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].readerror');
errorCode = "405"; errorCode = "405";
} }
} else { } else {
@ -402,7 +416,7 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
var parentmodel = ''; var parentmodel = '';
if (elementmodel.substr(elementmodel.length-childrenstr.length,elementmodel.length) == childrenstr) { if (elementmodel.substr(elementmodel.length-childrenstr.length,elementmodel.length) == childrenstr) {
parentmodel = elementmodel.substr(0,elementmodel.length-childrenstr.length); parentmodel = elementmodel.substr(0,elementmodel.length-childrenstr.length);
if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+parentmodel+'"]')) != "undefined") {
errorCode = "301"; errorCode = "301";
diagnostic = "Data Model Element Does Not Have Children"; diagnostic = "Data Model Element Does Not Have Children";
} else { } else {
@ -410,7 +424,7 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
} }
} else if (elementmodel.substr(elementmodel.length-countstr.length,elementmodel.length) == countstr) { } else if (elementmodel.substr(elementmodel.length-countstr.length,elementmodel.length) == countstr) {
parentmodel = elementmodel.substr(0,elementmodel.length-countstr.length); parentmodel = elementmodel.substr(0,elementmodel.length-countstr.length);
if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+parentmodel+'"]')) != "undefined") {
errorCode = "301"; errorCode = "301";
diagnostic = "Data Model Element Cannot Have Count"; diagnostic = "Data Model Element Cannot Have Count";
} else { } else {
@ -458,10 +472,10 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
if (element != "") { if (element != "") {
var expression = new RegExp(CMIIndex,'g'); var expression = new RegExp(CMIIndex,'g');
var elementmodel = String(element).replace(expression,'.n.'); var elementmodel = String(element).replace(expression,'.n.');
if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"]')) != "undefined") {
if (eval('datamodel["'+elementmodel+'"].mod') != 'r') { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].mod') != 'r') {
if (eval('datamodel["'+elementmodel+'"].format') != 'CMIFeedback') { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].format') != 'CMIFeedback') {
expression = new RegExp(eval('datamodel["'+elementmodel+'"].format')); expression = new RegExp(eval('datamodel["'+scoid+'"]["'+elementmodel+'"].format'));
} else { } else {
// cmi.interactions.n.type depending format accept everything at this stage // cmi.interactions.n.type depending format accept everything at this stage
expression = new RegExp(CMIFeedback); expression = new RegExp(CMIFeedback);
@ -517,15 +531,15 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
eval(parentelement+'._count++;'); eval(parentelement+'._count++;');
eval(subelement+' = new Object();'); eval(subelement+' = new Object();');
var subobject = eval(subelement); var subobject = eval(subelement);
subobject.success_status = datamodel["cmi.objectives.n.success_status"].defaultvalue; subobject.success_status = datamodel[scoid]["cmi.objectives.n.success_status"].defaultvalue;
subobject.completion_status = datamodel["cmi.objectives.n.completion_status"].defaultvalue; subobject.completion_status = datamodel[scoid]["cmi.objectives.n.completion_status"].defaultvalue;
subobject.progress_measure = datamodel["cmi.objectives.n.progress_measure"].defaultvalue; subobject.progress_measure = datamodel[scoid]["cmi.objectives.n.progress_measure"].defaultvalue;
subobject.score = new Object(); subobject.score = new Object();
subobject.score._children = score_children; subobject.score._children = score_children;
subobject.score.scaled = datamodel["cmi.objectives.n.score.scaled"].defaultvalue; subobject.score.scaled = datamodel[scoid]["cmi.objectives.n.score.scaled"].defaultvalue;
subobject.score.raw = datamodel["cmi.objectives.n.score.raw"].defaultvalue; subobject.score.raw = datamodel[scoid]["cmi.objectives.n.score.raw"].defaultvalue;
subobject.score.min = datamodel["cmi.objectives.n.score.min"].defaultvalue; subobject.score.min = datamodel[scoid]["cmi.objectives.n.score.min"].defaultvalue;
subobject.score.max = datamodel["cmi.objectives.n.score.max"].defaultvalue; subobject.score.max = datamodel[scoid]["cmi.objectives.n.score.max"].defaultvalue;
} }
} else { } else {
errorCode="351"; errorCode="351";
@ -731,8 +745,8 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
//Store data //Store data
if (errorCode == "0") { if (errorCode == "0") {
if ((typeof eval('datamodel["'+elementmodel+'"].range')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"].range')) != "undefined") {
range = eval('datamodel["'+elementmodel+'"].range'); range = eval('datamodel["'+scoid+'"]["'+elementmodel+'"].range');
ranges = range.split('#'); ranges = range.split('#');
value = value*1.0; value = value*1.0;
if (value >= ranges[0]) { if (value >= ranges[0]) {
@ -1068,12 +1082,12 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
} }
function getElementModel(element) { function getElementModel(element) {
if (typeof datamodel[element] != "undefined") { if (typeof datamodel[scoid][element] != "undefined") {
return element; return element;
} else { } else {
var expression = new RegExp(CMIIndex,'g'); var expression = new RegExp(CMIIndex,'g');
var elementmodel = String(element).replace(expression,'.n.'); var elementmodel = String(element).replace(expression,'.n.');
if (typeof datamodel[elementmodel] != "undefined") { if (typeof datamodel[scoid][elementmodel] != "undefined") {
return elementmodel; return elementmodel;
} }
} }
@ -1161,11 +1175,11 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
var element = parent+'.'+property; var element = parent+'.'+property;
var expression = new RegExp(CMIIndexStore,'g'); var expression = new RegExp(CMIIndexStore,'g');
var elementmodel = String(element).replace(expression,'.n.'); var elementmodel = String(element).replace(expression,'.n.');
if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"]')) != "undefined") {
if (eval('datamodel["'+elementmodel+'"].mod') != 'r') { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].mod') != 'r') {
var elementstring = '&'+underscore(element)+'='+encodeURIComponent(data[property]); var elementstring = '&'+underscore(element)+'='+encodeURIComponent(data[property]);
if ((typeof eval('datamodel["'+elementmodel+'"].defaultvalue')) != "undefined") { if ((typeof eval('datamodel["'+scoid+'"]["'+elementmodel+'"].defaultvalue')) != "undefined") {
if (eval('datamodel["'+elementmodel+'"].defaultvalue') != data[property] || eval('typeof(datamodel["'+elementmodel+'"].defaultvalue)') != typeof(data[property])) { if (eval('datamodel["'+scoid+'"]["'+elementmodel+'"].defaultvalue') != data[property] || eval('typeof(datamodel["'+scoid+'"]["'+elementmodel+'"].defaultvalue)') != typeof(data[property])) {
datastring += elementstring; datastring += elementstring;
} }
} else { } else {
@ -1203,7 +1217,7 @@ function SCORMapi1_3(def, cmiobj, cmiint, cmicommentsuser, cmicommentslms, scorm
} }
datastring += CollectData(data,'cmi'); datastring += CollectData(data,'cmi');
var element = 'adl.nav.request'; var element = 'adl.nav.request';
var navrequest = eval(element) != datamodel[element].defaultvalue ? '&'+underscore(element)+'='+encodeURIComponent(eval(element)) : ''; var navrequest = eval(element) != datamodel[scoid][element].defaultvalue ? '&'+underscore(element)+'='+encodeURIComponent(eval(element)) : '';
datastring += navrequest; datastring += navrequest;
var myRequest = NewHttpReq(); var myRequest = NewHttpReq();

View file

@ -17,24 +17,43 @@
require_once($CFG->dirroot.'/mod/scorm/locallib.php'); require_once($CFG->dirroot.'/mod/scorm/locallib.php');
$userdata = new stdClass(); $userdata = new stdClass();
$def = get_scorm_default($userdata, $scorm, $scoid, $attempt, $mode); $def = new stdClass();
$cmiobj = new stdClass();
$cmiint = new stdClass();
$cmicommentsuser = new stdClass();
$cmicommentslms = new stdClass();
if (!isset($currentorg)) { if (!isset($currentorg)) {
$currentorg = ''; $currentorg = '';
} }
// reconstitute objectives, comments_from_learner and comments_from_lms if ($scoes = $DB->get_records('scorm_scoes', array('scorm' => $scorm->id), 'sortorder, id')) {
$cmiobj = scorm_reconstitute_array_element($scorm->version, $userdata, 'cmi.objectives', array('score')); // Drop keys so that it is a simple array.
$cmiint = scorm_reconstitute_array_element($scorm->version, $userdata, 'cmi.interactions', array('objectives', 'correct_responses')); $scoes = array_values($scoes);
$cmicommentsuser = scorm_reconstitute_array_element($scorm->version, $userdata, 'cmi.comments_from_learner', array()); foreach ($scoes as $sco) {
$cmicommentslms = scorm_reconstitute_array_element($scorm->version, $userdata, 'cmi.comments_from_lms', array()); $def->{($sco->id)} = new stdClass();
$userdata->{($sco->id)} = new stdClass();
$def->{($sco->id)} = get_scorm_default($userdata->{($sco->id)}, $scorm, $sco->id, $attempt, $mode);
// Reconstitute objectives, comments_from_learner and comments_from_lms.
$cmiobj->{($sco->id)} = scorm_reconstitute_array_element($scorm->version, $userdata->{($sco->id)},
'cmi.objectives', array('score'));
$cmiint->{($sco->id)} = scorm_reconstitute_array_element($scorm->version, $userdata->{($sco->id)},
'cmi.interactions', array('objectives', 'correct_responses'));
$cmicommentsuser->{($sco->id)} = scorm_reconstitute_array_element($scorm->version, $userdata->{($sco->id)},
'cmi.comments_from_learner', array());
$cmicommentslms->{($sco->id)} = scorm_reconstitute_array_element($scorm->version, $userdata->{($sco->id)},
'cmi.comments_from_lms', array());
}
}
$PAGE->requires->js_init_call('M.scorm_api.init', array($def, $cmiobj, $cmiint, $cmicommentsuser, $cmicommentslms, $PAGE->requires->js_init_call('M.scorm_api.init', array($def, $cmiobj, $cmiint, $cmicommentsuser, $cmicommentslms,
scorm_debugging($scorm), $scorm->auto, $scorm->id, $CFG->wwwroot, scorm_debugging($scorm), $scorm->auto, $scorm->id, $CFG->wwwroot,
sesskey(), $scoid, $attempt, $mode, $id, $currentorg)); sesskey(), $scoid, $attempt, $mode, $id, $currentorg));
// pull in the debugging utilities // Pull in the debugging utilities.
if (scorm_debugging($scorm)) { if (scorm_debugging($scorm)) {
require_once($CFG->dirroot.'/mod/scorm/datamodels/debug.js.php'); require_once($CFG->dirroot.'/mod/scorm/datamodels/debug.js.php');
echo html_writer::script('AppendToLog("Moodle SCORM 1.3 API Loaded, Activity: '.$scorm->name.', SCO: '.$sco->identifier.'", 0);'); echo html_writer::script('AppendToLog("Moodle SCORM 1.3 API Loaded, Activity: '.$scorm->name.', SCO: '.$sco->identifier.'", 0);');

View file

@ -909,7 +909,7 @@ function scorm_view_display ($user, $scorm, $action, $cm) {
} }
} else if (!empty($attemptcount) && ($incomplete === false) && (($result->attemptleft > 0)||($scorm->maxattempt == 0))) { } else if (!empty($attemptcount) && ($incomplete === false) && (($result->attemptleft > 0)||($scorm->maxattempt == 0))) {
echo html_writer::empty_tag('br'); echo html_writer::empty_tag('br');
echo html_writer::checkbox('newattempt', '', false, '', array('id' => 'a')); echo html_writer::checkbox('newattempt', 'on', false, '', array('id' => 'a'));
echo html_writer::label(get_string('newattempt', 'scorm'), 'a'); echo html_writer::label(get_string('newattempt', 'scorm'), 'a');
} }
if (!empty($scorm->popup)) { if (!empty($scorm->popup)) {

View file

@ -27,6 +27,8 @@ mod_scorm_activate_item = null;
mod_scorm_parse_toc_tree = null; mod_scorm_parse_toc_tree = null;
scorm_layout_widget = null; scorm_layout_widget = null;
window.scorm_current_node = null;
function underscore(str) { function underscore(str) {
str = String(str).replace(/.N/g,"."); str = String(str).replace(/.N/g,".");
return str.replace(/\./g,"__"); return str.replace(/\./g,"__");
@ -48,7 +50,6 @@ M.mod_scorm.init = function(Y, nav_display, navposition_left, navposition_top, h
} }
scoes_nav = Y.JSON.parse(scoes_nav); scoes_nav = Y.JSON.parse(scoes_nav);
var scorm_current_node;
var scorm_buttons = []; var scorm_buttons = [];
var scorm_bloody_labelclick = false; var scorm_bloody_labelclick = false;
var scorm_nav_panel; var scorm_nav_panel;
@ -124,15 +125,23 @@ M.mod_scorm.init = function(Y, nav_display, navposition_left, navposition_top, h
return; return;
} }
// Check if the item is already active, avoid recursive calls. // Check if the item is already active, avoid recursive calls.
if (Y.one('#scorm_object')) { var content = Y.one('#scorm_content');
var old = Y.one('#scorm_object');
if (old) {
var scorm_active_url = Y.one('#scorm_object').getAttribute('src'); var scorm_active_url = Y.one('#scorm_object').getAttribute('src');
var node_full_url = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?' + node.title; var node_full_url = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?' + node.title;
if (node_full_url === scorm_active_url) { if (node_full_url === scorm_active_url) {
return; return;
} }
// Start to unload iframe here
if(!window_name){
content.removeChild(old);
old = null;
}
} }
// End of - Avoid recursive calls.
scorm_current_node = node; scorm_current_node = node;
// Avoid recursive calls.
if (!scorm_current_node.state.selected) { if (!scorm_current_node.state.selected) {
scorm_current_node.select(); scorm_current_node.select();
} }
@ -144,7 +153,6 @@ M.mod_scorm.init = function(Y, nav_display, navposition_left, navposition_top, h
el_old_api.parentNode.removeChild(el_old_api); el_old_api.parentNode.removeChild(el_old_api);
} }
var content = Y.one('#scorm_content');
var obj = document.createElement('iframe'); var obj = document.createElement('iframe');
obj.setAttribute('id', 'scorm_object'); obj.setAttribute('id', 'scorm_object');
obj.setAttribute('type', 'text/html'); obj.setAttribute('type', 'text/html');
@ -159,7 +167,6 @@ M.mod_scorm.init = function(Y, nav_display, navposition_left, navposition_top, h
mine.close(); mine.close();
} }
var old = Y.one('#scorm_object');
if (old) { if (old) {
if(window_name) { if(window_name) {
var cwidth = scormplayerdata.cwidth; var cwidth = scormplayerdata.cwidth;
@ -167,8 +174,6 @@ M.mod_scorm.init = function(Y, nav_display, navposition_left, navposition_top, h
var poptions = scormplayerdata.popupoptions; var poptions = scormplayerdata.popupoptions;
poptions = poptions + ',resizable=yes'; // Added for IE (MDL-32506). poptions = poptions + ',resizable=yes'; // Added for IE (MDL-32506).
scorm_openpopup(M.cfg.wwwroot + "/mod/scorm/loadSCO.php?" + node.title, window_name, poptions, cwidth, cheight); scorm_openpopup(M.cfg.wwwroot + "/mod/scorm/loadSCO.php?" + node.title, window_name, poptions, cwidth, cheight);
} else {
content.replaceChild(obj, old);
} }
} else { } else {
content.prepend(obj); content.prepend(obj);
@ -577,14 +582,18 @@ M.mod_scorm.init = function(Y, nav_display, navposition_left, navposition_top, h
if (node.title == '' || node.title == null) { if (node.title == '' || node.title == null) {
return; //this item has no navigation return; //this item has no navigation
} }
// If item is already active, return; avoid recursive calls. // If item is already active, return; avoid recursive calls.
if (Y.one('#scorm_data')) { if (obj = Y.one('#scorm_object')) {
var scorm_active_url = Y.one('#scorm_object').getAttribute('src'); var scorm_active_url = obj.getAttribute('src');
var node_full_url = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?' + node.title; var node_full_url = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?' + node.title;
if (node_full_url === scorm_active_url) { if (node_full_url === scorm_active_url) {
return; return;
} }
} else if(scorm_current_node == node){
return;
} }
// Update launch_sco. // Update launch_sco.
if (typeof node.scoid !== 'undefined') { if (typeof node.scoid !== 'undefined') {
launch_sco = node.scoid; launch_sco = node.scoid;