From 98ca59f6e17dfec6eb17e908160b11ff5af6c07c Mon Sep 17 00:00:00 2001 From: moodler Date: Thu, 20 May 2004 17:06:19 +0000 Subject: [PATCH] Putting SCORM into maintree CVS, to make it easier to test. It's getting pretty useful now! --- mod/scorm/README.txt | 24 + mod/scorm/api1_2.php | 304 ++++++++++++ mod/scorm/cmi.php | 64 +++ mod/scorm/coursefiles.php | 855 +++++++++++++++++++++++++++++++++ mod/scorm/db/mysql.php | 18 + mod/scorm/db/mysql.sql | 55 +++ mod/scorm/db/postgres7.php | 12 + mod/scorm/db/postgres7.sql | 50 ++ mod/scorm/details.php | 118 +++++ mod/scorm/icon.gif | Bin 0 -> 403 bytes mod/scorm/index.php | 80 +++ mod/scorm/lib.php | 364 ++++++++++++++ mod/scorm/mod.html | 79 +++ mod/scorm/pix/browsed.gif | Bin 0 -> 105 bytes mod/scorm/pix/completed.gif | Bin 0 -> 190 bytes mod/scorm/pix/failed.gif | Bin 0 -> 190 bytes mod/scorm/pix/incomplete.gif | Bin 0 -> 597 bytes mod/scorm/pix/minus.gif | Bin 0 -> 73 bytes mod/scorm/pix/notattempted.gif | Bin 0 -> 85 bytes mod/scorm/pix/passed.gif | Bin 0 -> 190 bytes mod/scorm/pix/plus.gif | Bin 0 -> 77 bytes mod/scorm/pix/spacer.gif | Bin 0 -> 52 bytes mod/scorm/playscorm.php | 203 ++++++++ mod/scorm/report.php | 110 +++++ mod/scorm/scormAPI.php | 110 +++++ mod/scorm/version.php | 11 + mod/scorm/view.php | 184 +++++++ 27 files changed, 2641 insertions(+) create mode 100644 mod/scorm/README.txt create mode 100644 mod/scorm/api1_2.php create mode 100755 mod/scorm/cmi.php create mode 100755 mod/scorm/coursefiles.php create mode 100755 mod/scorm/db/mysql.php create mode 100755 mod/scorm/db/mysql.sql create mode 100755 mod/scorm/db/postgres7.php create mode 100755 mod/scorm/db/postgres7.sql create mode 100755 mod/scorm/details.php create mode 100755 mod/scorm/icon.gif create mode 100755 mod/scorm/index.php create mode 100755 mod/scorm/lib.php create mode 100755 mod/scorm/mod.html create mode 100755 mod/scorm/pix/browsed.gif create mode 100755 mod/scorm/pix/completed.gif create mode 100755 mod/scorm/pix/failed.gif create mode 100755 mod/scorm/pix/incomplete.gif create mode 100755 mod/scorm/pix/minus.gif create mode 100755 mod/scorm/pix/notattempted.gif create mode 100755 mod/scorm/pix/passed.gif create mode 100755 mod/scorm/pix/plus.gif create mode 100755 mod/scorm/pix/spacer.gif create mode 100755 mod/scorm/playscorm.php create mode 100755 mod/scorm/report.php create mode 100755 mod/scorm/scormAPI.php create mode 100755 mod/scorm/version.php create mode 100755 mod/scorm/view.php diff --git a/mod/scorm/README.txt b/mod/scorm/README.txt new file mode 100644 index 0000000000..585c253613 --- /dev/null +++ b/mod/scorm/README.txt @@ -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 diff --git a/mod/scorm/api1_2.php b/mod/scorm/api1_2.php new file mode 100644 index 0000000000..25231d1f8c --- /dev/null +++ b/mod/scorm/api1_2.php @@ -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 = "username ?>"; + cmi.core.student_name = "firstname." ".$USER->lastname ?>"; + cmi.core.lesson_location = "cmi_core_lesson_location ?>"; + cmi.core.credit = "credit"; + cmi.core.lesson_status = "cmi_core_lesson_status ?>"; + cmi.core.exit = "cmi_core_exit ?>"; + cmi.core.entry = "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 = "cmi_core_session_time ?>"; + cmi.core.total_time = "cmi_core_total_time ?>"; + cmi.core.lesson_mode = ""; + + cmi.core.score = new Object(); + cmi.core.score._children = "raw"; + cmi.core.score.raw = "cmi_core_score_raw ?>"; + cmi.suspend_data = "cmi_suspend_data ?>"; + cmi.launch_data = "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 = "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; + 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() { +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=""; +} + +function changeSco(direction) { + if (direction == "prev") + top.nav.document.navform.scoid.value=""; + else + top.nav.document.navform.scoid.value=""; + + //alert ("Prev: \nNext: \nNew SCO: "+top.nav.document.navform.scoid.value); + top.nav.document.navform.submit(); +} diff --git a/mod/scorm/cmi.php b/mod/scorm/cmi.php new file mode 100755 index 0000000000..32f08dedd8 --- /dev/null +++ b/mod/scorm/cmi.php @@ -0,0 +1,64 @@ +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="\n"; */ + } +?> + + + cmi + + +
?id=id ?>"> + + + + + + + + +
+ + + diff --git a/mod/scorm/coursefiles.php b/mod/scorm/coursefiles.php new file mode 100755 index 0000000000..0414315835 --- /dev/null +++ b/mod/scorm/coursefiles.php @@ -0,0 +1,855 @@ +id); + + if (! isteacher($course->id) ) { + error("Only teachers can edit files"); + } + + function html_footer() { + echo ""; + } + + 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 .= "id&wdir=$link\">".$dirs[$i].""; + } + $fullnav = "id&wdir=/\">$strfiles $navigation"; + } + + print_header(); + ?> + + '; + echo ''; + echo ''; + echo ''."$course->shortname -> $fullnav".''; + echo ''; + echo ''; + echo ''; + + if ($course->id == $site->id) { + print_heading(get_string("publicsitefileswarning"), "center", 2); + } + + echo ""; + echo ""; + echo "\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 ""; + echo "
"; + } + + 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 "

