SCORM MDL-22951 New player for SCORM fixes major regression that prevents some SCORM...
authorDan Marsden <Dan@digitalclay.co.nz>
Thu, 22 Jul 2010 00:48:06 +0000 (00:48 +0000)
committerDan Marsden <Dan@digitalclay.co.nz>
Thu, 22 Jul 2010 00:48:06 +0000 (00:48 +0000)
mod/scorm/api.php [new file with mode: 0644]
mod/scorm/datamodels/aicclib.php
mod/scorm/datamodels/scorm_12.js.php
mod/scorm/datamodels/scorm_12lib.php
mod/scorm/datamodels/scorm_13lib.php
mod/scorm/lang/en/scorm.php
mod/scorm/locallib.php
mod/scorm/module.js [new file with mode: 0644]
mod/scorm/player.php
mod/scorm/prereqs.php [new file with mode: 0644]
mod/scorm/styles.css

diff --git a/mod/scorm/api.php b/mod/scorm/api.php
new file mode 100644 (file)
index 0000000..87eedf6
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+
+    require_once("../../config.php");
+    require_once('locallib.php');
+
+    $id = optional_param('id', '', PARAM_INT);       // Course Module ID, or
+    $a = optional_param('a', '', PARAM_INT);         // scorm ID
+    $scoid = required_param('scoid', PARAM_INT);     // sco ID
+    $mode = optional_param('mode', '', PARAM_ALPHA); // navigation mode
+    $attempt = required_param('attempt', PARAM_INT); // new attempt
+
+    //IE 6 Bug workaround
+    if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6') !== false && ini_get('zlib.output_compression') == 'On') {
+        ini_set('zlib.output_compression', 'Off');
+    }
+
+    if (!empty($id)) {
+        if (! $cm = get_coursemodule_from_id('scorm', $id)) {
+            print_error('invalidcoursemodule');
+        }
+        if (! $course = $DB->get_record('course', array('id'=>$cm->course))) {
+            print_error('coursemisconf');
+        }
+        if (! $scorm = $DB->get_record('scorm', array('id'=>$cm->instance))) {
+            print_error('invalidcoursemodule');
+        }
+    } else if (!empty($a)) {
+        if (! $scorm = $DB->get_record('scorm', array('id'=>$a))) {
+            print_error('coursemisconf');
+        }
+        if (! $course = $DB->get_record('course', array('id'=>$scorm->course))) {
+            print_error('coursemisconf');
+        }
+        if (! $cm = get_coursemodule_from_instance('scorm', $scorm->id, $course->id)) {
+            print_error('invalidcoursemodule');
+        }
+    } else {
+        print_error('missingparameter');
+    }
+
+    $PAGE->set_url('/mod/scorm/api.php', array('scoid'=>$scoid, 'id'=>$cm->id));
+
+    require_login($course->id, false, $cm);
+
+    if ($usertrack = scorm_get_tracks($scoid,$USER->id,$attempt)) {
+        if ((isset($usertrack->{'cmi.exit'}) && ($usertrack->{'cmi.exit'} != 'time-out')) || ($scorm->version != "SCORM_1.3")) {
+            foreach ($usertrack as $key => $value) {
+                $userdata->$key = addslashes_js($value);
+            }
+        } else {
+            $userdata->status = '';
+            $userdata->score_raw = '';
+        }
+    } else {
+        $userdata->status = '';
+        $userdata->score_raw = '';
+    }
+    $userdata->student_id = addslashes_js($USER->username);
+    $userdata->student_name = addslashes_js($USER->lastname .', '. $USER->firstname);
+    $userdata->mode = 'normal';
+    if (isset($mode)) {
+        $userdata->mode = $mode;
+    }
+    if ($userdata->mode == 'normal') {
+        $userdata->credit = 'credit';
+    } else {
+        $userdata->credit = 'no-credit';
+    }
+    if ($scodatas = scorm_get_sco($scoid, SCO_DATA)) {
+        foreach ($scodatas as $key => $value) {
+            $userdata->$key = addslashes_js($value);
+        }
+    } else {
+        error('Sco not found');
+    }
+    if (!$sco = scorm_get_sco($scoid)) {
+        error('Sco not found');
+    }
+    $scorm->version = strtolower(clean_param($scorm->version, PARAM_SAFEDIR));   // Just to be safe
+    if (file_exists($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'.js.php')) {
+        include_once($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'.js.php');
+    } else {
+        include_once($CFG->dirroot.'/mod/scorm/datamodels/scorm_12.js.php');
+    }
+    // set the start time of this SCO
+    scorm_insert_track($USER->id,$scorm->id,$scoid,$attempt,'x.start.time',time());
+?>
+
+
+var errorCode = "0";
+function underscore(str) {
+    str = String(str).replace(/.N/g,".");
+    return str.replace(/\./g,"__");
+}
index c8a8ba0..1f8e02f 100644 (file)
@@ -340,7 +340,10 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
     }
 
     $result = new stdClass();
-    $result->toc = "<ul id='s0' class='$liststyle'>\n";
+    //$result->toc = "<ul id='s0' class='$liststyle'>\n";
+    $result->toc = '<div id="scorm_layout">';
+    $result->toc .= '<div id="scorm_toc">';
+    $result->toc .= '<div id="scorm_tree"><ul>';
     $tocmenus = array();
     $result->prerequisites = true;
     $incomplete = false;
@@ -350,7 +353,12 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
     //
     if (!empty($currentorg)) {
         if (($organizationtitle = $DB->get_field('scorm_scoes','title', array('scorm'=>$scorm->id,'identifier'=>$currentorg))) != '') {
-            $result->toc .= "\t<li>$organizationtitle</li>\n";
+            if ($play) {
+                $result->toctitle = "$organizationtitle";
+            }
+            else {
+                $result->toc .= "\t<li>$organizationtitle</li>\n";
+            }
             $tocmenus[] = $organizationtitle;
         }
     }
@@ -411,7 +419,8 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
                         if (isset($_COOKIE['hide:SCORMitem'.$sco->id])) {
                             $style = ' style="display: none;"';
                         }
-                        $result->toc .= "\t\t<li><ul id='s$sublist' class='$liststyle'$style>\n";
+                        //$result->toc .= "\t\t<li><ul id='s$sublist' class='$liststyle'$style>\n";
+                        $result->toc .= "\t\t<ul>\n";
                         $level++;
                     } else {
                         $result->toc .= $closelist;
@@ -438,9 +447,9 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
                 if (isset($_COOKIE['hide:SCORMitem'.$nextsco->id])) {
                     $icon = 'plus';
                 }
-                $result->toc .= '<a href="javascript:expandCollide(\'img'.$sublist.'\',\'s'.$sublist.'\','.$nextsco->id.');"><img id="img'.$sublist.'" src="'.$OUTPUT->pix_url($icon, 'scorm').'" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>';
+                //$result->toc .= '<a href="javascript:expandCollide(\'img'.$sublist.'\',\'s'.$sublist.'\','.$nextsco->id.');"><img id="img'.$sublist.'" src="'.$OUTPUT->pix_url($icon, 'scorm').'" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>';
             } else if ($isvisible) {
-                $result->toc .= '<img src="'.$OUTPUT->pix_url('spacer', 'scorm').'" alt="" />';
+                //$result->toc .= '<img src="'.$OUTPUT->pix_url('spacer', 'scorm').'" alt="" />';
             }
             if (empty($sco->title)) {
                 $sco->title = $sco->identifier;
@@ -504,7 +513,10 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
                             $result->prerequisites = true;
                         }
                         $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid='.$sco->id;
