Putting SCORM into maintree CVS, to make it easier to test.

It's getting pretty useful now!
This commit is contained in:
moodler 2004-05-20 17:06:19 +00:00
parent 64d6c09b7a
commit 98ca59f6e1
27 changed files with 2641 additions and 0 deletions

24
mod/scorm/README.txt Normal file
View File

@ -0,0 +1,24 @@
SCORM Module by Roberto "Bobo" Pinna
The current module version seem to work fine but I tried it only with 3/4 SCORM courses (Marine Navigation distribuited with ADL RTE 1.2 and some courses developed by our course team).
I try to explain how SCORM module works:
SCORM packages come in .zip or .pif (is a zip file with another extension);
Like any other file we must upload the package using the files page.
* Create an activity:
When we create a new activity, we can choose from a popup menu the right package.
After that, on continue, the package is checked and validated (the current version check only if the package contains a imsmanifest.xml file; future versions will check if this file is well formed and other);
This operation creates a record in the scorm table and a directory containing the unpacked SCORM course.
* View an activity:
The first time someone try to view a SCORM activity the module parse the imsmanifest file and insert a record for every manifest item in the scorm_scoes table.
Then the module show the course summary with two buttons of three, browse and review or enter the course.
When we click one of them will load an new page that will show the first SCO or the last viewed not completed SCO.
* Activity report:
I develop also a begining report page that show the status of every SCO in the SCORM and the time spent in each SCO.
If anyone what to help me to design and develop this module is welcome.
Sorry for my poor English.
Bobo

304
mod/scorm/api1_2.php Normal file
View File

@ -0,0 +1,304 @@
//
// CMI Initialization SCORM 1.2
//
var cmi= new Object();
cmi.core = new Object();
cmi.core._children = "student_id,student_name,lesson_location,credit,lesson_status,exit,entry,session_time,total_time,lesson_mode,score,suspend_data,launch_data";
cmi.core.student_id = "<?php echo $USER->username ?>";
cmi.core.student_name = "<?php echo $USER->firstname." ".$USER->lastname ?>";
cmi.core.lesson_location = "<?php echo $sco_user->cmi_core_lesson_location ?>";
cmi.core.credit = "credit";
cmi.core.lesson_status = "<?php echo $sco_user->cmi_core_lesson_status ?>";
cmi.core.exit = "<?php echo $sco_user->cmi_core_exit ?>";
cmi.core.entry = "<?php if ($sco_user->cmi_core_lesson_status=="not attempted")
echo 'ab-initio';
else
if ($sco_user->cmi_core_lesson_status!="completed")
echo 'resume';
else
echo '';?>";
cmi.core.session_time = "<?php echo $sco_user->cmi_core_session_time ?>";
cmi.core.total_time = "<?php echo $sco_user->cmi_core_total_time ?>";
cmi.core.lesson_mode = "<?php echo $_GET["mode"] ?>";
cmi.core.score = new Object();
cmi.core.score._children = "raw";
cmi.core.score.raw = "<?php echo $sco_user->cmi_core_score_raw ?>";
cmi.suspend_data = "<?php echo $sco_user->cmi_suspend_data ?>";
cmi.launch_data = "<?php echo $sco_user->cmi_launch_data ?>";
/* cmi.interactions = new Object();
cmi.interactions._children = "id,objectives,time,type,correct_responses,weighting,student_response,result,latency";
cmi.interactions._count = 0;
*/
var errorCode = 0;
//
// end CMI Initialization
//
//
// SCORM API 1.2 Implementation
//
function SCORMapi() {
var Initialized = false;
function LMSInitialize (param) {
if (param != "") {
errorCode = 201;
return "false";
}
if (!Initialized) {
Initialized = true;
errorCode = 0;
return "true";
} else {
errorCode = 101;
return "false";
}
}
function LMSGetValue (param) {
if (Initialized) {
//top.status="GET "+param;
switch (param) {
case "cmi.core._children":
case "cmi.core.student_id":
case "cmi.core.student_name":
case "cmi.core.lesson_location":
case "cmi.core.credit":
case "cmi.core.lesson_status":
case "cmi.core.entry":
case "cmi.core.total_time":
case "cmi.core.lesson_mode":
case "cmi.core.score._children":
case "cmi.core.score.raw":
case "cmi.launch_data":
case "cmi.suspend_data":
errorCode = 0;
return eval(param);
break;
case "cmi.core.exit":
case "cmi.core.session_time":
errorCode = 404;
return "";
break;
default:
errorCode = 401;
return "";
break;
}
} else {
errorCode = 301;
return "";
}
}
function LMSSetValue (param,value) {
if (Initialized) {
//top.status="SET "+param+" = "+value;
switch (param) {
case "cmi.core.session_time":
cmi.core.total_time = AddTime(cmi.core.total_time, value);
//top.status="SET cmi.core.total_time = "+cmi.core.total_time;
eval(param+'="'+value+'";');
errorCode = 0;
return "true";
break;
case "cmi.core.lesson_status":
if ((value!="passed")&&(value!="completed")&&(value!="failed")&&(value!="incomplete")&&(value!="browsed")) {
errorCode = 405;
return "false";
}
eval(param+'="'+value+'";');
errorCode = 0;
return "true";
break;
case "cmi.core.score.raw":
if ((parseFloat(value,10)).toString() != value) {
errorCode = 405;
return "false";
}
eval(param+'="'+value+'";');
errorCode = 0;
return "true";
break;
case "cmi.core.exit":
if ((value!="time-out")&&(value!="suspend")&&(value!="logout")&&(value!="")) {
errorCode = 405;
return "false";
}
eval(param+'="'+value+'";');
errorCode = 0;
return "true";
break;
case "cmi.core.lesson_location":
case "cmi.suspend_data":
eval(param+'="'+value+'";');
errorCode = 0;
return "true";
break;
case "cmi.core._children":
case "cmi.core.score._children":
errorCode = 402;
return "false";
break;
case "cmi.core.student_id":
case "cmi.core.student_name":
case "cmi.core.credit":
case "cmi.core.entry":
case "cmi.core.total_time":
case "cmi.core.lesson_mode":
case "cmi.launch_data":
errorCode = 403;
return "false";
break;
default:
//errorCode = 401; This is more correct but may have problem with some SCOes
errorCode = 0; // With this disable any possible SCO errors alert
return "false";
break;
}
} else {
errorCode = 301;
return "false";
}
}
function LMSCommit (param) {
if (param != "") {
errorCode = 201;
return "false";
}
if (Initialized) {
if (top.nav.cmi.document.theform) {
cmiform = top.nav.cmi.document.forms[0];
cmiform.scoid.value = "<?php echo $sco->id ?>";
cmiform.cmi_core_lesson_location.value = cmi.core.lesson_location;
cmiform.cmi_core_lesson_status.value = cmi.core.lesson_status;
cmiform.cmi_core_exit.value = cmi.core.exit;
cmiform.cmi_core_session_time.value = cmi.core.session_time;
cmiform.cmi_core_total_time.value = cmi.core.total_time;
cmiform.cmi_core_score_raw.value = cmi.core.score.raw;
cmiform.cmi_suspend_data.value = cmi.suspend_data;
cmiform.submit();
}
errorCode = 0;
return "true";
} else {
errorCode = 301;
return "false";
}
}
function LMSFinish (param) {
if (param != "") {
errorCode = 201;
return "false";
}
if (!Initialized) {
errorCode = 301;
return "false";
} else {
Initialized = false;
errorCode = 0;
<?php
if ($scorm->auto) {
if ($sco != $last) {
print "setTimeout('top.nav.document.navform.next.click();',500);\n";
} else {
print "exitloc = '".$CFG->wwwroot."/mod/scorm/view.php?id=$cm->id';\n";
print "setTimeout('top.location = exitloc;',500);\n";
}
}
?>
return "true";
}
}
function LMSGetLastError () {
return errorCode;
}
function LMSGetErrorString (param) {
var errorString = new Array();
errorString["0"] = "No error";
errorString["101"] = "General exception";
errorString["201"] = "Invalid argument error";
errorString["202"] = "Element cannot have children";
errorString["203"] = "Element not an array - cannot have count";
errorString["301"] = "Not initializated";
errorString["401"] = "Not implemented error";
errorString["402"] = "Invalid set value, element is a keyword";
errorString["403"] = "Element is read only";
errorString["404"] = "Element is write only";
errorString["405"] = "Incorrect data type";
return errorString[param];
}
function LMSGetDiagnostic (param) {
return param;
}
function AddTime (first, second) {
var sFirst = first.split(":");
var sSecond = second.split(":");
var change = 0;
var secs = (Math.round((parseFloat(sFirst[2],10)+parseFloat(sSecond[2],10))*100))/100; //Seconds
if (secs > 60) {
secs = secs - 60;
change = 1;
} else {
change = 0;
}
if (Math.floor(secs) < 10) secs = "0" + secs.toString();
mins = parseInt(sFirst[1],10)+parseInt(sSecond[1],10)+change; //Minutes
if (mins > 60)
change = 1;
else
change = 0;
if (mins < 10) mins = "0" + mins.toString();
hours = parseInt(sFirst[0],10)+parseInt(sSecond[0],10)+change; //Hours
if (hours < 10) hours = "0" + hours.toString();
return hours + ":" + mins + ":" + secs;
}
this.LMSInitialize = LMSInitialize;
this.LMSGetValue = LMSGetValue;
this.LMSSetValue = LMSSetValue;
this.LMSCommit = LMSCommit;
this.LMSFinish = LMSFinish;
this.LMSGetLastError = LMSGetLastError;
this.LMSGetErrorString = LMSGetErrorString;
this.LMSGetDiagnostic = LMSGetDiagnostic;
}
var API = new SCORMapi();
function SCOInitialize() {
<?php
if ( $sco->previous || $first) {
print "\ttop.nav.document.navform.prev.disabled = true;\n";
print "\ttop.nav.document.navform.prev.style.display = 'none';\n";
}
if ( $sco->next || $last) {
print "\ttop.nav.document.navform.next.disabled = true;\n";
print "\ttop.nav.document.navform.next.style.display = 'none';\n";
}
?>
top.main.location="<?php echo $result ?>";
}
function changeSco(direction) {
if (direction == "prev")
top.nav.document.navform.scoid.value="<?php echo $prevsco ?>";
else
top.nav.document.navform.scoid.value="<?php echo $nextsco ?>";
//alert ("Prev: <?php echo $prevsco ?>\nNext: <?php echo $nextsco ?>\nNew SCO: "+top.nav.document.navform.scoid.value);
top.nav.document.navform.submit();
}

64
mod/scorm/cmi.php Executable file
View File