$struploadafile ($strmaxsize) --> $wdir"; + echo "
"; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo " "; + echo ""; + echo ""; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + } + html_footer(); + break; + + case "delete": + if (!empty($confirm)) { + html_header($course, $wdir); + foreach ($USER->filelist as $file) { + $fullfile = $basedir.$file; + if (! fulldelete($fullfile)) { + echo "
Error: Could not delete: $fullfile"; + } + } + clearfilelist(); + displaydir($wdir); + html_footer(); + + } else { + html_header($course, $wdir); + if (setfilelist($_POST)) { + echo "

".get_string("deletecheckwarning").":

"; + print_simple_box_start("center"); + printfilelist($USER->filelist); + print_simple_box_end(); + echo "
"; + 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 "

"; + print_string("selectednowmove", "moodle", $count); + echo "

"; + } + 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 "

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 "

$strrenamefileto:"; + echo "
"; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + } + 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 "

$strcreatefolder:"; + echo "
"; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + } + 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", "", "$file"); + $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 "
"; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + print_textarea($usehtmleditor, 25, 80, 680, 400, "text", $contents); + echo "
"; + echo " "; + echo ""; + echo ""; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + + 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 "

".get_string("youareabouttocreatezip").":

"; + print_simple_box_start("center"); + printfilelist($USER->filelist); + print_simple_box_end(); + echo "
"; + echo "

".get_string("whattocallzip"); + echo "
"; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + } 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 "

$strunpacking:

"; + + $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 ""; + echo ""; + echo ""; + echo ""; + echo ""; + foreach ($list as $item) { + echo ""; + $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 ""; + } + $filedate = userdate($item['mtime'], get_string("strftimedatetime")); + print_cell("right", $filedate); + print_cell("right", $item['status']); + echo ""; + } + echo "
$strname$strsize$strmodified$strstatus
 
"; + } + + } else { // Use external unzip program + print_simple_box_start("center"); + echo "
";
+                    $command = "cd $basedir/$wdir ; $CFG->unzip -o $file 2>&1";
+                    passthru($command);
+                    echo "
"; + print_simple_box_end(); + } + + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + } 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 "

$strlistfiles:

"; + $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 ""; + echo ""; + foreach ($list as $item) { + echo ""; + print_cell("left", $item['filename']); + if (! $item['folder']) { + print_cell("right", display_size($item['size'])); + } else { + echo ""; + } + $filedate = userdate($item['mtime'], get_string("strftimedatetime")); + print_cell("right", $filedate); + echo ""; + } + echo "
$strname$strsize$strmodified
 
"; + } + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + } 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 "pixpath/f/folder.gif\" height=16 width=16> $file
"; + $subfilelist = array(); + $currdir = opendir($basedir.$file); + while ($subfile = readdir($currdir)) { + if ($subfile <> ".." && $subfile <> ".") { + $subfilelist[] = $file."/".$subfile; + } + } + printfilelist($subfilelist); + + } else { + $icon = mimeinfo("icon", $file); + echo "pixpath/f/$icon\" height=16 width=16> $file
"; + } + } +} + + +function print_cell($alignment="center", $text=" ") { + echo "
"; + echo ""; + echo "$text"; + echo ""; + echo "
"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "\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 ""; + + print_cell("center", ""); + print_cell("left", "pixpath/f/folder.gif\" HEIGHT=16 WIDTH=16 BORDER=0 ALT=\"Folder\">".htmlspecialchars($dir).""); + print_cell("right", "-"); + print_cell("right", $filedate); + print_cell("right", "$strrename"); + + echo ""; + } + } + + + 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 ""; + + print_cell("center", ""); + + echo ""; + + $file_size = filesize($filename); + print_cell("right", display_size($file_size)); + print_cell("right", $filedate); + + $edittext = "$strchoose "; + + if ($icon == "text.gif" || $icon == "html.gif") { + $edittext .= "$stredit"; + } else if ($icon == "zip.gif") { + $edittext .= "$strunzip "; + $edittext .= "$strlist "; + } + + print_cell("right", "$edittext $strrename"); + + echo ""; + } + } + echo "
$strname$strsize$strmodified$straction
"; + link_to_popup_window ($ffurl, "display", + "pixpath/f/$icon\" height=16 width=16 border=0 alt=\"file\">", + 480, 640); + echo ""; + link_to_popup_window ($ffurl, "display", htmlspecialchars($file), 480, 640); + echo "
"; + echo "
"; + + if (empty($wdir)) { + $wdir = "/"; + } + + echo ""; + echo ""; + echo ""; + echo "
"; + echo ""; + echo " "; + $options = array ( + "move" => "$strmovetoanotherfolder", + "delete" => "$strdeletecompletely", + "zip" => "$strcreateziparchive" + ); + if (!empty($count)) { + choose_from_menu ($options, "action", "", "$strwithchosenfiles...", "javascript:document.dirform.submit()"); + } + + echo ""; + echo ""; + if (!empty($USER->fileop) and ($USER->fileop == "move") and ($USER->filesource <> $wdir)) { + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + } + echo "
"; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + echo "
"; + echo " "; + echo " "; + echo " "; + echo " "; + echo "
"; + echo "
"; + echo "
"; + +} + +?> diff --git a/mod/scorm/db/mysql.php b/mod/scorm/db/mysql.php new file mode 100755 index 0000000000..d9ae381bb2 --- /dev/null +++ b/mod/scorm/db/mysql.php @@ -0,0 +1,18 @@ +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; +} + + +?> + diff --git a/mod/scorm/db/mysql.sql b/mod/scorm/db/mysql.sql new file mode 100755 index 0000000000..58b2046730 --- /dev/null +++ b/mod/scorm/db/mysql.sql @@ -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'); \ No newline at end of file diff --git a/mod/scorm/db/postgres7.php b/mod/scorm/db/postgres7.php new file mode 100755 index 0000000000..0183dddee0 --- /dev/null +++ b/mod/scorm/db/postgres7.php @@ -0,0 +1,12 @@ + + diff --git a/mod/scorm/db/postgres7.sql b/mod/scorm/db/postgres7.sql new file mode 100755 index 0000000000..930b7a76b8 --- /dev/null +++ b/mod/scorm/db/postgres7.sql @@ -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'); diff --git a/mod/scorm/details.php b/mod/scorm/details.php new file mode 100755 index 0000000000..d9547d22e9 --- /dev/null +++ b/mod/scorm/details.php @@ -0,0 +1,118 @@ +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", + "wwwroot/course/view.php?id=$course->id\">$course->shortname -> $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 "\n"; + echo " \n"; + echo " \n"; + if (($form->mode == "update") && ($form->launch == 0) && (get_records("scorm_sco_user","scormid",$form->instance))) + echo " \n"; + echo "

