Support Opale/Scenarii by adding variable to better support SCORM 1.2 by watching over the definition, by the SCO, of the lesson_status and the call to LMSFinish() or the move to another element - refs #398 refs BT#8897

1.9.x
Yannick Warnier 11 years ago
parent b09b80a479
commit 1d68db47b2
  1. 3
      main/newscorm/lp_ajax_initialize.php
  2. 3
      main/newscorm/lp_ajax_switch_item.php
  3. 142
      main/newscorm/scorm_api.php

@ -129,7 +129,8 @@ function initialize_item($lp_id, $user_id, $view_id, $next_item) {
//"olms.item_objectives = new Array();" .
"olms.item_objectives = ".$myobjectives.";" .
"olms.G_lastError = 0;" .
"olms.G_LastErrorMessage = 'No error';" ;
"olms.G_LastErrorMessage = 'No error';".
"olms.finishSignalReceived = 0;";
/*
* and re-initialise the rest (proper to the LMS)
* -lms_lp_id

@ -171,7 +171,8 @@ function switch_item_details($lp_id, $user_id, $view_id, $current_item, $next_it
"olms.interactions = new Array(".$myistring.");".
"olms.item_objectives = new Array();".
"olms.G_lastError = 0;".
"olms.G_LastErrorMessage = 'No error';";
"olms.G_LastErrorMessage = 'No error';".
"olms.finishSignalReceived = 0;";
/*
* and re-initialise the rest
* -lms_lp_id

@ -2,7 +2,7 @@
/* For licensing terms, see /license.txt */
/**
* API event handler functions for Scorm 1.1 and 1.2 and 1.3
* API event handler functions for Scorm 1.1 and 1.2 and 1.3 (latter not fully supported)
* This script is divided into three sections.
* The first section (below) is the initialisation part.
* The second section is the SCORM object part
@ -10,7 +10,7 @@
* and frames refresh
* @author Denes Nagy <darkden@freemail.hu> (original author - 2003-2004)
* @author Yannick Warnier <ywarnier@beeznest.org> (extended and maintained - 2005-2014)
* @version v 1.1
* @version v 1.2
* @access public
* @package chamilo.learnpath.scorm
*/
@ -140,6 +140,10 @@ olms.variable_to_send=new Array();
// temporary list of variables (gets set to true when set through LMSSetValue)
olms.updatable_vars_list = new Array();
// marker of whether the LMSFinish() function was called, which is important for SCORM behaviour
olms.finishSignalReceived = 0;
// marker to remember if the SCO has calles a "set" on lesson_status
olms.statusSignalReceived = 0;
// Strictly scorm variables
olms.score=<?php echo $oItem->get_score();?>;
@ -182,6 +186,7 @@ olms.lms_item_core_exit = '<?php echo $oItem->get_core_exit();?>';
olms.lms_course_id = '<?php echo $oLP->get_course_int_id(); ?>';
olms.lms_session_id = '<?php echo api_get_session_id(); ?>';
olms.lms_course_code = '<?php echo $oLP->getCourseCode(); ?>';
olms.lms_course_id = '<?php echo $oLP->get_course_int_id(); ?>';
<?php echo $oLP->get_items_details_as_js('olms.lms_item_types');?>
olms.asset_timer = 0;
@ -198,27 +203,33 @@ addEvent(window, 'load', addListeners, false);
// Initialize stuff when the page is loaded
$(document).ready(function() {
logit_lms('document.ready start');
logit_lms('document.ready event starts');
logit_lms('These logs are generated by the main/newscorm/scorm_api.php JS '
+ 'library when the admin has clicked on the debug icon in the '
+ 'learning paths list: '
+ 'lines prefixed with "LMS:" refer to actions taken on the LMS side, '
+ 'while lines prefixed with "SCORM:" refer to actions taken to match '
+ 'the SCORM standard at the JS level.', 3);
logit_scorm('LMSSetValue calls are shown in red for better visibility.', 0);
logit_scorm('Other SCORM calls are shown in orange.', 1);
logit_lms('To add new messages to these logs, use logit_lms() or logit_scorm().');
olms.info_lms_item[0] = '<?php echo $oItem->get_id();?>';
olms.info_lms_item[1] = '<?php echo $oItem->get_id();?>';
$("#content_id").load(function() {
logit_lms('#content_id on load executing: ');
logit_lms('#content_id load event starts');
olms.info_lms_item[0] = olms.info_lms_item[1];
// Only trigger the LMSInitialize automatically if not SCO
if (olms.lms_item_types['i'+olms.info_lms_item[1]] != 'sco') {
LMSInitialize();
} else {
logit_lms('Cant execute LMSInitialize() (type is sco)',2);
logit_lms('Content type is SCO and is responsible to launch LMSInitialize() on its own - Skipping',2);
}
});
});
//Seems that this objs are not used
//oXAJAX = new XAJAXobject();
//oxajax = new XAJAXobject();
// This code was moved inside LMSInitialize()
if (olms.lms_lp_type == 1 || olms.lms_item_type == 'asset' || olms.lms_item_type == 'document') {
xajax_start_timer();
@ -235,7 +246,7 @@ if (olms.lms_lp_type == 1 || olms.lms_item_type == 'asset' || olms.lms_item_type
function LMSInitialize() {
/* load info for this new item by calling the js_api_refresh command in
* the message frame. The message frame will update the JS variables by
* itself, in JS, by doing things like top.lescsson_status = 'not attempted'
* itself, in JS, by doing things like top.lesson_status = 'not attempted'
* and that kind of stuff, so when the content loads in the content frame
* it will have all the correct variables set
*/
@ -246,10 +257,12 @@ function LMSInitialize() {
olms.G_LastErrorMessage = 'No error';
olms.lms_initialized = 0;
olms.finishSignalReceived = 0;
olms.statusSignalReceived = 0;
// if there are more parameters than ""
if (arguments.length > 1) {
olms.G_LastError = G_InvalidArgumentError;
olms.G_LastErrorMessage = G_InvalidArgumentErrorMessage;
olms.G_LastError = G_InvalidArgumentError;
olms.G_LastErrorMessage = G_InvalidArgumentErrorMessage;
logit_scorm('Error '+ G_InvalidArgumentError + G_InvalidArgumentErrorMessage, 0);
return('false');
} else {
@ -294,11 +307,13 @@ function LMSInitialize() {
+ '\nlms_lp_id : '+ olms.lms_lp_id
+ '\nlms_user_id : '+ olms.lms_user_id
+ '\nlms_view_id : '+ olms.lms_view_id
+ '\nfinishSignalReceived : '+ olms.finishSignalReceived
+ '\nstatusSignalReceived : '+ olms.statusSignalReceived
;
logit_scorm('LMSInitialize() with params: '+log);
if (olms.lms_lp_type == 1 || olms.lms_item_type == 'asset' || olms.lms_item_type == 'document') {
if (olms.lms_lp_type == 1 || olms.lms_item_type == 'asset' || olms.lms_item_type == 'document') {
xajax_start_timer();
}
@ -312,7 +327,7 @@ function LMSInitialize() {
} else {
attach_glossary_into_scorm('manual');
}
<?php } elseif (api_get_setting('show_glossary_in_documents') == 'isautomatic') { ?>
<?php } elseif (api_get_setting('show_glossary_in_documents') == 'isautomatic') { ?>
attach_glossary_into_scorm('automatic');
<?php } ?>
return('true');
@ -582,6 +597,7 @@ function LMSSetValue(param, val) {
olms.commit = true; //value has changed, need to re-commit
olms.G_LastError = G_NoError ;
olms.G_LastErrorMessage = 'No error';
return_value = 'false';
if ( param == "cmi.core.score.raw" ) {
@ -603,6 +619,7 @@ function LMSSetValue(param, val) {
} else if ( param == "cmi.core.lesson_status" ) {
olms.lesson_status = val;
olms.updatable_vars_list['cmi.core.lesson_status'] = true;
olms.statusSignalReceived = 1;
return_value='true';
} else if ( param == "cmi.completion_status" ) {
olms.lesson_status = val;
@ -693,8 +710,8 @@ function LMSSetValue(param, val) {
return_value='true';
break;
case "correct_responses":
//do nothing yet
olms.interactions[elem_id][4].push(val);
// Add at the end of the array
olms.interactions[elem_id][4][olms.interactions[elem_id][4].length] = val;
logit_scorm("Interaction "+elem_id+"'s correct_responses not updated",2);
return_value='true';
break;
@ -800,12 +817,10 @@ function SetValue(param, val) {
/**
* Saves the current data from JS memory to the LMS database
* @param string The origin of the call to save the data ('commit','finish', 'unload' or 'terminate')
* @note origin actually seems deprecated now
*/
function savedata(origin) {
function savedata() {
//origin can be 'commit', 'finish' or 'terminate' (depending on the calling function)
logit_lms('function savedata() with origin: ' + origin, 3);
logit_lms('function savedata()', 3);
//Status is NOT modified here see the lp_ajax_save_item.php file
@ -830,11 +845,27 @@ function savedata(origin) {
//xajax_save_item_scorm(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, old_item_id);
//Modified version
xajax_save_item_scorm(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, item_to_save);
xajax_save_item_scorm(
olms.lms_lp_id,
olms.lms_user_id,
olms.lms_view_id,
item_to_save,
olms.session_id,
olms.course_id,
olms.finishSignalReceived,
olms.userNavigatesAway,
olms.statusSignalReceived
);
olms.info_lms_item[1] = olms.lms_item_id;
if (olms.item_objectives.length > 0) {
xajax_save_objectives(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id, old_item_id, olms.item_objectives);
xajax_save_objectives(
olms.lms_lp_id,
olms.lms_user_id,
olms.lms_view_id,
old_item_id,
olms.item_objectives
);
}
olms.execute_stats = false;
//clean array
@ -854,10 +885,11 @@ function LMSCommit(val) {
olms.G_LastError = G_NoError ;
olms.G_LastErrorMessage = 'No error';
savedata('commit');
savedata();
reinit_updatable_vars_list();
//commit = 'false' ; //now changes have been commited, no need to update until next SetValue()
//now changes have been commited, no need to update until next SetValue()
//commit = 'false' ;
return('true');
}
@ -880,17 +912,16 @@ function Commit(val) {
function LMSFinish(val) {
olms.G_LastError = G_NoError ;
olms.G_LastErrorMessage = 'No error';
olms.finishSignalReceived = 1;
// if olms.commit == false, then the SCORM didn't ask for a commit, so we
// should at least report that
if ( !olms.commit ) {
logit_scorm('LMSFinish() (no LMSCommit())',1);
}
//if ( olms.commit ) {
logit_scorm('LMSFinish() called',1);
savedata('finish');
olms.commit = false;
//}
logit_scorm('LMSFinish() called',1);
savedata();
olms.commit = false;
//reinit the list of modified variables
reinit_updatable_vars_list();
@ -971,7 +1002,7 @@ function Terminate() {
olms.G_LastError = G_NoError ;
olms.G_LastErrorMessage = 'No error';
olms.commit = true;
savedata('terminate');
savedata();
return ('true');
}
}
@ -1064,7 +1095,7 @@ function lms_save_asset() {
if (olms.lms_lp_type == 1 || olms.lms_item_type == 'asset' || olms.lms_item_type == 'document') {
logit_lms('lms_save_asset');
logit_lms('execute_stats :'+ olms.execute_stats);
xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.session_time, olms.suspend_data, olms.lesson_location, olms.interactions, olms.lms_item_core_exit, olms.lms_item_type);
xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.session_time, olms.suspend_data, olms.lesson_location, olms.interactions, olms.lms_item_core_exit, olms.lms_item_type, olms.session_id, olms.course_id);
if (olms.item_objectives.length>0) {
xajax_save_objectives(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,olms.lms_item_id,olms.item_objectives);
}
@ -1344,7 +1375,7 @@ function switch_item(current_item, next_item){
} else {
logit_lms('Case 2 - current != sco but next == sco');
}
xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.asset_timer, olms.suspend_data, olms.lesson_location,olms.interactions, olms.lms_item_core_exit, orig_item_type);
xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.asset_timer, olms.suspend_data, olms.lesson_location,olms.interactions, olms.lms_item_core_exit, olms.session_id, olms.course_id, olms.finishSignalReceived, 1, olms.statusSignalReceived);
xajax_switch_item_details(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, next_item);
} else {
if (next_item_type != 'sco') {
@ -1352,7 +1383,7 @@ function switch_item(current_item, next_item){
} else {
logit_lms('Case 4 - current == sco and next == sco');
}
xajax_save_item_scorm(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id);
xajax_save_item_scorm(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.session_id, olms.course_id, olms.finishSignalReceived, 1, olms.statusSignalReceived);
reinit_updatable_vars_list();
xajax_switch_item_toc(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,olms.lms_item_id,next_item);
@ -1375,18 +1406,18 @@ function switch_item(current_item, next_item){
* because another onunload event can be triggered by the SCO itself,
* which can set, for example, the status to incomplete while the
* status has already been set to "completed" by the hand-made
* savedata(unload) (and then the status cannot be "incompleted"
* savedata() (and then the status cannot be "incompleted"
* anymore)
*/
/*
if (olms.lms_item_type=='sco' && olms.lesson_status != 'completed' && olms.lesson_status != 'passed' && olms.lesson_status != 'browsed' && olms.lesson_status != 'incomplete' && olms.lesson_status != 'failed') {
// savedata('finish') treats the special condition and saves the
// new status to the database, so switch_item_details() enjoys the
// new status
savedata('finish');
// savedata() with olms.finishSignalReceived == 1 treats the special
// condition and saves the new status to the database, so
// switch_item_details() enjoys the new status
savedata();
}
xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.session_time, olms.suspend_data, olms.lesson_location,olms.interactions, olms.lms_item_core_exit, olms.lms_item_type);
xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.session_time, olms.suspend_data, olms.lesson_location,olms.interactions, olms.lms_item_core_exit, olms.session_id, olms.course_id, olms.finishSignalReceived, 1, olms.statusSignalReceived);
*/
olms.execute_stats = false;
@ -1513,7 +1544,10 @@ function xajax_save_item(
lms_item_core_exit,
item_type,
session_id,
course_id) {
course_id,
finishSignalReceived = 0,
userNavigatesAway = 0,
statusSignalReceived = 0) {
var params = '';
params += 'lid='+lms_lp_id+'&uid='+lms_user_id+'&vid='+lms_view_id;
params += '&iid='+lms_item_id+'&s='+score+'&max='+max+'&min='+min;
@ -1522,6 +1556,10 @@ function xajax_save_item(
params += '&core_exit='+lms_item_core_exit;
params += '&session_id='+session_id;
params += '&course_id='+course_id;
params += '&finishSignalReceived='+finishSignalReceived;
params += '&userNavigatesAway='+userNavigatesAway;
params += '&statusSignalReceived='+statusSignalReceived;
//console.info(session_time);
if (olms.lms_lp_type == 1 || item_type == 'document') {
logit_lms('xajax_save_item with params:' + params,3);
@ -1548,12 +1586,30 @@ function xajax_save_item(
* @uses olms.updatable_vars_list
* @uses lp_ajax_save_item.php through an AJAX call
*/
function xajax_save_item_scorm(lms_lp_id, lms_user_id, lms_view_id, lms_item_id, finish) {
function xajax_save_item_scorm(
lms_lp_id,
lms_user_id,
lms_view_id,
lms_item_id,
session_id,
course_id,
finishSignalReceived = 0,
userNavigatesAway = 0,
statusSignalReceived = 0
)
{
if (typeof(finish) == 'undefined') {
finish = 0;
}
var is_interactions='false';
var params = 'lid='+lms_lp_id+'&uid='+lms_user_id+'&vid='+lms_view_id+'&iid='+lms_item_id+'&finish='+finish;
var params = 'lid='+lms_lp_id+'&uid='+lms_user_id+'&vid='+lms_view_id+'&iid='+lms_item_id;
// The missing arguments will be ignored by lp_ajax_save_item.php
//params += '&s=&max=&min=&status=&t=&suspend=&loc=&interact=&core_exit=';
params += '&session_id='+session_id;
params += '&course_id='+course_id;
params += '&finishSignalReceived='+finishSignalReceived;
params += '&userNavigatesAway='+userNavigatesAway;
params += '&statusSignalReceived='+statusSignalReceived;
var my_scorm_values = new Array();
my_scorm_values = process_scorm_values();
@ -1628,7 +1684,7 @@ function xajax_save_item_scorm(lms_lp_id, lms_user_id, lms_view_id, lms_item_id,
/**
* Starts the timer with the server clock time.
* @return void
* @todo check the timer stuff really works
* @todo check the timer stuff really works and rename function to startTimer()
* @uses lp_ajax_start_timer.php
*/
function xajax_start_timer() {

Loading…
Cancel
Save