Friday, 5 January 2007

Fun with SCORM 2004

I'm doing some work making one of our app "Scorm 2004" compliant. I'm baffled to see how easy it is now that we have prototype.js, as if the people who designed SCORM way back then had XHRs in mind... In any case, it helps to just do a ajax.request for the commit function...

Now, they didn't always have such a good visionnary view on things, especially when they decided to switch the format of cmi.session_time. WTF is that ? PT3H5M3.5S for 3 hours 5 minutes and 3.5 seconds...? Not only is it complex to parse (for the PHP minded, I give away the code right below), but now look at this: P1Y3M2DT3H equals 1 year, 3 months, 2 days and 3 hours. Her.... What's a month, please ? Is that 30 days ? 31 ? Should I guess ? And why choose the same character for months and minutes ? bah.

Ok. Now some code:
function GetSecondsForScormPeriod($strScormPeriod)
{
$matches = array();

if (!preg_match("/^P([0-9]+Y)?([0-9]+M)?([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+(.[0-9]+)?S)?)?$/", $strScormPeriod, $matches))
return 0;

$seconds = 0;
$InTime = false;

foreach ($matches as $aMatch)
{
if ($aMatch{0} == 'P')
continue;

if ($aMatch{0} == 'T')
{
$InTime = true;
continue;
}

$unit = substr($aMatch, -1);
$val = substr($aMatch, 0, -1);

switch ($unit)
{
case 'Y': $seconds += (int)($val) * 365 * 24 * 60 * 60; break;

case 'M':
if (!$InTime)
$seconds += (int)($val) * 30 * 24 * 60 * 60;
else
$seconds += (int)($val) * 60;
break;

case 'D': $seconds += (int)($val) * 24 * 60 * 60; break;
case 'H': $seconds += (int)($val) * 60 * 60; break;
case 'S': $seconds += (float)($val); break;
}
}

return $seconds;
}

Labels: ,

PHP Bug

Found what I'd call a rather anoying bug in PHP. Because of the historic way of passing POST and GET values through global variables instead of the $_POST and $_GET autoglobals everyone uses nowadays, any character that is not valid in the name of a variable is replaced with an underscore...

For example, if you have a form with <input name="cmi.session_time" value="P1Y3M2DT3H" type="hidden"> you'll get $_POST['cmi_session_time']. Not very usefull at all (spot the dot that became an underscore)...

Let's just hope it gets fixed someday.

Funilly enough, the bug reported on bugs.php.net got numbered 40000... lucky number !

Labels: , ,