$strname:

$form->name

".get_string("validation","scorm").":

".get_string($result,"scorm")."

".get_string("trackingloose","scorm")."

\n"; + if ($result == "regular") { + echo "
destination\">\n"; +?> + + + + + + + + + + + + + +
+ "> + "> +
+
+ +
+ " onClick="document.location='wwwroot ?>/course/view.php?id=id ?>';"> +
+ diff --git a/mod/scorm/icon.gif b/mod/scorm/icon.gif new file mode 100755 index 0000000000000000000000000000000000000000..2729187eb76a42b57c5fa07f07686826931cfe47 GIT binary patch literal 403 zcmV;E0c`$9Nk%w1VGsZi0M!5h|NsBf!?B=tJLTNesf=f>hgXMUIhJlY;=7G{S2vz^ zI?bqg>co}Ex~FzlHrlm^d{{T1bv=7oInJ__fnPWJ`ShA_HSXu#f@w~ic0%XCl6X}% z;nBX9gmB5LiJNdZdsj8~^X$>BhnsXfaZW6GRWf*0HJo!j{Qdd<|NnDQF?LZgw3&T& zR5O=zJ8Vxfo^w0<`uTKGFZ}!abX7S1{{Qv#^8Ww+`1kbx{{Gv~z;IGDdtO29=;QOt zo94rrA^8LV00000EC2ui01yBW000KCz+CMHC;}>j0nP|W87sX3XCe|!0=i2G6}n74 z2!w{A(S&~w4~D>c_!#6d1F+t|K12ghL06PMtt49C; literal 0 HcmV?d00001 diff --git a/mod/scorm/index.php b/mod/scorm/index.php new file mode 100755 index 0000000000..1505879be8 --- /dev/null +++ b/mod/scorm/index.php @@ -0,0 +1,80 @@ +category) { + require_login($course->id); + $navigation = "id\">$course->shortname ->"; + } + + 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 = "".userdate($scorm->timemodified); + } + if (!$scorm->visible) { + //Show dimmed if the mod is hidden + $table->data[] = array ($tt, "coursemodule\">$scorm->name", + text_to_html($scorm->summary) ); + } else { + //Show normal if the mod is visible + $table->data[] = array ($tt, "coursemodule\">$scorm->name", + text_to_html($scorm->summary) ); + } + } + + echo "
"; + + print_table($table); + + print_footer($course); + + +?> + diff --git a/mod/scorm/lib.php b/mod/scorm/lib.php new file mode 100755 index 0000000000..142326bcf8 --- /dev/null +++ b/mod/scorm/lib.php @@ -0,0 +1,364 @@ +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.="wwwroot/mod/scorm/pix/completed.gif\" alt=\"".get_string("completed","scorm")."\" title=\"".get_string("completed","scorm")."\"> $scores->completed "; + if ($scores->incomplete) + $result.="wwwroot/mod/scorm/pix/incomplete.gif\" alt=\"".get_string("incomplete","scorm")."\" title=\"".get_string("incomplete","scorm")."\"> $scores->incomplete "; + if ($scores->failed) + $result.="wwwroot/mod/scorm/pix/failed.gif\" alt=\"".get_string("failed","scorm")."\" title=\"".get_string("failed","scorm")."\"> $scores->failed "; + if ($scores->browsed) + $result.="wwwroot/mod/scorm/pix/browsed.gif\" alt=\"".get_string("browsed","scorm")."\" title=\"".get_string("browsed","scorm")."\"> $scores->browsed "; + if ($scores->notattempted) + $result.="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$len ) { + return "".substr($stringa,0,$len-4)."...".substr($stringa,strlen($stringa)-1,1).""; + } 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; +} +?> diff --git a/mod/scorm/mod.html b/mod/scorm/mod.html new file mode 100755 index 0000000000..521a97be9e --- /dev/null +++ b/mod/scorm/mod.html @@ -0,0 +1,79 @@ +name)) { + $form->name = ""; + } + if (empty($form->summary)) { + $form->summary = ""; + } + if (empty($form->alltext)) { + $form->alltext = ""; + } +?> + + +
+ + + + + + + + + + + + + + + + + + +

