mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
MDL-16088 scorm new file api conversion
This commit is contained in:
parent
fec2094ee6
commit
9528568bf0
@ -4,6 +4,12 @@
|
||||
|
||||
$string['activation'] = 'Activation';
|
||||
$string['advanced'] = 'Parameters';
|
||||
$string['allowtypeexternal'] = 'Enable external package type';
|
||||
$string['allowtypeimsrepository'] = 'Enable IMS package type';
|
||||
$string['allowtypelocalsync'] = 'Enable downloaded package type';
|
||||
$string['areaintro'] = 'Introduction files';
|
||||
$string['areacontent'] = 'Content files';
|
||||
$string['areapackage'] = 'Package file';
|
||||
$string['asset'] = 'Asset';
|
||||
$string['assetlaunched'] = 'Asset - Viewed';
|
||||
$string['attempt'] = 'attempt';
|
||||
@ -125,6 +131,7 @@ $string['scorm:skipview'] = 'Skip overview';
|
||||
$string['scorm:viewreport'] = 'View reports';
|
||||
$string['scorm:viewscores'] = 'View scores';
|
||||
$string['scormcourse'] = 'Learning Course';
|
||||
$string['scormtype'] = 'Type';
|
||||
$string['scrollbars'] = 'Allow the window to be scrolled';
|
||||
$string['sided'] = 'On the left side';
|
||||
$string['skipview'] = 'Student skip content structure page';
|
||||
@ -145,6 +152,12 @@ $string['toolbar'] = 'Show the toolbar';
|
||||
$string['totaltime'] = 'Time';
|
||||
$string['trackingloose'] = 'WARNING: The tracking data of this package will be lost!';
|
||||
$string['type'] = 'Type';
|
||||
$string['typeexternal'] = 'External SCORM manifest';
|
||||
$string['typeimsrepository'] = 'Local IMS content repository';
|
||||
$string['typelocal'] = 'Uploaded package';
|
||||
$string['typelocalsync'] = 'Downloaded package';
|
||||
$string['updatetime'] = 'Synchronisation time';
|
||||
$string['url'] = 'URL';
|
||||
$string['validateascorm'] = 'Validate a package';
|
||||
$string['validation'] = 'Validation result';
|
||||
$string['validationtype'] = 'This preference set the DOMXML library used for validating SCORM Manifest. If you don\'t know leave the selected choice.';
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
require_once("../../config.php");
|
||||
require_once('locallib.php');
|
||||
|
||||
|
||||
$id = optional_param('id', '', PARAM_INT); // Course Module ID, or
|
||||
$a = optional_param('a', '', PARAM_INT); // scorm ID
|
||||
$scoid = required_param('scoid', PARAM_INT); // sco ID
|
||||
@ -33,7 +33,7 @@
|
||||
print_error('missingparameter');
|
||||
}
|
||||
|
||||
require_login($course->id, false, $cm);
|
||||
require_login($course, false, $cm);
|
||||
|
||||
if ($usertrack = scorm_get_tracks($scoid,$USER->id,$attempt)) {
|
||||
if ((isset($usertrack->{'cmi.exit'}) && ($usertrack->{'cmi.exit'} != 'time-out')) || ($scorm->version != "SCORM_1.3")) {
|
||||
@ -58,7 +58,7 @@
|
||||
$userdata->credit = 'credit';
|
||||
} else {
|
||||
$userdata->credit = 'no-credit';
|
||||
}
|
||||
}
|
||||
if ($scodatas = scorm_get_sco($scoid, SCO_DATA)) {
|
||||
foreach ($scodatas as $key => $value) {
|
||||
$userdata->$key = addslashes_js($value);
|
||||
|
@ -90,49 +90,57 @@ function scorm_forge_cols_regexp($columns,$remodule='(".*")?,') {
|
||||
return $regexp;
|
||||
}
|
||||
|
||||
function scorm_parse_aicc($pkgdir,$scormid) {
|
||||
|
||||
function scorm_parse_aicc($scorm) {
|
||||
global $DB;
|
||||
|
||||
if (!isset($scorm->cmid)) {
|
||||
$cm = get_coursemodule_from_instance('scorm', $scorm->id);
|
||||
$scorm->cmid = $cm->id;
|
||||
}
|
||||
$context = get_context_instance(COURSE_MODULE, $scorm->cmid);
|
||||
|
||||
$fs = get_file_storage();
|
||||
|
||||
$files = $fs->get_area_files($context->id, 'scorm_content', 0, '', false);
|
||||
|
||||
|
||||
$version = 'AICC';
|
||||
$ids = array();
|
||||
$courses = array();
|
||||
$extaiccfiles = array('crs','des','au','cst','ort','pre','cmp');
|
||||
if ($handle = opendir($pkgdir)) {
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
if ($file[0] != '.') {
|
||||
$ext = substr($file,strrpos($file,'.'));
|
||||
$extension = strtolower(substr($ext,1));
|
||||
if (in_array($extension,$extaiccfiles)) {
|
||||
$id = strtolower(basename($file,$ext));
|
||||
$ids[$id]->$extension = $file;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
$filename = $file->get_filename();
|
||||
$ext = substr($filename,strrpos($filename,'.'));
|
||||
$extension = strtolower(substr($ext,1));
|
||||
if (in_array($extension,$extaiccfiles)) {
|
||||
$id = strtolower(basename($filename,$ext));
|
||||
$ids[$id]->$extension = $file;
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
|
||||
foreach ($ids as $courseid => $id) {
|
||||
if (isset($id->crs)) {
|
||||
if (is_file($pkgdir.'/'.$id->crs)) {
|
||||
$rows = file($pkgdir.'/'.$id->crs);
|
||||
foreach ($rows as $row) {
|
||||
if (preg_match("/^(.+)=(.+)$/",$row,$matches)) {
|
||||
switch (strtolower(trim($matches[1]))) {
|
||||
case 'course_id':
|
||||
$courses[$courseid]->id = trim($matches[2]);
|
||||
break;
|
||||
case 'course_title':
|
||||
$courses[$courseid]->title = trim($matches[2]);
|
||||
break;
|
||||
case 'version':
|
||||
$courses[$courseid]->version = 'AICC_'.trim($matches[2]);
|
||||
break;
|
||||
}
|
||||
$rows = $id->crs->get_content();
|
||||
foreach ($rows as $row) {
|
||||
if (preg_match("/^(.+)=(.+)$/",$row,$matches)) {
|
||||
switch (strtolower(trim($matches[1]))) {
|
||||
case 'course_id':
|
||||
$courses[$courseid]->id = trim($matches[2]);
|
||||
break;
|
||||
case 'course_title':
|
||||
$courses[$courseid]->title = trim($matches[2]);
|
||||
break;
|
||||
case 'version':
|
||||
$courses[$courseid]->version = 'AICC_'.trim($matches[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($id->des)) {
|
||||
$rows = file($pkgdir.'/'.$id->des);
|
||||
$rows = $id->des->get_content();
|
||||
$columns = scorm_get_aicc_columns($rows[0]);
|
||||
$regexp = scorm_forge_cols_regexp($columns->columns);
|
||||
for ($i=1;$i<count($rows);$i++) {
|
||||
@ -145,7 +153,7 @@ function scorm_parse_aicc($pkgdir,$scormid) {
|
||||
}
|
||||
}
|
||||
if (isset($id->au)) {
|
||||
$rows = file($pkgdir.'/'.$id->au);
|
||||
$rows = $id->au->get_content();
|
||||
$columns = scorm_get_aicc_columns($rows[0]);
|
||||
$regexp = scorm_forge_cols_regexp($columns->columns);
|
||||
for ($i=1;$i<count($rows);$i++) {
|
||||
@ -158,7 +166,7 @@ function scorm_parse_aicc($pkgdir,$scormid) {
|
||||
}
|
||||
}
|
||||
if (isset($id->cst)) {
|
||||
$rows = file($pkgdir.'/'.$id->cst);
|
||||
$rows = $id->cst->get_content();
|
||||
$columns = scorm_get_aicc_columns($rows[0],'block');
|
||||
$regexp = scorm_forge_cols_regexp($columns->columns,'(.+)?,');
|
||||
for ($i=1;$i<count($rows);$i++) {
|
||||
@ -172,7 +180,7 @@ function scorm_parse_aicc($pkgdir,$scormid) {
|
||||
}
|
||||
}
|
||||
if (isset($id->ort)) {
|
||||
$rows = file($pkgdir.'/'.$id->ort);
|
||||
$rows = $id->ort->get_content();
|
||||
$columns = scorm_get_aicc_columns($rows[0],'course_element');
|
||||
$regexp = scorm_forge_cols_regexp($columns->columns,'(.+)?,');
|
||||
for ($i=1;$i<count($rows);$i++) {
|
||||
@ -186,7 +194,7 @@ function scorm_parse_aicc($pkgdir,$scormid) {
|
||||
}
|
||||
}
|
||||
if (isset($id->pre)) {
|
||||
$rows = file($pkgdir.'/'.$id->pre);
|
||||
$rows = $id->pre->get_content();
|
||||
$columns = scorm_get_aicc_columns($rows[0],'structure_element');
|
||||
$regexp = scorm_forge_cols_regexp($columns->columns,'(.+),');
|
||||
for ($i=1;$i<count($rows);$i++) {
|
||||
@ -196,19 +204,19 @@ function scorm_parse_aicc($pkgdir,$scormid) {
|
||||
}
|
||||
}
|
||||
if (isset($id->cmp)) {
|
||||
$rows = file($pkgdir.'/'.$id->cmp);
|
||||
$rows = $id->cmp->get_content();
|
||||
}
|
||||
}
|
||||
//print_r($courses);
|
||||
|
||||
$oldscoes = $DB->get_records('scorm_scoes', array('scorm'=>$scormid));
|
||||
$oldscoes = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id));
|
||||
|
||||
$launch = 0;
|
||||
if (isset($courses)) {
|
||||
foreach ($courses as $course) {
|
||||
$sco = new object();
|
||||
$sco->identifier = $course->id;
|
||||
$sco->scorm = $scormid;
|
||||
$sco->scorm = $scorm->id;
|
||||
$sco->organization = '';
|
||||
$sco->title = $course->title;
|
||||
$sco->parent = '/';
|
||||
@ -216,7 +224,7 @@ function scorm_parse_aicc($pkgdir,$scormid) {
|
||||
$sco->scormtype = '';
|
||||
|
||||
//print_r($sco);
|
||||
if ($ss = $DB->get_record('scorm_scoes', array('scorm'=>$scormid,'identifier'=>$sco->identifier))) {
|
||||
if ($ss = $DB->get_record('scorm_scoes', array('scorm'=>$scorm->id,'identifier'=>$sco->identifier))) {
|
||||
$id = $ss->id;
|
||||
$DB->update_record('scorm_scoes',$sco);
|
||||
unset($oldscoes[$id]);
|
||||
@ -231,7 +239,7 @@ function scorm_parse_aicc($pkgdir,$scormid) {
|
||||
foreach($course->elements as $element) {
|
||||
unset($sco);
|
||||
$sco->identifier = $element->system_id;
|
||||
$sco->scorm = $scormid;
|
||||
$sco->scorm = $scorm->id;
|
||||
$sco->organization = $course->id;
|
||||
$sco->title = $element->title;
|
||||
|
||||
@ -302,8 +310,12 @@ function scorm_parse_aicc($pkgdir,$scormid) {
|
||||
$DB->delete_records('scorm_scoes_track', array('scoid'=>$oldsco->id));
|
||||
}
|
||||
}
|
||||
$DB->set_field('scorm','version','AICC', array('id'=>$scormid));
|
||||
return $launch;
|
||||
|
||||
$scorm->version = 'AICC';
|
||||
|
||||
$scorm->launch = $launch;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false) {
|
||||
|
@ -456,161 +456,165 @@ function scorm_get_manifest($blocks,$scoes) {
|
||||
return $scoes;
|
||||
}
|
||||
|
||||
function scorm_parse_scorm($pkgdir,$scormid) {
|
||||
function scorm_parse_scorm($scorm, $manifest) {
|
||||
global $CFG, $DB;
|
||||
|
||||
// load manifest into string
|
||||
if ($manifest instanceof stored_file) {
|
||||
$xmltext = $manifest->get_content();
|
||||
} else {
|
||||
require_once "$CFG->libdir/filelib.php";
|
||||
$xmltext = download_file_content($manifest);
|
||||
}
|
||||
|
||||
$launch = 0;
|
||||
$manifestfile = $pkgdir.'/imsmanifest.xml';
|
||||
|
||||
if (is_file($manifestfile)) {
|
||||
|
||||
$xmltext = file_get_contents($manifestfile);
|
||||
$pattern = '/&(?!\w{2,6};)/';
|
||||
$replacement = '&';
|
||||
$xmltext = preg_replace($pattern, $replacement, $xmltext);
|
||||
|
||||
$pattern = '/&(?!\w{2,6};)/';
|
||||
$replacement = '&';
|
||||
$xmltext = preg_replace($pattern, $replacement, $xmltext);
|
||||
|
||||
$objXML = new xml2Array();
|
||||
$manifests = $objXML->parse($xmltext);
|
||||
$objXML = new xml2Array();
|
||||
$manifests = $objXML->parse($xmltext);
|
||||
//print_object($manifests);
|
||||
$scoes = new stdClass();
|
||||
$scoes->version = '';
|
||||
$scoes = scorm_get_manifest($manifests,$scoes);
|
||||
$scoes = new stdClass();
|
||||
$scoes->version = '';
|
||||
$scoes = scorm_get_manifest($manifests,$scoes);
|
||||
//print_object($scoes);
|
||||
if (count($scoes->elements) > 0) {
|
||||
$olditems = $DB->get_records('scorm_scoes', array('scorm'=>$scormid));
|
||||
foreach ($scoes->elements as $manifest => $organizations) {
|
||||
foreach ($organizations as $organization => $items) {
|
||||
foreach ($items as $identifier => $item) {
|
||||
// This new db mngt will support all SCORM future extensions
|
||||
$newitem = new stdClass();
|
||||
$newitem->scorm = $scormid;
|
||||
$newitem->manifest = $manifest;
|
||||
$newitem->organization = $organization;
|
||||
$standarddatas = array('parent', 'identifier', 'launch', 'scormtype', 'title');
|
||||
foreach ($standarddatas as $standarddata) {
|
||||
if (isset($item->$standarddata)) {
|
||||
$newitem->$standarddata = $item->$standarddata;
|
||||
if (count($scoes->elements) > 0) {
|
||||
$olditems = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id));
|
||||
foreach ($scoes->elements as $manifest => $organizations) {
|
||||
foreach ($organizations as $organization => $items) {
|
||||
foreach ($items as $identifier => $item) {
|
||||
// This new db mngt will support all SCORM future extensions
|
||||
$newitem = new stdClass();
|
||||
$newitem->scorm = $scorm->id;
|
||||
$newitem->manifest = $manifest;
|
||||
$newitem->organization = $organization;
|
||||
$standarddatas = array('parent', 'identifier', 'launch', 'scormtype', 'title');
|
||||
foreach ($standarddatas as $standarddata) {
|
||||
if (isset($item->$standarddata)) {
|
||||
$newitem->$standarddata = $item->$standarddata;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the new SCO, and retain the link between the old and new for later adjustment
|
||||
$id = $DB->insert_record('scorm_scoes',$newitem);
|
||||
if (!empty($olditems) && ($olditemid = scorm_array_search('identifier',$newitem->identifier,$olditems))) {
|
||||
$olditems[$olditemid]->newid = $id;
|
||||
}
|
||||
|
||||
if ($optionaldatas = scorm_optionals_data($item,$standarddatas)) {
|
||||
$data = new stdClass();
|
||||
$data->scoid = $id;
|
||||
foreach ($optionaldatas as $optionaldata) {
|
||||
if (isset($item->$optionaldata)) {
|
||||
$data->name = $optionaldata;
|
||||
$data->value = $item->$optionaldata;
|
||||
$dataid = $DB->insert_record('scorm_scoes_data',$data);
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the new SCO, and retain the link between the old and new for later adjustment
|
||||
$id = $DB->insert_record('scorm_scoes',$newitem);
|
||||
if (!empty($olditems) && ($olditemid = scorm_array_search('identifier',$newitem->identifier,$olditems))) {
|
||||
$olditems[$olditemid]->newid = $id;
|
||||
}
|
||||
|
||||
if ($optionaldatas = scorm_optionals_data($item,$standarddatas)) {
|
||||
$data = new stdClass();
|
||||
$data->scoid = $id;
|
||||
foreach ($optionaldatas as $optionaldata) {
|
||||
if (isset($item->$optionaldata)) {
|
||||
$data->name = $optionaldata;
|
||||
$data->value = $item->$optionaldata;
|
||||
$dataid = $DB->insert_record('scorm_scoes_data',$data);
|
||||
}
|
||||
|
||||
if (isset($item->sequencingrules)) {
|
||||
foreach($item->sequencingrules as $sequencingrule) {
|
||||
$rule = new stdClass();
|
||||
$rule->scoid = $id;
|
||||
$rule->ruletype = $sequencingrule->type;
|
||||
$rule->conditioncombination = $sequencingrule->conditioncombination;
|
||||
$rule->action = $sequencingrule->action;
|
||||
$ruleid = $DB->insert_record('scorm_seq_ruleconds',$rule);
|
||||
if (isset($sequencingrule->ruleconditions)) {
|
||||
foreach($sequencingrule->ruleconditions as $rulecondition) {
|
||||
$rulecond = new stdClass();
|
||||
$rulecond->scoid = $id;
|
||||
$rulecond->ruleconditionsid = $ruleid;
|
||||
$rulecond->referencedobjective = $rulecondition->referencedobjective;
|
||||
$rulecond->measurethreshold = $rulecondition->measurethreshold;
|
||||
$rulecond->cond = $rulecondition->cond;
|
||||
$rulecondid = $DB->insert_record('scorm_seq_rulecond',$rulecond);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($item->rolluprules)) {
|
||||
foreach($item->rolluprules as $rolluprule) {
|
||||
$rollup = new stdClass();
|
||||
$rollup->scoid = $id;
|
||||
$rollup->childactivityset = $rolluprule->childactivityset;
|
||||
$rollup->minimumcount = $rolluprule->minimumcount;
|
||||
$rollup->minimumpercent = $rolluprule->minimumpercent;
|
||||
$rollup->rollupruleaction = $rolluprule->rollupruleaction;
|
||||
$rollup->conditioncombination = $rolluprule->conditioncombination;
|
||||
|
||||
if (isset($item->sequencingrules)) {
|
||||
foreach($item->sequencingrules as $sequencingrule) {
|
||||
$rule = new stdClass();
|
||||
$rule->scoid = $id;
|
||||
$rule->ruletype = $sequencingrule->type;
|
||||
$rule->conditioncombination = $sequencingrule->conditioncombination;
|
||||
$rule->action = $sequencingrule->action;
|
||||
$ruleid = $DB->insert_record('scorm_seq_ruleconds',$rule);
|
||||
if (isset($sequencingrule->ruleconditions)) {
|
||||
foreach($sequencingrule->ruleconditions as $rulecondition) {
|
||||
$rulecond = new stdClass();
|
||||
$rulecond->scoid = $id;
|
||||
$rulecond->ruleconditionsid = $ruleid;
|
||||
$rulecond->referencedobjective = $rulecondition->referencedobjective;
|
||||
$rulecond->measurethreshold = $rulecondition->measurethreshold;
|
||||
$rulecond->cond = $rulecondition->cond;
|
||||
$rulecondid = $DB->insert_record('scorm_seq_rulecond',$rulecond);
|
||||
}
|
||||
$rollupruleid = $DB->insert_record('scorm_seq_rolluprule',$rollup);
|
||||
if (isset($rollup->conditions)) {
|
||||
foreach($rollup->conditions as $condition){
|
||||
$cond = new stdClass();
|
||||
$cond->scoid = $rollup->scoid;
|
||||
$cond->rollupruleid = $rollupruleid;
|
||||
$cond->operator = $condition->operator;
|
||||
$cond->cond = $condition->cond;
|
||||
$conditionid = $DB->insert_record('scorm_seq_rolluprulecond',$cond);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($item->rolluprules)) {
|
||||
foreach($item->rolluprules as $rolluprule) {
|
||||
$rollup = new stdClass();
|
||||
$rollup->scoid = $id;
|
||||
$rollup->childactivityset = $rolluprule->childactivityset;
|
||||
$rollup->minimumcount = $rolluprule->minimumcount;
|
||||
$rollup->minimumpercent = $rolluprule->minimumpercent;
|
||||
$rollup->rollupruleaction = $rolluprule->rollupruleaction;
|
||||
$rollup->conditioncombination = $rolluprule->conditioncombination;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rollupruleid = $DB->insert_record('scorm_seq_rolluprule',$rollup);
|
||||
if (isset($rollup->conditions)) {
|
||||
foreach($rollup->conditions as $condition){
|
||||
$cond = new stdClass();
|
||||
$cond->scoid = $rollup->scoid;
|
||||
$cond->rollupruleid = $rollupruleid;
|
||||
$cond->operator = $condition->operator;
|
||||
$cond->cond = $condition->cond;
|
||||
$conditionid = $DB->insert_record('scorm_seq_rolluprulecond',$cond);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($item->objectives)) {
|
||||
foreach($item->objectives as $objective) {
|
||||
$obj = new stdClass();
|
||||
$obj->scoid = $id;
|
||||
$obj->primaryobj = $objective->primaryobj;
|
||||
$obj->satisfiedbumeasure = $objective->satisfiedbymeasure;
|
||||
$obj->objectiveid = $objective->objectiveid;
|
||||
$obj->minnormalizedmeasure = $objective->minnormalizedmeasure;
|
||||
$objectiveid = $DB->insert_record('scorm_seq_objective',$obj);
|
||||
if (isset($objective->mapinfos)) {
|
||||
if (isset($item->objectives)) {
|
||||
foreach($item->objectives as $objective) {
|
||||
$obj = new stdClass();
|
||||
$obj->scoid = $id;
|
||||
$obj->primaryobj = $objective->primaryobj;
|
||||
$obj->satisfiedbumeasure = $objective->satisfiedbymeasure;
|
||||
$obj->objectiveid = $objective->objectiveid;
|
||||
$obj->minnormalizedmeasure = $objective->minnormalizedmeasure;
|
||||
$objectiveid = $DB->insert_record('scorm_seq_objective',$obj);
|
||||
if (isset($objective->mapinfos)) {
|
||||
//print_object($objective->mapinfos);
|
||||
foreach($objective->mapinfos as $objmapinfo) {
|
||||
$mapinfo = new stdClass();
|
||||
$mapinfo->scoid = $id;
|
||||
$mapinfo->objectiveid = $objectiveid;
|
||||
$mapinfo->targetobjectiveid = $objmapinfo->targetobjectiveid;
|
||||
$mapinfo->readsatisfiedstatus = $objmapinfo->readsatisfiedstatus;
|
||||
$mapinfo->writesatisfiedstatus = $objmapinfo->writesatisfiedstatus;
|
||||
$mapinfo->readnormalizedmeasure = $objmapinfo->readnormalizedmeasure;
|
||||
$mapinfo->writenormalizedmeasure = $objmapinfo->writenormalizedmeasure;
|
||||
$mapinfoid = $DB->insert_record('scorm_seq_mapinfo',$mapinfo);
|
||||
}
|
||||
foreach($objective->mapinfos as $objmapinfo) {
|
||||
$mapinfo = new stdClass();
|
||||
$mapinfo->scoid = $id;
|
||||
$mapinfo->objectiveid = $objectiveid;
|
||||
$mapinfo->targetobjectiveid = $objmapinfo->targetobjectiveid;
|
||||
$mapinfo->readsatisfiedstatus = $objmapinfo->readsatisfiedstatus;
|
||||
$mapinfo->writesatisfiedstatus = $objmapinfo->writesatisfiedstatus;
|
||||
$mapinfo->readnormalizedmeasure = $objmapinfo->readnormalizedmeasure;
|
||||
$mapinfo->writenormalizedmeasure = $objmapinfo->writenormalizedmeasure;
|
||||
$mapinfoid = $DB->insert_record('scorm_seq_mapinfo',$mapinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//print_object($item);
|
||||
if (($launch == 0) && ((empty($scoes->defaultorg)) || ($scoes->defaultorg == $identifier))) {
|
||||
$launch = $id;
|
||||
}
|
||||
if (($launch == 0) && ((empty($scoes->defaultorg)) || ($scoes->defaultorg == $identifier))) {
|
||||
$launch = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($olditems)) {
|
||||
foreach($olditems as $olditem) {
|
||||
$DB->delete_records('scorm_scoes', array('id'=>$olditem->id));
|
||||
$DB->delete_records('scorm_scoes_data',array('scoid'=>$olditem->id));
|
||||
if (isset($olditem->newid)) {
|
||||
$DB->set_field('scorm_scoes_track', 'scoid', $olditem->newid, array('scoid' => $olditem->id));
|
||||
}
|
||||
$DB->delete_records('scorm_scoes_track',array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_objective', array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_mapinfo', array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_ruleconds', array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_rulecond', array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_rolluprule', array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_rolluprulecond', array('scoid'=>$olditem->id));
|
||||
}
|
||||
}
|
||||
$DB->set_field('scorm','version',$scoes->version, array('id'=>$scormid));
|
||||
}
|
||||
}
|
||||
if (!empty($olditems)) {
|
||||
foreach($olditems as $olditem) {
|
||||
$DB->delete_records('scorm_scoes', array('id'=>$olditem->id));
|
||||
$DB->delete_records('scorm_scoes_data',array('scoid'=>$olditem->id));
|
||||
if (isset($olditem->newid)) {
|
||||
$DB->set_field('scorm_scoes_track', 'scoid', $olditem->newid, array('scoid' => $olditem->id));
|
||||
}
|
||||
$DB->delete_records('scorm_scoes_track',array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_objective', array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_mapinfo', array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_ruleconds', array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_rulecond', array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_rolluprule', array('scoid'=>$olditem->id));
|
||||
$DB->delete_records('scorm_seq_rolluprulecond', array('scoid'=>$olditem->id));
|
||||
}
|
||||
}
|
||||
$scorm->version = $scoes->version;
|
||||
}
|
||||
|
||||
return $launch;
|
||||
$scorm->launch = $launch;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function scorm_optionals_data($item, $standarddata) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="mod/scorm/db" VERSION="20070124" COMMENT="XMLDB file for Moodle mod/scorm"
|
||||
<XMLDB PATH="mod/scorm/db" VERSION="20080903" COMMENT="XMLDB file for Moodle mod/scorm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
@ -8,17 +8,20 @@
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="course"/>
|
||||
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="name"/>
|
||||
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="course" NEXT="reference"/>
|
||||
<FIELD NAME="reference" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="summary"/>
|
||||
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="course" NEXT="scormtype"/>
|
||||
<FIELD NAME="scormtype" TYPE="char" LENGTH="50" NOTNULL="true" DEFAULT="local" SEQUENCE="false" ENUM="false" COMMENT="local, external or repository" PREVIOUS="name" NEXT="reference"/>
|
||||
<FIELD NAME="reference" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="scormtype" NEXT="summary"/>
|
||||
<FIELD NAME="summary" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="reference" NEXT="version"/>
|
||||
<FIELD NAME="version" TYPE="char" LENGTH="9" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="summary" NEXT="maxgrade"/>
|
||||
<FIELD NAME="maxgrade" TYPE="float" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="version" NEXT="grademethod"/>
|
||||
<FIELD NAME="grademethod" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="maxgrade" NEXT="whatgrade"/>
|
||||
<FIELD NAME="whatgrade" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="grademethod" NEXT="maxattempt"/>
|
||||
<FIELD NAME="maxattempt" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="whatgrade" NEXT="updatefreq"/>
|
||||
<FIELD NAME="updatefreq" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="Define when the package must be automatically update" PREVIOUS="maxattempt" NEXT="md5hash"/>
|
||||
<FIELD NAME="md5hash" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="MD5 Hash of package file" PREVIOUS="updatefreq" NEXT="launch"/>
|
||||
<FIELD NAME="launch" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="md5hash" NEXT="skipview"/>
|
||||
<FIELD NAME="updatefreq" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="Define when the package must be automatically update" PREVIOUS="maxattempt" NEXT="sha1hash"/>
|
||||
<FIELD NAME="sha1hash" TYPE="char" LENGTH="40" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="pacakge content or ext path hash" PREVIOUS="updatefreq" NEXT="md5hash"/>
|
||||
<FIELD NAME="md5hash" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="MD5 Hash of package file" PREVIOUS="sha1hash" NEXT="revision"/>
|
||||
<FIELD NAME="revision" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="revison number" PREVIOUS="md5hash" NEXT="launch"/>
|
||||
<FIELD NAME="launch" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="revision" NEXT="skipview"/>
|
||||
<FIELD NAME="skipview" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="launch" NEXT="hidebrowse"/>
|
||||
<FIELD NAME="hidebrowse" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="skipview" NEXT="hidetoc"/>
|
||||
<FIELD NAME="hidetoc" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="hidebrowse" NEXT="hidenav"/>
|
||||
@ -31,7 +34,7 @@
|
||||
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="height"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
</KEYS>
|
||||
<INDEXES>
|
||||
<INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
|
||||
@ -194,4 +197,4 @@
|
||||
</SENTENCES>
|
||||
</STATEMENT>
|
||||
</STATEMENTS>
|
||||
</XMLDB>
|
||||
</XMLDB>
|
@ -1,6 +1,6 @@
|
||||
<?php //$Id$
|
||||
|
||||
// This file keeps track of upgrades to
|
||||
// This file keeps track of upgrades to
|
||||
// the scorm module
|
||||
//
|
||||
// Sometimes, changes between versions involve
|
||||
@ -33,15 +33,207 @@ function xmldb_scorm_upgrade($oldversion) {
|
||||
$table = new xmldb_table('scorm');
|
||||
$field = new xmldb_field('whatgrade');
|
||||
$field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'grademethod');
|
||||
|
||||
|
||||
/// Launch add field whatgrade
|
||||
if (!$dbman->field_exists($table,$field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
|
||||
upgrade_mod_savepoint($result, 2008073000, 'scorm');
|
||||
}
|
||||
|
||||
|
||||
if ($result && $oldversion < 2008082500) {
|
||||
|
||||
/// Define field scormtype to be added to scorm
|
||||
$table = new xmldb_table('scorm');
|
||||
$field = new xmldb_field('scormtype', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null, null, 'local', 'name');
|
||||
|
||||
/// Launch add field scormtype
|
||||
$dbman->add_field($table, $field);
|
||||
|
||||
/// scorm savepoint reached
|
||||
upgrade_mod_savepoint($result, 2008082500, 'scorm');
|
||||
}
|
||||
|
||||
if ($result && $oldversion < 2008090300) {
|
||||
|
||||
/// Define field sha1hash to be added to scorm
|
||||
$table = new xmldb_table('scorm');
|
||||
$field = new xmldb_field('sha1hash', XMLDB_TYPE_CHAR, '40', null, null, null, null, null, null, 'updatefreq');
|
||||
|
||||
/// Launch add field sha1hash
|
||||
$dbman->add_field($table, $field);
|
||||
|
||||
/// scorm savepoint reached
|
||||
upgrade_mod_savepoint($result, 2008090300, 'scorm');
|
||||
}
|
||||
|
||||
if ($result && $oldversion < 2008090301) {
|
||||
|
||||
/// Define field revision to be added to scorm
|
||||
$table = new xmldb_table('scorm');
|
||||
$field = new xmldb_field('revision', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'md5hash');
|
||||
|
||||
/// Launch add field revision
|
||||
$dbman->add_field($table, $field);
|
||||
|
||||
/// scorm savepoint reached
|
||||
upgrade_mod_savepoint($result, 2008090301, 'scorm');
|
||||
}
|
||||
|
||||
if ($result && $oldversion < 2008090302) {
|
||||
$sql = "UPDATE {scorm}
|
||||
SET scormtype = 'external'
|
||||
WHERE reference LIKE ? OR reference LIKE ? OR reference LIKE ?";
|
||||
$DB->execute($sql, array('http://%imsmanifest.xml', 'https://%imsmanifest.xml', 'www.%imsmanifest.xml'));
|
||||
|
||||
$sql = "UPDATE {scorm}
|
||||
SET scormtype = 'localsync'
|
||||
WHERE reference LIKE ? OR reference LIKE ? OR reference LIKE ?
|
||||
OR reference LIKE ? OR reference LIKE ? OR reference LIKE ?";
|
||||
$DB->execute($sql, array('http://%.zip', 'https://%.zip', 'www.%.zip', 'http://%.pif', 'https://%.pif', 'www.%.pif'));
|
||||
|
||||
$sql = "UPDATE {scorm} SET scormtype = 'imsrepository' WHERE reference LIKE ?";
|
||||
$DB->execute($sql, array('#%'));
|
||||
|
||||
/// scorm savepoint reached
|
||||
upgrade_mod_savepoint($result, 2008090302, 'scorm');
|
||||
}
|
||||
|
||||
if ($result && $oldversion < 2008090303) {
|
||||
//remove obsoleted config settings
|
||||
unset_config('scorm_advancedsettings');
|
||||
unset_config('scorm_windowsettings');
|
||||
|
||||
/// scorm savepoint reached
|
||||
upgrade_mod_savepoint($result, 2008090303, 'scorm');
|
||||
}
|
||||
|
||||
if ($result && $oldversion < 2008090304) {
|
||||
|
||||
/////////////////////////////////////
|
||||
/// new file storage upgrade code ///
|
||||
/////////////////////////////////////
|
||||
|
||||
function scorm_migrate_content_files($context, $base, $path) {
|
||||
global $CFG;
|
||||
|
||||
$fullpathname = $base.$path;
|
||||
$fs = get_file_storage();
|
||||
$filearea = 'scorm_content';
|
||||
$items = new DirectoryIterator($fullpathname);
|
||||
|
||||
foreach ($items as $item) {
|
||||
if ($item->isDot()) {
|
||||
unset($item); // release file handle
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($item->isLink()) {
|
||||
// do not follow symlinks - they were never supported in moddata, sorry
|
||||
unset($item); // release file handle
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($item->isFile()) {
|
||||
if (!$item->isReadable()) {
|
||||
notify(" File not readable, skipping: ".$fullpathname.$item->getFilename());
|
||||
unset($item); // release file handle
|
||||
continue;
|
||||
}
|
||||
|
||||
$filepath = clean_param($path, PARAM_PATH);
|
||||
$filename = clean_param($item->getFilename(), PARAM_FILE);
|
||||
$oldpathname = $fullpathname.$item->getFilename();
|
||||
|
||||
if ($filename === '') {
|
||||
continue;
|
||||
unset($item); // release file handle
|
||||
}
|
||||
|
||||
if (!$fs->file_exists($context->id, $filearea, '0', $filepath, $filename)) {
|
||||
$file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>0, 'filepath'=>$filepath, 'filename'=>$filename,
|
||||
'timecreated'=>$item->getCTime(), 'timemodified'=>$item->getMTime());
|
||||
unset($item); // release file handle
|
||||
if ($fs->create_file_from_pathname($file_record, $oldpathname)) {
|
||||
@unlink($oldpathname);
|
||||
}
|
||||
} else {
|
||||
unset($item); // release file handle
|
||||
}
|
||||
|
||||
} else {
|
||||
//migrate recursively all subdirectories
|
||||
$oldpathname = $fullpathname.$item->getFilename().'/';
|
||||
$subpath = $path.$item->getFilename().'/';
|
||||
unset($item); // release file handle
|
||||
scorm_migrate_content_files($context, $base, $subpath);
|
||||
@rmdir($oldpathname); // deletes dir if empty
|
||||
}
|
||||
}
|
||||
unset($items); //release file handles
|
||||
}
|
||||
|
||||
$fs = get_file_storage();
|
||||
|
||||
$sqlfrom = "FROM {scorm} s
|
||||
JOIN {modules} m ON m.name = 'scorm'
|
||||
JOIN {course_modules} cm ON (cm.module = m.id AND cm.instance = s.id)";
|
||||
|
||||
$count = $DB->count_records_sql("SELECT COUNT('x') $sqlfrom");
|
||||
|
||||
if ($rs = $DB->get_recordset_sql("SELECT s.id, s.scormtype, s.reference, s.course, cm.id AS cmid $sqlfrom ORDER BY s.course, s.id")) {
|
||||
|
||||
$pbar = new progress_bar('migratescormfiles', 500, true);
|
||||
|
||||
$olddebug = $DB->get_debug();
|
||||
$DB->set_debug(false); // lower debug level, there might be many files
|
||||
$i = 0;
|
||||
foreach ($rs as $scorm) {
|
||||
$i++;
|
||||
upgrade_set_timeout(180); // set up timeout, may also abort execution
|
||||
$pbar->update($i, $count, "Migrating scorm files - $i/$count.");
|
||||
|
||||
$context = get_context_instance(CONTEXT_MODULE, $scorm->cmid);
|
||||
$coursecontext = get_context_instance(CONTEXT_COURSE, $scorm->course);
|
||||
|
||||
// first copy local packages if found - do not delete in case they are shared ;-)
|
||||
if ($scorm->scormtype === 'local' and preg_match('/.*(\.zip|\.pif)$/i', $scorm->reference)) {
|
||||
$packagefile = '/'.clean_param($scorm->reference, PARAM_PATH);
|
||||
$pathnamehash = sha1($coursecontext->id.'course_content0'.$packagefile);
|
||||
if ($file = $fs->get_file_by_hash($pathnamehash)) {
|
||||
$file_record = array('scontextid'=>$context->id, 'filearea'=>'scorm_pacakge',
|
||||
'itemid'=>0, 'filepath'=>'/');
|
||||
$packagefile = $fs->create_file_from_storedfile($file_record, $file);
|
||||
$scorm->reference = $packagefile->get_filename();
|
||||
} else {
|
||||
$scorm->reference = '';
|
||||
}
|
||||
$DB->update_record('scorm', $scorm);
|
||||
}
|
||||
|
||||
// now migrate the extracted package
|
||||
$basepath = "$CFG->dataroot/$scorm->course/$CFG->moddata/scorm/$scorm->id";
|
||||
if (!is_dir($basepath)) {
|
||||
//no files?
|
||||
continue;
|
||||
}
|
||||
|
||||
scorm_migrate_content_files($context, $basepath, '/');
|
||||
|
||||
// remove dirs if empty
|
||||
@rmdir("$CFG->dataroot/$scorm->course/$CFG->moddata/scorm/$scorm->id/");
|
||||
@rmdir("$CFG->dataroot/$scorm->course/$CFG->moddata/scorm/");
|
||||
@rmdir("$CFG->dataroot/$scorm->course/$CFG->moddata/");
|
||||
}
|
||||
$DB->set_debug($olddebug); // reset debug level
|
||||
$rs->close();
|
||||
}
|
||||
|
||||
/// scorm savepoint reached
|
||||
upgrade_mod_savepoint($result, 2008090304, 'scorm');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@ -1,72 +1,93 @@
|
||||
<?php // $Id$
|
||||
|
||||
define('SCORM_TYPE_LOCAL', 'local');
|
||||
define('SCORM_TYPE_LOCALSYNC', 'localsync');
|
||||
define('SCORM_TYPE_EXTERNAL', 'external');
|
||||
define('SCORM_TYPE_IMSREPOSITORY', 'imsrepository');
|
||||
|
||||
|
||||
/**
|
||||
* Given an object containing all the necessary data,
|
||||
* (defined by the form in mod_form.php) this function
|
||||
* will create a new instance and return the id number
|
||||
* of the new instance.
|
||||
*
|
||||
* @param mixed $scorm Form data
|
||||
* @return int
|
||||
* @param object $scorm Form data
|
||||
* @param object $mform
|
||||
* @return int new instance id
|
||||
*/
|
||||
//require_once('locallib.php');
|
||||
function scorm_add_instance($scorm) {
|
||||
|
||||
function scorm_add_instance($scorm, $mform=null) {
|
||||
global $CFG, $DB;
|
||||
|
||||
require_once('locallib.php');
|
||||
|
||||
if (($packagedata = scorm_check_package($scorm)) != null) {
|
||||
$scorm->pkgtype = $packagedata->pkgtype;
|
||||
$scorm->datadir = $packagedata->datadir;
|
||||
$scorm->launch = $packagedata->launch;
|
||||
$scorm->parse = 1;
|
||||
$cmid = $scorm->coursemodule;
|
||||
$cmidnumber = $scorm->cmidnumber;
|
||||
$courseid = $scorm->course;
|
||||
|
||||
$scorm->timemodified = time();
|
||||
if (!scorm_external_link($scorm->reference)) {
|
||||
$scorm->md5hash = md5_file($CFG->dataroot.'/'.$scorm->course.'/'.$scorm->reference);
|
||||
} else {
|
||||
$scorm->dir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm';
|
||||
$scorm->md5hash = md5_file($scorm->dir.$scorm->datadir.'/'.basename($scorm->reference));
|
||||
}
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cmid);
|
||||
|
||||
$scorm = scorm_option2text($scorm);
|
||||
$scorm->width = str_replace('%','',$scorm->width);
|
||||
$scorm->height = str_replace('%','',$scorm->height);
|
||||
$scorm = scorm_option2text($scorm);
|
||||
$scorm->width = (int)str_replace('%', '', $scorm->width);
|
||||
$scorm->height = (int)str_replace('%', '', $scorm->height);
|
||||
|
||||
//sanitize submitted values a bit
|
||||
$scorm->width = clean_param($scorm->width, PARAM_INT);
|
||||
$scorm->height = clean_param($scorm->height, PARAM_INT);
|
||||
|
||||
if (!isset($scorm->whatgrade)) {
|
||||
$scorm->whatgrade = 0;
|
||||
}
|
||||
$scorm->grademethod = ($scorm->whatgrade * 10) + $scorm->grademethod;
|
||||
|
||||
$id = $DB->insert_record('scorm', $scorm);
|
||||
|
||||
if (scorm_external_link($scorm->reference) || ((basename($scorm->reference) != 'imsmanifest.xml') && ($scorm->reference[0] != '#'))) {
|
||||
// Rename temp scorm dir to scorm id
|
||||
$scorm->dir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm';
|
||||
if (file_exists($scorm->dir.'/'.$id)) {
|
||||
//delete directory as it shouldn't exist! - most likely there from an old moodle install with old files in dataroot
|
||||
scorm_delete_files($scorm->dir.'/'.$id);
|
||||
}
|
||||
rename($scorm->dir.$scorm->datadir,$scorm->dir.'/'.$id);
|
||||
}
|
||||
|
||||
// Parse scorm manifest
|
||||
if ($scorm->parse == 1) {
|
||||
$scorm->id = $id;
|
||||
$scorm->launch = scorm_parse($scorm);
|
||||
$DB->set_field('scorm', 'launch', $scorm->launch, array('id'=>$scorm->id));
|
||||
}
|
||||
|
||||
scorm_grade_item_update($scorm);
|
||||
|
||||
return $id;
|
||||
} else {
|
||||
print_error('badpackage','scorm');
|
||||
if (!isset($scorm->whatgrade)) {
|
||||
$scorm->whatgrade = 0;
|
||||
}
|
||||
$scorm->grademethod = ($scorm->whatgrade * 10) + $scorm->grademethod;
|
||||
|
||||
if (!$id = $DB->insert_record('scorm', $scorm)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// update course module record - from now on this instance properly exists and all function may be used
|
||||
if (!$DB->set_field('course_modules', 'instance', $id, array('id'=>$cmid))) {
|
||||
print_error('cannotaddcoursemodule');
|
||||
}
|
||||
|
||||
/// reload scorm instance
|
||||
$scorm = $DB->get_record('scorm', array('id'=>$id));
|
||||
|
||||
/// store the package and verify
|
||||
if ($scorm->scormtype === SCORM_TYPE_LOCAL) {
|
||||
if ($mform) {
|
||||
$filename = $mform->get_new_filename('packagefile');
|
||||
if ($filename !== false) {
|
||||
$fs = get_file_storage();
|
||||
$fs->delete_area_files($context->id, 'scorm_package');
|
||||
$mform->save_stored_file('packagefile', $context->id, 'scorm_package', 0, '/', $filename);
|
||||
$scorm->reference = $filename;
|
||||
}
|
||||
}
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_LOCALSYNC) {
|
||||
$scorm->reference = $scorm->packageurl;
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_EXTERNAL) {
|
||||
$scorm->reference = $scorm->packageurl;
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_IMSREPOSITORY) {
|
||||
$scorm->reference = $scorm->packageurl;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// save reference
|
||||
$DB->update_record('scorm', $scorm);
|
||||
|
||||
|
||||
/// extra fields required in grade related functions
|
||||
$scorm->course = $courseid;
|
||||
$scorm->cmidnumber = $cmidnumber;
|
||||
$scorm->cmid = $cmid;
|
||||
|
||||
scorm_parse($scorm, true);
|
||||
|
||||
scorm_grade_item_update($scorm);
|
||||
|
||||
return $scorm->id;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,65 +95,73 @@ function scorm_add_instance($scorm) {
|
||||
* (defined by the form in mod_form.php) this function
|
||||
* will update an existing instance with new data.
|
||||
*
|
||||
* @param mixed $scorm Form data
|
||||
* @return int
|
||||
* @param object $scorm Form data
|
||||
* @param object $mform
|
||||
* @return bool success
|
||||
*/
|
||||
function scorm_update_instance($scorm) {
|
||||
function scorm_update_instance($scorm, $mform=null) {
|
||||
global $CFG, $DB;
|
||||
|
||||
require_once('locallib.php');
|
||||
|
||||
$scorm->parse = 0;
|
||||
if (($packagedata = scorm_check_package($scorm)) != null) {
|
||||
$scorm->pkgtype = $packagedata->pkgtype;
|
||||
if ($packagedata->launch == 0) {
|
||||
$scorm->launch = $packagedata->launch;
|
||||
$scorm->datadir = $packagedata->datadir;
|
||||
$scorm->parse = 1;
|
||||
if (!scorm_external_link($scorm->reference) && $scorm->reference[0] != '#') { //dont set md5hash if this is from a repo.
|
||||
$scorm->md5hash = md5_file($CFG->dataroot.'/'.$scorm->course.'/'.$scorm->reference);
|
||||
} elseif($scorm->reference[0] != '#') { //dont set md5hash if this is from a repo.
|
||||
$scorm->dir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm';
|
||||
$scorm->md5hash = md5_file($scorm->dir.$scorm->datadir.'/'.basename($scorm->reference));
|
||||
}
|
||||
}
|
||||
}
|
||||
$cmid = $scorm->coursemodule;
|
||||
$cmidnumber = $scorm->cmidnumber;
|
||||
$courseid = $scorm->course;
|
||||
|
||||
$scorm->timemodified = time();
|
||||
$scorm->id = $scorm->instance;
|
||||
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cmid);
|
||||
|
||||
if ($scorm->scormtype === SCORM_TYPE_LOCAL) {
|
||||
if ($mform) {
|
||||
$filename = $mform->get_new_filename('packagefile');
|
||||
if ($filename !== false) {
|
||||
$scorm->reference = $filename;
|
||||
$fs = get_file_storage();
|
||||
$fs->delete_area_files($context->id, 'scorm_package');
|
||||
$mform->save_stored_file('packagefile', $context->id, 'scorm_package', 0, '/', $filename);
|
||||
}
|
||||
}
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_LOCALSYNC) {
|
||||
$scorm->reference = $scorm->packageurl;
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_EXTERNAL) {
|
||||
$scorm->reference = $scorm->packageurl;
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_IMSREPOSITORY) {
|
||||
$scorm->reference = $scorm->packageurl;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
$scorm = scorm_option2text($scorm);
|
||||
$scorm->width = str_replace('%','',$scorm->width);
|
||||
$scorm->height = str_replace('%','',$scorm->height);
|
||||
$scorm->width = (int)str_replace('%','',$scorm->width);
|
||||
$scorm->height = (int)str_replace('%','',$scorm->height);
|
||||
$scorm->timemodified = time();
|
||||
|
||||
if (!isset($scorm->whatgrade)) {
|
||||
$scorm->whatgrade = 0;
|
||||
}
|
||||
$scorm->grademethod = ($scorm->whatgrade * 10) + $scorm->grademethod;
|
||||
$scorm->grademethod = ($scorm->whatgrade * 10) + $scorm->grademethod;
|
||||
|
||||
// Check if scorm manifest needs to be reparsed
|
||||
if ($scorm->parse == 1) {
|
||||
$scorm->dir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm';
|
||||
if (is_dir($scorm->dir.'/'.$scorm->id)) {
|
||||
scorm_delete_files($scorm->dir.'/'.$scorm->id);
|
||||
}
|
||||
if (isset($scorm->datadir) && ($scorm->datadir != $scorm->id) &&
|
||||
(scorm_external_link($scorm->reference) || ((basename($scorm->reference) != 'imsmanifest.xml') && ($scorm->reference[0] != '#')))) {
|
||||
rename($scorm->dir.$scorm->datadir,$scorm->dir.'/'.$scorm->id);
|
||||
}
|
||||
|
||||
$scorm->launch = scorm_parse($scorm);
|
||||
} else {
|
||||
$oldscorm = $DB->get_record('scorm', array('id'=>$scorm->id));
|
||||
$scorm->reference = $oldscorm->reference; // This fix a problem with Firefox when the teacher choose Cancel on overwrite question
|
||||
}
|
||||
|
||||
if ($result = $DB->update_record('scorm', $scorm)) {
|
||||
scorm_grade_item_update(stripslashes_recursive($scorm));
|
||||
//scorm_grade_item_update($scorm); // John Macklins fix - dont think this is needed
|
||||
if (!$DB->update_record('scorm', $scorm)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
$scorm = $DB->get_record('scorm', array('id'=>$scorm->id));
|
||||
|
||||
/// extra fields required in grade related functions
|
||||
$scorm->course = $courseid;
|
||||
$scorm->idnumber = $cmidnumber;
|
||||
$scorm->cmid = $cmid;
|
||||
|
||||
scorm_parse($scorm, (bool)$scorm->updatefreq);
|
||||
|
||||
scorm_grade_item_update($scorm);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,13 +181,6 @@ function scorm_delete_instance($id) {
|
||||
|
||||
$result = true;
|
||||
|
||||
$scorm->dir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm';
|
||||
if (is_dir($scorm->dir.'/'.$scorm->id)) {
|
||||
// Delete any dependent files
|
||||
require_once('locallib.php');
|
||||
scorm_delete_files($scorm->dir.'/'.$scorm->id);
|
||||
}
|
||||
|
||||
// Delete any dependent records
|
||||
if (! $DB->delete_records('scorm_scoes_track', array('scormid'=>$scorm->id))) {
|
||||
$result = false;
|
||||
@ -168,7 +190,7 @@ function scorm_delete_instance($id) {
|
||||
if (! $DB->delete_records('scorm_scoes_data', array('scoid'=>$sco->id))) {
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
$DB->delete_records('scorm_scoes', array('scorm'=>$scorm->id));
|
||||
} else {
|
||||
$result = false;
|
||||
@ -197,10 +219,10 @@ function scorm_delete_instance($id) {
|
||||
}
|
||||
if (! $DB->delete_records('scorm_sequencing_ruleconditions', array('scormid'=>$scorm->id))) {
|
||||
$result = false;
|
||||
}*/
|
||||
}*/
|
||||
|
||||
scorm_grade_item_delete($scorm);
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -211,11 +233,11 @@ function scorm_delete_instance($id) {
|
||||
*
|
||||
* @param int $course Course id
|
||||
* @param int $user User id
|
||||
* @param int $mod
|
||||
* @param int $mod
|
||||
* @param int $scorm The scorm id
|
||||
* @return mixed
|
||||
*/
|
||||
function scorm_user_outline($course, $user, $mod, $scorm) {
|
||||
function scorm_user_outline($course, $user, $mod, $scorm) {
|
||||
global $CFG;
|
||||
require_once('locallib.php');
|
||||
|
||||
@ -230,7 +252,7 @@ function scorm_user_outline($course, $user, $mod, $scorm) {
|
||||
*
|
||||
* @param int $course Course id
|
||||
* @param int $user User id
|
||||
* @param int $mod
|
||||
* @param int $mod
|
||||
* @param int $scorm The scorm id
|
||||
* @return boolean
|
||||
*/
|
||||
@ -244,7 +266,7 @@ function scorm_user_complete($course, $user, $mod, $scorm) {
|
||||
$lastmodify = 0;
|
||||
$sometoreport = false;
|
||||
$report = '';
|
||||
|
||||
|
||||
if ($orgs = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id, 'organization'=>'', 'launch'=>''),'id','id,identifier,title')) {
|
||||
if (count($orgs) <= 1) {
|
||||
unset($orgs);
|
||||
@ -263,7 +285,7 @@ function scorm_user_complete($course, $user, $mod, $scorm) {
|
||||
$conditions['scorm'] = $scorm->id;
|
||||
if ($scoes = $DB->get_records('scorm_scoes', $conditions, "id ASC")){
|
||||
// drop keys so that we can access array sequentially
|
||||
$scoes = array_values($scoes);
|
||||
$scoes = array_values($scoes);
|
||||
$level=0;
|
||||
$sublist=1;
|
||||
$parents[$level]='/';
|
||||
@ -336,7 +358,7 @@ function scorm_user_complete($course, $user, $mod, $scorm) {
|
||||
}
|
||||
}
|
||||
$report .= "\t\t\t</ul></li>\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$report .= " $sco->title</li>\n";
|
||||
}
|
||||
@ -380,7 +402,8 @@ function scorm_cron () {
|
||||
require_once('locallib.php');
|
||||
|
||||
$sitetimezone = $CFG->timezone;
|
||||
/// Now see if there are any digest mails waiting to be sent, and if we should send them
|
||||
/// Now see if there are any scorm updates to be done
|
||||
|
||||
if (!isset($CFG->scorm_updatetimelast)) { // To catch the first time
|
||||
set_config('scorm_updatetimelast', 0);
|
||||
}
|
||||
@ -395,11 +418,8 @@ function scorm_cron () {
|
||||
mtrace('Updating scorm packages which require daily update');//We are updating
|
||||
|
||||
$scormsupdate = $DB->get_records('scorm', array('updatefreq'=>UPDATE_EVERYDAY));
|
||||
if (!empty($scormsupdate)) {
|
||||
foreach($scormsupdate as $scormupdate) {
|
||||
$scormupdate->instance = $scormupdate->id;
|
||||
$id = scorm_update_instance($scormupdate);
|
||||
}
|
||||
foreach($scormsupdate as $scormupdate) {
|
||||
scorm_parse($scormupdate, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -514,7 +534,7 @@ function scorm_grade_item_update($scorm, $grades=NULL) {
|
||||
if (isset($scorm->cmidnumber)) {
|
||||
$params['idnumber'] = $scorm->cmidnumber;
|
||||
}
|
||||
|
||||
|
||||
if (($scorm->grademethod % 10) == 0) { // GRADESCOES
|
||||
if ($maxgrade = $DB->count_records_select('scorm_scoes', 'scorm = ? AND launch <> ?', array($scorm->id, $DB->sql_empty()))) {
|
||||
$params['gradetype'] = GRADE_TYPE_VALUE;
|
||||
@ -559,7 +579,14 @@ function scorm_get_post_actions() {
|
||||
}
|
||||
|
||||
function scorm_option2text($scorm) {
|
||||
global $SCORM_POPUP_OPTIONS;
|
||||
$SCORM_POPUP_OPTIONS = array('resizable'=>1,
|
||||
'scrollbars'=>1,
|
||||
'directories'=>0,
|
||||
'location'=>0,
|
||||
'menubar'=>0,
|
||||
'toolbar'=>0,
|
||||
'status'=>0);
|
||||
|
||||
if (isset($scorm->popup)) {
|
||||
if ($scorm->popup == 1) {
|
||||
$optionlist = array();
|
||||
@ -569,11 +596,11 @@ function scorm_option2text($scorm) {
|
||||
} else {
|
||||
$optionlist[] = $name.'=0';
|
||||
}
|
||||
}
|
||||
}
|
||||
$scorm->options = implode(',', $optionlist);
|
||||
} else {
|
||||
$scorm->options = '';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$scorm->popup = 0;
|
||||
$scorm->options = '';
|
||||
@ -656,4 +683,131 @@ function scorm_get_extra_capabilities() {
|
||||
return array('moodle/site:accessallgroups');
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all file areas current user may browse
|
||||
*/
|
||||
function scorm_get_file_areas($course, $cm, $context) {
|
||||
$areas = array();
|
||||
if (has_capability('moodle/course:managefiles', $context)) {
|
||||
$areas['scorm_intro'] = get_string('areaintro', 'scorm');
|
||||
$areas['scorm_content'] = get_string('areacontent', 'scorm');
|
||||
$areas['scorm_package'] = get_string('areapackage', 'scorm');
|
||||
}
|
||||
return $areas;
|
||||
}
|
||||
|
||||
/**
|
||||
* File browsing support
|
||||
*/
|
||||
function scorm_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
|
||||
global $CFG;
|
||||
|
||||
if (!has_capability('moodle/course:managefiles', $context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// no writing for now!
|
||||
|
||||
$fs = get_file_storage();
|
||||
|
||||
if ($filearea === 'scorm_content') {
|
||||
|
||||
$filepath = is_null($filepath) ? '/' : $filepath;
|
||||
$filename = is_null($filename) ? '.' : $filename;
|
||||
|
||||
$urlbase = $CFG->wwwroot.'/pluginfile.php';
|
||||
if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
|
||||
if ($filepath === '/' and $filename === '.') {
|
||||
$storedfile = new virtual_root_file($context->id, $filearea, 0);
|
||||
} else {
|
||||
// not found
|
||||
return null;
|
||||
}
|
||||
}
|
||||
class scorm_package_file_info extends file_info_stored {
|
||||
public function get_parent() {
|
||||
if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') {
|
||||
return $this->browser->get_file_info($this->context);
|
||||
}
|
||||
return parent::get_parent();
|
||||
}
|
||||
public function get_visible_name() {
|
||||
if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') {
|
||||
return $this->areavisiblename;
|
||||
}
|
||||
return parent::get_visible_name();
|
||||
}
|
||||
}
|
||||
return new scorm_package_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, false);
|
||||
|
||||
} else if ($filearea === 'scorm_package') {
|
||||
$filepath = is_null($filepath) ? '/' : $filepath;
|
||||
$filename = is_null($filename) ? '.' : $filename;
|
||||
|
||||
$urlbase = $CFG->wwwroot.'/pluginfile.php';
|
||||
if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
|
||||
if ($filepath === '/' and $filename === '.') {
|
||||
$storedfile = new virtual_root_file($context->id, $filearea, 0);
|
||||
} else {
|
||||
// not found
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return new file_info_stored($browser, $context, $storedfile, $urlbase, $areas[$filearea], false, true, false);
|
||||
}
|
||||
|
||||
// scorm_intro handled in file_browser
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves scorm content, introduction images and packages. Implements needed access control ;-)
|
||||
*/
|
||||
function scorm_pluginfile($course, $cminfo, $context, $filearea, $args) {
|
||||
global $CFG;
|
||||
|
||||
if (!$cminfo->uservisible) {
|
||||
return false; // probably hidden
|
||||
}
|
||||
|
||||
$lifetime = isset($CFG->filelifetime) ? $CFG->filelifetime : 86400;
|
||||
|
||||
if ($filearea === 'scorm_intro') {
|
||||
// all users may access it
|
||||
$relativepath = '/'.implode('/', $args);
|
||||
$fullpath = $context->id.'scorm_intro0'.$relativepath;
|
||||
|
||||
$fs = get_file_storage();
|
||||
if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if ($filearea === 'scorm_content') {
|
||||
$revision = (int)array_shift($args); // prevents caching problems - ignored here
|
||||
$relativepath = '/'.implode('/', $args);
|
||||
$fullpath = $context->id.'scorm_content0'.$relativepath;
|
||||
// TODO: add any other access restrictions here if needed!
|
||||
|
||||
} else if ($filearea === 'scorm_package') {
|
||||
if (!has_capability('moodle/course:manageactivities', $context)) {
|
||||
return false;
|
||||
}
|
||||
$relativepath = '/'.implode('/', $args);
|
||||
$fullpath = $context->id.'scorm_package0'.$relativepath;
|
||||
$lifetime = 0; // no caching here
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fs = get_file_storage();
|
||||
if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// finally send the file
|
||||
send_stored_file($file, $lifetime, 0, false);
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -2,8 +2,8 @@
|
||||
require_once('../../config.php');
|
||||
require_once('locallib.php');
|
||||
|
||||
$id = optional_param('id', '', PARAM_INT); // Course Module ID, or
|
||||
$a = optional_param('a', '', PARAM_INT); // scorm ID
|
||||
$id = optional_param('id', '', PARAM_INT); // Course Module ID, or
|
||||
$a = optional_param('a', '', PARAM_INT); // scorm ID
|
||||
$scoid = required_param('scoid', PARAM_INT); // sco ID
|
||||
|
||||
$delayseconds = 2; // Delay time before sco launch, used to give time to browser to define API
|
||||
@ -33,6 +33,9 @@
|
||||
}
|
||||
|
||||
require_login($course->id, false, $cm);
|
||||
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
|
||||
if (!empty($scoid)) {
|
||||
//
|
||||
// Direct SCO request
|
||||
@ -60,7 +63,7 @@
|
||||
$value = 'completed';
|
||||
$result = scorm_insert_track($USER->id, $scorm->id, $sco->id, $attempt, $element, $value);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Forge SCO URL
|
||||
//
|
||||
@ -76,7 +79,7 @@
|
||||
$sco->parameters = substr($sco->parameters,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($version == 'AICC') {
|
||||
if (isset($sco->parameters) && (!empty($sco->parameters))) {
|
||||
$sco->parameters = '&'. $sco->parameters;
|
||||
@ -89,31 +92,26 @@
|
||||
$launcher = $sco->launch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (scorm_external_link($sco->launch)) {
|
||||
// Remote learning activity
|
||||
//TODO: does this happen?
|
||||
$result = $launcher;
|
||||
} else if ($scorm->reference[0] == '#') {
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_EXTERNAL) {
|
||||
// Remote learning activity
|
||||
$result = dirname($scorm->reference).'/'.$launcher;
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_IMSREPOSITORY) {
|
||||
// Repository
|
||||
$result = $CFG->repositorywebroot.substr($scorm->reference,1).'/'.$sco->launch;
|
||||
} else {
|
||||
if ((basename($scorm->reference) == 'imsmanifest.xml') && scorm_external_link($scorm->reference)) {
|
||||
// Remote manifest
|
||||
$result = dirname($scorm->reference).'/'.$launcher;
|
||||
} else {
|
||||
// Moodle internal package/manifest or remote (auto-imported) package
|
||||
if (basename($scorm->reference) == 'imsmanifest.xml') {
|
||||
$basedir = dirname($scorm->reference);
|
||||
} else {
|
||||
$basedir = $CFG->moddata.'/scorm/'.$scorm->id;
|
||||
}
|
||||
//note: do not convert this to use get_file_url()!
|
||||
// SCORM does not work without slasharguments anyway and there might be some extra ?xx=yy params
|
||||
// see MDL-16060
|
||||
$result = $CFG->wwwroot.'/file.php/'.$scorm->course.'/'.$basedir.'/'.$launcher;
|
||||
}
|
||||
$result = $CFG->repositorywebroot.substr($scorm->reference, 1).'/'.$sco->launch;
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_LOCAL or $scorm->scormtype === SCORM_TYPE_LOCALSYNC) {
|
||||
//note: do not convert this to use get_file_url()!
|
||||
// SCORM does not work without slasharguments anyway and there might be some extra ?xx=yy params
|
||||
// see MDL-16060
|
||||
$result = "$CFG->wwwroot/pluginfile.php/$context->id/scorm_content/$scorm->revision/$launcher";
|
||||
}
|
||||
|
||||
|
||||
$scormpixdir = $CFG->modpixpath.'/scorm/pix';
|
||||
?>
|
||||
<html>
|
||||
@ -134,11 +132,11 @@
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
//]]>
|
||||
//]]>
|
||||
</script>
|
||||
<noscript>
|
||||
<meta http-equiv="refresh" content="<?php echo $delayseconds ?>;url=<?php echo $result ?>" />
|
||||
</noscript>
|
||||
</noscript>
|
||||
</head>
|
||||
<body onload="doredirect();">
|
||||
<p><?php echo get_string('activityloading', 'scorm');?> <span id="countdown"><?php echo $delayseconds ?></span> <?php echo get_string('numseconds');?>. <img src='<?php echo $scormpixdir;?>/wait.gif'><p>
|
||||
@ -146,5 +144,5 @@
|
||||
add_to_log($course->id, 'scorm', 'launch', 'view.php?id='.$cm->id, $result, $cm->id);
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php // $Id$
|
||||
|
||||
require_once("$CFG->dirroot/mod/scorm/lib.php");
|
||||
|
||||
/// Constants and settings for module scorm
|
||||
define('UPDATE_NEVER', '0');
|
||||
define('UPDATE_ONCHANGE', '1');
|
||||
@ -14,122 +16,129 @@ define('GRADESCOES', '0');
|
||||
define('GRADEHIGHEST', '1');
|
||||
define('GRADEAVERAGE', '2');
|
||||
define('GRADESUM', '3');
|
||||
$SCORM_GRADE_METHOD = array (GRADESCOES => get_string('gradescoes', 'scorm'),
|
||||
GRADEHIGHEST => get_string('gradehighest', 'scorm'),
|
||||
GRADEAVERAGE => get_string('gradeaverage', 'scorm'),
|
||||
GRADESUM => get_string('gradesum', 'scorm'));
|
||||
|
||||
define('HIGHESTATTEMPT', '0');
|
||||
define('AVERAGEATTEMPT', '1');
|
||||
define('FIRSTATTEMPT', '2');
|
||||
define('LASTATTEMPT', '3');
|
||||
$SCORM_WHAT_GRADE = array (HIGHESTATTEMPT => get_string('highestattempt', 'scorm'),
|
||||
AVERAGEATTEMPT => get_string('averageattempt', 'scorm'),
|
||||
FIRSTATTEMPT => get_string('firstattempt', 'scorm'),
|
||||
LASTATTEMPT => get_string('lastattempt', 'scorm'));
|
||||
|
||||
$SCORM_POPUP_OPTIONS = array('resizable'=>1,
|
||||
'scrollbars'=>1,
|
||||
'directories'=>0,
|
||||
'location'=>0,
|
||||
'menubar'=>0,
|
||||
'toolbar'=>0,
|
||||
'status'=>0);
|
||||
$stdoptions = '';
|
||||
foreach ($SCORM_POPUP_OPTIONS as $popupopt => $value) {
|
||||
$stdoptions .= $popupopt.'='.$value;
|
||||
if ($popupopt != 'status') {
|
||||
$stdoptions .= ',';
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($CFG->scorm_maxattempts)) {
|
||||
set_config('scorm_maxattempts','6');
|
||||
}
|
||||
|
||||
if (!isset($CFG->scorm_frameheight)) {
|
||||
set_config('scorm_frameheight','500');
|
||||
}
|
||||
|
||||
if (!isset($CFG->scorm_framewidth)) {
|
||||
set_config('scorm_framewidth','100%');
|
||||
}
|
||||
|
||||
if (!isset($CFG->scorm_updatetime)) {
|
||||
set_config('scorm_updatetime','2');
|
||||
}
|
||||
|
||||
if (!isset($CFG->scorm_advancedsettings)) {
|
||||
set_config('scorm_advancedsettings','0');
|
||||
}
|
||||
|
||||
if (!isset($CFG->scorm_windowsettings)) {
|
||||
set_config('scorm_windowsettings','0');
|
||||
}
|
||||
|
||||
/// Local Library of functions for module scorm
|
||||
|
||||
/**
|
||||
* This function will permanently delete the given
|
||||
* directory and all files and subdirectories.
|
||||
*
|
||||
* @param string $directory The directory to remove
|
||||
* @return boolean
|
||||
*/
|
||||
function scorm_delete_files($directory) {
|
||||
if (is_dir($directory)) {
|
||||
$files=scandir($directory);
|
||||
set_time_limit(0);
|
||||
foreach($files as $file) {
|
||||
if (($file != '.') && ($file != '..')) {
|
||||
if (!is_dir($directory.'/'.$file)) {
|
||||
unlink($directory.'/'.$file);
|
||||
* Extracts scrom package, sets up all variables.
|
||||
* Called whenever scorm changes
|
||||
* @param object $scorm instance - fields are updated and changes saved into database
|
||||
* @param bool $full force full update if true
|
||||
* @return void
|
||||
*/
|
||||
function scorm_parse($scorm, $full) {
|
||||
global $CFG, $DB;
|
||||
|
||||
if (!isset($scorm->cmid)) {
|
||||
$cm = get_coursemodule_from_instance('scorm', $scorm->id);
|
||||
$scorm->cmid = $cm->id;
|
||||
}
|
||||
$context = get_context_instance(CONTEXT_MODULE, $scorm->cmid);
|
||||
$newhash = $scorm->sha1hash;
|
||||
|
||||
if ($scorm->scormtype === SCORM_TYPE_LOCAL or $scorm->scormtype === SCORM_TYPE_LOCALSYNC) {
|
||||
|
||||
$fs = get_file_storage();
|
||||
$packagefile = false;
|
||||
|
||||
if ($scorm->scormtype === SCORM_TYPE_LOCAL) {
|
||||
if ($packagefile = $fs->get_file($context->id, 'scorm_package', 0, '/', $scorm->reference)) {
|
||||
$newhash = $packagefile->get_contenthash();
|
||||
} else {
|
||||
$newhash = null;
|
||||
}
|
||||
} else {
|
||||
if (!$CFG->scorm_allowtypelocalsync) {
|
||||
// sorry - localsync disabled
|
||||
return;
|
||||
}
|
||||
if ($scorm->reference !== '' and (!$full or $scorm->sha1hash !== sha1($scorm->reference))) {
|
||||
$fs->delete_area_files($context->id, 'scorm_package');
|
||||
$file_record = array('contextid'=>$context->id, 'filearea'=>'scorm_package', 'itemid'=>0, 'filepath'=>'/');
|
||||
if ($packagefile = $fs->create_file_from_url($file_record, $scorm->reference)) {
|
||||
$newhash = sha1($scorm->reference);
|
||||
} else {
|
||||
scorm_delete_files($directory.'/'.$file);
|
||||
$newhash = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
rmdir($directory);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new temporary subdirectory with a random name in the given path
|
||||
*
|
||||
* @param string $strpath The scorm data directory
|
||||
* @return string/boolean
|
||||
*/
|
||||
function scorm_tempdir($strPath)
|
||||
{
|
||||
global $CFG;
|
||||
|
||||
if (is_dir($strPath)) {
|
||||
do {
|
||||
// Create a random string of 8 chars
|
||||
$randstring = NULL;
|
||||
$lchar = '';
|
||||
$len = 8;
|
||||
for ($i=0; $i<$len; $i++) {
|
||||
$char = chr(rand(48,122));
|
||||
while (!ereg('[a-zA-Z0-9]', $char)){
|
||||
if ($char == $lchar) continue;
|
||||
$char = chr(rand(48,90));
|
||||
if ($packagefile) {
|
||||
if (!$full and $packagefile and $scorm->sha1hash === $newhash) {
|
||||
if (strpos($scorm->version, 'SCORM') !== false) {
|
||||
if ($fs->get_file($context->id, 'scorm_content', 0, '/', 'imsmanifest.xml')) {
|
||||
// no need to update
|
||||
return;
|
||||
}
|
||||
$randstring .= $char;
|
||||
$lchar = $char;
|
||||
}
|
||||
$datadir='/'.$randstring;
|
||||
} while (file_exists($strPath.$datadir));
|
||||
mkdir($strPath.$datadir, $CFG->directorypermissions);
|
||||
@chmod($strPath.$datadir, $CFG->directorypermissions); // Just in case mkdir didn't do it
|
||||
return $strPath.$datadir;
|
||||
} else if (strpos($scorm->version, 'AICC') !== false) {
|
||||
// TODO: add more sanity checks - something really exists in scorm_content area
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// now extract files
|
||||
$fs->delete_area_files($context->id, 'scorm_content');
|
||||
|
||||
$packer = get_file_packer('application/zip');
|
||||
$packagefile->extract_to_storage($packer, $context->id, 'scorm_content', 0, '/');
|
||||
|
||||
} else if (!$full) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ($manifest = $fs->get_file($context->id, 'scorm_content', 0, '/', 'imsmanifest.xml')) {
|
||||
require_once("$CFG->dirroot/mod/scorm/datamodels/scormlib.php");
|
||||
// SCORM
|
||||
if (!scorm_parse_scorm($scorm, $manifest)) {
|
||||
$scorm->version = 'ERROR';
|
||||
}
|
||||
} else {
|
||||
require_once("$CFG->dirroot/mod/scorm/datamodels/aicclib.php");
|
||||
// AICC
|
||||
if (!scorm_parse_aicc($scorm)) {
|
||||
$scorm->version = 'ERROR';
|
||||
}
|
||||
}
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_EXTERNAL and $CFG->scorm_allowtypeexternal) {
|
||||
if (!$full and $scorm->sha1hash === sha1($scorm->reference)) {
|
||||
return;
|
||||
}
|
||||
require_once("$CFG->dirroot/mod/scorm/datamodels/scormlib.php");
|
||||
// SCORM only, AICC can not be external
|
||||
if (!scorm_parse_scorm($scorm, $scorm->reference)) {
|
||||
$scorm->version = 'ERROR';
|
||||
}
|
||||
$newhash = sha1($scorm->reference);
|
||||
|
||||
} else if ($scorm->scormtype === SCORM_TYPE_IMSREPOSITORY and !empty($CFG->repositoryactivate) and $CFG->scorm_allowtypeimsrepository) {
|
||||
if (!$full and $scorm->sha1hash === sha1($scorm->reference)) {
|
||||
return;
|
||||
}
|
||||
require_once("$CFG->dirroot/mod/scorm/datamodels/scormlib.php");
|
||||
if (!scorm_parse_scorm($scorm, $CFG->repository.substr($scorm->reference,1).'/imsmanifest.xml')) {
|
||||
$scorm->version = 'ERROR';
|
||||
}
|
||||
$newhash = sha1($scorm->reference);
|
||||
|
||||
} else {
|
||||
return false;
|
||||
// sorry, disabled type
|
||||
return;
|
||||
}
|
||||
|
||||
$scorm->revision++;
|
||||
$scorm->sha1hash = $newhash;
|
||||
$DB->update_record('scorm', $scorm);
|
||||
}
|
||||
|
||||
|
||||
function scorm_array_search($item, $needle, $haystacks, $strict=false) {
|
||||
if (!empty($haystacks)) {
|
||||
foreach ($haystacks as $key => $element) {
|
||||
@ -189,7 +198,7 @@ function scorm_get_sco($id,$what=SCO_ALL) {
|
||||
$sco->{$scodata->name} = $scodata->value;
|
||||
}
|
||||
} else if (($what != SCO_ONLY) && (!($scodatas = $DB->get_records('scorm_scoes_data', array('scoid'=>$id))))) {
|
||||
$sco->parameters = '';
|
||||
$sco->parameters = '';
|
||||
}
|
||||
return $sco;
|
||||
} else {
|
||||
@ -247,10 +256,10 @@ function scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value) {
|
||||
$track->timemodified = time();
|
||||
$id = $DB->insert_record('scorm_scoes_track',$track);
|
||||
}
|
||||
|
||||
|
||||
// MDL-9552, update the gradebook everything raw score is sent
|
||||
// Scoring by learning objects also needs to be included in the gradebook update
|
||||
if (strstr($element, '.score.raw') ||
|
||||
if (strstr($element, '.score.raw') ||
|
||||
(($element == 'cmi.core.lesson_status' || $element == 'cmi.completion_status') && ($track->value == 'completed' || $track->value == 'passed'))) {
|
||||
$scorm = $DB->get_record('scorm', array('id' => $scormid));
|
||||
$grademethod = $scorm->grademethod % 10;
|
||||
@ -259,7 +268,7 @@ function scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value) {
|
||||
scorm_update_grades($scorm, $userid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
@ -276,7 +285,7 @@ function scorm_get_tracks($scoid,$userid,$attempt='') {
|
||||
}
|
||||
if ($tracks = $DB->get_records('scorm_scoes_track', array('userid'=>$userid, 'scoid'=>$scoid, 'attempt'=>$attempt),'element ASC')) {
|
||||
$usertrack->userid = $userid;
|
||||
$usertrack->scoid = $scoid;
|
||||
$usertrack->scoid = $scoid;
|
||||
// Defined in order to unify scorm1.2 and scorm2004
|
||||
$usertrack->score_raw = '';
|
||||
$usertrack->status = '';
|
||||
@ -291,27 +300,27 @@ function scorm_get_tracks($scoid,$userid,$attempt='') {
|
||||
case 'cmi.completion_status':
|
||||
if ($track->value == 'not attempted') {
|
||||
$track->value = 'notattempted';
|
||||
}
|
||||
}
|
||||
$usertrack->status = $track->value;
|
||||
break;
|
||||
break;
|
||||
case 'cmi.core.score.raw':
|
||||
case 'cmi.score.raw':
|
||||
$usertrack->score_raw = $track->value;
|
||||
break;
|
||||
break;
|
||||
case 'cmi.core.session_time':
|
||||
case 'cmi.session_time':
|
||||
$usertrack->session_time = $track->value;
|
||||
break;
|
||||
break;
|
||||
case 'cmi.core.total_time':
|
||||
case 'cmi.total_time':
|
||||
$usertrack->total_time = $track->value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (isset($track->timemodified) && ($track->timemodified > $usertrack->timemodified)) {
|
||||
$usertrack->timemodified = $track->timemodified;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_array($usertrack)) {
|
||||
if (is_array($usertrack)) {
|
||||
ksort($usertrack);
|
||||
}
|
||||
return $usertrack;
|
||||
@ -330,13 +339,13 @@ function scorm_get_user_data($userid) {
|
||||
|
||||
function scorm_grade_user_attempt($scorm, $userid, $attempt=1, $time=false) {
|
||||
global $DB;
|
||||
$attemptscore = NULL;
|
||||
$attemptscore = NULL;
|
||||
$attemptscore->scoes = 0;
|
||||
$attemptscore->values = 0;
|
||||
$attemptscore->max = 0;
|
||||
$attemptscore->sum = 0;
|
||||
$attemptscore->lastmodify = 0;
|
||||
|
||||
|
||||
if (!$scoes = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id))) {
|
||||
return NULL;
|
||||
}
|
||||
@ -346,11 +355,11 @@ function scorm_grade_user_attempt($scorm, $userid, $attempt=1, $time=false) {
|
||||
// and 1s are grademethod
|
||||
$grademethod = $scorm->grademethod % 10;
|
||||
|
||||
foreach ($scoes as $sco) {
|
||||
foreach ($scoes as $sco) {
|
||||
if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {
|
||||
if (($userdata->status == 'completed') || ($userdata->status == 'passed')) {
|
||||
$attemptscore->scoes++;
|
||||
}
|
||||
}
|
||||
if (!empty($userdata->score_raw)) {
|
||||
$attemptscore->values++;
|
||||
$attemptscore->sum += $userdata->score_raw;
|
||||
@ -360,23 +369,23 @@ function scorm_grade_user_attempt($scorm, $userid, $attempt=1, $time=false) {
|
||||
} else {
|
||||
$attemptscore->lastmodify = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch ($grademethod) {
|
||||
case GRADEHIGHEST:
|
||||
$score = $attemptscore->max;
|
||||
break;
|
||||
break;
|
||||
case GRADEAVERAGE:
|
||||
if ($attemptscore->values > 0) {
|
||||
$score = $attemptscore->sum/$attemptscore->values;
|
||||
} else {
|
||||
$score = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GRADESUM:
|
||||
$score = $attemptscore->sum;
|
||||
break;
|
||||
break;
|
||||
case GRADESCOES:
|
||||
$score = $attemptscore->scoes;
|
||||
break;
|
||||
@ -410,7 +419,7 @@ function scorm_grade_user($scorm, $userid, $time=false) {
|
||||
switch ($whatgrade) {
|
||||
case FIRSTATTEMPT:
|
||||
return scorm_grade_user_attempt($scorm, $userid, 1, $time);
|
||||
break;
|
||||
break;
|
||||
case LASTATTEMPT:
|
||||
return scorm_grade_user_attempt($scorm, $userid, scorm_get_last_attempt($scorm->id, $userid), $time);
|
||||
break;
|
||||
@ -502,7 +511,7 @@ function scorm_course_format_display($user,$course) {
|
||||
|
||||
echo '<div class="mod-scorm">';
|
||||
if ($scorms = get_all_instances_in_course('scorm', $course)) {
|
||||
// The module SCORM activity with the least id is the course
|
||||
// The module SCORM activity with the least id is the course
|
||||
$scorm = current($scorms);
|
||||
if (! $cm = get_coursemodule_from_instance('scorm', $scorm->id, $course->id)) {
|
||||
print_error('invalidcoursemodule');
|
||||
@ -528,7 +537,7 @@ function scorm_course_format_display($user,$course) {
|
||||
$headertext .= '<td class="reportlink">'.get_string('noreports','scorm');
|
||||
}
|
||||
$colspan = ' colspan="2"';
|
||||
}
|
||||
}
|
||||
$headertext .= '</td></tr><tr><td'.$colspan.'>'.format_text(get_string('summary').':<br />'.$scorm->summary).'</td></tr></table>';
|
||||
print_simple_box($headertext,'','100%');
|
||||
scorm_view_display($user, $scorm, 'view.php?id='.$course->id, $cm, '100%');
|
||||
@ -546,11 +555,8 @@ function scorm_course_format_display($user,$course) {
|
||||
function scorm_view_display ($user, $scorm, $action, $cm, $boxwidth='') {
|
||||
global $CFG, $DB;
|
||||
|
||||
if ($scorm->updatefreq == UPDATE_EVERYTIME){
|
||||
require_once($CFG->dirroot.'/mod/scorm/lib.php');
|
||||
|
||||
$scorm->instance = $scorm->id;
|
||||
scorm_update_instance($scorm);
|
||||
if ($scorm->updatefreq == UPDATE_EVERYTIME) {
|
||||
scorm_parse($scorm, false);
|
||||
}
|
||||
|
||||
$organization = optional_param('organization', '', PARAM_INT);
|
||||
@ -637,9 +643,9 @@ function scorm_simple_play($scorm,$user) {
|
||||
global $DB;
|
||||
|
||||
$result = false;
|
||||
|
||||
|
||||
$scoes = $DB->get_records_select('scorm_scoes', 'scorm = ? AND launch <> ?', array($scorm->id, $DB->sql_empty()));
|
||||
|
||||
|
||||
if ($scoes && (count($scoes) == 1)) {
|
||||
if ($scorm->skipview >= 1) {
|
||||
$sco = current($scoes);
|
||||
@ -675,356 +681,26 @@ function scorm_simple_play($scorm,$user) {
|
||||
return $result;
|
||||
}
|
||||
*/
|
||||
function scorm_parse($scorm) {
|
||||
global $CFG;
|
||||
|
||||
if ($scorm->reference[0] == '#') {
|
||||
if (isset($CFG->repositoryactivate) && $CFG->repositoryactivate) {
|
||||
$referencedir = $CFG->repository.substr($scorm->reference,1);
|
||||
}
|
||||
} else {
|
||||
if ((!scorm_external_link($scorm->reference)) && (basename($scorm->reference) == 'imsmanifest.xml')) {
|
||||
$referencedir = $CFG->dataroot.'/'.$scorm->course.'/'.$scorm->datadir;
|
||||
} else {
|
||||
$referencedir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm/'.$scorm->id;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse scorm manifest
|
||||
if ($scorm->pkgtype == 'AICC') {
|
||||
require_once('datamodels/aicclib.php');
|
||||
$scorm->launch = scorm_parse_aicc($referencedir, $scorm->id);
|
||||
} else {
|
||||
require_once('datamodels/scormlib.php');
|
||||
$scorm->launch = scorm_parse_scorm($referencedir,$scorm->id);
|
||||
}
|
||||
return $scorm->launch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a manifest path, this function will check if the manifest is valid
|
||||
*
|
||||
* @param string $manifest The manifest file
|
||||
* @return object
|
||||
*/
|
||||
function scorm_validate_manifest($manifest) {
|
||||
$validation = new stdClass();
|
||||
if (is_file($manifest)) {
|
||||
$validation->result = true;
|
||||
} else {
|
||||
$validation->result = false;
|
||||
$validation->errors['reference'] = get_string('nomanifest','scorm');
|
||||
}
|
||||
return $validation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a aicc package directory, this function will check if the course structure is valid
|
||||
*
|
||||
* @param string $packagedir The aicc package directory path
|
||||
* @return object
|
||||
*/
|
||||
function scorm_validate_aicc($packagedir) {
|
||||
$validation = new stdClass();
|
||||
$validation->result = false;
|
||||
if (is_dir($packagedir)) {
|
||||
if ($handle = opendir($packagedir)) {
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
$ext = substr($file,strrpos($file,'.'));
|
||||
if (strtolower($ext) == '.cst') {
|
||||
$validation->result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
}
|
||||
if ($validation->result == false) {
|
||||
$validation->errors['reference'] = get_string('nomanifest','scorm');
|
||||
}
|
||||
return $validation;
|
||||
}
|
||||
|
||||
|
||||
function scorm_validate($data) {
|
||||
global $CFG, $DB;
|
||||
|
||||
$validation = new stdClass();
|
||||
$validation->errors = array();
|
||||
|
||||
if (!isset($data['course']) || empty($data['course'])) {
|
||||
$validation->errors['reference'] = get_string('missingparam','scorm');
|
||||
$validation->result = false;
|
||||
return $validation;
|
||||
}
|
||||
$courseid = $data['course']; // Course Module ID
|
||||
|
||||
if (!isset($data['reference']) || empty($data['reference'])) {
|
||||
$validation->errors['reference'] = get_string('packagefile','scorm');
|
||||
$validation->result = false;
|
||||
return $validation;
|
||||
}
|
||||
$reference = $data['reference']; // Package/manifest path/location
|
||||
|
||||
$scormid = $data['instance']; // scorm ID
|
||||
$scorm = new stdClass();
|
||||
if (!empty($scormid)) {
|
||||
if (!$scorm = $DB->get_record('scorm', array('id'=>$scormid))) {
|
||||
$validation->errors['reference'] = get_string('missingparam','scorm');
|
||||
$validation->result = false;
|
||||
return $validation;
|
||||
}
|
||||
}
|
||||
|
||||
if ($reference[0] == '#') {
|
||||
if (isset($CFG->repositoryactivate) && $CFG->repositoryactivate) {
|
||||
$reference = $CFG->repository.substr($reference,1).'/imsmanifest.xml';
|
||||
} else {
|
||||
$validation->errors['reference'] = get_string('badpackage','scorm');
|
||||
$validation->result = false;
|
||||
return $validation;
|
||||
}
|
||||
} else if (!scorm_external_link($reference)) {
|
||||
$reference = $CFG->dataroot.'/'.$courseid.'/'.$reference;
|
||||
}
|
||||
|
||||
// Create a temporary directory to unzip package or copy manifest and validate package
|
||||
$tempdir = '';
|
||||
$scormdir = '';
|
||||
if ($scormdir = make_upload_directory("$courseid/$CFG->moddata/scorm")) {
|
||||
if ($tempdir = scorm_tempdir($scormdir)) {
|
||||
$localreference = $tempdir.'/'.basename($reference);
|
||||
copy ("$reference", $localreference);
|
||||
if (!is_file($localreference)) {
|
||||
$validation->errors['reference'] = get_string('badpackage','scorm');
|
||||
$validation->result = false;
|
||||
} else {
|
||||
$ext = strtolower(substr(basename($localreference),strrpos(basename($localreference),'.')));
|
||||
switch ($ext) {
|
||||
case '.pif':
|
||||
case '.zip':
|
||||
if (!unzip_file($localreference, $tempdir, false)) {
|
||||
$validation->errors['reference'] = get_string('unziperror','scorm');
|
||||
$validation->result = false;
|
||||
} else {
|
||||
unlink ($localreference);
|
||||
if (is_file($tempdir.'/imsmanifest.xml')) {
|
||||
$validation = scorm_validate_manifest($tempdir.'/imsmanifest.xml');
|
||||
$validation->pkgtype = 'SCORM';
|
||||
} else {
|
||||
$validation = scorm_validate_aicc($tempdir);
|
||||
if (($validation->result == 'regular') || ($validation->result == 'found')) {
|
||||
$validation->pkgtype = 'AICC';
|
||||
} else {
|
||||
$validation->errors['reference'] = get_string('nomanifest','scorm');
|
||||
$validation->result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '.xml':
|
||||
if (basename($localreference) == 'imsmanifest.xml') {
|
||||
$validation = scorm_validate_manifest($localreference);
|
||||
} else {
|
||||
$validation->errors['reference'] = get_string('nomanifest','scorm');
|
||||
$validation->result = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$validation->errors['reference'] = get_string('badpackage','scorm');
|
||||
$validation->result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_dir($tempdir)) {
|
||||
// Delete files and temporary directory
|
||||
scorm_delete_files($tempdir);
|
||||
}
|
||||
} else {
|
||||
$validation->errors['reference'] = get_string('packagedir','scorm');
|
||||
$validation->result = false;
|
||||
}
|
||||
} else {
|
||||
$validation->errors['reference'] = get_string('datadir','scorm');
|
||||
$validation->result = false;
|
||||
}
|
||||
return $validation;
|
||||
}
|
||||
|
||||
function scorm_check_package($data) {
|
||||
global $CFG, $COURSE, $DB;
|
||||
|
||||
$courseid = $data->course; // Course Module ID
|
||||
$reference = $data->reference; // Package path
|
||||
$scormid = $data->instance; // scorm ID
|
||||
|
||||
$validation = new stdClass();
|
||||
|
||||
if (!empty($courseid) && !empty($reference)) {
|
||||
$externalpackage = scorm_external_link($reference);
|
||||
|
||||
$validation->launch = 0;
|
||||
$referencefield = $reference;
|
||||
if (empty($reference)) {
|
||||
$validation = null;
|
||||
} else if ($reference[0] == '#') {
|
||||
if (isset($CFG->repositoryactivate) && $CFG->repositoryactivate) {
|
||||
$referencefield = $reference.'/imsmanifest.xml';
|
||||
$reference = $CFG->repository.substr($reference,1).'/imsmanifest.xml';
|
||||
} else {
|
||||
$validation = null;
|
||||
}
|
||||
} else if (!$externalpackage) {
|
||||
$reference = $CFG->dataroot.'/'.$courseid.'/'.$reference;
|
||||
}
|
||||
|
||||
if (!empty($scormid)) {
|
||||
//
|
||||
// SCORM Update
|
||||
//
|
||||
if ((!empty($validation)) && (is_file($reference) || $externalpackage)){
|
||||
|
||||
if (!$externalpackage) {
|
||||
$mdcheck = md5_file($reference);
|
||||
} else if ($externalpackage){
|
||||
if ($scormdir = make_upload_directory("$courseid/$CFG->moddata/scorm")) {
|
||||
if ($tempdir = scorm_tempdir($scormdir)) {
|
||||
copy ("$reference", $tempdir.'/'.basename($reference));
|
||||
$mdcheck = md5_file($tempdir.'/'.basename($reference));
|
||||
scorm_delete_files($tempdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($scorm = $DB->get_record('scorm', array('id'=>$scormid))) {
|
||||
if ($scorm->reference[0] == '#') {
|
||||
if (isset($CFG->repositoryactivate) && $CFG->repositoryactivate) {
|
||||
$oldreference = $CFG->repository.substr($scorm->reference,1).'/imsmanifest.xml';
|
||||
} else {
|
||||
$oldreference = $scorm->reference;
|
||||
}
|
||||
} else if (!scorm_external_link($scorm->reference)) {
|
||||
$oldreference = $CFG->dataroot.'/'.$courseid.'/'.$scorm->reference;
|
||||
} else {
|
||||
$oldreference = $scorm->reference;
|
||||
}
|
||||
$validation->launch = $scorm->launch;
|
||||
if ((($oldreference == $reference) && ($mdcheck != $scorm->md5hash)) || ($oldreference != $reference)) {
|
||||
// This is a new or a modified package
|
||||
$validation->launch = 0;
|
||||
} else {
|
||||
// Old package already validated
|
||||
if (strpos($scorm->version,'AICC') !== false) {
|
||||
$validation->pkgtype = 'AICC';
|
||||
} else {
|
||||
$validation->pkgtype = 'SCORM';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$validation = null;
|
||||
}
|
||||
} else {
|
||||
$validation = null;
|
||||
}
|
||||
}
|
||||
//$validation->launch = 0;
|
||||
if (($validation != null) && ($validation->launch == 0)) {
|
||||
//
|
||||
// Package must be validated
|
||||
//
|
||||
$ext = strtolower(substr(basename($reference),strrpos(basename($reference),'.')));
|
||||
$tempdir = '';
|
||||
switch ($ext) {
|
||||
case '.pif':
|
||||
case '.zip':
|
||||
// Create a temporary directory to unzip package and validate package
|
||||
$scormdir = '';
|
||||
if ($scormdir = make_upload_directory("$courseid/$CFG->moddata/scorm")) {
|
||||
if ($tempdir = scorm_tempdir($scormdir)) {
|
||||
copy ("$reference", $tempdir.'/'.basename($reference));
|
||||
unzip_file($tempdir.'/'.basename($reference), $tempdir, false);
|
||||
if (!$externalpackage) {
|
||||
unlink ($tempdir.'/'.basename($reference));
|
||||
}
|
||||
if (is_file($tempdir.'/imsmanifest.xml')) {
|
||||
$validation = scorm_validate_manifest($tempdir.'/imsmanifest.xml');
|
||||
$validation->pkgtype = 'SCORM';
|
||||
} else {
|
||||
$validation = scorm_validate_aicc($tempdir);
|
||||
$validation->pkgtype = 'AICC';
|
||||
}
|
||||
} else {
|
||||
$validation = null;
|
||||
}
|
||||
} else {
|
||||
$validation = null;
|
||||
}
|
||||
break;
|
||||
case '.xml':
|
||||
if (basename($reference) == 'imsmanifest.xml') {
|
||||
if ($externalpackage) {
|
||||
if ($scormdir = make_upload_directory("$courseid/$CFG->moddata/scorm")) {
|
||||
if ($tempdir = scorm_tempdir($scormdir)) {
|
||||
copy ("$reference", $tempdir.'/'.basename($reference));
|
||||
if (is_file($tempdir.'/'.basename($reference))) {
|
||||
$validation = scorm_validate_manifest($tempdir.'/'.basename($reference));
|
||||
} else {
|
||||
$validation = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$validation = scorm_validate_manifest($reference);
|
||||
}
|
||||
$validation->pkgtype = 'SCORM';
|
||||
} else {
|
||||
$validation = null;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$validation = null;
|
||||
break;
|
||||
}
|
||||
if ($validation == null) {
|
||||
if (is_dir($tempdir)) {
|
||||
// Delete files and temporary directory
|
||||
scorm_delete_files($tempdir);
|
||||
}
|
||||
} else {
|
||||
if (($ext == '.xml') && (!$externalpackage)) {
|
||||
$validation->datadir = dirname($referencefield);
|
||||
} else {
|
||||
$validation->datadir = substr($tempdir,strlen($scormdir));
|
||||
}
|
||||
$validation->launch = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$validation = null;
|
||||
}
|
||||
return $validation;
|
||||
}
|
||||
|
||||
|
||||
function scorm_get_count_users($scormid, $groupingid=null) {
|
||||
global $CFG, $DB;
|
||||
|
||||
|
||||
if (!empty($CFG->enablegroupings) && !empty($groupingid)) {
|
||||
$sql = "SELECT COUNT(DISTINCT st.userid)
|
||||
FROM {scorm_scoes_track} st
|
||||
INNER JOIN {groups_members} gm ON st.userid = gm.userid
|
||||
INNER JOIN {groupings_groups} gg ON gm.groupid = gg.groupid
|
||||
INNER JOIN {groupings_groups} gg ON gm.groupid = gg.groupid
|
||||
WHERE st.scormid = ? AND gg.groupingid = ?
|
||||
";
|
||||
$params = array($scormid, $groupingid);
|
||||
} else {
|
||||
$sql = "SELECT COUNT(DISTINCT st.userid)
|
||||
FROM {scorm_scoes_track} st
|
||||
FROM {scorm_scoes_track} st
|
||||
WHERE st.scormid = ?
|
||||
";
|
||||
$params = array($scormid);
|
||||
}
|
||||
|
||||
|
||||
return ($DB->count_records_sql($sql, $params));
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,22 @@ require_once($CFG->dirroot.'/mod/scorm/locallib.php');
|
||||
class mod_scorm_mod_form extends moodleform_mod {
|
||||
|
||||
function definition() {
|
||||
global $CFG;
|
||||
|
||||
global $CFG, $COURSE, $SCORM_GRADE_METHOD, $SCORM_WHAT_GRADE;
|
||||
$mform =& $this->_form;
|
||||
if (isset($CFG->slasharguments) && !$CFG->slasharguments) {
|
||||
$mform = $this->_form;
|
||||
|
||||
$SCORM_GRADE_METHOD = array (GRADESCOES => get_string('gradescoes', 'scorm'),
|
||||
GRADEHIGHEST => get_string('gradehighest', 'scorm'),
|
||||
GRADEAVERAGE => get_string('gradeaverage', 'scorm'),
|
||||
GRADESUM => get_string('gradesum', 'scorm'));
|
||||
|
||||
$SCORM_WHAT_GRADE = array (HIGHESTATTEMPT => get_string('highestattempt', 'scorm'),
|
||||
AVERAGEATTEMPT => get_string('averageattempt', 'scorm'),
|
||||
FIRSTATTEMPT => get_string('firstattempt', 'scorm'),
|
||||
LASTATTEMPT => get_string('lastattempt', 'scorm'));
|
||||
|
||||
|
||||
if (!$CFG->slasharguments) {
|
||||
$mform->addElement('static', '', '',notify(get_string('slashargs', 'scorm'), 'notifyproblem', 'center', true));
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
@ -29,11 +41,34 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
$mform->addRule('summary', get_string('required'), 'required', null, 'client');
|
||||
$mform->setHelpButton('summary', array('writing', 'questions', 'richtext'), false, 'editorhelpbutton');
|
||||
|
||||
// Scorm types
|
||||
$options = array(SCORM_TYPE_LOCAL => get_string('typelocal', 'scorm'));
|
||||
|
||||
if ($CFG->scorm_allowtypeexternal) {
|
||||
$options[SCORM_TYPE_EXTERNAL] = get_string('typeexternal', 'scorm');
|
||||
}
|
||||
|
||||
if ($CFG->scorm_allowtypelocalsync) {
|
||||
$options[SCORM_TYPE_LOCALSYNC] = get_string('typelocalsync', 'scorm');
|
||||
}
|
||||
|
||||
if (!empty($CFG->repositoryactivate) and $CFG->scorm_allowtypeimsrepository) {
|
||||
$options[SCORM_TYPE_IMSREPOSITORY] = get_string('typeimsrepository', 'scorm');
|
||||
}
|
||||
|
||||
$mform->addElement('select', 'scormtype', get_string('scormtype', 'scorm'), $options);
|
||||
|
||||
// Reference
|
||||
$mform->addElement('choosecoursefileorimsrepo', 'reference', get_string('package','scorm'));
|
||||
$mform->setType('reference', PARAM_RAW); // We need to find a better PARAM
|
||||
$mform->addRule('reference', get_string('required'), 'required');
|
||||
$mform->setHelpButton('reference',array('package', get_string('package', 'scorm'), 'scorm'));
|
||||
if (count($options) > 1) {
|
||||
$mform->addElement('text', 'packageurl', get_string('url', 'scorm'), array('size'=>60));
|
||||
$mform->setType('packageurl', PARAM_RAW);
|
||||
$mform->setHelpButton('packageurl', array('packagefile', get_string('package', 'scorm'), 'scorm'));
|
||||
$mform->disabledIf('packageurl', 'scormtype', 'eq', SCORM_TYPE_LOCAL);
|
||||
}
|
||||
|
||||
// New local package upload
|
||||
$mform->addElement('file', 'packagefile', get_string('package','scorm'));
|
||||
$mform->disabledIf('packagefile', 'scormtype', 'noteq', SCORM_TYPE_LOCAL);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Other Settings
|
||||
@ -41,7 +76,7 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
|
||||
// Grade Method
|
||||
$mform->addElement('select', 'grademethod', get_string('grademethod', 'scorm'), $SCORM_GRADE_METHOD);
|
||||
$mform->setHelpButton('grademethod', array('grademethod',get_string('grademethod', 'scorm'),'scorm'));
|
||||
$mform->setHelpButton('grademethod', array('grademethod', get_string('grademethod', 'scorm'),'scorm'));
|
||||
$mform->setDefault('grademethod', 0);
|
||||
|
||||
// Maximum Grade
|
||||
@ -50,7 +85,7 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
}
|
||||
$mform->addElement('select', 'maxgrade', get_string('maximumgrade'), $grades);
|
||||
$mform->setDefault('maxgrade', 0);
|
||||
$mform->disabledIf('maxgrade', 'grademethod','eq',GRADESCOES);
|
||||
$mform->disabledIf('maxgrade', 'grademethod','eq', GRADESCOES);
|
||||
|
||||
// Attempts
|
||||
$mform->addElement('static', '', '' ,'<hr />');
|
||||
@ -99,12 +134,12 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
$mform->addElement('static', 'stagesize', get_string('stagesize','scorm'));
|
||||
$mform->setHelpButton('stagesize', array('stagesize',get_string('stagesize', 'scorm'), 'scorm'));
|
||||
// Width
|
||||
$mform->addElement('text', 'width', get_string('width','scorm'),'maxlength="5" size="5"');
|
||||
$mform->addElement('text', 'width', get_string('width','scorm'), 'maxlength="5" size="5"');
|
||||
$mform->setDefault('width', $CFG->scorm_framewidth);
|
||||
$mform->setType('width', PARAM_INT);
|
||||
|
||||
|
||||
// Height
|
||||
$mform->addElement('text', 'height', get_string('height','scorm'),'maxlength="5" size="5"');
|
||||
$mform->addElement('text', 'height', get_string('height','scorm'), 'maxlength="5" size="5"');
|
||||
$mform->setDefault('height', $CFG->scorm_frameheight);
|
||||
$mform->setType('height', PARAM_INT);
|
||||
|
||||
@ -112,7 +147,7 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
$options = array();
|
||||
$options[0] = get_string('iframe', 'scorm');
|
||||
$options[1] = get_string('popup', 'scorm');
|
||||
$mform->addElement('select', 'popup', get_string('display','scorm'), $options);
|
||||
$mform->addElement('select', 'popup', get_string('display', 'scorm'), $options);
|
||||
$mform->setDefault('popup', 0);
|
||||
$mform->setAdvanced('popup');
|
||||
|
||||
@ -211,7 +246,7 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
foreach ($options as $option) {
|
||||
list($element,$value) = explode('=',$option);
|
||||
$element = trim($element);
|
||||
$default_values[$element] = trim($value);
|
||||
$default_values[$element] = trim($value);
|
||||
}
|
||||
}
|
||||
if (isset($default_values['grademethod'])) {
|
||||
@ -228,7 +263,7 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
$coursescorm = current($scorms);
|
||||
if (($COURSE->format == 'scorm') && ((count($scorms) == 0) || ($default_values['instance'] == $coursescorm->id))) {
|
||||
$default_values['redirect'] = 'yes';
|
||||
$default_values['redirecturl'] = '../course/view.php?id='.$default_values['course'];
|
||||
$default_values['redirecturl'] = '../course/view.php?id='.$default_values['course'];
|
||||
} else {
|
||||
$default_values['redirect'] = 'no';
|
||||
$default_values['redirecturl'] = '../mod/scorm/view.php?id='.$default_values['coursemodule'];
|
||||
@ -244,30 +279,88 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
function validation($data, $files) {
|
||||
$errors = parent::validation($data, $files);
|
||||
|
||||
$validate = scorm_validate($data);
|
||||
$type = $data['scormtype'];
|
||||
|
||||
if (!$validate->result) {
|
||||
$errors = $errors + $validate->errors;
|
||||
if ($type === SCORM_TYPE_LOCAL) {
|
||||
if (!empty($data['update'])) {
|
||||
//ok, not required
|
||||
|
||||
} else if (empty($files['packagefile'])) {
|
||||
$errors['packagefile'] = get_string('required');
|
||||
|
||||
} else {
|
||||
$packer = get_file_packer('application/zip');
|
||||
|
||||
$filelist = $packer->list_files($files['packagefile']);
|
||||
if (!is_array($filelist)) {
|
||||
$errors['packagefile'] = 'Incorrect file package - not an archive'; //TODO: localise
|
||||
} else {
|
||||
$manifestpresent = false;
|
||||
$aiccfound = false;
|
||||
foreach ($filelist as $info) {
|
||||
if ($info->pathname == 'imsmanifest.xml') {
|
||||
$manifestpresent = true;
|
||||
break;
|
||||
}
|
||||
if (preg_match('/\.cst$/', $info->pathname)) {
|
||||
$aiccfound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$manifestpresent and !$aiccfound) {
|
||||
$errors['packagefile'] = 'Incorrect file package - missing imsmanifest.xml or AICC structure'; //TODO: localise
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if ($type === SCORM_TYPE_EXTERNAL) {
|
||||
$reference = $data['packageurl'];
|
||||
if (!preg_match('/(http:\/\/|https:\/\/|www).*\/imsmanifest.xml$/i', $reference)) {
|
||||
$errors['packageurl'] = get_string('required'); // TODO: improve help
|
||||
}
|
||||
|
||||
} else if ($type === 'packageurl') {
|
||||
$reference = $data['reference'];
|
||||
if (!preg_match('/(http:\/\/|https:\/\/|www).*(\.zip|\.pif)$/i', $reference)) {
|
||||
$errors['packageurl'] = get_string('required'); // TODO: improve help
|
||||
}
|
||||
|
||||
} else if ($type === SCORM_TYPE_IMSREPOSITORY) {
|
||||
$reference = $data['packageurl'];
|
||||
if (stripos($reference, '#') !== 0) {
|
||||
$errors['packageurl'] = get_string('required');
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
//need to translate the "options" field.
|
||||
|
||||
//need to translate the "options" and "reference" field.
|
||||
function set_data($default_values) {
|
||||
if (is_object($default_values)) {
|
||||
if (!empty($default_values->options)) {
|
||||
$options = explode(',', $default_values->options);
|
||||
foreach ($options as $option) {
|
||||
$opt = explode('=', $option);
|
||||
if (isset($opt[1])) {
|
||||
$default_values->$opt[0] = $opt[1];
|
||||
}
|
||||
$default_values = (array)$default_values;
|
||||
|
||||
if (isset($default_values['scormtype']) and isset($default_values['reference'])) {
|
||||
switch ($default_values['scormtype']) {
|
||||
case SCORM_TYPE_LOCALSYNC :
|
||||
case SCORM_TYPE_EXTERNAL:
|
||||
case SCORM_TYPE_IMSREPOSITORY:
|
||||
$default_values['packageurl'] = $default_values['reference'];
|
||||
}
|
||||
}
|
||||
unset($default_values['reference']);
|
||||
|
||||
if (!empty($default_values['options'])) {
|
||||
$options = explode(',', $default_values['options']);
|
||||
foreach ($options as $option) {
|
||||
$opt = explode('=', $option);
|
||||
if (isset($opt[1])) {
|
||||
$default_values[$opt][0] = $opt[1];
|
||||
}
|
||||
}
|
||||
$default_values = (array)$default_values;
|
||||
}
|
||||
|
||||
$this->data_preprocessing($default_values);
|
||||
parent::set_data($default_values); //never slashed for moodleform_mod
|
||||
parent::set_data($default_values);
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,9 +1,25 @@
|
||||
<?php //$Id$
|
||||
|
||||
$settings->add(new admin_setting_configtext('scorm_framewidth', get_string('width', 'scorm'),
|
||||
get_string('framewidth', 'scorm'), '100%'));
|
||||
get_string('framewidth', 'scorm'), 100));
|
||||
|
||||
$settings->add(new admin_setting_configtext('scorm_frameheight', get_string('height', 'scorm'),
|
||||
get_string('frameheight', 'scorm'), 500));
|
||||
|
||||
?>
|
||||
$settings->add(new admin_setting_configtext('scorm_maxattempts', get_string('maximumattempts', 'scorm'),
|
||||
'', 6));
|
||||
|
||||
$settings->add(new admin_setting_configtext('scorm_updatetime', get_string('updatetime', 'scorm'),
|
||||
'', 2));
|
||||
|
||||
$settings->add(new admin_setting_configcheckbox('scorm_allowtypeexternal', get_string('allowtypeexternal', 'scorm'),
|
||||
'', 0));
|
||||
|
||||
$settings->add(new admin_setting_configcheckbox('scorm_allowtypelocalsync', get_string('allowtypelocalsync', 'scorm'),
|
||||
'', 0));
|
||||
|
||||
$settings->add(new admin_setting_configcheckbox('scorm_allowtypeimsrepository', get_string('allowtypeimsrepository', 'scorm'),
|
||||
'', 0));
|
||||
|
||||
|
||||
|
||||
|
@ -6,12 +6,12 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// NOTE The version below was accidentally set a month into the future! We need to
|
||||
// catch up now, so until 27th October please only increment in very tiny steps
|
||||
// NOTE The version below was accidentally set a month into the future! We need to
|
||||
// catch up now, so until 27th October please only increment in very tiny steps
|
||||
// in HEAD, until we get past that date..
|
||||
|
||||
$module->version = 2008073100; // The (date) version of this module
|
||||
$module->requires = 2007101509; // The version of Moodle that is required
|
||||
$module->version = 2008090304; // The (date) version of this module
|
||||
$module->requires = 2008090108; // The version of Moodle that is required
|
||||
$module->cron = 300; // How often should cron check this module (seconds)?
|
||||
|
||||
?>
|
Loading…
x
Reference in New Issue
Block a user