@ -0,0 +1,64 @@
<?php
require_once("../../config.php");
require_once("lib.php");
optional_variable($id); // Course Module ID, or
optional_variable($a); // scorm ID
if ($id) {
if (! $cm = get_record("course_modules", "id", $id)) {
error("Course Module ID was incorrect");
}
if (! $course = get_record("course", "id", $cm->course)) {
error("Course is misconfigured");
}
if (! $scorm = get_record("scorm", "id", $cm->instance)) {
error("Course module is incorrect");
}
} else {
if (! $scorm = get_record("scorm", "id", $a)) {
error("Course module is incorrect");
}
if (! $course = get_record("course", "id", $scorm->course)) {
error("Course is misconfigured");
}
if (! $cm = get_coursemodule_from_instance("scorm", $scorm->id, $course->id)) {
error("Course Module ID was incorrect");
}
}
require_login($course->id);
if ($_POST["scoid"]) {
set_field("scorm_sco_users","cmi_core_lesson_location",$_POST["cmi_core_lesson_location"],"scoid",$_POST["scoid"],"userid",$USER->id);
set_field("scorm_sco_users","cmi_core_lesson_status",$_POST["cmi_core_lesson_status"],"scoid",$_POST["scoid"],"userid",$USER->id);
set_field("scorm_sco_users","cmi_core_exit",$_POST["cmi_core_exit"],"scoid",$_POST["scoid"],"userid",$USER->id);
set_field("scorm_sco_users","cmi_core_session_time",$_POST["cmi_core_session_time"],"scoid",$_POST["scoid"],"userid",$USER->id);
set_field("scorm_sco_users","cmi_core_total_time",$_POST["cmi_core_total_time"],"scoid",$_POST["scoid"],"userid",$USER->id);
set_field("scorm_sco_users","cmi_core_score_raw",$_POST["cmi_core_score_raw"],"scoid",$_POST["scoid"],"userid",$USER->id);
set_field("scorm_sco_users","cmi_suspend_data",$_POST["cmi_suspend_data"],"scoid",$_POST["scoid"],"userid",$USER->id);
/* if ($scorm->auto)
$result="<script language=\"Javascript\">\n\ttop.nav.document.navform.next.click();\n </script>\n"; */
}
?>
<html>
<head>
<title>cmi</title>
</head>
<body>
<form name="theform" method="POST" action="<?php echo $_SERVER["PHP_SELF"] ?>?id=<?php echo $cm->id ?>">
<input type="hidden" name="scoid" />
<input type="hidden" name="cmi_core_lesson_location" />
<input type="hidden" name="cmi_core_lesson_status" />
<input type="hidden" name="cmi_core_exit" />
<input type="hidden" name="cmi_core_session_time" />
<input type="hidden" name="cmi_core_total_time" />
<input type="hidden" name="cmi_core_score_raw" />
<input type="hidden" name="cmi_suspend_data" />
</form>
<?php echo $result?>
</body>
</html>

855
mod/scorm/coursefiles.php Executable file
View File

