Fixed some manifest parsing problems and a structure display bug

This commit is contained in:
bobopinna
2005-07-13 20:11:56 +00:00
parent 901d0f94a8
commit 28a774b13e
+195 -226
View File
@@ -3,6 +3,8 @@
/// Library of functions and constants for module scorm
/// (replace scorm with the name of your module and delete this line)
require_once('xml2array.class.php'); // Used to parse manifest
define('VALUESCOES', '0');
define('VALUEHIGHEST', '1');
define('VALUEAVERAGE', '2');
@@ -517,118 +519,6 @@ function scorm_scandir($directory) {
}
}
function scorm_startElement($parser, $name, $attrs) {
global $scoes,$i,$resources,$parent,$level,$organization,$manifest,$defaultorg;
switch ($name) {
case 'ITEM':
$i++;
$scoes[$i]['manifest'] = $manifest;
$scoes[$i]['organization'] = $organization;
$scoes[$i]['identifier'] = $attrs['IDENTIFIER'];
if (empty($attrs['IDENTIFIERREF'])) {
$attrs['IDENTIFIERREF'] = '';
}
$scoes[$i]['identifierref'] = $attrs['IDENTIFIERREF'];
if (empty($attrs['ISVISIBLE'])) {
$attrs['ISVISIBLE'] = '';
}
$scoes[$i]['isvisible'] = $attrs['ISVISIBLE'];
if (empty($attrs['PARAMETERS'])) {
$attrs['PARAMETERS'] = '';
}
$scoes[$i]['parameters'] = $attrs['PARAMETERS'];
$scoes[$i]['parent'] = $parent[$level];
$level++;
$parent[$level] = $attrs['IDENTIFIER'];
break;
case 'RESOURCE':
if (!isset($attrs['HREF'])) {
$attrs['HREF'] = '';
}
$resources[$attrs['IDENTIFIER']]['href']=$attrs['HREF'];
if (!isset($attrs['ADLCP:SCORMTYPE'])) {
$attrs['ADLCP:SCORMTYPE'] = 'sco'; //Default scorm type
}
$resources[$attrs['IDENTIFIER']]['scormtype']=$attrs['ADLCP:SCORMTYPE'];
break;
case 'ORGANIZATION':
$i++;
$scoes[$i]['manifest'] = $manifest;
$scoes[$i]['organization'] = '';
$scoes[$i]['identifier'] = $attrs['IDENTIFIER'];
$scoes[$i]['identifierref'] = '';
$scoes[$i]['isvisible'] = '';
$scoes[$i]['parent'] = $parent[$level];
$level++;
$parent[$level] = $attrs['IDENTIFIER'];
$organization = $attrs['IDENTIFIER'];
break;
case 'MANIFEST':
$manifest = $attrs['IDENTIFIER'];
break;
case 'ORGANIZATIONS':
if (!isset($attrs['DEFAULT'])) {
$attrs['DEFAULT'] = '';
}
$defaultorg = $attrs['DEFAULT'];
break;
}
}
function scorm_endElement($parser, $name) {
global $scoes,$i,$level,$datacontent,$manifest,$organization,$version;
$datacontent = trim($datacontent);
if ($name == 'ITEM') {
$level--;
}
//if ($name == 'TITLE' && $level>0) {
if (($name == 'TITLE') && !isset($scoes[$i]['title'])) {
$scoes[$i]['title'] = $datacontent;
}
if ($name == 'ADLCP:HIDERTSUI') {
$scoes[$i][$datacontent] = 1;
}
if ($name == 'ADLCP:DATAFROMLMS') {
$scoes[$i]['datafromlms'] = $datacontent;
}
if ($name == 'ADLCP:PREREQUISITES') {
$scoes[$i]['prerequisites'] = $datacontent;
}
if ($name == 'ADLCP:MAXTIMEALLOWED') {
$scoes[$i]['maxtimeallowed'] = $datacontent;
}
if ($name == 'ADLCP:TIMELIMITACTION') {
$scoes[$i]['timelimitaction'] = $datacontent;
}
if ($name == 'ADLCP:MASTERYSCORE') {
$scoes[$i]['masteryscore'] = $datacontent;
}
if ($name == 'ORGANIZATION') {
$organization = '';
$level--;
}
if ($name == 'MANIFEST') {
$manifest = '';
}
if ($name == 'SCHEMAVERSION') {
if (preg_match("/^(1\.2)$|^(CAM )?(1\.3)$/",$datacontent,$matches)) {
$version = 'SCORM_'.$matches[count($matches)-1];
} else {
$version = 'SCORM_1.2';
}
}
$datacontent = '';
}
function scorm_characterData($parser, $data) {
global $datacontent;
$datacontent .= utf8_decode($data);
}
function scorm_parse($pkgdir,$pkgtype,$scormid){
delete_records('scorm_scoes','scorm',$scormid);
delete_records('scorm_scoes_track','scormid',$scormid);
@@ -636,7 +526,7 @@ function scorm_parse($pkgdir,$pkgtype,$scormid){
if ($pkgtype == 'AICC') {
return scorm_parse_aicc($pkgdir,$scormid);
} else {
return scorm_parse_scorm($pkgdir,'/imsmanifest.xml',$scormid);
return scorm_parse_scorm($pkgdir.'/imsmanifest.xml',$scormid);
}
}
@@ -823,120 +713,197 @@ function scorm_parse_aicc($pkgdir,$scormid){
return $launch;
}
function scorm_parse_scorm($pkgdir,$file,$scormid) {
global $scoes,$i,$resources,$parent,$level,$defaultorg,$version,$organization,$manifest;
$datacontent = '';
$scoes[][] = '';
$resources[] = '';
$manifest = '';
$version = 'SCORM';
$organization = '';
$defaultorg = '';
$i = 0;
$level = 0;
$parent[$level] = '/';
$xmlparser = xml_parser_create('UTF-8');
// use case-folding so we are sure to find the tag in $map_array
xml_parser_set_option($xmlparser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($xmlparser, 'scorm_startElement', 'scorm_endElement');
xml_set_character_data_handler($xmlparser, 'scorm_characterData');
if (!($fp = fopen($pkgdir.$file, 'r'))) {
die('could not open XML input');
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xmlparser, $data, feof($fp))) {
die(sprintf('XML error: %s at line %d',
xml_error_string(xml_get_error_code($xmlparser)),
xml_get_current_line_number($xmlparser)));
}
}
xml_parser_free($xmlparser);
$launch = 0;
$sco->scorm = $scormid;
if (isset($scoes[1])) {
for ($j=1; $j<=$i; $j++) {
$sco->identifier = $scoes[$j]['identifier'];
$sco->parent = $scoes[$j]['parent'];
if (!isset($scoes[$j]['title'])) {
$scoes[$j]['title'] = '';
}
$sco->title = $scoes[$j]['title'];
$sco->manifest = $scoes[$j]['manifest'];
$sco->organization = $scoes[$j]['organization'];
if (!isset($scoes[$j]['datafromlms'])) {
$scoes[$j]['datafromlms'] = '';
}
$sco->datafromlms = $scoes[$j]['datafromlms'];
if (!isset($scoes[$j]['prerequisites'])) {
$scoes[$j]['prerequisites'] = '';
}
$sco->prerequisites = $scoes[$j]['prerequisites'];
if (!isset($scoes[$j]['maxtimeallowed'])) {
$scoes[$j]['maxtimeallowed'] = '';
}
$sco->maxtimeallowed = $scoes[$j]['maxtimeallowed'];
if (!isset($scoes[$j]['timelimitaction'])) {
$scoes[$j]['timelimitaction'] = '';
}
$sco->timelimitaction = $scoes[$j]['timelimitaction'];
if (!isset($scoes[$j]['masteryscore'])) {
$scoes[$j]['masteryscore'] = '';
}
$sco->masteryscore = $scoes[$j]['masteryscore'];
if (!isset($resources[($scoes[$j]['identifierref'])]['href'])) {
$resources[($scoes[$j]['identifierref'])]['href'] = '';
}
$sco->launch = $resources[($scoes[$j]['identifierref'])]['href'];
if (!isset($scoes[$j]['parameters'])) {
$scoes[$j]['parameters'] = '';
}
$sco->parameters = $scoes[$j]['parameters'];
if (!isset($resources[($scoes[$j]['identifierref'])]['scormtype'])) {
$resources[($scoes[$j]['identifierref'])]['scormtype'] = '';
}
$sco->scormtype = $resources[($scoes[$j]['identifierref'])]['scormtype'];
if (!isset($scoes[$j]['previous'])) {
$scoes[$j]['previous'] = 0;
}
$sco->previous = $scoes[$j]['previous'];
if (!isset($scoes[$j]['continue'])) {
$scoes[$j]['continue'] = 0;
}
$sco->next = $scoes[$j]['continue'];
if (scorm_remove_spaces($scoes[$j]['isvisible']) != 'false') {
$id = insert_record('scorm_scoes',$sco);
}
if (($launch==0) && ($defaultorg==$sco->identifier)) {
$launch = $id;
}
}
} else {
foreach ($resources as $label => $resource) {
if (!empty($resource['href'])) {
$sco->identifier = $label;
$sco->title = $label;
$sco->parent = '/';
$sco->launch = $resource['href'];
$sco->scormtype = $resource['type'];
$id = insert_record('scorm_scoes',$sco);
if ($launch == 0) {
$launch = $id;
function scorm_get_resources($blocks) {
foreach ($blocks as $block) {
if ($block['name'] == 'RESOURCES') {
foreach ($block['children'] as $resource) {
if ($resource['name'] == 'RESOURCE') {
$resources[addslashes($resource['attrs']['IDENTIFIER'])] = $resource['attrs'];
}
}
}
}
set_field('scorm','version',$version,'id',$scormid);
return $resources;
}
function scorm_get_manifest($blocks,$scoes) {
static $parents = array();
static $resources;
static $manifest;
static $organization;
if (count($blocks) > 0) {
foreach ($blocks as $block) {
switch ($block['name']) {
case 'METADATA':
if (isset($block['children'])) {
foreach ($block['children'] as $metadata) {
if ($metadata['name'] == 'SCHEMAVERSION') {
if (empty($scoes->version)) {
if (preg_match("/^(1\.2)$|^(CAM )?(1\.3)$/",$metadata['tagData'],$matches)) {
$scoes->version = 'SCORM_'.$matches[count($matches)-1];
} else {
$scoes->version = 'SCORM_1.2';
}
}
}
}
}
break;
case 'MANIFEST':
$manifest = addslashes($block['attrs']['IDENTIFIER']);
$organization = '';
$resources = array();
$resources = scorm_get_resources($block['children']);
$scoes = scorm_get_manifest($block['children'],$scoes);
if (count($scoes->elements) <= 0) {
foreach ($resources as $item => $resource) {
if (!empty($resource['HREF'])) {
$sco = new stdClass();
$sco->identifier = $item;
$sco->title = $item;
$sco->parent = '/';
$sco->launch = addslashes($resource['HREF']);
$sco->scormtype = addslashes($resource['ADLCP:SCORMTYPE']);
$scoes->elements[$manifest][$organization][$item] = $sco;
}
}
}
break;
case 'ORGANIZATIONS':
if (!isset($scoes->defaultorg)) {
$scoes->defaultorg = addslashes($block['attrs']['DEFAULT']);
}
$scoes = scorm_get_manifest($block['children'],$scoes);
break;
case 'ORGANIZATION':
$identifier = addslashes($block['attrs']['IDENTIFIER']);
$organization = '';
$scoes->elements[$manifest][$organization][$identifier]->identifier = $identifier;
$scoes->elements[$manifest][$organization][$identifier]->parent = '/';
$scoes->elements[$manifest][$organization][$identifier]->launch = '';
$scoes->elements[$manifest][$organization][$identifier]->scormtype = '';
$parents = array();
$parent = new stdClass();
$parent->identifier = $identifier;
$parent->organization = $organization;
array_push($parents, $parent);
$organization = $identifier;
$scoes = scorm_get_manifest($block['children'],$scoes);
array_pop($parents);
break;
case 'ITEM':
$parent = array_pop($parents);
array_push($parents, $parent);
$identifier = addslashes($block['attrs']['IDENTIFIER']);
$scoes->elements[$manifest][$organization][$identifier]->identifier = $identifier;
$scoes->elements[$manifest][$organization][$identifier]->parent = $parent->identifier;
if (!isset($block['attrs']['ISVISIBLE'])) {
$block['attrs']['ISVISIBLE'] = 'true';
}
$scoes->elements[$manifest][$organization][$identifier]->isvisible = addslashes($block['attrs']['ISVISIBLE']);
if (!isset($block['attrs']['PARAMETERS'])) {
$block['attrs']['PARAMETERS'] = '';
}
$scoes->elements[$manifest][$organization][$identifier]->parameters = addslashes($block['attrs']['PARAMETERS']);
if (!isset($block['attrs']['IDENTIFIERREF'])) {
$scoes->elements[$manifest][$organization][$identifier]->launch = '';
$scoes->elements[$manifest][$organization][$identifier]->scormtype = 'asset';
} else {
$idref = addslashes($block['attrs']['IDENTIFIERREF']);
$scoes->elements[$manifest][$organization][$identifier]->launch = addslashes($resources[$idref]['HREF']);
if (empty($resources[$idref]['ADLCP:SCORMTYPE'])) {
$resources[$idref]['ADLCP:SCORMTYPE'] = 'asset';
}
$scoes->elements[$manifest][$organization][$identifier]->scormtype = addslashes($resources[$idref]['ADLCP:SCORMTYPE']);
}
$parent = new stdClass();
$parent->identifier = $identifier;
$parent->organization = $organization;
array_push($parents, $parent);
$scoes = scorm_get_manifest($block['children'],$scoes);
array_pop($parents);
break;
case 'TITLE':
$parent = array_pop($parents);
array_push($parents, $parent);
$scoes->elements[$manifest][$parent->organization][$parent->identifier]->title = addslashes($block['tagData']);
break;
case 'ADLCP:PREREQUISITES':
if ($block['attrs']['TYPE'] == 'aicc_script') {
$parent = array_pop($parents);
array_push($parents, $parent);
$scoes->elements[$manifest][$parent->organization][$parent->identifier]->prerequisites = addslashes($block['tagData']);
}
break;
case 'ADLCP:MAXTIMEALLOWED':
$parent = array_pop($parents);
array_push($parents, $parent);
$scoes->elements[$manifest][$parent->organization][$parent->identifier]->maxtimeallowed = addslashes($block['tagData']);
break;
case 'ADLCP:TIMELIMITACTION':
$parent = array_pop($parents);
array_push($parents, $parent);
$scoes->elements[$manifest][$parent->organization][$parent->identifier]->timelimitaction = addslashes($block['tagData']);
break;
case 'ADLCP:DATAFROMLMS':
$parent = array_pop($parents);
array_push($parents, $parent);
$scoes->elements[$manifest][$parent->organization][$parent->identifier]->datafromlms = addslashes($block['tagData']);
break;
case 'ADLCP:MASTERYSCORE':
$parent = array_pop($parents);
array_push($parents, $parent);
$scoes->elements[$manifest][$parent->organization][$parent->identifier]->masteryscore = addslashes($block['tagData']);
break;
}
}
}
return $scoes;
}
function scorm_parse_scorm($manifestfile,$scormid) {
$launch = 0;
if (is_file($manifestfile)) {
$xmlstring = file_get_contents($manifestfile);
$objXML = new xml2Array();
$manifests = $objXML->parse($xmlstring);
$scoes = new stdClass();
$scoes->version = 'SCORM';
$scoes = scorm_get_manifest($manifests,$scoes);
if (count($scoes->elements) > 0) {
foreach ($scoes->elements as $manifest => $organizations) {
foreach ($organizations as $organization => $items) {
foreach ($items as $identifier => $item) {
$item->scorm = $scormid;
$item->manifest = $manifest;
$item->organization = $organization;
$id = insert_record('scorm_scoes',$item);
if (($launch == 0) && ((empty($scoes->defaultorg)) || ($scoes->defaultorg == $identifier))) {
$launch = $id;
}
}
}
}
set_field('scorm','version',$scoes->version,'id',$scormid);
}
}
return $launch;
}
@@ -1050,9 +1017,11 @@ function scorm_display_structure($scorm,$liststyle,$currentorg='',$scoid='',$mod
$parents[$level]='/';
foreach ($scoes as $sco) {
if ($parents[$level]!=$sco->parent) {
if ($level>0 && $parents[$level-1]==$sco->parent) {
echo "\t\t</ul></li>\n";
$level--;
if ($newlevel = array_search($sco->parent,$parents)) {
for ($i=0; $i<($level-$newlevel); $i++) {
echo "\t\t</ul></li>\n";
}
$level = $newlevel;
} else {
$i = $level;
$closelist = '';