:

+ +
+

:

+
+ reference\"> "; + button_to_popup_window ("/mod/scorm/coursefiles.php?id=$course->id", + "coursefiles", $strchooseafile, 500, 750, $strchooseafile); + ?> +

:

+ + "; + helpbutton("writing", get_string("helpwriting"), "moodle", true, true); + echo "
"; + helpbutton("text", get_string("helptext"), "moodle", true, true); + ?> +
+
+
+ +

:

+ auto); + ?> +
+ + + + + + + + + + +
+ "> +
+
\ No newline at end of file diff --git a/mod/scorm/pix/browsed.gif b/mod/scorm/pix/browsed.gif new file mode 100755 index 0000000000000000000000000000000000000000..f0607e8250b53f0857e0e27fbb9ba2a4fdb13df5 GIT binary patch literal 105 zcmZ?wbhEHb6krfwn8?8J|Nnm=!2o6`{$yblVPIy^0dj$|0t^gHR&)ASW*^|XW36yP zd6U>xt|P8V4ovcDZYh;g3wKpLkT{(YKD&7DtB_gQym50EeYm>%N6eNhMJHZn`mi!s F0{{-PCy4+6 literal 0 HcmV?d00001 diff --git a/mod/scorm/pix/completed.gif b/mod/scorm/pix/completed.gif new file mode 100755 index 0000000000000000000000000000000000000000..7c60c3ff3e44bd843e0dd3265dcf9876bcaafa7d GIT binary patch literal 190 zcmZ?wbhEHb6krfw*v!E2|Ns9p|IYxy%>OfIo|&0;CM|7dn(-N9irL@_WZ{$yblVc=!Z0dYWPFtB7#nBqBWFR#EN?nM#89?=Gp!40016F6C;A}19J zXsvz2v-yq9G1UbNG6Gl`9V#M4^3)y+ZMHZuuZ!AzxA1$Q)EJZfnQg(=W(i4FHswMA!fT literal 0 HcmV?d00001 diff --git a/mod/scorm/pix/failed.gif b/mod/scorm/pix/failed.gif new file mode 100755 index 0000000000000000000000000000000000000000..aea7dedabcdabd82a57238022ceed0f97578d6e2 GIT binary patch literal 190 zcmZ?wbhEHb6krfw*v!E29|+Ez`9E{!|FpFK#>W2{7|t*-%w%9lV_-0500E#pn1&LH zKUr8s7`Pd9KzxuH3@q6JJdD%!nssbwlb2!hIP^^L-n7~{femYqa7{0{(^h!Db5Ts= z;f4T(1sV(o-Y=4n;$E;sXmWv6^vS169KTtXi8W4mAhf_Hp|?O`u5Nr=#_!1-{4JMK d9>m1om{6(0QO4d7l$y`PVQbgR)g#DY4FK1ELYM#m literal 0 HcmV?d00001 diff --git a/mod/scorm/pix/incomplete.gif b/mod/scorm/pix/incomplete.gif new file mode 100755 index 0000000000000000000000000000000000000000..1f4661e2b0c3a0d3aefa4ce66a0955e7c29c54a3 GIT binary patch literal 597 zcmb7>+e^~{97n&!yq5OM%rv~s%hGM;)RxzplWjVjrn#w8w@jTNw$X^FhY0hxrA85? zP?C|EQ>R6y*fd?6B9;gtB?Os);1>0i7(q{;@=xfzoTu}23YChi?DGsUsy%c%0ap!-gH}gIKp=eF&fWu-1c*_weB^R=e=tik0hFzJlee zcy}3ZFJZ}yrHfc>#X>XYo8Z#JRgX71IBVdng;R^UYRpz*t_rgn%&PJFEN03ua|Y9; zm@a{%7!DO)DKS-uDFvqFm@L4g6qEUwkl^R1R7!_cY4|_7~$1swJ z;RFoF!4?BsG;C2AjKshZ41}RS1dkbqiKb07+Dvu>jTmUCiENGZw1N8T>5-oL^z=|i zy>;}UmU^^wM?<&O)KO0DrDT*+i-hWPs4kN#(n%>Kc{1@MC@hHf`%$1T`TNj60PN~N z;r`+Hgp!GbyWQ>+@|$QgwX+uM&5q8lu04T4p&^{k3kF?X*?o0mi_vIlh=~zq=A6n+ z4D)YgeYFA}PmnK@oj$>9VwtMc)aaCyJcUY?rDqRTq$M29$dM|GOXM}|fl84mN>uQr z=xZ4pP|J^xPy3c8k!4r2bdI|nz7u&^EY?|?V`JmOgM)oV%x3#OuK19wt;qbueS=9V kXydLa+}2R0d_2p%cQN9YarIhnx@WmNNwe@QfJ3=|0bK(A?EnA( literal 0 HcmV?d00001 diff --git a/mod/scorm/pix/minus.gif b/mod/scorm/pix/minus.gif new file mode 100755 index 0000000000000000000000000000000000000000..e37cf32d17855e8a2ec8967f0e27fc12c51f64fd GIT binary patch literal 73 zcmZ?wbhEHb?4(!cWb+x(_EA&VF` i-Fx_szl5DFD=B1FoYcCPniJMXA1d-~E;}mDU=09UdmR)2 literal 0 HcmV?d00001 diff --git a/mod/scorm/pix/passed.gif b/mod/scorm/pix/passed.gif new file mode 100755 index 0000000000000000000000000000000000000000..7c60c3ff3e44bd843e0dd3265dcf9876bcaafa7d GIT binary patch literal 190 zcmZ?wbhEHb6krfw*v!E2|Ns9p|IYxy%>OfIo|&0;CM|7dn(-N9irL@_WZ{$yblVc=!Z0dYWPFtB7#nBqBWFR#EN?nM#89?=Gp!40016F6C;A}19J zXsvz2v-yq9G1UbNG6Gl`9V#M4^3)y+ZMHZuuZ!AzxA1$Q)EJZfnQg(=W(i4FHswMA!fT literal 0 HcmV?d00001 diff --git a/mod/scorm/pix/plus.gif b/mod/scorm/pix/plus.gif new file mode 100755 index 0000000000000000000000000000000000000000..bb5f2627d0ea71af26daebcaa26e6e526d55dec9 GIT binary patch literal 77 zcmZ?wbhEHb5{)%wuA(1^}mm B5FY>l literal 0 HcmV?d00001 diff --git a/mod/scorm/playscorm.php b/mod/scorm/playscorm.php new file mode 100755 index 0000000000..4d5edecb0c --- /dev/null +++ b/mod/scorm/playscorm.php @@ -0,0 +1,203 @@ +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 = "framename}\" href=\"../../course/view.php?id=$course->id\">$course->shortname -> + framename}\" href=\"index.php?id=$course->id\">$strscorms ->"; + } else { + $navigation = "framename}\" href=\"index.php?id=$course->id\">$strscorms ->"; + } + + $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 framename}\" href=\"view.php?id=$cm->id\" title=\"$scorm->summary\">$scorm->name", + "", "", true, update_module_button($cm->id, $course->id, $strscorm), navmenu($course, $cm)); + + echo "
".text_to_html($scorm->summary, true, false)."
\n"; + echo "\n\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 = "\n$meta\n"; + echo "\n\n"; + echo $meta; + echo "Navigator\n"; + echo "\n"; + //echo "\n"; + echo "\nbody."\" leftmargin=\"0\">\n"; + echo "\n"; + if ($_GET["mode"] == "browse") + echo " "; + echo " \n"; + echo "
".get_string("browsemode","scorm")."
+ +
id\" target=\"_top\"> + + +   + +
+
\n"; + echo "\n"; + echo "
    \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 "
\n"; + $level--; + } else { + echo "
    \n"; + $level++; + $parents[$level]=$sco->parent; + } + } + echo "
  • "; + $nextsco = next($scoes); + if (($nextsco !== false) && ($sco->parent != $nextsco->parent) && ($nextsco->parent != $parents[$level-1])) { + $sublist++; + echo ""; + } else + echo ""; + 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 "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 "\"".get_string("notattempted","scorm")."\""; + $incomplete = true; + } + echo " id.")\">$sco->title
  • \n"; + } else { + echo " $sco->title\n"; + } + } + + for ($i=0;$i<$level;$i++){ + echo "
\n"; + } + } + echo "

\n"; + echo "\n"; + echo "\n\n"; + break; + default: + // + // Frameset + // + if ($_POST["scoid"]) + $scoid = "&scoid=".$_POST["scoid"]; + echo "\n"; + echo "$course->shortname: $scorm->name\n"; + echo "\n"; + echo "\n"; + echo " id&mode=".$_POST["mode"]."&frameset=top\">\n"; + echo " \n"; + echo " id&mode=".$_POST["mode"]."&frameset=left\">\n"; + echo " \n"; + echo " \n"; + echo "\n"; + echo "\n"; + break; + } +?> diff --git a/mod/scorm/report.php b/mod/scorm/report.php new file mode 100755 index 0000000000..c757c40554 --- /dev/null +++ b/mod/scorm/report.php @@ -0,0 +1,110 @@ +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 = "id\">$course->shortname ->"; + } + + $strscorms = get_string("modulenameplural", "scorm"); + $strscorm = get_string("modulename", "scorm"); + $strreport = get_string("report", "scorm"); + + print_header("$course->shortname: $scorm->name", "$course->fullname", + "$navigation id>$strscorms + -> id\">$scorm->name -> $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(" ", $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[] = "wwwroot/user/view.php?id=$data->userid&course=$course->id\">". + "$data->firstname $data->lastname"; + foreach ($user_data as $data) { + $row[]="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")."\"> " + .$data->cmi_core_total_time; + } + } + $table->data[] = $row; + } + + print_table($table); + + } else { + notice("No users to report"); + } + } + if (empty($noheader)) { + print_footer($course); + } + + +?> diff --git a/mod/scorm/scormAPI.php b/mod/scorm/scormAPI.php new file mode 100755 index 0000000000..2681c22152 --- /dev/null +++ b/mod/scorm/scormAPI.php @@ -0,0 +1,110 @@ +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"); +?> diff --git a/mod/scorm/version.php b/mod/scorm/version.php new file mode 100755 index 0000000000..e3ee06f79d --- /dev/null +++ b/mod/scorm/version.php @@ -0,0 +1,11 @@ +version = 2004040900; // The (date) version of this module +$module->cron = 0; // How often should cron check this module (seconds)? + +?> diff --git a/mod/scorm/view.php b/mod/scorm/view.php new file mode 100755 index 0000000000..c1cca74995 --- /dev/null +++ b/mod/scorm/view.php @@ -0,0 +1,184 @@ +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 = "framename}\" href=\"../../course/view.php?id=$course->id\">$course->shortname -> + framename}\" href=\"index.php?id=$course->id\">$strscorms ->"; + } else { + $navigation = "framename}\" href=\"index.php?id=$course->id\">$strscorms ->"; + } + + $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 framename}\" href=\"$ME?id=$cm->id\" title=\"$scorm->summary\">$scorm->name", + "", "", 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 "

