Step 23 – More About cmi.core.lesson_status

OK … time to implement the handling of cmi.core.lesson_status as I discussed in Step 22.

I’ve already covered the initialization of cmi.core.lesson_status in Step 20, so I don’t have to worry about that. So most of my changes will be to the finish.php code that’s used when LMSFinish() is invoked by the SCO (if you don’t know what a SCO is, please see my last post). Just as a reminder, here’s the logic flow that I’m going to follow.

Setting cmi.core.lesson_status - much easier!

The first part of the process is pretty simple. I find the current value of cmi.core.lesson_status and, if it’s still set to the initial value (‘not attempted’), I change it to ‘completed’.

// find existing value of cmi.core.lesson_status
$result = mysql_query("select varValue from scormvars where (varName='cmi.core.lesson_status')",$link);
list($value) = mysql_fetch_row($result);

// if it's 'not attempted', change it to 'completed'
if ($value == 'not attempted') {
  mysql_query("update scormvars set varValue='completed' where (varName='cmi.core.lesson_status')",$link);
}

So far, so good. Now I have to look to see if a mastery score has been set in the IMS manifest file. If I had a functional LMS, the manifest file would have been read by the LMS when the content aggregation package (what many of us would commonly call a course package) was imported and installed. But I don’t have a real LMS right now (I’ll work on that later), so I’m going to assume that it’s been read and stored in my database as an element called ‘adlcp:masteryscore’. To mimic this, I modify my initialize.php code like this (assuming a 90% passing score).

// if not set, adlcp:masteryscore should be set to the value from the IMS manifest file
$result = mysql_query("select varValue from scormvars where (varName='adlcp:masteryscore')",$link);
list($value) = mysql_fetch_row($result);
if (! $value) { 
  mysql_query("delete from scormvars where (varName='adlcp:masteryscore')",$link);
  mysql_query("insert into scormvars (varName,varValue) values ('adlcp:masteryscore','90')",$link);
}

And my new finish.php code looks like this.

// find existing value of cmi.core.lesson_status
$result = mysql_query("select varValue from scormvars where (varName='cmi.core.lesson_status')",$link);
list($value) = mysql_fetch_row($result);

// if it's 'not attempted', change it to 'completed'
if ($value == 'not attempted') {
  mysql_query("update scormvars set varValue='completed' where (varName='cmi.core.lesson_status')",$link);
}

// has a mastery score been specified in the IMS manifest file?
$result = mysql_query("select varValue from scormvars where (varName='adlcp:masteryscore')",$link);
list($value) = mysql_fetch_row($result);
$value *= 1;

if ($value) {

  // yes - so read the score
  $result2 = mysql_query("select varValue from scormvars where (varName='cmi.score.raw')",$link);
  list($value2) = mysql_fetch_row($result2);
  $value2 *= 1;

  // set cmi.core.lesson_status to passed/failed
  if ($value2 >= $value) {
    mysql_query("update scormvars set varValue='passed' where (varName='cmi.core.lesson_status')",$link);
  }
  else {
    mysql_query("update scormvars set varValue='failed' where (varName='cmi.core.lesson_status')",$link);
  }

}

Time to test it out … the SCO runs through to the end and I score 88 – enough to pass according to the SCO itself. This is what the database table looks like at the end of the SCO but before LMSFinish() has been called.

varName varValue
adlcp:masteryscore 90
cmi.core.credit credit
cmi.core.entry ab initio
cmi.core.lesson_location 13
cmi.core.lesson_status passed
cmi.core.score.raw 88
cmi.core.session_time 00:02:04
cmi.core.total_time 0000:00:00
cmi.suspend_data K01BB000IA%7E%24KS%2AXQov%5F110BBBB1 …

Then I close the SCO window causing LMSFinish() to be called and here’s what happens.

varName varValue
adlcp:masteryscore 90
cmi.core.credit credit
cmi.core.entry  
cmi.core.lesson_location 13
cmi.core.lesson_status failed
cmi.core.score.raw 88
cmi.core.total_time 0000:02:04
cmi.suspend_data K01BB000IA%7E%24KS%2AXQov%5F110BBBB1 …

The mastery score set by my ‘imaginary’ LMS has caused the SCO to be graded as a fail rather than as the pass that the SCO intended which is – from my reading of the SCORM specification – what is intended.

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

10 Responses to Step 23 – More About cmi.core.lesson_status

  1. vanjeer says:

    I am at this stage and I have a question. I have the above output but I can’t seem to have the cmi.core.exit status set to suspend. Doesn’t this particular sample SCO support cmi.core.exit?

  2. vanjeer says:

    Also after completing the SCO once and after reload of the course, it starts and hangs-up in the last location(10) of the Simulation exercise. Problem with SCO or expected behaviour and up to LMS to allow this particular SCO to be allowed only once?

  3. Steve Addison says:

    I have the same problem when using the simulation SCO as a test case. But I don’t know how it was designed, so I can’t comment in any great detail. If you’re having problems, you could try the VERY simple test case that I’ve just posted.

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

  5. Carl utter says:

    I’m pretty sure that the value passed from the “adlcp:mastery_score” in the manifest xml is set in the LMS as the value of “cmi.student_data.mastery_score” and not of itself so your database table and your script logic should reflect that.

    varName value
    cmi.student_data.mastery_score 90

  6. Steve Addison says:

    That would certainly be the case in a logical world. However SCORM 1.2 isn’t totally logical …

    I omitted this variable (and many others) from the original design because one of my initial design choices was to limit support to only the mandatory data elements, and cmi.student_data.mastery_score isn’t mandatory – see page 3-43 of the specification for the SCORM 1.2 Run-Time Environment (RTE). Since I’m now adding in some of the optional elements, it would probably make sense to include this one as well. I’ll add it to my list of things to do,

  7. FadelMS says:

    I Know this thread is old but may be someone will answer my question:
    In the logic presented by Steve, there is no mentioning of “Suspend”. If the activity is suspended, what would happen? I think the logic should include check if the activity is suspended and set the lesson status to incomplete if it is suspended.
    Steve: If you are still there, please answer my question.

  8. rex says:

    Hi,

    How can I set the max score to 100?
    I don’t know where to insert this code. cmi.core.score.max
    Is there an xml tag where i can insert it in manifest file?

    thanks for any inputs.

  9. Steve Addison says:

    Hi rex

    I don’t see anything in the manifest file schema that would allow you to set that value although it’s a complicated document and I might well have missed it. The nearest thing that I could see in the manifest file is an ADL extension called – see page 2-141 of the SCORM 1.2 Specification – Book 2 – Content Aggregation Model (CAM) for more details.

    Just a reminder that ‘cmi.core.score.max’ is an optional data element, and courses are probably going to be designed to work without it.

  10. Aykut says:

    Hi,
    I step to step process in this project. But I implemented in .Net. End of this step,I am looking “cmi.core.score.raw 88” in your output . I can not “cmi.core.score.raw” variable name from setValue.aspx page.
    So , The page don’t store “cmi.core.score.raw” to my database.
    Please help me this section.

Comments are closed.