The scorm status is now set in the lp_ajax_save_utem.php file and not in the savedata() function in scorm_api.php

This change makrd possible to validate the status depending in the mastery score see BT#5153
skala
Julio Montoya 13 years ago
parent fab5432018
commit 9227616ca9
  1. 110
      main/newscorm/lp_ajax_save_item.php
  2. 121
      main/newscorm/scorm_api.php

@ -18,6 +18,12 @@ $use_anonymous = true;
$language_file[] = 'learnpath';
require_once 'back_compat.inc.php';
require_once 'learnpath.class.php';
require_once 'scorm.class.php';
require_once 'aicc.class.php';
require_once 'learnpathItem.class.php';
require_once 'scormItem.class.php';
require_once 'aiccItem.class.php';
/**
* Writes an item's new values into the database and returns the operation result
@ -38,31 +44,29 @@ require_once 'back_compat.inc.php';
function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1, $min = -1, $status = '', $time = 0, $suspend = '', $location = '', $interactions = array(), $core_exit = 'none') {
global $_configuration;
$return = '';
if ($debug > 0) { error_log('In save_item('.$lp_id.','.$user_id.','.$view_id.','.$item_id.','.$score.','.$max.','.$min.',"'.$status.'",'.$time.',"'.$suspend.'","'.$location.'","'.(count($interactions) > 0 ? $interactions[0] : '').'","'.$core_exit.'")', 0); }
$debug = 10;
require_once 'learnpath.class.php';
require_once 'scorm.class.php';
require_once 'aicc.class.php';
require_once 'learnpathItem.class.php';
require_once 'scormItem.class.php';
require_once 'aiccItem.class.php';
if ($debug > 0) {
error_log('lp_ajax_save_item.php : save_item params: ');
error_log("lp_id: $lp_id - user_id: - $user_id - view_id: $view_id - item_id: $item_id");
error_log("score: $score - max:$max - min: $min - status:$status - time:$time - suspend: $suspend - location: $location - core_exit: $core_exit");
}
$mylp = '';
if (isset($_SESSION['lpobject'])) {
if ($debug > 1) { error_log('////$_SESSION[lpobject] is set', 0); }
$mylp = null;
if (isset($_SESSION['lpobject'])) {
$oLP = unserialize($_SESSION['lpobject']);
if (!is_object($oLP)) {
if ($debug > 2) { error_log(print_r($oLP,true), 0); }
if ($debug > 2) { error_log('////Building new lp', 0); }
if (!is_object($oLP)) {
unset($oLP);
$code = api_get_course_id();
$mylp = new learnpath($code, $lp_id, $user_id);
} else {
if ($debug > 2) { error_log('////Reusing session lp', 0); }
$mylp = & $oLP;
}
}
if (!is_a($mylp, 'learnpath')) { return ''; }
if (!is_a($mylp, 'learnpath')) {
return '';
}
$prereq_check = $mylp->prerequisites_match($item_id);
@ -71,39 +75,48 @@ function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1,
$mylpi->set_lp_view($view_id);
if ($prereq_check === true) {
// Launch the prerequisites check and set error if needed
//$mylpi =& $mylp->items[$item_id];
//$mylpi->set_lp_view($view_id);
if ($debug > 1) { error_log('Prereq are check'); }
// Launch the prerequisites check and set error if needed
if (isset($max) && $max != -1) {
$mylpi->max_score = $max;
$mylpi->set_max_score($max);
if ($debug > 1) { error_log("Setting max_score: $max"); }
}
if (isset($min) && $min != -1 && $min != 'undefined') {
$mylpi->min_score = $min;
if ($debug > 1) { error_log("Setting min_score: $min"); }
}
//set_score function already saves the status
if (isset($score) && $score != -1) {
if ($debug > 1) { error_log('Calling set_score('.$score.') from xajax', 0); }
if ($debug > 1) { error_log('Calling set_score('.$score.')', 0); }
$mylpi->set_score($score);
if ($debug > 1) { error_log('Done calling set_score from xajax - now '.$mylpi->get_score(), 0); }
if ($debug > 1) { error_log('Done calling set_score '.$mylpi->get_score(), 0); }
} else {
if ($debug > 1) { error_log("Score not updated"); }
//Default behaviour
if (isset($status) && $status != '' && $status != 'undefined') {
if ($debug > 1) { error_log('Calling set_status('.$status.') from xajax', 0); }
if (isset($status) && $status != '' && $status != 'undefined') {
//Implements scorm 1.2 constraint
//If SCO_MasteryScore does not evaluate to a number, passed/failed status won't be set at all
//Score was not set
//@todo remove the switch
switch ($status) {
case 'failed':
case 'passed':
if ($debug > 1) { error_log("Cant't set status to these values only if a score was set"); }
case 'passed':
$mylpi->set_status($status);
//if ($debug > 1) { error_log("Cant't set status to these values only if a score was set"); }
break;
default:
if ($debug > 1) { error_log('Status was set'); }
default:
if ($debug > 1) { error_log('Calling set_status('.$status.')', 0); }
$mylpi->set_status($status);
if ($debug > 1) { error_log('Done calling set_status from xajax - now '.$mylpi->get_status(false), 0); }
if ($debug > 1) { error_log('Done calling set_status: checking from memory:'.$mylpi->get_status(false), 0); }
break;
}
} else {
if ($debug > 1) { error_log("Status not updated"); }
}
}
@ -114,31 +127,32 @@ function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1,
if ((empty($status) || $status == 'undefined' || $status == 'not attempted') && $max > 0) {
if (($score/$max) > 0.8) {
$mystatus = 'completed';
if ($debug > 1) { error_log('Calling set_status('.$mystatus.') from xajax for hotpotatoes', 0); }
if ($debug > 1) { error_log('Calling set_status('.$mystatus.') for hotpotatoes', 0); }
$mylpi->set_status($mystatus);
if ($debug > 1) { error_log('Done calling set_status from xajax for hotpotatoes - now '.$mylpi->get_status(false), 0); }
if ($debug > 1) { error_log('Done calling set_status for hotpotatoes - now '.$mylpi->get_status(false), 0); }
}
} elseif ($status == 'completed' && $max > 0 && ($score/$max) < 0.8) {
$mystatus = 'failed';
if ($debug > 1) { error_log('Calling set_status('.$mystatus.') from xajax for hotpotatoes', 0); }
if ($debug > 1) { error_log('Calling set_status('.$mystatus.') for hotpotatoes', 0); }
$mylpi->set_status($mystatus);
if ($debug > 1) { error_log('Done calling set_status from xajax for hotpotatoes - now '.$mylpi->get_status(false), 0); }
if ($debug > 1) { error_log('Done calling set_status for hotpotatoes - now '.$mylpi->get_status(false), 0); }
}
}
if (isset($time) && $time!='' && $time!='undefined') {
// If big integer, then it's a timestamp, otherwise it's normal scorm time.
if ($debug > 1) { error_log('Calling set_time('.$time.') from xajax', 0); }
if ($debug > 1) { error_log('Calling set_time('.$time.') ', 0); }
if ($time == intval(strval($time)) && $time > 1000000) {
$real_time = time() - $time;
//$real_time += $mylpi->get_total_time();
if ($debug > 1) { error_log("Time is INT"); }
$real_time = time() - $time;
if ($debug > 1) { error_log('Calling $real_time '.$real_time.' ', 0); }
$mylpi->set_time($real_time, 'int');
} else {
if ($debug > 1) { error_log("Time is in SCORM format"); }
if ($debug > 1) { error_log('Calling $time '.$time.' ', 0); }
$mylpi->set_time($time);
$mylpi->set_time($time, 'scorm');
}
if ($debug > 1) { error_log('Done calling set_time from xajax - now '.$mylpi->get_total_time(), 0); }
//if ($debug > 1) { error_log('Done calling set_time - now '.$mylpi->get_total_time(), 0); }
} else {
$time = $mylpi->get_total_time();
}
@ -161,15 +175,19 @@ function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1,
$mylpi->add_interaction($index, $clean_interaction);
}
}
if ($core_exit != 'undefined') {
$mylpi->set_core_exit($core_exit);
}
$mylp->save_item($item_id, false);
} else {
return $return;
}
$mystatus_in_db = $mylpi->get_status(true);
error_log("Status in DB: $mystatus_in_db");
if ($mystatus_in_db != 'completed' && $mystatus_in_db != 'passed' && $mystatus_in_db != 'browsed' && $mystatus_in_db != 'failed') {
$mystatus_in_memory = $mylpi->get_status(false);
if ($mystatus_in_memory != $mystatus_in_db) {
@ -180,14 +198,18 @@ function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1,
} else {
$mystatus = $mystatus_in_db;
}
$mytotal = $mylp->get_total_items_count_without_chapters();
$mycomplete = $mylp->get_complete_items_count();
$myprogress_mode = $mylp->get_progress_bar_mode();
$myprogress_mode = ($myprogress_mode == '' ? '%' : $myprogress_mode);
if ($debug > 1) { error_log("myprogress_mode $myprogress_mode", 0); }
if ($debug > 1) { error_log("mytotal $mytotal", 0); }
if ($debug > 1) { error_log("mycomplete $mycomplete", 0); }
//$mylpi->write_to_db();
$myprogress_mode = $myprogress_mode == '' ? '%' : $myprogress_mode;
if ($debug > 1) { error_log("mystatus: $mystatus", 0); }
if ($debug > 1) { error_log("myprogress_mode: $myprogress_mode", 0); }
if ($debug > 1) { error_log("mytotal: $mytotal", 0); }
if ($debug > 1) { error_log("mycomplete: $mycomplete", 0); }
$_SESSION['lpobject'] = serialize($mylp);
if ($mylpi->get_type() != 'sco') {
// If this object's JS status has not been updated by the SCORM API, update now.
@ -196,7 +218,7 @@ function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1,
$return .= "update_toc('".$mystatus."','".$item_id."');";
$update_list = $mylp->get_update_queue();
foreach ($update_list as $my_upd_id => $my_upd_status) {
if ($my_upd_id != $item_id){ // Only update the status from other items (i.e. parents and brothers), do not update current as we just did it already.
if ($my_upd_id != $item_id) { // Only update the status from other items (i.e. parents and brothers), do not update current as we just did it already.
$return .= "update_toc('".$my_upd_status."','".$my_upd_id."');";
}
}
@ -209,7 +231,6 @@ function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1,
if (!isset($_SESSION['login_as'])) {
// If $_SESSION['login_as'] is set, then the user is an admin logged as the user.
$tbl_track_login = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_LOGIN);
$sql_last_connection = "SELECT login_id, login_date
@ -232,8 +253,11 @@ function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1,
}
//To be sure progress is updated
$mylp->save_last();
if ($debug > 0) { error_log('lp_ajax_save_item.php : save_item end ----- '); }
return $return;
}
$interactions = array();
if (isset($_REQUEST['interact'])) {
if (is_array($_REQUEST['interact'])) {

@ -34,11 +34,9 @@ require_once 'learnpath.class.php';
require_once 'learnpathItem.class.php';
require_once 'scorm.class.php';
// Is this needed? This is probabaly done in the header file
//$_user = $_SESSION['_user'];
$file = (empty($_SESSION['file'])?'':$_SESSION['file']);
$oLP = unserialize($_SESSION['lpobject']);
$oItem = $oLP->items[$oLP->current];
$file = (empty($_SESSION['file'])?'':$_SESSION['file']);
$oLP = unserialize($_SESSION['lpobject']);
$oItem = $oLP->items[$oLP->current];
if (!is_object($oItem)) {
error_log('New LP - scorm_api - Could not load oItem item',0);
@ -56,25 +54,25 @@ var lms_logs=0; //debug log level for LMS actions. 0=none, 1=light, 2=a lot, 3=a
// API Object initialization (eases access later on)
function APIobject() {
this.LMSInitialize=LMSInitialize; //for Scorm 1.2
this.Initialize=LMSInitialize; //for Scorm 1.3
this.LMSGetValue=LMSGetValue;
this.GetValue=LMSGetValue;
this.LMSSetValue=LMSSetValue;
this.SetValue=LMSSetValue;
this.LMSCommit=LMSCommit;
this.Commit=LMSCommit;
this.LMSFinish=LMSFinish;
this.Finish=LMSFinish;
this.LMSGetLastError=LMSGetLastError;
this.GetLastError=LMSGetLastError;
this.LMSGetErrorString=LMSGetErrorString;
this.GetErrorString=LMSGetErrorString;
this.LMSGetDiagnostic=LMSGetDiagnostic;
this.GetDiagnostic=LMSGetDiagnostic;
this.Terminate=Terminate; //only in Scorm 1.3
this.save_asset = lms_save_asset;
this.void_save_asset = chamilo_void_save_asset;
this.LMSInitialize=LMSInitialize; //for Scorm 1.2
this.Initialize=LMSInitialize; //for Scorm 1.3
this.LMSGetValue=LMSGetValue;
this.GetValue=LMSGetValue;
this.LMSSetValue=LMSSetValue;
this.SetValue=LMSSetValue;
this.LMSCommit=LMSCommit;
this.Commit=LMSCommit;
this.LMSFinish=LMSFinish;
this.Finish=LMSFinish;
this.LMSGetLastError=LMSGetLastError;
this.GetLastError=LMSGetLastError;
this.LMSGetErrorString=LMSGetErrorString;
this.GetErrorString=LMSGetErrorString;
this.LMSGetDiagnostic=LMSGetDiagnostic;
this.GetDiagnostic=LMSGetDiagnostic;
this.Terminate=Terminate; //only in Scorm 1.3
this.save_asset = lms_save_asset;
this.void_save_asset = chamilo_void_save_asset;
}
// it is not sure that the scos use the above declarations. The following
@ -215,12 +213,13 @@ $(document).ready( function() {
frames['content_name'].document.body.style.margin="0 12px 0px 5px";
} catch (ex) { }
}*/
olms.info_lms_item[0]=olms.info_lms_item[1];
if (olms.lms_item_types['i'+olms.info_lms_item[1]] != 'sco') {
LMSInitialize();
LMSInitialize();
}
});
});
});
@ -229,10 +228,10 @@ $(document).ready( function() {
*/
/**
* Function called mandatorily by the SCORM content to start the SCORM comm
* @return string 'true' or 'false'. Returning a string is mandatory (SCORM).
* This is the initialize function of all APIobjects
* @return string 'true' or 'false'. Returning a string is mandatory (SCORM).
*/
function LMSInitialize() { //this is the initialize function of all APIobjects
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.lesson_status = 'not attempted'
@ -302,10 +301,10 @@ function LMSInitialize() { //this is the initialize function of all APIobjects
/**
* Twin sister of LMSInitialize(). Only provided for backwards compatibility.
* this is the initialize function of all APIobjects
*/
function Initialize()
{ //this is the initialize function of all APIobjects
return LMSInitialize();
function Initialize() {
return LMSInitialize();
}
/**
@ -475,9 +474,7 @@ function LMSGetValue(param)
}else if(req_type == 'status'){
result = 'not attempted';
}
}
else
{
} else {
//the object is not null
if(req_type == 'id')
{
@ -775,7 +772,7 @@ function LMSSetValue(param, val) {
}
}
}
}else{
} else {
olms.G_LastError = G_NotImplementedError;
olms.G_LastErrorString = G_NotImplementedErrorMessage;
}
@ -793,23 +790,35 @@ function LMSSetValue(param, val) {
function SetValue(param, val) {
return LMSSetValue(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) {
//origin can be 'commit', 'finish' or 'terminate' (depending on the calling function)
if ((olms.lesson_status != 'completed') && (olms.lesson_status != 'passed') && (olms.mastery_score >=0) && (olms.score >= olms.mastery_score)) {
olms.lesson_status = 'passed';
//origin can be 'commit', 'finish' or 'terminate' (depending on the calling function)
/* console.log('savedata');
console.log(olms.lesson_status);
console.log(olms.mastery_score);
console.log(olms.score);
*/
if (olms.lesson_status != '') {
olms.updatable_vars_list['cmi.core.lesson_status']=true;
}
//If lesson_status is empty we left the status like that
if (olms.lesson_status != '' && olms.lesson_status != 'completed' && olms.lesson_status != 'passed' && olms.mastery_score >=0 && olms.score >= olms.mastery_score) {
//olms.lesson_status = 'passed';
//olms.updatable_vars_list['cmi.core.lesson_status']=true;
} else if( (olms.mastery_score < 0) && (olms.lms_lp_type != '2') && ( olms.lesson_status == 'incomplete') && (olms.score >= (0.8*olms.max) ) ) {
//the status cannot be modified automatically by the LMS under SCORM 1.2's rules
<?php if ($autocomplete_when_80pct){ ?>
olms.lesson_status = 'completed';
olms.updatable_vars_list['cmi.core.lesson_status']=true;
<?php }?>
;
//olms.lesson_status = 'completed';
//olms.updatable_vars_list['cmi.core.lesson_status']=true;
<?php } ?>
} else {
/* DEPRECATED
* See notes in switch_item for why this has been disabled
@ -832,20 +841,18 @@ function savedata(origin) {
}
*/
}
//console.log(olms.lesson_status);
logit_lms('saving data (status='+olms.lesson_status+' - interactions: '+ olms.interactions.length +')',1);
old_item_id=olms.info_lms_item[0];
xajax_save_item_scorm(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, old_item_id);
//olms.info_lms_item[0] is old_item_id and olms.info_lms_item[1] is current_item_id
xajax_save_item_scorm(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, old_item_id);
olms.info_lms_item[1]=olms.lms_item_id;
if(olms.item_objectives.length>0) {
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);
}
olms.execute_stats = false;
//clean array
olms.variable_to_send=new Array();
}
@ -1013,6 +1020,7 @@ function addEvent(elm, evType, fn, useCapture){
elm['on'+evType] = fn;
}
}
/**
* Add listeners to the page objects. This has to be defined for
* the current context as it acts on objects that should exist
@ -1046,9 +1054,8 @@ function addListeners(){
* Save a Chamilo learnpath item's time and mark as completed upon
* leaving it
*/
function lms_save_asset(){
function lms_save_asset() {
// only for Chamilo lps
if (olms.execute_stats) {
olms.execute_stats = false;
} else {
@ -1057,13 +1064,13 @@ function lms_save_asset(){
//For scorms do not show stats
if (olms.lms_lp_type == 2) {
olms.execute_stats = false;
olms.execute_stats = false;
}
if (olms.lms_lp_type == 1 || olms.lms_item_type == 'asset'){
logit_lms('lms_save_asset', 2);
if (olms.lms_lp_type == 1 || olms.lms_item_type == 'asset') {
logit_lms('lms_save_asset', 2);
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);
if(olms.item_objectives.length>0) {
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);
}
}
@ -1211,11 +1218,11 @@ function update_toc(update_action, update_id, change_ids) {
/**
* Update the stats frame using a reload of the frame to avoid unsynched data
*/
function update_stats() {
function update_stats() {
if (olms.execute_stats) {
try {
cont_f = document.getElementById('content_id');
cont_f.src="lp_controller.php?action=stats";
cont_f.src = "lp_controller.php?action=stats";
cont_f.reload();
} catch (e) {
return false;

Loading…
Cancel
Save