@ -0,0 +1,855 @@
<?PHP // $Id$
// Manage ONLY ZIP & PIF uploaded files in a course file area
// This file is a hack to files/index.php that removes
// the headers and adds some controls so that images
// can be selected within the Richtext editor.
// All the Moodle-specific stuff is in this top section
// Configuration and access control occurs here.
// Must define: USER, basedir, baseweb, html_header and html_footer
// USER is a persistent variable using sessions
require("../../config.php");
require("../../files/mimetypes.php");
require_variable($id);
optional_variable($file, "");
optional_variable($wdir, "");
optional_variable($action, "");
if (! $course = get_record("course", "id", $id) ) {
error("That's an invalid course id");
}
require_login($course->id);
if (! isteacher($course->id) ) {
error("Only teachers can edit files");
}
function html_footer() {
echo "</td></tr></table></body></html>";
}
function html_header($course, $wdir, $formfield=""){
global $CFG,$THEME;
if (! $site = get_site()) {
error("Invalid site!");
}
if ($course->id == $site->id) {
$strfiles = get_string("sitefiles");
} else {
$strfiles = get_string("files");
}
if ($wdir == "/") {
$fullnav = "$strfiles";
} else {
$dirs = explode("/", $wdir);
$numdirs = count($dirs);
$link = "";
$navigation = "";
for ($i=1; $i<$numdirs; $i++) {
$navigation .= " -> ";
$link .= "/".urlencode($dirs[$i]);
$navigation .= "<a href=\"".$_SERVER['PHP_SELF']."?id=$course->id&wdir=$link\">".$dirs[$i]."</a>";
}
$fullnav = "<a href=\"".$_SERVER['PHP_SELF']."?id=$course->id&wdir=/\">$strfiles</a> $navigation";
}
print_header();
?>
<script language="javascript" type="text/javascript">
<!--
function set_value(txt) {
opener.document.forms['form'].reference.value = txt;
window.close();
}
-->
</script>
<?php
echo '<table border="0" cellpadding="3" cellspacing="0" width="100%">';
echo '<tr>';
echo '<td bgcolor="'.$THEME->cellheading.'" class="navbar">';
echo '<font size="2"><b>'."$course->shortname -> $fullnav".'</b></font>';
echo '</td>';
echo '</tr>';
echo '</table>';
if ($course->id == $site->id) {
print_heading(get_string("publicsitefileswarning"), "center", 2);
}
echo "<table border=0 align=center cellspacing=3 cellpadding=3 width=640>";
echo "<tr>";
echo "<td colspan=\"2\">";
}
if (! $basedir = make_upload_directory("$course->id")) {
error("The site administrator needs to fix the file permissions");
}
$baseweb = $CFG->wwwroot;
// End of configuration and access control
$regexp="\\.\\.";
if (ereg( $regexp, $file, $regs )| ereg( $regexp, $wdir,$regs )) {
$message = "Error: Directories can not contain \"..\"";
$wdir = "/";
$action = "";
}
if (!$wdir) {
$wdir="/";
}
switch ($action) {
case "upload":
html_header($course, $wdir);
if (!empty($_FILES['userfile'])) {
$userfile = $_FILES['userfile'];
} else {
$save = false;
}
if (!empty($save)) {
if (!is_uploaded_file($userfile['tmp_name']) or $userfile['size'] == 0) {
notify(get_string("uploadnofilefound"));
} else {
$userfile_name = clean_filename($userfile['name']);
if ($userfile_name) {
$newfile = "$basedir$wdir/$userfile_name";
if (move_uploaded_file($userfile['tmp_name'], $newfile)) {
chmod($newfile, 0666);
$a = NULL;
$a->file = "$userfile_name (".$userfile['type'].")";
$a->directory = $wdir;
print_string("uploadedfileto", "", $a);
} else {
notify(get_string("uploadproblem", "", $userfile_name));
}
}
}
displaydir($wdir);
} else {
$upload_max_filesize = get_max_upload_file_size($CFG->maxbytes);
$filesize = display_size($upload_max_filesize);
$struploadafile = get_string("uploadafile");
$struploadthisfile = get_string("uploadthisfile");
$strmaxsize = get_string("maxsize", "", $filesize);
$strcancel = get_string("cancel");
echo "<P>$struploadafile ($strmaxsize) --> <B>$wdir</B>";
echo "<TABLE><TR><TD COLSPAN=2>";
echo "<FORM ENCTYPE=\"multipart/form-data\" METHOD=\"post\" ACTION=\"".$_SERVER['PHP_SELF']."\">";
echo " <INPUT TYPE=hidden NAME=MAX_FILE_SIZE value=\"$upload_max_filesize\">";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
echo " <INPUT TYPE=hidden NAME=action VALUE=upload>";
echo " <INPUT NAME=\"userfile\" TYPE=\"file\" size=\"60\">";
echo " </TD><TR><TD WIDTH=10>";
echo " <INPUT TYPE=submit NAME=save VALUE=\"$struploadthisfile\">";
echo "</FORM>";
echo "</TD><TD WIDTH=100%>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=\"get\">";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
echo " <INPUT TYPE=submit VALUE=\"$strcancel\">";
echo "</FORM>";
echo "</TD></TR></TABLE>";
}
html_footer();
break;
case "delete":
if (!empty($confirm)) {
html_header($course, $wdir);
foreach ($USER->filelist as $file) {
$fullfile = $basedir.$file;
if (! fulldelete($fullfile)) {
echo "<BR>Error: Could not delete: $fullfile";
}
}
clearfilelist();
displaydir($wdir);
html_footer();
} else {
html_header($course, $wdir);
if (setfilelist($_POST)) {
echo "<p align=center>".get_string("deletecheckwarning").":</p>";
print_simple_box_start("center");
printfilelist($USER->filelist);
print_simple_box_end();
echo "<br />";
notice_yesno (get_string("deletecheckfiles"),
"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&action=delete&confirm=1",
"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&action=cancel");
} else {
displaydir($wdir);
}
html_footer();
}
break;
case "move":
html_header($course, $wdir);
if ($count = setfilelist($_POST)) {
$USER->fileop = $action;
$USER->filesource = $wdir;
echo "<p align=center>";
print_string("selectednowmove", "moodle", $count);
echo "</p>";
}
displaydir($wdir);
html_footer();
break;
case "paste":
html_header($course, $wdir);
if (isset($USER->fileop) and $USER->fileop == "move") {
foreach ($USER->filelist as $file) {
$shortfile = basename($file);
$oldfile = $basedir.$file;
$newfile = $basedir.$wdir."/".$shortfile;
if (!rename($oldfile, $newfile)) {
echo "<P>Error: $shortfile not moved";
}
}
}
clearfilelist();
displaydir($wdir);
html_footer();
break;
case "rename":
if (!empty($name)) {
html_header($course, $wdir);
$name = clean_filename($name);
if (file_exists($basedir.$wdir."/".$name)) {
echo "Error: $name already exists!";
} else if (!rename($basedir.$wdir."/".$oldname, $basedir.$wdir."/".$name)) {
echo "Error: could not rename $oldname to $name";
}
displaydir($wdir);
} else {
$strrename = get_string("rename");
$strcancel = get_string("cancel");
$strrenamefileto = get_string("renamefileto", "moodle", $file);
html_header($course, $wdir, "form.name");
echo "<P>$strrenamefileto:";
echo "<TABLE><TR><TD>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=\"post\" NAME=\"form\">";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
echo " <INPUT TYPE=hidden NAME=action VALUE=rename>";
echo " <INPUT TYPE=hidden NAME=oldname VALUE=\"$file\">";
echo " <INPUT TYPE=text NAME=name SIZE=35 VALUE=\"$file\">";
echo " <INPUT TYPE=submit VALUE=\"$strrename\">";
echo "</FORM>";
echo "</TD><TD>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
echo " <INPUT TYPE=submit VALUE=\"$strcancel\">";
echo "</FORM>";
echo "</TD></TR></TABLE>";
}
html_footer();
break;
case "mkdir":
if (!empty($name)) {
html_header($course, $wdir);
$name = clean_filename($name);
if (file_exists("$basedir$wdir/$name")) {
echo "Error: $name already exists!";
} else if (! make_upload_directory("$course->id/$wdir/$name")) {
echo "Error: could not create $name";
}
displaydir($wdir);
} else {
$strcreate = get_string("create");
$strcancel = get_string("cancel");
$strcreatefolder = get_string("createfolder", "moodle", $wdir);
html_header($course, $wdir, "form.name");
echo "<P>$strcreatefolder:";
echo "<TABLE><TR><TD>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=post NAME=form>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
echo " <INPUT TYPE=hidden NAME=action VALUE=mkdir>";
echo " <INPUT TYPE=text NAME=name SIZE=35>";
echo " <INPUT TYPE=submit VALUE=\"$strcreate\">";
echo "</FORM>";
echo "</TD><TD>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
echo " <INPUT TYPE=submit VALUE=\"$strcancel\">";
echo "</FORM>";
echo "</TD></TR></TABLE>";
}
html_footer();
break;
case "edit":
html_header($course, $wdir);
if (isset($text)) {
$fileptr = fopen($basedir.$file,"w");
fputs($fileptr, stripslashes($text));
fclose($fileptr);
displaydir($wdir);
} else {
$streditfile = get_string("edit", "", "<B>$file</B>");
$fileptr = fopen($basedir.$file, "r");
$contents = fread($fileptr, filesize($basedir.$file));
fclose($fileptr);
if (mimeinfo("type", $file) == "text/html") {
if ($usehtmleditor = can_use_richtext_editor()) {
$onsubmit = "onsubmit=\"copyrichtext(document.form.text);\"";
} else {
$onsubmit = "";
}
} else {
$usehtmleditor = false;
$onsubmit = "";
}
print_heading("$streditfile");
echo "<TABLE><TR><TD COLSPAN=2>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=\"post\" NAME=\"form\" $onsubmit>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
echo " <INPUT TYPE=hidden NAME=file VALUE=\"$file\">";
echo " <INPUT TYPE=hidden NAME=action VALUE=edit>";
print_textarea($usehtmleditor, 25, 80, 680, 400, "text", $contents);
echo "</TD></TR><TR><TD>";
echo " <INPUT TYPE=submit VALUE=\"".get_string("savechanges")."\">";
echo "</FORM>";
echo "</TD><TD>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
echo " <INPUT TYPE=submit VALUE=\"".get_string("cancel")."\">";
echo "</FORM>";
echo "</TD></TR></TABLE>";
if ($usehtmleditor) {
print_richedit_javascript("form", "text", "yes");
}
}
html_footer();
break;
case "zip":
if (!empty($name)) {
html_header($course, $wdir);
$name = clean_filename($name);
if (empty($CFG->zip)) { // Use built-in php-based zip function
$files = array();
foreach ($USER->filelist as $file) {
$files[] = "$basedir/$file";
}
include_once($CFG->libdir.'/pclzip/pclzip.lib.php');
$archive = new PclZip("$basedir/$wdir/$name");
if (($list = $archive->create($files,'',"$basedir/$wdir/")) == 0) {
error($archive->errorInfo(true));
}
} else { // Use external zip program
$files = "";
foreach ($USER->filelist as $file) {
$files .= basename($file);
$files .= " ";
}
$command = "cd $basedir/$wdir ; $CFG->zip -r $name $files";
Exec($command);
}
clearfilelist();
displaydir($wdir);
} else {
html_header($course, $wdir, "form.name");
if (setfilelist($_POST)) {
echo "<P ALIGN=CENTER>".get_string("youareabouttocreatezip").":</P>";
print_simple_box_start("center");
printfilelist($USER->filelist);
print_simple_box_end();
echo "<BR>";
echo "<P ALIGN=CENTER>".get_string("whattocallzip");
echo "<TABLE><TR><TD>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=post NAME=form>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
echo " <INPUT TYPE=hidden NAME=action VALUE=zip>";
echo " <INPUT TYPE=text NAME=name SIZE=35 VALUE=\"new.zip\">";
echo " <INPUT TYPE=submit VALUE=\"".get_string("createziparchive")."\">";
echo "</FORM>";
echo "</TD><TD>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
echo " <INPUT TYPE=submit VALUE=\"".get_string("cancel")."\">";
echo "</FORM>";
echo "</TD></TR></TABLE>";
} else {
displaydir($wdir);
clearfilelist();
}
}
html_footer();
break;
case "unzip":
html_header($course, $wdir);
if (!empty($file)) {
$strname = get_string("name");
$strsize = get_string("size");
$strmodified = get_string("modified");
$strstatus = get_string("status");
$strok = get_string("ok");
$strunpacking = get_string("unpacking", "", $file);
echo "<P ALIGN=CENTER>$strunpacking:</P>";
$file = basename($file);
if (empty($CFG->unzip)) { // Use built-in php-based unzip function
include_once($CFG->libdir.'/pclzip/pclzip.lib.php');
$archive = new PclZip("$basedir/$wdir/$file");
if (!$list = $archive->extract("$basedir/$wdir")) {
error($archive->errorInfo(true));
} else { // print some output
echo "<table cellpadding=\"4\" cellspacing=\"2\" border=\"0\" width=640>";
echo "<tr><th align=left>$strname</th>";
echo "<th align=right>$strsize</th>";
echo "<th align=right>$strmodified</th>";
echo "<th align=right>$strstatus</th></tr>";
foreach ($list as $item) {
echo "<tr>";
$item['filename'] = str_replace("$basedir/$wdir/", "", $item['filename']);
print_cell("left", $item['filename']);
if (! $item['folder']) {
print_cell("right", display_size($item['size']));
} else {
echo "<td>&nbsp;</td>";
}
$filedate = userdate($item['mtime'], get_string("strftimedatetime"));
print_cell("right", $filedate);
print_cell("right", $item['status']);
echo "</tr>";
}
echo "</table>";
}
} else { // Use external unzip program
print_simple_box_start("center");
echo "<PRE>";
$command = "cd $basedir/$wdir ; $CFG->unzip -o $file 2>&1";
passthru($command);
echo "</PRE>";
print_simple_box_end();
}
echo "<CENTER><FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
echo " <INPUT TYPE=submit VALUE=\"$strok\">";
echo "</FORM>";
echo "</CENTER>";
} else {
displaydir($wdir);
}
html_footer();
break;
case "listzip":
html_header($course, $wdir);
if (!empty($file)) {
$strname = get_string("name");
$strsize = get_string("size");
$strmodified = get_string("modified");
$strok = get_string("ok");
$strlistfiles = get_string("listfiles", "", $file);
echo "<P ALIGN=CENTER>$strlistfiles:</P>";
$file = basename($file);
include_once($CFG->libdir.'/pclzip/pclzip.lib.php');
$archive = new PclZip("$basedir/$wdir/$file");
if (!$list = $archive->listContent("$basedir/$wdir")) {
notify($archive->errorInfo(true));
} else {
echo "<table cellpadding=\"4\" cellspacing=\"2\" border=\"0\" width=640>";
echo "<tr><th align=left>$strname</th><th align=right>$strsize</th><th align=right>$strmodified</th></tr>";
foreach ($list as $item) {
echo "<tr>";
print_cell("left", $item['filename']);
if (! $item['folder']) {
print_cell("right", display_size($item['size']));
} else {
echo "<td>&nbsp;</td>";
}
$filedate = userdate($item['mtime'], get_string("strftimedatetime"));
print_cell("right", $filedate);
echo "</tr>";
}
echo "</table>";
}
echo "<br><center><form action=\"".$_SERVER['PHP_SELF']."\" method=get>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
echo " <INPUT TYPE=submit VALUE=\"$strok\">";
echo "</FORM>";
echo "</CENTER>";
} else {
displaydir($wdir);
}
html_footer();
break;
case "torte":
if($_POST)
{
while(list($key, $val) = each($_POST))
{
if(ereg("file([0-9]+)", $key, $regs))
{
$file = $val;
}
}
if(@filetype($CFG->dataroot ."/". $course->id . $file) == "file")
{
if(mimeinfo("icon", $file) == "image.gif")
{
$url = $CFG->wwwroot ."/file.php?file=/" .$course->id . $file;
runjavascript($url);
}
else
{
print "File is not a image!";
}
}
else
{
print "You cannot insert FOLDER into richtext editor!!!";
}
}
break;
case "cancel";
clearfilelist();
default:
html_header($course, $wdir);
displaydir($wdir);
html_footer();
break;
}
/// FILE FUNCTIONS ///////////////////////////////////////////////////////////
function fulldelete($location) {
if (is_dir($location)) {
$currdir = opendir($location);
while ($file = readdir($currdir)) {
if ($file <> ".." && $file <> ".") {
$fullfile = $location."/".$file;
if (is_dir($fullfile)) {
if (!fulldelete($fullfile)) {
return false;
}
} else {
if (!unlink($fullfile)) {
return false;
}
}
}
}
closedir($currdir);
if (! rmdir($location)) {
return false;
}
} else {
if (!unlink($location)) {
return false;
}
}
return true;
}
function setfilelist($VARS) {
global $USER;
$USER->filelist = array ();
$USER->fileop = "";
$count = 0;
foreach ($VARS as $key => $val) {
if (substr($key,0,4) == "file") {
$count++;
$USER->filelist[] = rawurldecode($val);
}
}
return $count;
}
function clearfilelist() {
global $USER;
$USER->filelist = array ();
$USER->fileop = "";
}
function printfilelist($filelist) {
global $basedir, $CFG;
foreach ($filelist as $file) {
if (is_dir($basedir.$file)) {
echo "<img src=\"$CFG->pixpath/f/folder.gif\" height=16 width=16> $file<br>";
$subfilelist = array();
$currdir = opendir($basedir.$file);
while ($subfile = readdir($currdir)) {
if ($subfile <> ".." && $subfile <> ".") {
$subfilelist[] = $file."/".$subfile;
}
}
printfilelist($subfilelist);
} else {
$icon = mimeinfo("icon", $file);
echo "<img src=\"$CFG->pixpath/f/$icon\" height=16 width=16> $file<br>";
}
}
}
function print_cell($alignment="center", $text="&nbsp;") {
echo "<TD ALIGN=\"$alignment\" NOWRAP>";
echo "<FONT SIZE=\"-1\" FACE=\"Arial, Helvetica\">";
echo "$text";
echo "</FONT>";
echo "</TD>\n";
}
function displaydir ($wdir) {
// $wdir == / or /a or /a/b/c/d etc
global $basedir;
global $id;
global $USER, $CFG;
$fullpath = $basedir.$wdir;
$directory = opendir($fullpath); // Find all files
while ($file = readdir($directory)) {
if ($file == "." || $file == "..") {
continue;
}
if (is_dir($fullpath."/".$file)) {
$dirlist[] = $file;
} else {
if ((basename(strtolower($file),".zip") != basename(strtolower($file))) || (basename(strtolower($file),".pif") != basename(strtolower($file))))
$filelist[] = $file;
}
}
closedir($directory);
$strname = get_string("name");
$strsize = get_string("size");
$strmodified = get_string("modified");
$straction = get_string("action");
$strmakeafolder = get_string("makeafolder");
$struploadafile = get_string("uploadafile");
$strwithchosenfiles = get_string("withchosenfiles");
$strmovetoanotherfolder = get_string("movetoanotherfolder");
$strmovefilestohere = get_string("movefilestohere");
$strdeletecompletely = get_string("deletecompletely");
$strcreateziparchive = get_string("createziparchive");
$strrename = get_string("rename");
$stredit = get_string("edit");
$strunzip = get_string("unzip");
$strlist = get_string("list");
$strchoose = get_string("choose");
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=post NAME=dirform>";
echo "<TABLE BORDER=0 cellspacing=2 cellpadding=2 width=640>";
echo "<TR>";
echo "<TH WIDTH=5></TH>";
echo "<TH ALIGN=left>$strname</TH>";
echo "<TH ALIGN=right>$strsize</TH>";
echo "<TH ALIGN=right>$strmodified</TH>";
echo "<TH ALIGN=right>$straction</TH>";
echo "</TR>\n";
if ($wdir == "/") {
$wdir = "";
}
$count = 0;
if (!empty($dirlist)) {
asort($dirlist);
foreach ($dirlist as $dir) {
$count++;
$filename = $fullpath."/".$dir;
$fileurl = rawurlencode($wdir."/".$dir);
$filesafe = rawurlencode($dir);
$filedate = userdate(filectime($filename), "%d %b %Y, %I:%M %p");
echo "<TR>";
print_cell("center", "<INPUT TYPE=checkbox NAME=\"file$count\" VALUE=\"$fileurl\">");
print_cell("left", "<A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$fileurl\"><IMG SRC=\"$CFG->pixpath/f/folder.gif\" HEIGHT=16 WIDTH=16 BORDER=0 ALT=\"Folder\"></A> <A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$fileurl\">".htmlspecialchars($dir)."</A>");
print_cell("right", "-");
print_cell("right", $filedate);
print_cell("right", "<A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$filesafe&action=rename\">$strrename</A>");
echo "</TR>";
}
}
if (!empty($filelist)) {
asort($filelist);
foreach ($filelist as $file) {
$icon = mimeinfo("icon", $file);
$count++;
$filename = "$fullpath/$file";
$fileurl = "$wdir/$file";
$filesafe = rawurlencode($file);
$fileurlsafe = rawurlencode($fileurl);
$filedate = userdate(filectime($filename), "%d %b %Y, %I:%M %p");
if (substr($fileurl,0,1) == '/') {
$selectfile = substr($fileurl,1);
} else {
$selectfile = $fileurl;
}
if ($CFG->slasharguments) {
$ffurl = "/file.php/$id$fileurl";
} else {
$ffurl = "/file.php?file=/$id$fileurl";
}
echo "<tr>";
print_cell("center", "<input type=\"checkbox\" name=\"file$count\" value=\"$fileurl\">");
echo "<td align=left nowrap>";
link_to_popup_window ($ffurl, "display",
"<img src=\"$CFG->pixpath/f/$icon\" height=16 width=16 border=0 alt=\"file\">",
480, 640);
echo "<font size=\"-1\" face=\"Arial, Helvetica\">";
link_to_popup_window ($ffurl, "display", htmlspecialchars($file), 480, 640);
echo "</font></td>";
$file_size = filesize($filename);
print_cell("right", display_size($file_size));
print_cell("right", $filedate);
$edittext = "<b><a onMouseDown=\"return set_value('$selectfile')\" href=\"\">$strchoose</a></b>&nbsp;";
if ($icon == "text.gif" || $icon == "html.gif") {
$edittext .= "<a href=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$fileurl&action=edit\">$stredit</a>";
} else if ($icon == "zip.gif") {
$edittext .= "<a href=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$fileurl&action=unzip\">$strunzip</a>&nbsp;";
$edittext .= "<a href=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$fileurl&action=listzip\">$strlist</a> ";
}
print_cell("right", "$edittext <A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$filesafe&action=rename\">$strrename</A>");
echo "</tr>";
}
}
echo "</table>";
echo "<hr width=640 align=center noshade size=1>";
if (empty($wdir)) {
$wdir = "/";
}
echo "<TABLE BORDER=0 cellspacing=2 cellpadding=2 width=640>";
echo "<TR><TD>";
echo "<INPUT TYPE=hidden NAME=id VALUE=\"$id\">";
echo "<INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\"> ";
$options = array (
"move" => "$strmovetoanotherfolder",
"delete" => "$strdeletecompletely",
"zip" => "$strcreateziparchive"
);
if (!empty($count)) {
choose_from_menu ($options, "action", "", "$strwithchosenfiles...", "javascript:document.dirform.submit()");
}
echo "</FORM>";
echo "<TD ALIGN=center>";
if (!empty($USER->fileop) and ($USER->fileop == "move") and ($USER->filesource <> $wdir)) {
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
echo " <INPUT TYPE=hidden NAME=action VALUE=paste>";
echo " <INPUT TYPE=submit VALUE=\"$strmovefilestohere\">";
echo "</FORM>";
}
echo "<TD ALIGN=right>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
echo " <INPUT TYPE=hidden NAME=action VALUE=mkdir>";
echo " <INPUT TYPE=submit VALUE=\"$strmakeafolder\">";
echo "</FORM>";
echo "</TD>";
echo "<TD ALIGN=right>";
echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
echo " <INPUT TYPE=hidden NAME=action VALUE=upload>";
echo " <INPUT TYPE=submit VALUE=\"$struploadafile\">";
echo "</FORM>";
echo "</TD></TR>";
echo "</TABLE>";
echo "<HR WIDTH=640 ALIGN=CENTER NOSHADE SIZE=1>";
}
?>