-                        $result->toc .= $statusicon.'&nbsp;'.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."</li>\n";
+                        $thisscoidstr = '&scoid='.$sco->id;
+                        $link = $CFG->wwwroot.'/mod/scorm/loadSCO.php?a='.$scorm->id.$thisscoidstr.$modestr;
+                        //$result->toc .= $statusicon.'&nbsp;'.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."</li>\n";
+                        $result->toc .= '<a title="'.$link.'">'.$statusicon.'&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>';
                         $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);
                     } else {
                         if ($sco->id == $scoid) {
@@ -536,7 +548,14 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
             $result->incomplete = $incomplete;
         }
     }
-    $result->toc .= "\t</ul>\n";
+    //$result->toc .= "\t</ul>\n";
+
+    // NEW IMS TOC
+    $result->toc .= '</ul></div></div>';
+    $result->toc .= '</div>';
+    $result->toc .= '<div id="scorm_navpanel"></div>';
+
+
     if ($scorm->hidetoc == 0) {
         $result->toc .= html_writer::script(js_writer::set_variable('scormdata', array(
                 'plusicon' => $OUTPUT->pix_url('plus', 'scorm'),
index 2fa6505..37c35e0 100644 (file)
@@ -12,6 +12,9 @@
             }
         }
     }
+    if (!isset($currentorg)) {
+        $currentorg = '';
+    }
 ?>
 //
 // SCORM 1.2 API Implementation
@@ -181,12 +184,70 @@ function SCORMapi1_2() {
         return "false";
     }
 
+
+    this.connectPrereqCallback = {
+
+        success: function(o) {
+            scorm_tree_node = YAHOO.widget.TreeView.getTree('scorm_tree');
+            if (o.responseText !== undefined) {
+                if (scorm_tree_node && o.responseText) {
+                    var hnode = scorm_tree_node.getHighlightedNode();
+                    var hidx = null;
+                    if (hnode) {
+                        hidx = hnode.index + scorm_tree_node.getNodeCount();
+                    }
+                    // all gone
+                    var root_node = scorm_tree_node.getRoot();
+                        scorm_tree_node.removeNode(root_node.children[0]);
+                    }
+                    // make sure the temporary tree element is not there
+                    var el_old_tree = document.getElementById('scormtree123');
+                    if (el_old_tree) {
+                        el_old_tree.parentNode.removeChild(el_old_tree);
+                    }
+                    var el_new_tree = document.createElement('div');
+                    var pagecontent = document.getElementById("page-content");
+                    el_new_tree.setAttribute('id','scormtree123');
+                    el_new_tree.innerHTML = o.responseText;
+                    // make sure it doesnt show
+                    el_new_tree.style.display = 'none';
+                    pagecontent.appendChild(el_new_tree)
+                    // ignore the first level element as this is the title
+                    scorm_tree_node.buildTreeFromMarkup(el_new_tree.firstChild.firstChild);
+                    var el = document.getElementById('scormtree123');
+                    el.parentNode.removeChild(el);
+                    scorm_tree_node.expandAll();
+                    scorm_tree_node.render();
+                    if (hidx != null) {
+                        hnode = scorm_tree_node.getNodeByIndex(hidx);
+                        if (hnode) {
+                            hnode.highlight();
+                            hnode.focus();
+                        }
+                    }
+                }
+        },
+
+        failure: function(o) {
+            // do some sort of error handling
+            var sURL = "<?php echo $CFG->wwwroot; ?>" + "/mod/scorm/prereqs.php?a=<?php echo $scorm->id ?>&scoid=<?php echo $scoid ?>&attempt=<?php echo $attempt ?>&mode=<?php echo $mode ?>&currentorg=<?php echo $currentorg ?>&sesskey=<?php echo sesskey(); ?>";
+            alert('Prerequisites update failed - must restart SCORM player');
+            window.location.href = sURL;
+        }
+
+    };
+
+
     function LMSFinish (param) {
         errorCode = "0";
         if (param == "") {
             if (Initialized) {
                 Initialized = false;
                 result = StoreData(cmi,true);
+                // trigger TOC update
+                //alert('trigger TOC update');
+                var sURL = "<?php echo $CFG->wwwroot; ?>" + "/mod/scorm/prereqs.php?a=<?php echo $scorm->id ?>&scoid=<?php echo $scoid ?>&attempt=<?php echo $attempt ?>&mode=<?php echo $mode ?>&currentorg=<?php echo $currentorg ?>&sesskey=<?php echo sesskey(); ?>";
+                YAHOO.util.Connect.asyncRequest('GET', sURL, this.connectPrereqCallback, null);
                 if (nav.event != '') {
                     if (nav.event == 'continue') {
                         setTimeout('top.document.location=top.next;',500);
@@ -607,7 +668,8 @@ function SCORMapi1_2() {
         datastring += '&scoid=<?php echo $scoid ?>';
 
         var myRequest = NewHttpReq();
-        result = DoRequest(myRequest,"<?php p($CFG->wwwroot) ?>/mod/scorm/datamodel.php","id=<?php p($id) ?>&sesskey=<?php echo sesskey() ?>"+datastring);
+        //alert('going to:' + "<?php p($CFG->wwwroot) ?>/mod/scorm/datamodel.php" + "id=<?php p($id) ?>&a=<?php p($a) ?>&sesskey=<?php echo sesskey() ?>"+datastring);
+        result = DoRequest(myRequest,"<?php p($CFG->wwwroot) ?>/mod/scorm/datamodel.php","id=<?php p($id) ?>&a=<?php p($a) ?>&sesskey=<?php echo sesskey() ?>"+datastring);
         results = String(result).split('\n');
         errorCode = results[1];
         return results[0];
index fed9155..526114a 100644 (file)
@@ -106,7 +106,7 @@ function scorm_eval_prerequisites($prerequisites, $usertracks) {
     return eval('return '.implode($stack).';');
 }
 
-function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false) {
+function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false, $tocheader=true) {
     global $CFG, $DB, $PAGE, $OUTPUT;
 
     $strexpand = get_string('expcoll','scorm');
@@ -116,7 +116,13 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
     }
 
     $result = new stdClass();
-    $result->toc = "<ul id='s0' class='$liststyle'>\n";
+    //$result->toc = "<ul id='s0' class='$liststyle'>\n";
+    if ($tocheader) {
+        $result->toc = '<div id="scorm_layout">';
+        $result->toc .= '<div id="scorm_toc">';
+        $result->toc .= '<div id="scorm_tree">';
+    }
+    $result->toc .= '<ul>';
     $tocmenus = array();
     $result->prerequisites = true;
     $incomplete = false;
@@ -126,10 +132,16 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
     //
     if (!empty($currentorg)) {
         if (($organizationtitle = $DB->get_field('scorm_scoes','title', array('scorm'=>$scorm->id,'identifier'=>$currentorg))) != '') {
-            $result->toc .= "\t<li>$organizationtitle</li>\n";
+            if ($play) {
+                $result->toctitle = "$organizationtitle";
+            }
+            else {
+                $result->toc .= "\t<li>$organizationtitle</li>\n";
+            }
             $tocmenus[] = $organizationtitle;
         }
     }
+
     //
     // If not specified retrieve the last attempt number
     //
@@ -170,14 +182,14 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
             if ($parents[$level] != $sco->parent) {
                 if ($newlevel = array_search($sco->parent,$parents)) {
                     for ($i=0; $i<($level-$newlevel); $i++) {
-                        $result->toc .= "\t\t</ul></li>\n";
+                        $result->toc .= "\t\t</li></ul></li>\n";
                     }
                     $level = $newlevel;
                 } else {
                     $i = $level;
                     $closelist = '';
                     while (($i > 0) && ($parents[$level] != $sco->parent)) {
-                        $closelist .= "\t\t</ul></li>\n";
+                        $closelist .= "\t\t</li></ul></li>\n";
                         $i--;
                     }
                     if (($i == 0) && ($sco->parent != $currentorg)) {
@@ -185,7 +197,11 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
                         if (isset($_COOKIE['hide:SCORMitem'.$sco->id])) {
                             $style = ' style="display: none;"';
                         }
-                        $result->toc .= "\t\t<li><ul id='s$sublist' class='$liststyle'$style>\n";
+                        //$result->toc .= "\t\t<li><ul id='s$sublist' class='$liststyle'$style>\n";
+                        $result->toc .= "\t\t<ul>\n";
+
+
+
                         $level++;
                     } else {
                         $result->toc .= $closelist;
@@ -195,7 +211,7 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
                 }
             }
             if ($isvisible) {
-                $result->toc .= "\t\t<li>";
+                $result->toc .= "<li>";
             }
             if (isset($scoes[$pos+1])) {
                 $nextsco = $scoes[$pos+1];
@@ -212,9 +228,9 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
                 if (isset($_COOKIE['hide:SCORMitem'.$nextsco->id])) {
                     $icon = 'plus';
                 }
-                $result->toc .= '<a href="javascript:expandCollide(\'img'.$sublist.'\',\'s'.$sublist.'\','.$nextsco->id.');"><img id="img'.$sublist.'" src="'.$OUTPUT->pix_url($icon, 'scorm').'" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>';
+                //$result->toc .= '<a href="javascript:expandCollide(\'img'.$sublist.'\',\'s'.$sublist.'\','.$nextsco->id.');"><img id="img'.$sublist.'" src="'.$OUTPUT->pix_url($icon, 'scorm').'" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>';
             } else if ($isvisible) {
-                $result->toc .= '<img src="'.$OUTPUT->pix_url('spacer', 'scorm').'" alt="" />';
+                //$result->toc .= '<img src="'.$OUTPUT->pix_url('spacer', 'scorm').'" alt="" />';
             }
             if (empty($sco->title)) {
                 $sco->title = $sco->identifier;
@@ -279,18 +295,38 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
                         if ($sco->id == $scoid) {
                             $result->prerequisites = true;
                         }
-                        $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid='.$sco->id;
-                        $result->toc .= $statusicon.'&nbsp;'.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."</li>\n";
+                       // $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid='.$sco->id;
+                        $thisscoidstr = '&scoid='.$sco->id;
+                        //$link = $CFG->wwwroot.'/mod/scorm/loadSCO.php?a='.$scorm->id.$thisscoidstr.$modestr;
+                        $link = 'a='.$scorm->id.$thisscoidstr.'&currentorg='.$currentorg.$modestr.'&attempt='.$attempt;
+
+                        //$result->toc .= $statusicon.'&nbsp;'.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."\n";
+                        //$result->toc .= $startbold.'<a title="'.$link.'">'.$statusicon.'&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>'.$endbold."\n";
+                        if ($sco->launch) {
+                            $result->toc .= '<a title="'.$link.'">'.$statusicon.'&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>';
+                        }
+                        else {
+                            $result->toc .= '<span>'.$statusicon.'&nbsp;'.format_string($sco->title).'</span>';
+                        }
                         $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);
                     } else {
                         if ($sco->id == $scoid) {
                             $result->prerequisites = false;
                         }
-                        $result->toc .= $statusicon.'&nbsp;'.format_string($sco->title)."</li>\n";
+                        if ($play) {
+                            // should be disabled
+                            $result->toc .= '<span>'.$statusicon.'&nbsp;'.format_string($sco->title).'</span>';
+                        }
+                        else {
+                            $result->toc .= $statusicon.'&nbsp;'.format_string($sco->title)."\n";
+                        }
+                    }
+                    if (($nextsco === false) || $nextsco->parent == $sco->parent) {
+                    $result->toc .= '</li>';
                     }
                 }
             } else {
-                $result->toc .= '&nbsp;'.format_string($sco->title)."</li>\n";
+                $result->toc .= '&nbsp;'.format_string($sco->title)."\n";
             }
             if (($nextsco !== false) && ($nextid == 0) && ($findnext)) {
                 if (!empty($nextsco->launch)) {
@@ -315,7 +351,16 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
             $result->incomplete = $incomplete;
         }
     }
-    $result->toc .= "\t</ul>\n";
+    $result->toc .= '</ul>';
+
+    // NEW IMS TOC
+    if ($tocheader) {
+        $result->toc .= '</div></div></div>';
+        $result->toc .= '<div id="scorm_navpanel"></div>';
+    }
+
+
+
     if ($scorm->hidetoc == 0) {
         $PAGE->requires->data_for_js('scormdata', array(
                 'plusicon' => $OUTPUT->pix_url('plus', 'scorm'),
index 52dc9c2..9b4e883 100644 (file)
@@ -10,7 +10,9 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
     }
 
     $result = new stdClass();
-    $result->toc = "<ul id='s0' class='$liststyle'>\n";
+    $result->toc = '<div id="scorm_layout">';
+    $result->toc .= '<div id="scorm_toc">';
+    $result->toc .= '<div id="scorm_tree"><ul>';
     $tocmenus = array();
     $result->prerequisites = true;
     $incomplete = false;
@@ -20,7 +22,12 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
     //
     if (!empty($currentorg)) {
         if (($organizationtitle = $DB->get_field('scorm_scoes', 'title', array('scorm'=>$scorm->id,'identifier'=>$currentorg))) != '') {
-            $result->toc .= "\t<li>$organizationtitle</li>\n";
+            if ($play) {
+            $result->toctitle = "$organizationtitle";
+            }
+            else {
+                $result->toc .= "\t<li>$organizationtitle</li>\n";
+            }
             $tocmenus[] = $organizationtitle;
         }
     }
@@ -78,7 +85,8 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
                         if (isset($_COOKIE['hide:SCORMitem'.$sco->id])) {
                             $style = ' style="display: none;"';
                         }
-                        $result->toc .= "\t\t<li><ul id='s$sublist' class='$liststyle'$style>\n";
+                        //$result->toc .= "\t\t<li><ul id='s$sublist' class='$liststyle'$style>\n";
+                        $result->toc .= "\t\t><ul>\n";
                         $level++;
                     } else {
                         $result->toc .= $closelist;
@@ -103,10 +111,10 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
                 if (isset($_COOKIE['hide:SCORMitem'.$nextsco->id])) {
                     $icon = 'plus';
                 }
-                $result->toc .= "\t\t".'<li><a href="javascript:expandCollide(\'img'.$sublist.'\',\'s'.$sublist.'\','.$nextsco->id.');">'.
-                                '<img id="img'.$sublist.'" src="'.$OUTPUT->pix_url($icon, 'scorm').'" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>';
+//                $result->toc .= "\t\t".'<li><a href="javascript:expandCollide(\'img'.$sublist.'\',\'s'.$sublist.'\','.$nextsco->id.');">'.
+//                                '<img id="img'.$sublist.'" src="'.$OUTPUT->pix_url($icon, 'scorm').'" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>';
             } else if ($isvisible) {
-                $result->toc .= "\t\t".'<li><img src="'.$OUTPUT->pix_url('spacer', 'scorm').'" alt="" />';
+//                $result->toc .= "\t\t".'<li><img src="'.$OUTPUT->pix_url('spacer', 'scorm').'" alt="" />';
             }
             if (empty($sco->title)) {
                 $sco->title = $sco->identifier;
@@ -174,13 +182,16 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
                             $result->prerequisites = true;
                         }
                             $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid='.$sco->id;
-                            $result->toc .= $statusicon.'&nbsp;'.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."</li>\n";
+                            $thisscoidstr = '&scoid='.$sco->id;
+                            $link = $CFG->wwwroot.'/mod/scorm/loadSCO.php?a='.$scorm->id.$thisscoidstr.$modestr;
+                            //$result->toc .= $statusicon.'&nbsp;'.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."</li>\n";
+                            $result->toc .= '<li><a title="'.$link.'">'.$statusicon.'&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>'."</li>\n";
                             $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);
                     } else {
                         if ($sco->id == $scoid) {
                             $result->prerequisites = false;
                         }
-                        $result->toc .= '&nbsp;'.format_string($sco->title)."</li>\n";
+                        $result->toc .= $statusicon.'&nbsp;'.format_string($sco->title)."\n";
                     }
                 }
             } else {
@@ -206,7 +217,16 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n
             $result->incomplete = $incomplete;
         }
     }
