Step 17 – cmi.core.total_time and cmi.core.session_time

Let’s look at another pair of SCORM 1.2 data elements – cmi.core.total_time and cmi.core.session_time. These elements are used to track the amount of time that the student spends on the course.

Now, I could argue that the whole concept of ‘seat time’ for web-based training courses is meaningless – after all, there’s really no way to know whether the 4 hours that a student appears to spend on a course was actually spent on the course material, or on browsing the Internet in another window. But, some organizations still require students to take a certain number of hours training to receive continuing education credits, or retain their professional certification. So I should support this SCORM functionality just in case it’s needed.

I’m going to start with cmi.core.total_time element. It’s a read-only element which can be read by my LMSGetValue() function and the associated server-side script – getValue.php – without any modification. But there’s a twist … its initial/default value should be ‘0000:00:00’ where this is a time in ‘hours:minutes:seconds’ notation (presumably students aren’t expected to take more than 9999 hours to do a course!).

To handle initial/default values (and this won’t be the only one) I’m going to change the way that the LMSInitialize() call works, and make it call a new server-side script – initialize.php. Here’s the new LMSInitialize() call in the api.html file.

function LMSInitialize(dummyString) { 

	// create request object 
	var req = createRequest();

	// code to prevent caching
	var d = new Date();

	// set up request parameters - uses GET method
	req.open('GET','initialize.php?code='+d.getTime(),false);    

	// submit to the server for processing
	req.send(null);

	// process returned data - error condition
	if (req.status != 200) {
		alert('Problem with Request');
		return "";
	}

	// process returned data - OK
	else {
		return "true";
	}

}

As an aside, you’ll also note that I’ve changed the way that I’m preventing caching. Instead of a random number which could – in theory – recur at an awkward moment, I’m going to append to the URL the time in milliseconds measured from Jan. 1, 1970. So, unless a query is repeated within 1 millisecond of precisely the same query (extremely unlikely!) we won’t have a problem. I think this is probably a better way to handle this problem.

Anyway, back to the matter in hand. Here’s the new initialize.php server-side script.

<?php 

/*

VS SCORM - initialize.php 
Rev 1.0 - Wednesday, July 08, 2009
Copyright (C) 2009, Addison Robson LLC

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, 
Boston, MA  02110-1301, USA.

*/

//  database login information
require "config.php";

// connect to the database
$link = mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db($dbname,$link);

// if not set, cmi.core.total_time should be set to '0000:00:00'
$result = mysql_query("select varValue from scormvars where (varName='cmi.core.total_time')",$link);
list($totalTime) = mysql_fetch_row($result);
if (! $totalTime) { 
  mysql_query("delete from scormvars where (varName='cmi.core.total_time')",$link);
  mysql_query("insert into scormvars (varName,varValue) values ('cmi.core.total_time','0000:00:00')",$link);
}
	
// clear any pre-existing cmi.core.session_time and set to '0000:00:00'
mysql_query("delete from scormvars where (varName='cmi.core.session_time')",$link);
mysql_query("insert into scormvars (varName,varValue) values ('cmi.core.session_time','0000:00:00')",$link);

// return value to the calling program
print "true";

?>

Nothing very complex – I simply check to see if cmi.core.total_time has already been set and, if not, set it to ‘0000:00:00’. I also set the cmi.core.session_time to ‘0000:00:00’ since it’s the start of a new session.

The cmi.core.session_time element is a write-only element. But it’s a little more difficult to handle. The SCORM specification says that this variable can be set any number of times during the session but, when LMSFinish() is called at the end of the session, the time that’s recorded in the cmi.core.session_time element should be added to the value stored in the cmi.core.total_time element, and the value in the cmi.core.session_time element should be reset ready for the next session.

As with LMSInitialize(), I’m going to change the way that I handle the LMSFinish() and make it invoke a script on the server called finish.php.

function LMSFinish(dummyString) {

	// create request object 
	var req = createRequest();

	// code to prevent caching
	var d = new Date();

	// set up request parameters - uses GET method
	req.open('GET','finish.php?code='+d.getTime(),false);    

	// submit to the server for processing
	req.send(null);

	// process returned data - error condition
	if (req.status != 200) {
		alert('Problem with Request');
		return "";
	}

	// process returned data - OK
	else {
		return "true";
	}

}

In the finish.php script, I add cmi.core.session_time to cmi.core.total_time. The coding isn’t very complicated – just inelegant because of the format that the SCORM standard requires for the times. Here it is.

<?php 

/*

VS SCORM - finish.php 
Rev 1.0 - Wednesday, July 08, 2009
Copyright (C) 2009, Addison Robson LLC

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, 
Boston, MA  02110-1301, USA.

*/

//  database login information
require "config.php";

// connect to the database
$link = mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db($dbname,$link);

// process the changes to cmi.core.total_time

// read cmi.core.total_time from the 'scormvars' table
$result = mysql_query("select varValue from scormvars where (varName='cmi.core.total_time')",$link);
list($totalTime) = mysql_fetch_row($result);

// convert total time to seconds
$time = explode(':',$totalTime);
$totalSeconds = $time[0]*60*60 + $time[1]*60 + $time[2];

// read the last set cmi.core.session_time from the 'scormvars' table
$result = mysql_query("select varValue from scormvars where (varName='cmi.core.session_time')",$link);
list($sessionTime) = mysql_fetch_row($result);

// convert session time to seconds
$time = explode(':',$sessionTime);
$sessionSeconds = $time[0]*60*60 + $time[1]*60 + $time[2];

// new total time is ...
$totalSeconds += $sessionSeconds;

// break total time into hours, minutes and seconds
$totalHours = intval($totalSeconds/3600);
$totalSeconds -= $totalHours * 3600;
$totalMinutes = intval($totalSeconds/60);
$totalSeconds -= $totalMinutes * 60;

// reformat to comply with the SCORM data model
$totalTime = sprintf("%04d:%02d:%02d",$totalHours,$totalMinutes,$totalSeconds);

// save new total time to the 'scormvars' table
mysql_query("delete from scormvars where (varName='cmi.core.total_time')",$link);
mysql_query("insert into scormvars (varName,varValue) values ('cmi.core.total_time','$totalTime')",$link);

// delete the last session time
mysql_query("delete from scormvars where (varName='cmi.core.session_time')",$link);

// return value to the calling program
print "true";

?>

Now, I run my test course again. The course runs successfully and successive session times are added to the total time as planned. This is what the ‘scormvars’ table looks like after a typical run.

The 'scormvars' table after a typical run

Doing well so far! Time to move on …

This entry was posted in Run Time Environment. Bookmark the permalink.

2 Responses to Step 17 – cmi.core.total_time and cmi.core.session_time

  1. Pingback: Desarrollando un LMS(con soporte de SCORM)

  2. Deva says:

    is it possible to get total_time with respect to scorm scos (lesson wise) ?

Leave a Reply

Your email address will not be published. Required fields are marked *