framename}\" href=\"report.php?id=$cm->id\">".get_string("viewallreports","scorm",count($sco_users))."

"; + } else { + echo "

".get_string("noreports","scorm")."

"; + } + } + // 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 "
"; + print_simple_box_start("CENTER"); + echo "\n"; + echo " \n"; + echo " \n"; + echo "
".get_string("coursestruct","scorm")."
\n
    \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 "
\n"; + $level--; + } else { + echo "
    \n"; + $level++; + $parents[$level]=$sco->parent; + } + } + echo "
  • \n"; + $nextsco = next($scoes); + if (($nextsco !== false) && ($sco->parent != $nextsco->parent) && ($nextsco->parent != $parents[$level-1])) { + $sublist++; + echo " \n"; + } else + echo " \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 " 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 " \"".get_string("notattempted","scorm")."\""; + $incomplete = true; + } + echo "  id.")\">$sco->title\n
  • \n"; + } else { + echo "  $sco->title\n \n"; + } + } + } + echo "
\n
\n"; + print_simple_box_end(); + echo "
id\">\n"; + echo "\n\n\n\n\n\n
"; + print_string("mode","scorm"); + echo ": \n"; + if ($incomplete) { + echo "\n"; + } else { + echo "\n"; + } + echo "
"; + echo ' + '; + echo "\n
\n

"; +?> + + -- 2.39.5