-    $result->toc .= "\t</ul>\n";
+//    $result->toc .= "\t</ul>\n";
+
+
+    // NEW IMS TOC
+    $result->toc .= '</ul></div></div>';
+    $result->toc .= '</div>';
+    $result->toc .= '<div id="scorm_navpanel"></div>';
+
+
+
     if ($scorm->hidetoc == 0) {
         $PAGE->requires->data_for_js('scormdata', array(
                 'plusicon' => $OUTPUT->pix_url('plus', 'scorm'),
index 8699e51..6b76a72 100644 (file)
@@ -22,6 +22,8 @@
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
+$string['toc'] = 'TOC';
+$string['navigation'] = 'Navigation';
 
 $string['activation'] = 'Activation';
 $string['activityloading'] = 'You will be automatically redirected to the activity in';
index 51e9ea9..27812b1 100755 (executable)
@@ -530,7 +530,7 @@ function scorm_grade_user_attempt($scorm, $userid, $attempt=1, $time=false) {
             if (($userdata->status == 'completed') || ($userdata->status == 'passed')) {
                 $attemptscore->scoes++;
             }
-            if (!empty($userdata->score_raw) || ($scorm->type=='sco' && isset($userdata->score_raw))) {
+            if (!empty($userdata->score_raw) || (isset($scorm->type) && $scorm->type=='sco' && isset($userdata->score_raw))) {
                 $attemptscore->values++;
                 $attemptscore->sum += $userdata->score_raw;
                 $attemptscore->max = ($userdata->score_raw > $attemptscore->max)?$userdata->score_raw:$attemptscore->max;
diff --git a/mod/scorm/module.js b/mod/scorm/module.js
new file mode 100644 (file)
index 0000000..aa2e367
--- /dev/null
@@ -0,0 +1,412 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Javascript helper function for IMS Content Package module.
+ *
+ * @package   mod-scorm
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+M.mod_scorm = {};
+
+M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, window_options, window_width, window_height, launch_sco) {
+
+    var popup_winHandle = false;
+
+    if (hide_nav == 0) {
+        scorm_hide_nav = false;
+    }
+    else {
+        scorm_hide_nav = true;
+    }
+    if (hide_toc == 0) {
+        scorm_hide_toc = false;
+    }
+    else {
+        scorm_hide_toc = true;
+    }
+
+    var scorm_layout_widget;
+    var scorm_current_node;
+    var scorm_buttons = [];
+    var scorm_bloody_labelclick = false;
+    var scorm_panel;
+
+
+    Y.use('yui2-resize', 'yui2-dragdrop', 'yui2-container', 'yui2-button', 'yui2-layout', 'yui2-treeview', 'yui2-json', 'yui2-event', function(Y) {
+
+        var scorm_activate_item = function(node) {
+            if (!node) {
+                return;
+            }
+            scorm_current_node = node;
+            scorm_current_node.highlight();
+
+            // remove any reference to the old API
+            if (window.API) {
+                window.API = null;
+            }
+            if (window.API_1484_11) {
+                window.API_1484_11 = null;
+            }
+            var url_prefix = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?';
+            var el_old_api = document.getElementById('scormapi123');
+            if (el_old_api) {
+                el_old_api.parentNode.removeChild(el_old_api);
+            }
+
+            if (node.title) {
+               var el_scorm_api = document.getElementById("external-scormapi");
+               el_scorm_api.parentNode.removeChild(el_scorm_api);
+                el_scorm_api = document.createElement('script');
+                el_scorm_api.setAttribute('id','external-scormapi');
+                el_scorm_api.setAttribute('type','text/javascript');
+                var pel_scorm_api = document.getElementById('scormapi-parent');
+                pel_scorm_api.appendChild(el_scorm_api);
+                var api_url = M.cfg.wwwroot + '/mod/scorm/api.php?' + node.title;
+                document.getElementById('external-scormapi').src = api_url;
+            }
+
+            // make the popup work
+            if (window_name) {
+                popup_winHandle = window.open('', window_name, window_options, window_width, window_height);
+                popup_winHandle.location.href =  url_prefix + node.title;
+                popup_winHandle.resizeTo(window_width, window_height);
+            }
+         
+            var content = new YAHOO.util.Element('scorm_content');
+            try {
+                // first try IE way - it can not set name attribute later
+                // and also it has some restrictions on DOM access from object tag
+                if (window_name || node.title == null) {
+                    var obj = document.createElement('<iframe id="scorm_object" src="">');
+                }
+                else {
+                    var obj = document.createElement('<iframe id="scorm_object" src="'+url_prefix + node.title+'">');
+                }
+            } catch (e) {
+                var obj = document.createElement('object');
+                obj.setAttribute('id', 'scorm_object');
+                obj.setAttribute('type', 'text/html');
+                if (!window_name && node.title != null) {
+                    obj.setAttribute('data', url_prefix + node.title);
+                }
+            }
+            var old = YAHOO.util.Dom.get('scorm_object');
+            if (old) {
+                content.replaceChild(obj, old);
+            } else {
+                content.appendChild(obj);
+            }
+          
+            scorm_resize_frame();
+
+            scorm_current_node.focus();
+            if (scorm_hide_nav == false) {
+                scorm_fixnav();
+            }
+        };
+
+        /**
+         * Enables/disables navigation buttons as needed.
+         * @return void
+         */
+        var scorm_fixnav = function() {
+            scorm_buttons[0].set('disabled', (scorm_skipprev(scorm_current_node) == null));
+            scorm_buttons[1].set('disabled', (scorm_prev(scorm_current_node) == null));
+            scorm_buttons[2].set('disabled', (scorm_up(scorm_current_node) == null));
+            scorm_buttons[3].set('disabled', (scorm_next(scorm_current_node) == null));
+            scorm_buttons[4].set('disabled', (scorm_skipnext(scorm_current_node) == null));
+        };
+
+
+        var scorm_resize_layout = function(alsowidth) {
+            if (window_name) {
+                //scorm_layout_widget.setStyle('width', '260px');
+                //scorm_layout_widget.render();
+                return;
+            }
+
+            if (alsowidth) {
+                //var layout = YAHOO.util.Dom.get('scorm_layout');
+                //layout.style.width = '600px';
+                scorm_layout_widget.setStyle('width', '');
+                var newwidth = scorm_get_htmlelement_size('content', 'width');
+                if (newwidth > 600) {
+                    //layout.style.width = newwidth+'px';
+                    scorm_layout_widget.setStyle('width', newwidth+'px');
+                }
+            }
+            // make sure that the max width of the TOC doesn't go to far
+            var left = scorm_layout_widget.getUnitByPosition('left');
+            var maxwidth = parseInt(YAHOO.util.Dom.getStyle('scorm_layout', 'width'));
+            left.set('maxWidth', (maxwidth - 10));
+            var cwidth = left.get('width');
+            if (cwidth > (maxwidth - 10)) {
+                left.set('width', (maxwidth - 10));
+            }
+
+            var pageheight = scorm_get_htmlelement_size('page', 'height');
+            var layoutheight = scorm_get_htmlelement_size(scorm_layout_widget, 'height');
+            var newheight = layoutheight + parseInt(YAHOO.util.Dom.getViewportHeight()) - pageheight - 20;
+            if (newheight > 400) {
+                if (newheight > 768) {
+                    scorm_layout_widget.setStyle('height', '768px');
+                }
+                else {
+                    scorm_layout_widget.setStyle('height', newheight+'px');
+                }
+            }
+
+            scorm_layout_widget.render();
+            scorm_resize_frame();
+
+            scorm_panel.align('bl', 'bl');
+        };
+
+        var scorm_get_htmlelement_size = function(el, prop) {
+            var val = YAHOO.util.Dom.getStyle(el, prop);
+            if (val == 'auto') {
+                if (el.get) {
+                    el = el.get('element'); // get real HTMLElement from YUI element
+                }
+                val = YAHOO.util.Dom.getComputedStyle(YAHOO.util.Dom.get(el), prop);
+            }
+            return parseInt(val);
+        };
+
+        var scorm_resize_frame = function() {
+            var obj = YAHOO.util.Dom.get('scorm_object');
+            if (obj) {
+                var content = scorm_layout_widget.getUnitByPosition('center').get('wrap');
+                // basically trap IE6 and 7
+                if (YAHOO.env.ua.ie > 5 && YAHOO.env.ua.ie < 8) {
+                    if( obj.style.setAttribute ) {
+                        obj.style.setAttribute("cssText", 'width: ' +(content.offsetWidth - 6)+'px; height: ' + (content.offsetHeight - 10)+'px;');
+                    }
+                    else {
+                        obj.style.setAttribute('width', (content.offsetWidth - 6)+'px', 0);
+                        obj.style.setAttribute('height', (content.offsetHeight - 10)+'px', 0);
+                    }
+                }
+                else {
+                    obj.style.width = (content.offsetWidth - 6)+'px';
+                    obj.style.height = (content.offsetHeight - 10)+'px';
+                }
+            }
+        };
+
+
+        var scorm_up = function(node) {
+            var node = scorm_tree_node.getHighlightedNode();
+            if (node.depth > 0) {
+                return node.parent;
+            }
+            return null;
+        };
+
+        var scorm_lastchild = function(node) {
+            if (node.children.length) {
+                return scorm_lastchild(node.children[node.children.length-1]);
+            } else {
+                return node;
+            }
+        };
+
+        var scorm_prev = function(node) {
+            if (node.previousSibling && node.previousSibling.children.length) {
+                return scorm_lastchild(node.previousSibling);
+            }
+            return scorm_skipprev(node);
+        };
+
+        var scorm_skipprev = function(node) {
+            /*
+            if (node == scorm_tree_node.getRoot().children[0]) {
+                return null;
+            }
+            else {
+                return scorm_tree_node.getRoot().children[0];
+            }
+            */
+            if (node.previousSibling) {
+                return node.previousSibling;
+            } else if (node.depth > 0) {
+                return node.parent;
+            }
+            return null;
+        };
+
+        var scorm_next = function(node) {
+            if (node === false) {
+                return scorm_tree_node.getRoot().children[0];
+            }
+            if (node.children.length) {
+                return node.children[0];
+            }
+            return scorm_skipnext(node);
+        };
+
+        var scorm_skipnext = function(node) {
+            /*
+            var toc_children = scorm_tree_node.getRoot().children;
+            if (node == toc_children[toc_children.length - 1]) {
+                return null;
+            }
+            else {
+                return toc_children[toc_children.length - 1];
+            }
+            */
+            if (node.nextSibling) {
+                return node.nextSibling;
+            } else if (node.depth > 0) {
+                return scorm_skipnext(node.parent);
+            }
+            return null;
+        };
+
+
+        // layout
+        YAHOO.widget.LayoutUnit.prototype.STR_COLLAPSE = M.str.moodle.hide;
+        YAHOO.widget.LayoutUnit.prototype.STR_EXPAND = M.str.moodle.show;
+
+/*
+        scorm_layout_widget = new YAHOO.widget.Layout('scorm_layout', {
+            minWidth: 600,
+            minHeight: 400,
+            units: [
+                { position: 'left', body: 'scorm_toc', header: M.str.scorm.toc, width: 250, resize: true, gutter: '2px 5px 5px 2px', collapse: true, minWidth:150},
+                { position: 'center', body: '<div id="scorm_content"></div>', gutter: '2px 5px 5px 2px', scroll: true}
+            ]
+        });
+        */
+        scorm_layout_widget = new YAHOO.widget.Layout('scorm_layout', {
+            minWidth: 255,
+            minHeight: 400,
+            units: [
+                { position: 'left', body: 'scorm_toc', header: toc_title, width: 250, resize: true, gutter: '2px 5px 5px 2px', collapse: true, minWidth:250, maxWidth: 590},
+                { position: 'center', body: '<div id="scorm_content"></div>', gutter: '2px 5px 5px 2px', scroll: true}
+            ]
+        });
+        scorm_layout_widget.render();
+        var left = scorm_layout_widget.getUnitByPosition('left');
+        left.on('collapse', function() {
+            scorm_resize_frame();
+        });
+        left.on('expand', function() {
+            scorm_resize_frame();
+        });
+
+        // ugly resizing hack that works around problems with resizing of iframes and objects
+        left._resize.on('startResize', function() {
+            var obj = YAHOO.util.Dom.get('scorm_object');
+            obj.style.display = 'none';
+        });
+        left._resize.on('endResize', function() {
+            var obj = YAHOO.util.Dom.get('scorm_object');
+            obj.style.display = 'block';
+            scorm_resize_frame();
+        });
+
+        // hide the TOC if that is the default
+        if (scorm_hide_toc == true) {
+            left.collapse();
+        }
+
+        // TOC tree
+        var tree = new YAHOO.widget.TreeView('scorm_tree');
+        scorm_tree_node = tree;
+        tree.singleNodeHighlight = true;
+        tree.subscribe('labelClick', function(node) {
+            scorm_activate_item(node);
+            if (node.children.length) {
+                scorm_bloody_labelclick = true;
+            }
+        });
+        tree.subscribe('collapse', function(node) {
+            if (scorm_bloody_labelclick) {
+                scorm_bloody_labelclick = false;
+                return false;
+            }
+        });
+        tree.subscribe('expand', function(node) {
+            if (scorm_bloody_labelclick) {
+                scorm_bloody_labelclick = false;
+                return false;
+            }
+        });
+        tree.expandAll();
+        tree.render();
+
+        // navigation
+        if (scorm_hide_nav == false) {
+            //scorm_panel = new YAHOO.widget.Panel('scorm_navpanel', { visible:true, draggable:true, close:false,
+            //                                                       context: ['page', 'bl', 'bl', ["windowScroll", "textResize", "windowResize"]], constraintoviewport:true} );
+            scorm_panel = new YAHOO.widget.Panel('scorm_navpanel', { visible:true, draggable:true, close:false, xy: [250, 450],
+                                                                    autofillheight: "body"} );
+            scorm_panel.setHeader(M.str.scorm.navigation);
+    
+            //TODO: make some better&accessible buttons
+            scorm_panel.setBody('<span id="scorm_nav"><button id="nav_skipprev">&lt;&lt;</button><button id="nav_prev">&lt;</button><button id="nav_up">^</button><button id="nav_next">&gt;</button><button id="nav_skipnext">&gt;&gt;</button></span>');
+            scorm_panel.render();
+            scorm_buttons[0] = new YAHOO.widget.Button('nav_skipprev');
+            scorm_buttons[1] = new YAHOO.widget.Button('nav_prev');
+            scorm_buttons[2] = new YAHOO.widget.Button('nav_up');
+            scorm_buttons[3] = new YAHOO.widget.Button('nav_next');
+            scorm_buttons[4] = new YAHOO.widget.Button('nav_skipnext');
+            scorm_buttons[0].on('click', function(ev) {
+                scorm_activate_item(scorm_skipprev(scorm_tree_node.getHighlightedNode()));
+            });
+            scorm_buttons[1].on('click', function(ev) {
+                scorm_activate_item(scorm_prev(scorm_tree_node.getHighlightedNode()));
+            });
+            scorm_buttons[2].on('click', function(ev) {
+                scorm_activate_item(scorm_up(scorm_tree_node.getHighlightedNode()));
+            });
+            scorm_buttons[3].on('click', function(ev) {
+                scorm_activate_item(scorm_next(scorm_tree_node.getHighlightedNode()));
+            });
+            scorm_buttons[4].on('click', function(ev) {
+                scorm_activate_item(scorm_skipnext(scorm_tree_node.getHighlightedNode()));
+            });
+            scorm_panel.render();
+        }
+
+        // finally activate the chosen item
+        var scorm_first_url = tree.getRoot().children[0];
+        var nxt = false;
+        while (nxt = scorm_next(nxt)) {
+            if (nxt.title) {
+                expression = new RegExp('^.*?scoid=' + launch_sco + '.*?$');
+                matches = nxt.title.match(expression);
+                if (matches != null) {
+                    scorm_first_url = nxt;
+                    break;
+                }
+            }
+        }
+        scorm_activate_item(scorm_first_url);
+
+        // resizing
+        scorm_resize_layout(false);
+
+        // fix layout if window resized
+        window.onresize = function() {
+            scorm_resize_layout(true);
+        };
+    });
+};
index 2d1096a..4313740 100755 (executable)
     $PAGE->requires->data_for_js('scormplayerdata', Array('cwidth'=>$scorm->width,'cheight'=>$scorm->height), true);
     $PAGE->requires->js('/mod/scorm/request.js', true);
     $PAGE->requires->js('/lib/cookies.js', true);
-    $PAGE->requires->js('/mod/scorm/loaddatamodel.php?id='.$cm->id.$scoidstr.$modestr.$attemptstr, true);
-    $PAGE->requires->js('/mod/scorm/rd.js', true);
+    //$PAGE->requires->js('/mod/scorm/loaddatamodel.php?id='.$cm->id.$scoidstr.$modestr.$attemptstr, true);
+    $PAGE->requires->css('/mod/scorm/styles.css');
 
     echo $OUTPUT->header();
 
-    $PAGE->requires->js_function_call('attach_resize_event');
-    if (($sco->previd != 0) && ((!isset($sco->previous)) || ($sco->previous == 0))) {
-        $scostr = '&scoid='.$sco->previd;
-        $PAGE->requires->js_function_call('scorm_set_prev', Array($CFG->wwwroot.'/mod/scorm/player.php?cm='.$cm->id.$orgstr.$modepop.$scostr));
-    } else {
-        $PAGE->requires->js_function_call('scorm_set_prev', Array($CFG->wwwroot.'/mod/scorm/view.php?id='.$cm->id));
-    }
-    if (($sco->nextid != 0) && ((!isset($sco->next)) || ($sco->next == 0))) {
-        $scostr = '&scoid='.$sco->nextid;
-        $PAGE->requires->js_function_call('scorm_set_next', Array($CFG->wwwroot.'/mod/scorm/player.php?cm='.$cm->id.$orgstr.$modepop.$scostr));
-    } else {
-        $PAGE->requires->js_function_call('scorm_set_next', Array($CFG->wwwroot.'/mod/scorm/view.php?id='.$cm->id));
-    }
+    // NEW IMS TOC
+    $PAGE->requires->string_for_js('navigation', 'scorm');
+    $PAGE->requires->string_for_js('toc', 'scorm');
+    $PAGE->requires->string_for_js('hide', 'moodle');
+    $PAGE->requires->string_for_js('show', 'moodle');
+
+    $name = false;
+
 ?>
     <div id="scormpage">
+    
+      <div id="tocbox">
+        <div id='scormapi-parent'>
+            <script id="external-scormapi" type="text/JavaScript"></script>
+        </div>
+        <div id="scormtop">
 <?php
-    if ($scorm->hidetoc == 0) {
-?>
-        <div id="tocbox">
-<?php
-        if ($scorm->hidenav ==0){
-?>
-            <!-- Bottons nav at left-->
-            <div id="tochead">
-                <form name="tochead" method="post" action="player.php?cm=<?php echo $cm->id ?>" target="_top">
-<?php
-            $orgstr = '&amp;currentorg='.$currentorg;
-            if (($scorm->hidenav == 0) && ($sco->previd != 0) && (!isset($sco->previous) || $sco->previous == 0)) {
-                // Print the prev LO button
-                $scostr = '&amp;scoid='.$sco->previd;
-                $url = $CFG->wwwroot.'/mod/scorm/player.php?cm='.$cm->id.$orgstr.$modestr.$scostr;
-?>
-                    <input name="prev" type="button" value="<?php print_string('prev','scorm') ?>" onClick="document.location.href=' <?php echo $url; ?> '"/>
-<?php
-            }
-            if (($scorm->hidenav == 0) && ($sco->nextid != 0) && (!isset($sco->next) || $sco->next == 0)) {
-                // Print the next LO button
-                $scostr = '&amp;scoid='.$sco->nextid;
-                $url = $CFG->wwwroot.'/mod/scorm/player.php?cm='.$cm->id.$orgstr.$modestr.$scostr;
-?>
-                    <input name="next" type="button" value="<?php print_string('next','scorm') ?>" onClick="document.location.href=' <?php echo $url; ?> '"/>
-<?php
-            }
-?>
-                </form>
-            </div> <!-- tochead -->
-<?php
+    if ($result->prerequisites) {
+        if ($scorm->popup != 0) {
+            $linkcourse = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$scorm->course.'">' . get_string('finishscormlinkname','scorm') . '</a>';
+            echo $OUTPUT->box(get_string('finishscorm','scorm',$linkcourse), 'generalbox', 'altfinishlink');
         }
-?>
-            <div id="toctree" class="generalbox">
-            <?php echo $result->toc; ?>
-            </div> <!-- toctree -->
-        </div> <!--  tocbox -->
-<?php
-        $class = ' class="toc"';
-    } else {
-        $class = ' class="no-toc"';
     }
 ?>
-        <div id="scormbox"<?php echo $class; if(($scorm->hidetoc == 2) || ($scorm->hidetoc == 1)){echo 'style="width:100%"';}?>>
-<?php
-    // This very big test check if is necessary the "scormtop" div
-    if (
-           ($mode != 'normal') ||  // We are not in normal mode so review or browse text will displayed
-           (
-               ($scorm->hidenav == 0) &&  // Teacher want to display navigation links
-               ($scorm->hidetoc != 0) &&  // The buttons has not been displayed
-               (
-                   (
-                       ($sco->previd != 0) &&  // This is not the first learning object of the package
-                       ((!isset($sco->previous)) || ($sco->previous == 0))   // Moodle must manage the previous link
-                   ) ||
-                   (
-                       ($sco->nextid != 0) &&  // This is not the last learning object of the package
-                       ((!isset($sco->next)) || ($sco->next == 0))       // Moodle must manage the next link
-                   )
-               )
-           ) || ($scorm->hidetoc == 2)      // Teacher want to display toc in a small dropdown menu
-       ) {
-?>
-            <div id="scormtop">
         <?php echo $mode == 'browse' ? '<div id="scormmode" class="scorm-left">'.get_string('browsemode','scorm')."</div>\n" : ''; ?>
         <?php echo $mode == 'review' ? '<div id="scormmode" class="scorm-left">'.get_string('reviewmode','scorm')."</div>\n" : ''; ?>
+            <div id="scormnav" class="scorm-right">
 <?php
-        if (($scorm->hidenav == 0) || ($scorm->hidetoc == 2) || ($scorm->hidetoc == 1)) {
-?>
-                <div id="scormnav" class="scorm-right">
-        <?php
-            $orgstr = '&amp;currentorg='.$currentorg;
-            if (($scorm->hidenav == 0) && ($sco->previd != 0) && (!isset($sco->previous) || $sco->previous == 0) && (($scorm->hidetoc == 2) || ($scorm->hidetoc == 1)) ) {
-                // Print the prev LO button
-                $scostr = '&amp;scoid='.$sco->previd;
-                $url = $CFG->wwwroot.'/mod/scorm/player.php?cm='.$cm->id.$orgstr.$modestr.$scostr;
-?>
-                    <form name="scormnavprev" method="post" action="player.php?cm=<?php echo $cm->id ?>" target="_top" style= "display:inline">
-                        <input name="prev" type="button" value="<?php print_string('prev','scorm') ?>" onClick="document.location.href=' <?php echo $url; ?> '"/>
-                    </form>
-<?php
-            }
-            if ($scorm->hidetoc == 2) {
-                echo $result->tocmenu;
-            }
-            if (($scorm->hidenav == 0) && ($sco->nextid != 0) && (!isset($sco->next) || $sco->next == 0) && (($scorm->hidetoc == 2) || ($scorm->hidetoc == 1))) {
-                // Print the next LO button
-                $scostr = '&amp;scoid='.$sco->nextid;
-                $url = $CFG->wwwroot.'/mod/scorm/player.php?cm='.$cm->id.$orgstr.$modestr.$scostr;
-?>
-                    <form name="scormnavnext" method="post" action="player.php?cm=<?php echo $cm->id ?>" target="_top" style= "display:inline">
-                        <input name="next" type="button" value="<?php print_string('next','scorm') ?>" onClick="document.location.href=' <?php echo $url; ?> '"/>
-                    </form>
-<?php
-            }
-        ?>
-                </div>
-<?php
+        if ($scorm->hidetoc == 2) {
+             echo $result->tocmenu;
         }
 ?>
-            </div> <!-- Scormtop -->
-<?php
-    } // The end of the very big test
-?>
-            <div id="scormobject" class="scorm-right">
+            </div> <!-- Scormnav -->
+        </div> <!-- Scormtop -->
+            <div id="toctree" class="generalbox">
+            <?php echo $result->toc; ?>
+            </div> <!-- toctree -->
+        </div> <!--  tocbox -->
                 <noscript>
                     <div id="noscript">
                         <?php print_string('noscriptnoscorm','scorm'); // No Martin(i), No Party ;-) ?>
 <?php
     if ($result->prerequisites) {
         if ($scorm->popup == 0) {
-            $fullurl="loadSCO.php?id=".$cm->id.$scoidstr.$modestr;
-            ?>
-            <!--[if IE]>
-                <iframe id="scoframe1" class="scoframe" name="scoframe1" src="<?php echo $fullurl; ?>"></iframe>
-            <![endif]-->
-            <![if !IE]>
-                <object id="scoframe1" class="scoframe" type="text/html" data="<?php echo $fullurl; ?>"></object>
-            <![endif]>
-
-<?php
             if (scorm_debugging($scorm)) {
 ?>
                 <script>
                 </script>
 <?php
             }
-            $PAGE->requires->js_function_call('scorm_resize');
         } else {
             // Clean the name for the window as IE is fussy
             $name = preg_replace("/[^A-Za-z0-9]/", "", $scorm->name);
             }
             $name = 'scorm_'.$name;
 
-            echo html_writer::script(js_writer::function_call('scorm_resize'));
             echo html_writer::script('', $CFG->wwwroot.'/mod/scorm/player.js');
             echo html_writer::script(js_writer::function_call('scorm_openpopup', Array("loadSCO.php?id=".$cm->id.$scoidpop, $name, $scorm->options, $scorm->width, $scorm->height)));
             ?>
             //Added incase javascript popups are blocked
             $link = '<a href="'.$CFG->wwwroot.'/mod/scorm/loadSCO.php?id='.$cm->id.$scoidstr.$modestr.'" target="_blank">'.get_string('popupblockedlinkname','scorm').'</a>';
             echo $OUTPUT->box(get_string('popupblocked','scorm',$link), 'generalbox', 'altpopuplink');
-            $linkcourse = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$scorm->course.'">' . get_string('finishscormlinkname','scorm') . '</a>';
-            echo $OUTPUT->box(get_string('finishscorm','scorm',$linkcourse), 'generalbox', 'altfinishlink');
+            //$linkcourse = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$scorm->course.'">' . get_string('finishscormlinkname','scorm') . '</a>';
+            //echo $OUTPUT->box(get_string('finishscorm','scorm',$linkcourse), 'generalbox', 'altfinishlink');
         }
     } else {
         echo $OUTPUT->box(get_string('noprerequisites','scorm'));
     }
 ?>
-            </div> <!-- SCORM object -->
-        </div> <!-- SCORM box  -->
     </div> <!-- SCORM page -->
 <?php 
+// NEW IMS TOC
+if (!isset($result->toctitle)) {
+    $result->toctitle = get_string('toc', 'scorm');
+}
+
+$PAGE->requires->js_init_call('M.mod_scorm.init', array($scorm->hidenav, $scorm->hidetoc, $result->toctitle, $name, $scorm->options, $scorm->width, $scorm->height, $sco->id));
+
+
 $completion=new completion_info($course);
 $completion->set_module_viewed($cm);
 
diff --git a/mod/scorm/prereqs.php b/mod/scorm/prereqs.php
new file mode 100644 (file)
index 0000000..6d25bbc
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+    require_once('../../config.php');
+    require_once($CFG->dirroot.'/mod/scorm/locallib.php');
+
+    $id = optional_param('id', '', PARAM_INT);       // Course Module ID, or
+    $a = optional_param('a', '', PARAM_INT);         // scorm ID
+    $scoid = required_param('scoid', PARAM_INT);  // sco ID
+    $attempt = required_param('attempt', PARAM_INT);  // attempt number
+    $mode = optional_param('mode', 'normal', PARAM_ALPHA); // navigation mode
+    $currentorg = optional_param('currentorg', '', PARAM_RAW); // selected organization
+
+
+    if (!empty($id)) {
+        if (! $cm = get_coursemodule_from_id('scorm', $id)) {
+            print_error('invalidcoursemodule');
+        }
+        if (! $course = $DB->get_record("course", array("id"=>$cm->course))) {
+            print_error('coursemisconf');
+        }
+        if (! $scorm = $DB->get_record("scorm", array("id"=>$cm->instance))) {
+            print_error('invalidcoursemodule');
+        }
+    } else if (!empty($a)) {
+        if (! $scorm = $DB->get_record("scorm", array("id"=>$a))) {
+            print_error('invalidcoursemodule');
+        }
+        if (! $course = $DB->get_record("course", array("id"=>$scorm->course))) {
+            print_error('coursemisconf');
+        }
+        if (! $cm = get_coursemodule_from_instance("scorm", $scorm->id, $course->id)) {
+            print_error('invalidcoursemodule');
+        }
+    } else {
+        print_error('missingparameter');
+    }
+
+    $PAGE->set_url('/mod/scorm/prereqs.php', array('scoid'=>$scoid,'attempt'=>$attempt, 'id'=>$cm->id));
+
+    require_login($course->id, false, $cm);
+
+    $scorm->version = strtolower(clean_param($scorm->version, PARAM_SAFEDIR));   // Just to be safe
+    if (!file_exists($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'lib.php')) {
+        $scorm->version = 'scorm_12';
+    }
+    require_once($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'lib.php');
+
+
+    if (confirm_sesskey() && (!empty($scoid))) {
+        $result = true;
+        $request = null;
+        if (has_capability('mod/scorm:savetrack', get_context_instance(CONTEXT_MODULE,$cm->id))) {
+            $result = scorm_get_toc($USER,$scorm,'structurelist',$currentorg,$scoid,$mode,$attempt,true, false);
+            echo $result->toc;
+        }
+        //echo "<ul><li>The Heading<ul>";
+        //echo "<li><a title='/moodledev/blah1'>Blah 1</a></li>";
+        //echo "<li><a title='/moodledev/blah2'>Blah 2</a></li>";
+        //echo "</ul></li></ul>";
+    }
+
index ebdf20c..5a8a50e 100644 (file)
@@ -11,7 +11,7 @@
 #page-mod-scorm-player #scormbox {width: 74%;position: absolute;right: 0px;top: 0px;}
 #page-mod-scorm-player #scormpage {position: relative;width: 100%;}
 #page-mod-scorm-player #scormpage #toctree {position:relative;width:100%;overflow-x: auto;overflow-y: auto;}
-#page-mod-scorm-player #tocbox {position: relative;left: 0px;width: 24%;font-size: 0.8em;}
+#page-mod-scorm-player #tocbox {position: relative;left: 0px;width: 80%;font-size: 0.8em;}
 #page-mod-scorm-player #tochead {position: relative;text-align: center;top: 3px;height: 30px;}
 
 #page-mod-scorm-player .toc,
@@ -21,4 +21,8 @@
 #page-mod-scorm-player .structurelist ul {padding-left: 0.5em;margin-left: 0.5em;}
 
 #page-mod-scorm-view .structurelist  {list-style-type: none;white-space: nowrap;}
-#page-mod-scorm-view .structurelist  {list-style-type: none;white-space: nowrap;}
\ No newline at end of file
+#page-mod-scorm-view .structurelist  {list-style-type: none;white-space: nowrap;}
+
+#page-mod-scorm-player #altfinishlink {float: right; border: 0px; padding: 0px; }
+#page-mod-scorm-player #altpopuplink  {position: left; padding: 5px; border: 0px; }
+#page-mod-scorm-player #scormmode  {float: left; border: 0px; }