18
mod/scorm/db/mysql.php Executable file
View File

@ -0,0 +1,18 @@
<?PHP // $Id$
function scorm_upgrade($oldversion) {
/// This function does anything necessary to upgrade
/// older versions to match current functionality
global $CFG;
if ($oldversion < 2004033000) {
execute_sql(" ALTER TABLE `{$CFG->prefix}scorm` ADD `auto` TINYINT( 1 ) UNSIGNED DEFAULT '0' NOT NULL AFTER `summary`");
}
if ($oldversion < 2004040900) {
execute_sql(" ALTER TABLE `{$CFG->prefix}scorm_sco_users` ADD `cmi_core_score_raw` FLOAT( 3 ) DEFAULT '0' NOT NULL AFTER `cmi_core_session_time`");
}
return true;
}
?>

55
mod/scorm/db/mysql.sql Executable file
View File

@ -0,0 +1,55 @@
#
# Table structure for table `scorm`
#
CREATE TABLE prefix_scorm (
id int(10) unsigned NOT NULL auto_increment,
course int(10) unsigned NOT NULL default '0',
name varchar(255) NOT NULL default '',
reference varchar(255) default NULL,
datadir varchar(255) NOT NULL default '',
launch int(10) unsigned NOT NULL default 0,
summary text NOT NULL,
auto tinyint(1) unsigned NOT NULL default '0',
timemodified int(10) unsigned NOT NULL default '0',
PRIMARY KEY (id),
UNIQUE KEY id (id)
) TYPE=MyISAM;
CREATE TABLE prefix_scorm_scoes (
id int(10) unsigned NOT NULL auto_increment,
scorm int(10) unsigned NOT NULL default '0',
parent varchar(255) NOT NULL default '',
identifier varchar(255) NOT NULL default '',
launch varchar(255) NOT NULL default '',
type varchar(5) NOT NULL default '',
title varchar(255) NOT NULL default '',
next tinyint(1) unsigned NOT NULL default '0',
previous tinyint(1) unsigned NOT NULL default '0',
PRIMARY KEY (id),
UNIQUE KEY id (id)
) TYPE=MyISAM;
CREATE TABLE prefix_scorm_sco_users (
id int(10) unsigned NOT NULL auto_increment,
userid int(10) unsigned NOT NULL default '0',
scormid int(10) NOT NULL default '0',
scoid int(10) unsigned NOT NULL default '0',
cmi_core_lesson_location varchar(255) NOT NULL default '',
cmi_core_lesson_status varchar(30) NOT NULL default '',
cmi_core_exit varchar(30) NOT NULL default '',
cmi_core_total_time varchar(13) NOT NULL default '00:00:00',
cmi_core_session_time varchar(13) NOT NULL default '00:00:00',
cmi_core_score_raw float(3) NOT NULL default '0',
cmi_suspend_data longtext,
cmi_launch_data longtext,
PRIMARY KEY (id)
) TYPE=MyISAM;
#
# Dumping data for table log_display
#
INSERT INTO prefix_log_display VALUES ('scorm', 'view', 'scorm', 'name');
INSERT INTO prefix_log_display VALUES ('scorm', 'update', 'scorm', 'name');
INSERT INTO prefix_log_display VALUES ('scorm', 'add', 'scorm', 'name');

12
mod/scorm/db/postgres7.php Executable file
View File

@ -0,0 +1,12 @@
<?PHP // $Id$
function resource_upgrade($oldversion) {
// This function does anything necessary to upgrade
// older versions to match current functionality
return true;
}
?>

50
mod/scorm/db/postgres7.sql Executable file
View File

@ -0,0 +1,50 @@
#
# Table structure for table `scorm`
#
CREATE TABLE prefix_scorm (
id SERIAL PRIMARY KEY,
course integer NOT NULL default '0',
name varchar(255) NOT NULL default '',
reference varchar(255) default NULL,
datadir varchar(255) NOT NULL default '',
launch integer NOT NULL default '0',
summary text NOT NULL default '',
auto integer NOT NULL default '0',
timemodified integer NOT NULL default '0'
);
CREATE TABLE prefix_scorm_scoes (
id SERIAL PRIMARY KEY,
scorm integer NOT NULL default '0',
parent varchar(255) NOT NULL default '',
identifier varchar(255) NOT NULL default '',
launch varchar(255) NOT NULL default '',
type varchar(5) NOT NULL default '',
title varchar(255) NOT NULL default '',
next integer NOT NULL default '0',
previous integer NOT NULL default '0'
);
CREATE TABLE prefix_scorm_sco_users (
id iSERIAL PRIMARY KEY,
userid integer NOT NULL default '0',
scormid integer NOT NULL default '0',
scoid integer NOT NULL default '0',
cmi_core_lesson_location varchar(255) NOT NULL default '',
cmi_core_lesson_status varchar(30) NOT NULL default '',
cmi_core_exit varchar(30) NOT NULL default '',
cmi_core_total_time varchar(13) NOT NULL default '00:00:00',,
cmi_core_session_time varchar(13) NOT NULL default '00:00:00',
cmi_core_score_raw real NOT NULL default '0',
cmi_suspend_data text NOT NULL default '',
cmi_launch_data text NOT NULL default ''
);
#
# Dumping data for table `log_display`
#
INSERT INTO prefix_log_display VALUES ('resource', 'view', 'resource', 'name');
INSERT INTO prefix_log_display VALUES ('resource', 'update', 'resource', 'name');
INSERT INTO prefix_log_display VALUES ('resource', 'add', 'resource', 'name');

118
mod/scorm/details.php Executable file
View File

