diff --git a/main/newscorm/lp_ajax_save_item.php b/main/newscorm/lp_ajax_save_item.php index 1c2a59bced..0b2b2632b3 100644 --- a/main/newscorm/lp_ajax_save_item.php +++ b/main/newscorm/lp_ajax_save_item.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'])) { diff --git a/main/newscorm/scorm_api.php b/main/newscorm/scorm_api.php index 1ff94f39c7..47ca59ac74 100644 --- a/main/newscorm/scorm_api.php +++ b/main/newscorm/scorm_api.php @@ -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 - olms.lesson_status = 'completed'; - olms.updatable_vars_list['cmi.core.lesson_status']=true; - - ; + //olms.lesson_status = 'completed'; + //olms.updatable_vars_list['cmi.core.lesson_status']=true; + } 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;