@ -0,0 +1,118 @@
<?PHP // $Id$
require_once("../../config.php");
require_once("lib.php");
require_login();
if ($form = data_submitted($destination)) {
if (! $course = get_record("course", "id", $form->course)) {
error("This course doesn't exist");
}
require_login($course->id);
if (!isteacher($course->id)) {
error("You can't modify this course!");
}
$strediting = get_string("validateascorm", "scorm");
$strname = get_string("name");
print_header("$course->shortname: $strediting", "$course->shortname: $strediting",
"<A HREF=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</A> -> $strediting");
if (!$form->name or !$form->reference or !$form->summary) {
error(get_string("filloutallfields"), $_SERVER["HTTP_REFERER"]);
}
//
// Create a temporary directory to unzip package and validate imsmanifest
//
$basedir = $CFG->dataroot."/".$course->id;
$scormdir = "/moddata/scorm";
if (scorm_mkdirs($basedir.$scormdir)) {
if ($tempdir = scorm_datadir($basedir.$scormdir, $form->datadir)) {
copy ($basedir."/".$form->reference, $tempdir."/".basename($form->reference));
if (empty($CFG->unzip)) { // Use built-in php-based unzip function
include_once($CFG->dirroot.'/lib/pclzip/pclzip.lib.php');
$archive = new PclZip($tempdir."/".basename($form->reference));
if (!$list = $archive->extract($tempdir)) {
error($archive->errorInfo(true));
}
} else {
$command = "cd $tempdir; $CFG->unzip -o ".basename($form->reference)." 2>&1";
exec($command);
}
$result = scorm_validate($tempdir."/imsmanifest.xml");
} else {
$result = "packagedir";
}
} else {
$result = "datadir";
}
if ($result != "regular") {
//
// Delete files and temporary directory
//
if (is_dir($tempdir))
scorm_delete_files($tempdir);
} else {
//
// Delete package file
//
unlink ($tempdir."/".basename($form->reference));
if ($form->mode == "update") {
$fp = fopen($basedir."/".$form->reference,"r");
$fstat = fstat($fp);
fclose($fp);
if (get_field("scorm","timemodified","id",$form->instance) < $fstat["mtime"])
$form->launch = 0;
}
}
//
// Print validation result
//
print_simple_box_start("center", "", "$THEME->cellheading");
echo "<table cellpadding=\"5\" align=\"center\">\n";
echo " <tr><td align=\"right\" nowrap><p><b>$strname:</b></p></td><td><p>$form->name</p></a></td></tr>\n";
echo " <tr><td align=\"right\" nowrap><p><b>".get_string("validation","scorm").":</b></p></td><td><p>".get_string($result,"scorm")."</p></a></td></tr>\n";
if (($form->mode == "update") && ($form->launch == 0) && (get_records("scorm_sco_user","scormid",$form->instance)))
echo " <tr><td align=\"center\" colspan=\"2\" nowrap><p><b>".get_string("trackingloose","scorm")."</b></p></td></tr>\n";
echo "</table>\n";
if ($result == "regular") {
echo "<form name=\"theform\" method=\"post\" $onsubmit action=\"$form->destination\">\n";
?>
<input type="hidden" name="reference" value="<?php p($form->reference) ?>">
<input type="hidden" name="datadir" value="<?php p(substr($tempdir,strlen($basedir)+strlen($scormdir))) ?>">
<input type="hidden" name="summary" value="<?php p($form->summary) ?>">
<input type="hidden" name="auto" value="<?php p($form->auto) ?>">
<input type="hidden" name="name" value="<?php p($form->name) ?>">
<input type="hidden" name="launch" value="<?php p($form->launch) ?>">
<input type="hidden" name="course" value="<?php p($form->course) ?>">
<input type="hidden" name="coursemodule" value="<?php p($form->coursemodule) ?>">
<input type="hidden" name="section" value="<?php p($form->section) ?>">
<input type="hidden" name="module" value="<?php p($form->module) ?>">
<input type="hidden" name="modulename" value="<?php p($form->modulename) ?>">
<input type="hidden" name="instance" value="<?php p($form->instance) ?>">
<input type="hidden" name="mode" value="<?php p($form->mode) ?>">
<center>
<input type="submit" value="<?php print_string("savechanges") ?>">
<input type="submit" name=cancel value="<?php print_string("cancel") ?>">
</center>
</form>
<?
} else {
?>
<center>
<input type="button" value="<?php print_string("continue") ?>" onClick="document.location='<?php echo $CFG->wwwroot ?>/course/view.php?id=<?php echo $course->id ?>';">
</center>
<?
}
print_simple_box_end();
print_footer($course);
} else {
error("This script was called incorrectly");
}
?>

BIN
mod/scorm/icon.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

80
mod/scorm/index.php Executable file
View File

@ -0,0 +1,80 @@
<?PHP // $Id$
require_once("../../config.php");
require_variable($id); // course
if (! $course = get_record("course", "id", $id)) {
error("Course ID is incorrect");
}
if ($course->category) {
require_login($course->id);
$navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
}
add_to_log($course->id, "scorm", "view all", "index.php?id=$course->id", "");
$strscorm = get_string("modulename", "scorm");
$strscorms = get_string("modulenameplural", "scorm");
$strweek = get_string("week");
$strtopic = get_string("topic");
$strname = get_string("name");
$strsummary = get_string("summary");
$strlastmodified = get_string("lastmodified");
print_header("$course->shortname: $strscorms", "$course->fullname", "$navigation $strscorms",
"", "", true, "", navmenu($course));
if ($course->format == "weeks" or $course->format == "topics") {
$sortorder = "cw.section ASC";
} else {
$sortorder = "m.timemodified DESC";
}
if (! $scorms = get_all_instances_in_course("scorm", $course)) {
notice("There are no scorms", "../../course/view.php?id=$course->id");
exit;
}
if ($course->format == "weeks") {
$table->head = array ($strweek, $strname, $strsummary);
$table->align = array ("CENTER", "LEFT", "LEFT");
} else if ($course->format == "topics") {
$table->head = array ($strtopic, $strname, $strsummary);
$table->align = array ("CENTER", "LEFT", "LEFT");
} else {
$table->head = array ($strlastmodified, $strname, $strsummary);
$table->align = array ("LEFT", "LEFT", "LEFT");
}
foreach ($scorms as $scorm) {
$tt = "";
if ($course->format == "weeks" or $course->format == "topics") {
if ($scorm->section) {
$tt = "$scorm->section";
}
} else {
$tt = "<FONT SIZE=1>".userdate($scorm->timemodified);
}
if (!$scorm->visible) {
//Show dimmed if the mod is hidden
$table->data[] = array ($tt, "<A class=\"dimmed\" HREF=\"view.php?id=$scorm->coursemodule\">$scorm->name</A>",
text_to_html($scorm->summary) );
} else {
//Show normal if the mod is visible
$table->data[] = array ($tt, "<A HREF=\"view.php?id=$scorm->coursemodule\">$scorm->name</A>",
text_to_html($scorm->summary) );
}
}
echo "<BR>";
print_table($table);
print_footer($course);
?>

364
mod/scorm/lib.php Executable file
View File

@ -0,0 +1,364 @@
<?PHP // $Id$
/// Library of functions and constants for module scorm
/// (replace scorm with the name of your module and delete this line)
$scorm_CONSTANT = 7; /// for example
$SCORM_TOP_FRAME_SIZE = 120;
$SCORM_LEFT_FRAME_SIZE = 210;
function scorm_add_instance($scorm) {
/// Given an object containing all the necessary data,
/// (defined by the form in mod.html) this function
/// will create a new instance and return the id number
/// of the new instance.
$scorm->timemodified = time();
# May have to add extra stuff in here #
return insert_record("scorm", $scorm);
}
function scorm_update_instance($scorm) {
/// Given an object containing all the necessary data,
/// (defined by the form in mod.html) this function
/// will update an existing instance with new data.
$scorm->timemodified = time();
$scorm->id = $scorm->instance;
# May have to add extra stuff in here #
return update_record("scorm", $scorm);
}
function scorm_delete_instance($id) {
/// Given an ID of an instance of this module,
/// this function will permanently delete the instance
/// and any data that depends on it.
require('../config.php');
if (! $scorm = get_record("scorm", "id", "$id")) {
return false;
}
$result = true;
# Delete any dependent files #
scorm_delete_files($CFG->dataroot."/".$scorm->course."/moddata/scorm".$scorm->datadir);
# Delete any dependent records here #
if (! delete_records("scorm_sco_users", "scormid", "$scorm->id")) {
$result = false;
}
if (! delete_records("scorm_scoes", "scorm", "$scorm->id")) {
$result = false;
}
if (! delete_records("scorm", "id", "$scorm->id")) {
$result = false;
}
return $result;
}
function scorm_user_outline($course, $user, $mod, $scorm) {
/// Return a small object with summary information about what a
/// user has done with a given particular instance of this module
/// Used for user activity reports.
/// $return->time = the time they did it
/// $return->info = a short text description
return $return;
}
function scorm_user_complete($course, $user, $mod, $scorm) {
/// Print a detailed representation of what a user has done with
/// a given particular instance of this module, for user activity reports.
return true;
}
function scorm_print_recent_activity(&$logs, $isteacher=false) {
/// Given a list of logs, assumed to be those since the last login
/// this function prints a short list of changes related to this module
/// If isteacher is true then perhaps additional information is printed.
/// This function is called from course/lib.php: print_recent_activity()
global $CFG, $COURSE_TEACHER_COLOR;
return $content; // True if anything was printed, otherwise false
}
function scorm_cron () {
/// Function to be run periodically according to the moodle cron
/// This function searches for things that need to be done, such
/// as sending out mail, toggling flags etc ...
global $CFG;
return true;
}
function scorm_grades($scormid) {
/// Must return an array of grades for a given instance of this module,
/// indexed by user. It also returns a maximum allowed grade.
global $CFG;
$return->grades = NULL;
if ($sco_users=get_records_select("scorm_sco_users", "scormid='$scormid' GROUP BY userid")) {
foreach ($sco_users as $sco_user) {
$user_data=get_records_select("scorm_sco_users","scormid='$scormid' AND userid='$sco_user->userid'");
$scores->completed=0;
$scores->browsed=0;
$scores->incomplete=0;
$scores->failed=0;
$scores->notattempted=0;
$result="";
$data = current($user_data);
foreach ($user_data as $data) {
if ($data->cmi_core_lesson_status=="passed")
$scores->completed++;
else
$scores->{scorm_remove_spaces($data->cmi_core_lesson_status)}++;
}
if ($scores->completed)
$result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/completed.gif\" alt=\"".get_string("completed","scorm")."\" title=\"".get_string("completed","scorm")."\"> $scores->completed ";
if ($scores->incomplete)
$result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/incomplete.gif\" alt=\"".get_string("incomplete","scorm")."\" title=\"".get_string("incomplete","scorm")."\"> $scores->incomplete ";
if ($scores->failed)
$result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/failed.gif\" alt=\"".get_string("failed","scorm")."\" title=\"".get_string("failed","scorm")."\"> $scores->failed ";
if ($scores->browsed)
$result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/browsed.gif\" alt=\"".get_string("browsed","scorm")."\" title=\"".get_string("browsed","scorm")."\"> $scores->browsed ";
if ($scores->notattempted)
$result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/notattempted.gif\" alt=\"".get_string("notattempted","scorm")."\" title=\"".get_string("notattempted","scorm")."\"> $scores->notattempted ";
$return->grades[$sco_user->userid]=$result;
}
}
$return->maxgrade = count_records_select("scorm_scoes","scorm='$scormid' AND launch<>''");
return $return;
}
//////////////////////////////////////////////////////////////////////////////////////
/// Any other scorm functions go here. Each of them must have a name that
/// starts with scorm_
function scorm_randstring($len = "8")
{
$rstring = NULL;
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));
}
$rstring .= $char;
$lchar = $char;
}
return $rstring;
}
function scorm_mkdirs($strPath)
{
if (is_dir($strPath))
return true;
$pStrPath = dirname($strPath);
if (!scorm_mkdirs($pStrPath))
return false;
return mkdir($strPath);
}
function scorm_datadir($strPath, $existingdir="", $prefix = "SCORM")
{
if (($existingdir!="") && (is_dir($strPath.$existingdir)))
return $strPath.$existingdir;
if (is_dir($strPath)) {
do {
$datadir="/".$prefix.scorm_randstring();
} while (file_exists($strPath.$datadir));
mkdir($strPath.$datadir);
return $strPath.$datadir;
} else {
return false;
}
}
function scorm_validate($manifest)
{
if (is_file ($manifest)) {
if (file_exists($manifest))
{
return "regular";
}
} else {
return "nomanifest";
}
}
function scorm_delete_files($directory)
{
if (is_dir($directory))
{
$handle=opendir($directory);
while (($file = readdir($handle)) != '')
{
if ($file != "." && $file != "..")
{
if (!is_dir($directory."/".$file))
unlink($directory."/".$file);
else
scorm_delete_files($directory."/".$file);
}
}
rmdir($directory);
}
}
function scorm_startElement($parser, $name, $attrs) {
global $manifest,$i,$resources,$parent,$level;
if ($name == "ITEM") {
$i++;
$manifest[$i]["identifier"] = $attrs["IDENTIFIER"];
$manifest[$i]["identifierref"] = $attrs["IDENTIFIERREF"];
$manifest[$i]["isvisible"] = $attrs["ISVISIBLE"];
$manifest[$i]["parent"] = $parent[$level];
$level++;
$parent[$level] = $attrs["IDENTIFIER"];
}
if ($name == "RESOURCE") {
$resources[$attrs["IDENTIFIER"]]["href"]=$attrs["HREF"];
$resources[$attrs["IDENTIFIER"]]["type"]=$attrs["ADLCP:SCORMTYPE"];
}
}
function scorm_endElement($parser, $name) {
global $manifest,$i,$level,$datacontent,$navigation;
if ($name == "ITEM") {
$level--;
}
if ($name == "TITLE" && $level>0)
$manifest[$i]["title"] = $datacontent;
if ($name == "ADLCP:HIDERTSUI")
$manifest[$i][$datacontent] = 1;
}
function scorm_characterData($parser, $data) {
global $datacontent;
$datacontent = $data;
}
function scorm_parse($basedir,$file,$scorm_id) {
global $manifest,$i,$resources,$parent,$level;
$datacontent = "";
$manifest[][] = "";
$resources[] = "";
$i = 0;
$level = 0;
$parent[$level] = "/";
$xml_parser = xml_parser_create();
// use case-folding so we are sure to find the tag in $map_array
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($xml_parser, "scorm_startElement", "scorm_endElement");
xml_set_character_data_handler($xml_parser, "scorm_characterData");
if (!($fp = fopen($basedir.$file, "r"))) {
die("could not open XML input");
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}
}
xml_parser_free($xml_parser);
$launch = 0;
$sco->scorm = $scorm_id;
delete_records("scorm_scoes","scorm",$scorm_id);
delete_records("scorm_sco_users","scormid",$scorm_id);
for ($j=1; $j<=$i; $j++) {
$sco->identifier = $manifest[$j]["identifier"];
$sco->parent = $manifest[$j]["parent"];
$sco->title = $manifest[$j]["title"];
$sco->launch = $resources[$manifest[$j]["identifierref"]]["href"];
$sco->type = $resources[$manifest[$j]["identifierref"]]["type"];
$sco->previous = $manifest[$j]["previous"];
$sco->next = $manifest[$j]["continue"];
if (scorm_remove_spaces($manifest[$j]["isvisible"]) != "false")
$id = insert_record("scorm_scoes",$sco);
if ($launch==0 && $sco->launch)
$launch = $id;
}
return $launch;
}
function scorm_get_scoes_records($sco_user) {
/// Gets all info required to display the table of scorm results
/// for report.php
global $CFG;
return get_records_sql("SELECT su.*, u.firstname, u.lastname, u.picture
FROM {$CFG->prefix}scorm_sco_users su,
{$CFG->prefix}user u
WHERE su.scormid = '$sco_user->scormid'
AND su.userid = u.id
AND su.userid = $sco_user->userid
ORDER BY scoid");
}
function scorm_remove_spaces($sourcestr) {
// Remove blank space from a string
$newstr="";
for( $i=0; $i<strlen($sourcestr); $i++) {
if ($sourcestr[$i]!=' ')
$newstr .=$sourcestr[$i];
}
return $newstr;
}
function scorm_string_round($stringa) {
// Crop a string to $len character and set an anchor title to the full string
$len=11;
if ( strlen($stringa)>$len ) {
return "<A name=\"\" title=\"$stringa\">".substr($stringa,0,$len-4)."...".substr($stringa,strlen($stringa)-1,1)."</A>";
} else
return $stringa;
}
function scorm_external_link($link) {
// check if a link is external
$result = false;
$link = strtolower($link);
if (substr($link,0,7) == "http://")
$result = true;
else if (substr($link,0,8) == "https://")
$result = true;
else if (substr($link,0,4) == "www.")
$result = true;
else if (substr($link,0,7) == "rstp://")
$result = true;
else if (substr($link,0,6) == "rtp://")
$result = true;
else if (substr($link,0,6) == "ftp://")
$result = true;
else if (substr($link,0,9) == "gopher://")
$result = true;
return $result;
}
?>

79
mod/scorm/mod.html Executable file
View File

@ -0,0 +1,79 @@
<?php
if (empty($form->name)) {
$form->name = "";
}
if (empty($form->summary)) {
$form->summary = "";
}
if (empty($form->alltext)) {
$form->alltext = "";
}
?>
<form name="form" method="post" action="<?php echo $CFG->wwwroot ?>/mod/scorm/details.php">
<table cellpadding=5>
<tr valign=top>
<td align=right><p><b><?php print_string("name") ?>:</b></p></td>
<td>
<input type="text" name="name" size=50 value="<?php p($form->name) ?>">
</td>
</tr>
<?php
$strfilename = get_string("coursepacket", "scorm");
$strchooseafile = get_string("chooseapacket", "scorm");
?>
<tr valign="top">
<td align="right" nowrap>
<p><b><?php echo $strfilename?>:</b></p>
</td>
<td>
<?php
echo "<input name=\"reference\" size=\"50\" value=\"$form->reference\">&nbsp;";
button_to_popup_window ("/mod/scorm/coursefiles.php?id=$course->id",
"coursefiles", $strchooseafile, 500, 750, $strchooseafile);
?>
</td>
</tr>
<tr valign=top>
<td align=right><p><b><?php print_string("summary") ?>:</b></p>
<font size="1">
<?php
helpbutton("summary", get_string("summary"), "scorm", true, true);
echo "<br \>";
helpbutton("writing", get_string("helpwriting"), "moodle", true, true);
echo "<br \>";
helpbutton("text", get_string("helptext"), "moodle", true, true);
?>
<br />
</font>
</td>
<td>
<textarea name="summary" rows=5 cols=50 wrap="virtual"><?php p($form->summary) ?></textarea>
</td>
</tr>
<tr valign=top>
<td align=right><p><b><?php print_string("autocontinue","scorm") ?>:</b></p></td>
<td>
<?php
$options[]=get_string("no");
$options[]=get_string("yes");
choose_from_menu ($options, "auto", $form->auto);
?>
</td>
</tr>
</table>
<input type="hidden" name=course value="<?php p($form->course) ?>">
<input type="hidden" name=coursemodule value="<?php p($form->coursemodule) ?>">
<input type="hidden" name=datadir value="<?php p($form->datadir) ?>">
<input type="hidden" name=launch value="<?php p($form->launch) ?>">
<input type="hidden" name=section value="<?php p($form->section) ?>">
<input type="hidden" name=module value="<?php p($form->module) ?>">
<input type="hidden" name=modulename value="<?php p($form->modulename) ?>">
<input type="hidden" name=instance value="<?php p($form->instance) ?>">
<input type="hidden" name=mode value="<?php p($form->mode) ?>">
<input type="hidden" name=destination value="<?php echo $ME ?>">
<center>
<input type="submit" value="<?php print_string("continue") ?>">
</center>
</form>

BIN
mod/scorm/pix/browsed.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 B

BIN
mod/scorm/pix/completed.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

BIN
mod/scorm/pix/failed.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

BIN
mod/scorm/pix/incomplete.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

BIN
mod/scorm/pix/minus.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 B

BIN
mod/scorm/pix/notattempted.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

BIN
mod/scorm/pix/passed.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

BIN
mod/scorm/pix/plus.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 B

BIN
mod/scorm/pix/spacer.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 B

203
mod/scorm/playscorm.php Executable file
View File

@ -0,0 +1,203 @@
<?PHP // $Id$
/// This page prints a particular instance of scorm
/// (Replace scorm with the name of your module)
require_once("../../config.php");
require_once("lib.php");
optional_variable($id); // Course Module ID, or
optional_variable($a); // scorm ID
if ($id) {
if (! $cm = get_record("course_modules", "id", $id)) {
error("Course Module ID was incorrect");
}
if (! $course = get_record("course", "id", $cm->course)) {
error("Course is misconfigured");
}
if (! $scorm = get_record("scorm", "id", $cm->instance)) {
error("Course module is incorrect");
}
} else {
if (! $scorm = get_record("scorm", "id", $a)) {
error("Course module is incorrect");
}
if (! $course = get_record("course", "id", $scorm->course)) {
error("Course is misconfigured");
}
if (! $cm = get_coursemodule_from_instance("scorm", $scorm->id, $course->id)) {
error("Course Module ID was incorrect");
}
}
require_login($course->id);
$strscorms = get_string("modulenameplural", "scorm");
$strscorm = get_string("modulename", "scorm");
if ($course->category) {
$navigation = "<a target=\"{$CFG->framename}\" href=\"../../course/view.php?id=$course->id\">$course->shortname</a> ->
<a target=\"{$CFG->framename}\" href=\"index.php?id=$course->id\">$strscorms</a> ->";
} else {
$navigation = "<a target=\"{$CFG->framename}\" href=\"index.php?id=$course->id\">$strscorms</a> ->";
}
$pagetitle = strip_tags("$course->shortname: $scorm->name");
if (!$cm->visible and !isteacher($course->id)) {
print_header($pagetitle, "$course->fullname", "$navigation $scorm->name", "", "", true,
update_module_button($cm->id, $course->id, $strscorm), navmenu($course, $cm));
notice(get_string("activityiscurrentlyhidden"));
}
switch ($frameset) {
case "top":
add_to_log($course->id, "scorm", "view", "playscorm.php?id=$cm->id", "$scorm->id");
//
// Print the page header
//
print_header($pagetitle, "$course->fullname",
"$navigation <a target=\"{$CFG->framename}\" href=\"view.php?id=$cm->id\" title=\"$scorm->summary\">$scorm->name</a>",
"", "", true, update_module_button($cm->id, $course->id, $strscorm), navmenu($course, $cm));
echo "<table width=\"100%\"><tr><td align=\"center\">".text_to_html($scorm->summary, true, false)."</td></tr></table>\n";
echo "</body>\n</html>\n";
break;
case "left":
//
// Print SCORM Nav button
//
if (file_exists("$CFG->dirroot/theme/$CFG->theme/styles.php")) {
$styles = $CFG->stylesheet;
require_once("$CFG->dirroot/theme/$CFG->theme/config.php");
} else {
$styles = "$CFG->wwwroot/theme/standard/styles.php";
require_once("$CFG->dirroot/theme/standard/config.php");
}
if ( get_string("thisdirection") == "rtl" ) {
$direction = " dir=\"rtl\"";
} else {
$direction = " dir=\"ltr\"";
}
$meta = "<meta http-equiv=\"content-type\" content=\"text/html; charset=$encoding\" />\n$meta\n";
echo "<html $direction>\n<head>\n";
echo $meta;
echo "<title>Navigator</title>\n";
echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"".$styles."\" />\n";
//echo "<script language=\"JavaScript\" type=\"text/javascript\" src=\"scormAPI.php?id=$cm->id&mode=".$_GET["mode"].$scoid."\"></script>\n";
echo "</head>\n<body bgcolor=\"".$THEME->body."\" leftmargin=\"0\">\n";
echo "<table width=\"100%\">\n";
if ($_GET["mode"] == "browse")
echo " <tr><td align=\"center\"><b>".get_string("browsemode","scorm")."</b></td></tr>";
echo " <tr><td align=\"center\" width=\"20%\" nowrap>
<iframe name=\"cmi\" width=\"1\" height=\"1\" src=\"cmi.php?id=$cm->id\" style=\"visibility: hidden;\"></iframe>
<form name=\"navform\" method=\"POST\" action=\"playscorm.php?id=$cm->id\" target=\"_top\">
<input name=\"scoid\" type=\"hidden\" />
<input name=\"mode\" type=\"hidden\" value=\"".$_GET["mode"]."\" />
<input name=\"prev\" type=\"button\" value=\"".get_string("prev","scorm")."\" onClick=\"top.changeSco('prev');\" />&nbsp;
<input name=\"next\" type=\"button\" value=\"".get_string("next","scorm")."\" onClick=\"top.changeSco('next')\" />
</form>
</td></tr>\n";
echo "</table>\n";
echo "<style type=\"text/css\">.scormlist { list-style-type:none;font-size:small; }</style>\n";
echo "<ul class=\"scormlist\">\n";
if ($scoes = get_records_select("scorm_scoes","scorm='$scorm->id' order by id ASC")){
$level=0;
$sublist=0;
$parents[$level]="/";
$incomplete=false;
foreach ($scoes as $sco) {
if ($parents[$level]!=$sco->parent) {
if ($level>0 && $parents[$level-1]==$sco->parent) {
echo " </ul>\n";
$level--;
} else {
echo " <ul id='".$sublist."' class=\"scormlist\">\n";
$level++;
$parents[$level]=$sco->parent;
}
}
echo " <li>";
$nextsco = next($scoes);
if (($nextsco !== false) && ($sco->parent != $nextsco->parent) && ($nextsco->parent != $parents[$level-1])) {
$sublist++;
echo "<img src=\"pix/minus.gif\" onClick='expandCollide(this,".$sublist.");'/>";
} else
echo "<img src=\"pix/spacer.gif\" />";
if ($sco->launch) {
if ($sco_user=get_record("scorm_sco_users","scoid",$sco->id,"userid",$USER->id)) {
if ( $sco_user->cmi_core_lesson_status == "")
$sco_user->cmi_core_lesson_status = "not attempted";
echo "<img src=\"pix/".scorm_remove_spaces($sco_user->cmi_core_lesson_status).".gif\" alt=\"".get_string(scorm_remove_spaces($sco_user->cmi_core_lesson_status),"scorm")."\" title=\"".get_string(scorm_remove_spaces($sco_user->cmi_core_lesson_status),"scorm")."\" />";
switch ($sco_user->cmi_core_lesson_status) {
case "not attempted":
case "incomplete":
case "browsed":
$incomplete = true;
}
} else {
echo "<img src=\"pix/notattempted.gif\" alt=\"".get_string("notattempted","scorm")."\" />";
$incomplete = true;
}
echo "&nbsp;<a href=\"javascript:playSCO(".$sco->id.")\">$sco->title</a></li>\n";
} else {
echo "&nbsp;$sco->title</li>\n";
}
}
for ($i=0;$i<$level;$i++){
echo " </ul>\n";
}
}
echo "</ul></p>\n";
echo "<script language=\"javascript\">
<!--
function playSCO(scoid,status) {
document.navform.scoid.value = scoid;
document.navform.submit();
}
function expandCollide(which,list) {
var nn=document.ids?true:false
var w3c=document.getElementById?true:false
var beg=nn?\"document.ids.\":w3c?\"document.getElementById(\":\"document.all.\";
var mid=w3c?\").style\":\".style\";
if (eval(beg+list+mid+\".display\") != \"none\") {
which.src = \"pix/plus.gif\";
eval(beg+list+mid+\".display='none';\");
} else {
which.src = \"pix/minus.gif\";
eval(beg+list+mid+\".display='block';\");
}
}
-->
</script>\n";
echo "</body>\n</html>\n";
break;
default:
//
// Frameset
//
if ($_POST["scoid"])
$scoid = "&scoid=".$_POST["scoid"];
echo "<html>\n";
echo "<head><title>$course->shortname: $scorm->name</title></head>\n";
echo "<script id=\"scormAPI\" language=\"JavaScript\" type=\"text/javascript\" src=\"scormAPI.php?id=$cm->id&mode=".$_GET["mode"].$scoid."\"></script>\n";
echo "<frameset rows=\"$SCORM_TOP_FRAME_SIZE,*\">\n";
echo " <frame name=\"upper\" src=\"playscorm.php?id=$cm->id&mode=".$_POST["mode"]."&frameset=top\">\n";
echo " <frameset cols=\"$SCORM_LEFT_FRAME_SIZE,*\" onload=\"SCOInitialize();\">\n";
echo " <frame name=\"nav\" src=\"playscorm.php?id=$cm->id&mode=".$_POST["mode"]."&frameset=left\">\n";
echo " <frame name=\"main\" src=\"\">\n";
echo " </frameset>\n";
echo "</frameset>\n";
echo "</html>\n";
break;
}
?>

110
mod/scorm/report.php Executable file
View File

@ -0,0 +1,110 @@
<?PHP // $Id$
// This script uses installed report plugins to print quiz reports
require_once("../../config.php");
require_once("lib.php");
optional_variable($id); // Course Module ID, or
if ($id) {
if (! $cm = get_record("course_modules", "id", $id)) {
error("Course Module ID was incorrect");
}
if (! $course = get_record("course", "id", $cm->course)) {
error("Course is misconfigured");
}
if (! $scorm = get_record("scorm", "id", $cm->instance)) {
error("Course module is incorrect");
}
} else {
if (! $scorm = get_record("scorm", "id", $q)) {
error("Course module is incorrect");
}
if (! $course = get_record("course", "id", $scorm->course)) {
error("Course is misconfigured");
}
if (! $cm = get_coursemodule_from_instance("scorm", $scorm->id, $course->id)) {
error("Course Module ID was incorrect");
}
}
require_login($course->id);
if (!isteacher($course->id)) {
error("You are not allowed to use this script");
}
add_to_log($course->id, "scorm", "report", "report.php?id=$cm->id", "$scorm->id");
/// Print the page header
if (empty($noheader)) {
if ($course->category) {
$navigation = "<a href=\"../../course/view.php?id=$course->id\">$course->shortname</a> ->";
}
$strscorms = get_string("modulenameplural", "scorm");
$strscorm = get_string("modulename", "scorm");
$strreport = get_string("report", "scorm");
print_header("$course->shortname: $scorm->name", "$course->fullname",
"$navigation <A HREF=index.php?id=$course->id>$strscorms</A>
-> <a href=\"view.php?id=$cm->id\">$scorm->name</a> -> $strreport",
"", "", true);
print_heading($scorm->name);
}
if ($scoes =get_records_select("scorm_scoes","scorm='$scorm->id' ORDER BY id")) {
if ($sco_users=get_records_select("scorm_sco_users", "scormid='$scorm->id' GROUP BY userid")) {
$strname = get_string("name");
$table->head = array("&nbsp;", $strname);
$table->align = array("center", "left");
$table->wrap = array("nowrap", "nowrap");
$table->width = "100%";
$table->size = array(10, "*");
foreach ($scoes as $sco) {
if ($sco->launch!="") {
$table->head[]=scorm_string_round($sco->title);
$table->align[] = "center";
$table->wrap[] = "nowrap";
$table->size[] = "*";
}
}
foreach ($sco_users as $sco_user) {
$user_data=scorm_get_scoes_records($sco_user);
$picture = print_user_picture($sco_user->userid, $course->id, $user_data->picture, false, true);
$row="";
$row[] = $picture;
if (is_array($user_data)) {
$data = current($user_data);
$row[] = "<a href=\"$CFG->wwwroot/user/view.php?id=$data->userid&course=$course->id\">".
"$data->firstname $data->lastname</a>";
foreach ($user_data as $data) {
$row[]="<img src=\"pix/".scorm_remove_spaces($data->cmi_core_lesson_status).".gif\"
alt=\"".get_string(scorm_remove_spaces($data->cmi_core_lesson_status),"scorm")."\"
title=\"".get_string(scorm_remove_spaces($data->cmi_core_lesson_status),"scorm")."\">&nbsp;"
.$data->cmi_core_total_time;
}
}
$table->data[] = $row;
}
print_table($table);
} else {
notice("No users to report");
}
}
if (empty($noheader)) {
print_footer($course);
}
?>

110
mod/scorm/scormAPI.php Executable file
View File

@ -0,0 +1,110 @@
<?php
require_once("../../config.php");
require_once("lib.php");
optional_variable($id); // Course Module ID, or
optional_variable($a); // scorm ID
if ($id) {
if (! $cm = get_record("course_modules", "id", $id)) {
error("Course Module ID was incorrect");
}
if (! $course = get_record("course", "id", $cm->course)) {
error("Course is misconfigured");
}
if (! $scorm = get_record("scorm", "id", $cm->instance)) {
error("Course module is incorrect");
}
} else {
if (! $scorm = get_record("scorm", "id", $a)) {
error("Course module is incorrect");
}
if (! $course = get_record("course", "id", $scorm->course)) {
error("Course is misconfigured");
}
if (! $cm = get_coursemodule_from_instance("scorm", $scorm->id, $course->id)) {
error("Course Module ID was incorrect");
}
}
require_login($course->id);
if ( $scoes_user = get_records_select("scorm_sco_users","userid = ".$USER->id." AND scormid = ".$scorm->id,"scoid ASC") ) {
if ($_GET["scoid"]) {
$sco = get_record("scorm_scoes","id",$_GET["scoid"]);
} else {
foreach ( $scoes_user as $sco_user ) {
if (($sco_user->cmi_core_lesson_status != "completed") && ($sco_user->cmi_core_lesson_status != "passed") && ($sco_user->cmi_core_lesson_status != "failed")) {
$sco = get_record("scorm_scoes","id",$sco_user->scoid);
break;
} else {
if ($_GET["mode"] == "review") {
$sco = get_record("scorm_scoes","id",$sco_user->scoid);
break;
}
}
}
}
if (!$sco)
$sco = get_record_select("scorm_scoes","scorm=".$scorm->id." AND launch<>'' order by id ASC");
} else {
if ($scoes = get_records("scorm_scoes","scorm",$scorm->id,"id ASC")) {
foreach ($scoes as $sco) {
if ($sco->launch != "") {
if (!$first)
$first = $sco;
$sco_user->userid = $USER->id;
$sco_user->scoid = $sco->id;
$sco_user->scormid = $scorm->id;
$element = "cmi_core_lesson_status";
if ($sco->type == "sco")
$sco_user->$element = "not attempted";
else if ($sco->type == "sca")
$sco_user->$element = "completed";
$ident = insert_record("scorm_sco_users",$sco_user);
}
}
$sco = $first;
if ($_GET["scoid"])
$sco = get_record("scorm_scoes","id",$_GET["scoid"]);
}
}
//
// Get first, last, prev and next scoes
//
$scoes = get_records("scorm_scoes","scorm",$scorm->id,"id ASC");
foreach ($scoes as $fsco) {
if ($fsco->launch != "") {
if (!$min || ($min > $fsco->id))
$min = $fsco->id;
if (!$max || ($max < $fsco->id))
$max = $fsco->id;
if ((!$prevsco) || ($sco->id > $fsco->id)) {
$prevsco = $fsco->id;
}
if ((!$nextsco) && ($sco->id < $fsco->id)) {
$nextsco = $fsco->id;
}
}
}
if ($sco->id == $min)
$first = $sco;
if ($sco->id == $max)
$last = $sco;
// Get User data
$sco_user = get_record("scorm_sco_users","userid",$USER->id,"scoid",$sco->id);
if (scorm_external_link($sco->launch)) {
$result = $sco->launch;
} else {
if ($CFG->slasharguments) {
$result = "$CFG->wwwroot/file.php/$scorm->course/moddata/scorm$scorm->datadir/$sco->launch";
} else {
$result = "$CFG->wwwroot/file.php?file=/$scorm->course/moddata/scorm$scorm->datadir/$sco->launch";
}
}
include("api1_2.php");
?>

11
mod/scorm/version.php Executable file
View File

@ -0,0 +1,11 @@
<?PHP // $Id$
/////////////////////////////////////////////////////////////////////////////////
/// Code fragment to define the version of scorm
/// This fragment is called by moodle_needs_upgrading() and /admin/index.php
/////////////////////////////////////////////////////////////////////////////////
$module->version = 2004040900; // The (date) version of this module
$module->cron = 0; // How often should cron check this module (seconds)?
?>

184
mod/scorm/view.php Executable file
View File

@ -0,0 +1,184 @@
<?PHP // $Id$
/// This page prints a particular instance of scorm
/// (Replace scorm with the name of your module)
require_once("../../config.php");
require_once("lib.php");
optional_variable($id); // Course Module ID, or
optional_variable($a); // scorm ID
if ($id) {
if (! $cm = get_record("course_modules", "id", $id)) {
error("Course Module ID was incorrect");
}
if (! $course = get_record("course", "id", $cm->course)) {
error("Course is misconfigured");
}
if (! $scorm = get_record("scorm", "id", $cm->instance)) {
error("Course module is incorrect");
}
} else {
if (! $scorm = get_record("scorm", "id", $a)) {
error("Course module is incorrect");
}
if (! $course = get_record("course", "id", $scorm->course)) {
error("Course is misconfigured");
}
if (! $cm = get_coursemodule_from_instance("scorm", $scorm->id, $course->id)) {
error("Course Module ID was incorrect");
}
}
require_login($course->id);
$strscorms = get_string("modulenameplural", "scorm");
$strscorm = get_string("modulename", "scorm");
if ($course->category) {
$navigation = "<a target=\"{$CFG->framename}\" href=\"../../course/view.php?id=$course->id\">$course->shortname</a> ->
<a target=\"{$CFG->framename}\" href=\"index.php?id=$course->id\">$strscorms</a> ->";
} else {
$navigation = "<a target=\"{$CFG->framename}\" href=\"index.php?id=$course->id\">$strscorms</a> ->";
}
$pagetitle = strip_tags("$course->shortname: $scorm->name");
add_to_log($course->id, "scorm", "pre-view", "view.php?id=$cm->id", "$scorm->id");
//
// Checking if parsed scorm manifest
//
if ($scorm->launch == 0) {
$basedir = $CFG->dataroot."/".$course->id;
$scormdir = "/moddata/scorm";
$scorm->launch = scorm_parse($basedir,$scormdir.$scorm->datadir."/imsmanifest.xml",$scorm->id);
set_field("scorm","launch",$scorm->launch,"id",$scorm->id);
}
//
// Print the page header
//
if (!$cm->visible and !isteacher($course->id)) {
print_header($pagetitle, "$course->fullname", "$navigation $scorm->name", "", "", true,
update_module_button($cm->id, $course->id, $strscorm), navmenu($course, $cm));
notice(get_string("activityiscurrentlyhidden"));
} else {
print_header($pagetitle, "$course->fullname","$navigation <a target=\"{$CFG->framename}\" href=\"$ME?id=$cm->id\" title=\"$scorm->summary\">$scorm->name</a>",
"", "", true, update_module_button($cm->id, $course->id, $strscorm), navmenu($course, $cm));
if (isteacher($course->id)) {
if ($sco_users = get_records_select("scorm_sco_users", "scormid='$scorm->id' GROUP BY userid")) {
echo "<p align=right><a target=\"{$CFG->framename}\" href=\"report.php?id=$cm->id\">".get_string("viewallreports","scorm",count($sco_users))."</a></p>";
} else {
echo "<p align=right>".get_string("noreports","scorm")."</p>";
}
}
// Print the main part of the page
print_heading($scorm->name);
print_simple_box(text_to_html($scorm->summary), "CENTER");
if (isguest()) {
print_heading(get_string("guestsno", "scorm"));
print_footer($course);
exit;
}
echo "<br />";
print_simple_box_start("CENTER");
echo "<table>\n";
echo " <tr><th>".get_string("coursestruct","scorm")."</th></tr>\n";
echo " <tr><td nowrap>\n<ul compact style='list-style-type:none'>\n";
if ($scoes = get_records_select("scorm_scoes","scorm='$scorm->id' order by id ASC")){
$level=0;
$sublist=0;
$parents[$level]="/";
$incomplete=false;
foreach ($scoes as $sco) {
if ($parents[$level]!=$sco->parent) {
if ($level>0 && $parents[$level-1]==$sco->parent) {
echo " </ul>\n";
$level--;
} else {
echo " <ul id='".$sublist."'compact style='list-style-type:none;'>\n";
$level++;
$parents[$level]=$sco->parent;
}
}
echo " <li>\n";
$nextsco = next($scoes);
if (($nextsco !== false) && ($sco->parent != $nextsco->parent) && ($nextsco->parent != $parents[$level-1])) {
$sublist++;
echo " <img src=\"pix/minus.gif\" onClick='expandCollide(this,".$sublist.");'/>\n";
} else
echo " <img src=\"pix/spacer.gif\" />\n";
if ($sco->launch) {
if ($sco_user=get_record("scorm_sco_users","scoid",$sco->id,"userid",$USER->id)) {
if ( $sco_user->cmi_core_lesson_status == "")
$sco_user->cmi_core_lesson_status = "not attempted";
echo " <img src=\"pix/".scorm_remove_spaces($sco_user->cmi_core_lesson_status).".gif\" alt=\"".get_string(scorm_remove_spaces($sco_user->cmi_core_lesson_status),"scorm")."\" title=\"".get_string(scorm_remove_spaces($sco_user->cmi_core_lesson_status),"scorm")."\" />\n";
switch ($sco_user->cmi_core_lesson_status) {
case "not attempted":
case "incomplete":
case "browsed":
$incomplete = true;
}
} else {
echo " <img src=\"pix/notattempted.gif\" alt=\"".get_string("notattempted","scorm")."\" />";
$incomplete = true;
}
echo " &nbsp;<a href=\"javascript:playSCO(".$sco->id.")\">$sco->title</a>\n </li>\n";
} else {
echo " &nbsp;$sco->title\n </li>\n";
}
}
}
echo "</ul>\n</td></tr>\n";
echo "</table>\n";
print_simple_box_end();
echo "<form name=\"theform\" method=\"POST\" action=\"playscorm.php?id=$cm->id\">\n";
echo "<table align=\"CENTER\">\n<tr>\n<td align=\"center\">";
print_string("mode","scorm");
echo ": <input type=\"radio\" id=\"b\" name=\"mode\" value=\"browse\" /><label for=\"b\">".get_string("browse","scorm")."</label>\n";
if ($incomplete) {
echo "<input type=\"radio\" id=\"n\" name=\"mode\" value=\"normal\" checked /><label for=\"n\">".get_string("normal","scorm")."</label>\n";
} else {
echo "<input type=\"radio\" id=\"r\" name=\"mode\" value=\"review\" checked /><label for=\"r\">".get_string("review","scorm")."</label>\n";
}
echo "</td>\n</tr>\n<tr><td align=\"center\">";
echo '<input type="hidden" name="scoid" />
<input type="submit" value="'.get_string("entercourse","scorm").'" />';
echo "\n</td>\n</tr>\n</table>\n</form><br />";
?>
<script language="javascript">
<!--
function playSCO(scoid,status) {
document.theform.scoid.value = scoid;
document.theform.submit();
}
function expandCollide(which,list) {
var nn=document.ids?true:false
var w3c=document.getElementById?true:false
var beg=nn?"document.ids.":w3c?"document.getElementById(":"document.all.";
var mid=w3c?").style":".style";
if (eval(beg+list+mid+".display") != "none") {
which.src = "pix/plus.gif";
eval(beg+list+mid+".display='none';");
} else {
which.src = "pix/minus.gif";
eval(beg+list+mid+".display='block';");
}
}
-->
</script>
<?php
print_footer($course);
}
?>