]> git.mjollnir.org Git - moodle.git/commitdiff
resource.class.php changes:
authorwildgirl <wildgirl>
Tue, 18 Apr 2006 18:04:30 +0000 (18:04 +0000)
committerwildgirl <wildgirl>
Tue, 18 Apr 2006 18:04:30 +0000 (18:04 +0000)
1. Added logic to process repository paths. A repository path is marked with a # as the first character of the reference field.
2. Added a new error code for repository items not being deployed / bad reference.

ims.html change:
Added a button to link to the repository browser.

New files:
finder.php \96 browser for the repository
preview.php \96 cut down display routine from resource.class.php, forces sidemenu etc.
repository_deploy.php \96 deploy for repository items (same results as deploy.php)
repository_config.php (repository disabled by default)
resize.js - for iframe resizing
dummyapi.js - dummy SCORM API

(Tom's work, with help from Andy)

mod/resource/type/ims/deploy.php
mod/resource/type/ims/dummyapi.js [new file with mode: 0644]
mod/resource/type/ims/finder.php [new file with mode: 0644]
mod/resource/type/ims/images/dir.gif [new file with mode: 0644]
mod/resource/type/ims/images/ims.gif [new file with mode: 0644]
mod/resource/type/ims/ims.html
mod/resource/type/ims/preview.php [new file with mode: 0644]
mod/resource/type/ims/repository_config.php [new file with mode: 0644]
mod/resource/type/ims/repository_deploy.php [new file with mode: 0644]
mod/resource/type/ims/resize.js [new file with mode: 0644]
mod/resource/type/ims/resource.class.php

index d82d5eeae82231df2f9f3ce0ee98ea12729597b1..7f94afa0b6fac3438f92f06f010f7175137a0d5b 100644 (file)
     
 /// Copy files
     $origin = $CFG->dataroot.'/'.$courseid.'/'.$file;
+
     if (!is_file($origin)) {
         error (get_string('filenotfound' , 'error', $file));
     }
             if (empty($obj_resource->href)) {
                 $obj_resource->href = $resource['#']['file']['0']['@']['href'];
             }
-
+            
+        /// Some packages are poorly done and use \ in roots. This makes them 
+        /// not display since the URLs are not valid.
+            if (!empty($obj_resource->href)) {
+               $obj_resource->href = strtr($obj_resource->href, "\\", '/');    
+            }
+            
         /// Only if the resource has everything
             if (!empty($obj_resource->identifier) &&
                 !empty($obj_resource->href)) {
         return $resources;
     }
 
-?>
+?>
\ No newline at end of file
diff --git a/mod/resource/type/ims/dummyapi.js b/mod/resource/type/ims/dummyapi.js
new file mode 100644 (file)
index 0000000..2a95694
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+* Dummy SCORM API
+*/
+function GenericAPIAdaptor(){
+        this.LMSInitialize = LMSInitializeMethod;
+        this.LMSGetValue = LMSGetValueMethod;
+        this.LMSSetValue = LMSSetValueMethod;
+        this.LMSCommit = LMSCommitMethod;
+        this.LMSFinish = LMSFinishMethod;
+        this.LMSGetLastError = LMSGetLastErrorMethod;
+        this.LMSGetErrorString = LMSGetErrorStringMethod;
+        this.LMSGetDiagnostic = LMSGetDiagnosticMethod;
+}
+/*
+* LMSInitialize.
+*/
+function LMSInitializeMethod(parameter){return "true";}
+/*
+* LMSFinish.
+*/
+function LMSFinishMethod(parameter){return "true";}
+/*
+* LMSCommit.
+*/
+function LMSCommitMethod(parameter){return "true";}
+/*
+* LMSGetValue.
+*/
+function LMSGetValueMethod(element){return "";}
+/*
+* LMSSetValue.
+*/
+function LMSSetValueMethod(element, value){return "true";}
+/*
+* LMSGetLastErrorString
+*/
+function LMSGetErrorStringMethod(errorCode){return "No error";}
+/*
+* LMSGetLastError
+*/
+function LMSGetLastErrorMethod(){return "0";}
+/*
+* LMSGetDiagnostic
+*/
+function LMSGetDiagnosticMethod(errorCode){return "No error. No errors were encountered. Successful API call.";}
+var API = new GenericAPIAdaptor;
\ No newline at end of file
diff --git a/mod/resource/type/ims/finder.php b/mod/resource/type/ims/finder.php
new file mode 100644 (file)
index 0000000..125b160
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+    require_once('../../../../config.php');
+    require_once('../../lib.php');
+    require_once('resource.class.php');
+    require_once('../../../../backup/lib.php');
+    require_once('../../../../lib/filelib.php');
+    require_once('../../../../lib/xmlize.php');
+    
+    require_once('repository_config.php');
+
+/// Directory to browse, inside repository. Starts on ''.    
+    $directory = optional_param ('directory', '', PARAM_PATH);
+    
+/// Get the language strings needed
+    $strdeployall = get_string('deployall','resource');
+    $strpreview = get_string('preview','resource');
+    $strchoose = get_string('choose','resource');
+    $strdeploy = get_string('deploy','resource');
+    $strnotdeployed = get_string('notdeployed','resource');
+    $stremptyfolder = get_string('emptyfolder','resource');
+    
+/// Print header. Blank, nothing fancy. 
+    print_header();
+    
+    $items = array();
+/// Open $directory
+    if (!($repository_dir = opendir("$CFG->repository/$directory"))) die("Can't open directory \"$CFG->repository/$directory\"");
+    
+/// Loops though dir building a list of all relevent entries. Ignores files.
+/// Asks for deploy if admin user AND no serialized file found.
+    while (false != ($filename = readdir($repository_dir))) {
+        if ($filename != '.' && $filename != '..' && is_dir("$CFG->repository/$directory/$filename")) {
+            unset($item);
+            $item->type = '';
+            $item->name = 0;
+            $item->path = "$directory/$filename";
+            
+        /// No manifest => normal, browsable directory.
+            if (!file_exists("$CFG->repository/$item->path/imsmanifest.xml")) {
+                $item->type = 'directory';
+                $item->name = $filename;
+            }
+        /// Manifest, so IMS CP.
+            else {
+                if (file_exists("$CFG->repository/$item->path/moodle_inx.ser")) {
+                    $item->type = 'deployed';
+                    $index = ims_load_serialized_file("$CFG->repository/$item->path/moodle_inx.ser");
+                    $item->name = $index['title'];
+                }
+                else {
+                    $item->type = 'not deployed';
+                    $item->name = $filename;
+                }
+            }
+            $items[] = $item;   
+        }   
+    }
+    closedir($repository_dir);
+
+/// Prints the toolbar. 
+    echo '<div id="ims_toolbar" style="padding:10px;">';
+    ims_print_crumbtrail($directory);
+    
+/// If admin, add extra buttons - redeploy & help.
+    if (isadmin()) {
+        echo " | (<a href=\"repository_deploy.php?file=$directory&all=force\">$strdeployall</a>) ";
+        helpbutton("deploy", get_string("deployall", "resource"), "resource", true);
+    }
+    echo '</div>';
+
+/// Prints the file list from list generated above.
+    echo '<div id="ims_filelist"><ul style="list-style:none;padding:10px;margin:0px;">';  
+    if ($items != array()) {
+        
+        foreach ($items as $item) {
+            if ($item->type == 'deployed') {
+                echo "<li><img src='images/ims.gif' /> $item->name (<a href=\"javascript:
+                        opener.document.forms['form'].reference.value = '#$item->path'; 
+                        opener.document.forms['form'].name.value = '$item->name'; 
+                        window.close();
+                    \">$strchoose</a>) (<a href=\"preview.php?directory=$item->path\">$strpreview</a>)</li>\n";
+            }
+            else if ($item->type == 'not deployed') {
+            /// Only displays non-deployed IMS CP's if admin user.
+                if (isadmin()) {
+                    echo "<li><img src='images/ims.gif' /> <em>$item->path - $strnotdeployed</em> (<a href=\"repository_deploy.php?file=$item->path\">$strdeploy</a>)</li>\n";
+                }
+            }
+            else if ($item->type == 'directory') {
+                echo "<li><img src='images/dir.gif' /> <a href=\"?directory=$item->path\">$item->name</a></li>\n";
+            }
+        }
+    }
+    else {
+        echo "<li><em>$stremptyfolder</em></li>";
+    }
+    echo "</ul>";
+    
+/// Print footer and exit.
+    echo "</div></div></div></body></html>";
+    exit;
+    
+/// Generates the crumbtrial from $directory. Just splits up on '/'.
+    function ims_print_crumbtrail($directory) {
+        $strrepository = get_string('repository','resource');
+        
+        $arr = explode('/', $directory);
+        $last = array_pop($arr);
+        if (trim($directory, '/') == '') {
+            echo $strrepository;
+            return;
+        }
+        else {
+            $output = "<a href=\"?directory=\">$strrepository</a> » ";
+        }
+        $itemdir = '';
+        foreach ($arr as $item) {
+            if ($item == '') continue;
+            $itemdir .= '/'.$item;
+            $output .= "<a href=\"?directory=$itemdir\">$item</a> » ";
+        }
+        $output .= $last;
+        echo $output;
+    }
+?>
diff --git a/mod/resource/type/ims/images/dir.gif b/mod/resource/type/ims/images/dir.gif
new file mode 100644 (file)
index 0000000..81230c6
Binary files /dev/null and b/mod/resource/type/ims/images/dir.gif differ
diff --git a/mod/resource/type/ims/images/ims.gif b/mod/resource/type/ims/images/ims.gif
new file mode 100644 (file)
index 0000000..6b387cb
Binary files /dev/null and b/mod/resource/type/ims/images/ims.gif differ
index d99b34a25a948b15db4febb13d6693d09b157996..d60619d4fed85eaa2144ef158e2aefc24724b204 100644 (file)
     }
     
     function optiondeselector () {
-       currentstate = document.getElementById('menuparam_navigationmenu').value;
-       if (currentstate == 1) {
-               document.getElementById('menuparam_tableofcontents').value = 0;
-               document.getElementById('menuparam_skipsubmenus').value = 1;
-               document.getElementById('menuparam_navigationupbutton').value = 0;
-               document.getElementById('menuparam_tableofcontents').disabled = true;
-               document.getElementById('menuparam_skipsubmenus').disabled = true;
-               document.getElementById('menuparam_navigationupbutton').disabled = true;
-       }
-       else {
-               document.getElementById('menuparam_tableofcontents').disabled = false;
-               document.getElementById('menuparam_skipsubmenus').disabled = false;
-               document.getElementById('menuparam_navigationupbutton').disabled = false;               
-       }
+        document.getElementById('menuparam_tableofcontents').disabled = false;
+        document.getElementById('menuparam_skipsubmenus').disabled = false;
+        document.getElementById('menuparam_navigationupbutton').disabled = false; 
+        
+        if (document.getElementById('menuparam_navigationmenu').value == 1) {
+            document.getElementById('menuparam_tableofcontents').value = 0;
+            document.getElementById('menuparam_skipsubmenus').value = 1;
+            document.getElementById('menuparam_navigationupbutton').value = 0;
+            document.getElementById('menuparam_tableofcontents').disabled = true;
+            document.getElementById('menuparam_skipsubmenus').disabled = true;
+            document.getElementById('menuparam_navigationupbutton').disabled = true;
+        }
+        
+        if (document.getElementById('menuparam_navigationbuttons').value == 0) {
+            document.getElementById('menuparam_navigationupbutton').value = 0;
+            document.getElementById('menuparam_navigationupbutton').disabled = true;
+        }
+
     }
 </script>
 
     </td>
     <td>
     <?php
+        $strbrowserepository = get_string('browserepository', 'resource');
         echo "<input type=\"text\" name=\"reference\" size=\"90\" value=\"$form->reference\" alt=\"reference\" /><br />";
         button_to_popup_window ("/files/index.php?id=$form->course&amp;choose=form.reference", "coursefiles", $strchooseafile, 500, 750, $strchooseafile);
+        if ($CFG->repositoryactivate) button_to_popup_window ("/mod/resource/type/ims/finder.php?directory=", "", $strbrowserepository, 500, 750, "Browse repository");
+    
     ?>
     </td>
 </tr>
     
     echo "<tr>\n";
     echo "<td valign=\"top\" align=\"right\">\n";
-    echo 'Navigation Menu: ';
+    echo get_string('navigationmenu','resource').': ';
     echo "</td>\n";
     echo "<td valign=\"top\">\n";
     choose_from_menu($yesno, "param_navigationmenu", $form->param_navigationmenu, "", "optiondeselector();");
     echo get_string('navigationbuttons','resource').': ';
     echo "</td>\n";
     echo "<td valign=\"top\">\n";
-    choose_from_menu($yesno, "param_navigationbuttons", $form->param_navigationbuttons, "");
+    choose_from_menu($yesno, "param_navigationbuttons", $form->param_navigationbuttons, "", "optiondeselector();");
     echo "</td>\n";
     echo "</tr>\n";
     
     echo "<tr>\n";
     echo "<td valign=\"top\" align=\"right\">\n";
-    echo 'Skip Submenu Entries: ';
+    echo get_string('skipsubmenus','resource').': ';
     echo "</td>\n";
     echo "<td valign=\"top\">\n";
     choose_from_menu($yesno, "param_skipsubmenus", $form->param_skipsubmenus, "");
     
     echo "<tr>\n";
     echo "<td valign=\"top\" align=\"right\">\n";
-    echo 'Navigation \'Up\' Button: ';
+    echo get_string('navigationup','resource').': ';
     echo "</td>\n";
     echo "<td valign=\"top\">\n";
     choose_from_menu($yesno, "param_navigationupbutton", $form->param_navigationupbutton, "");
diff --git a/mod/resource/type/ims/preview.php b/mod/resource/type/ims/preview.php
new file mode 100644 (file)
index 0000000..c931b91
--- /dev/null
@@ -0,0 +1,195 @@
+<?php
+    require_once('../../../../config.php');
+    require_once('../../lib.php');
+    require_once('resource.class.php');
+    require_once('../../../../backup/lib.php');
+    require_once('../../../../lib/filelib.php');
+    require_once('../../../../lib/xmlize.php');
+    
+    require_once('repository_config.php');
+    
+    $directory = required_param ('directory', PARAM_PATH);
+    $page = optional_param ('page', 0, PARAM_INT);
+
+/// Calculate the path of the IMS CP to be displayed
+    $deploydir = $CFG->repository . '/' . $directory;
+
+/// Confirm that the IMS package has been deployed. Hash not generated
+/// for repository ones.
+    if (!file_exists($deploydir.'/moodle_inx.ser')) {
+            $errortext = "Not Deployed";
+            print_header();
+            print_simple_box_start('center', '60%');
+            echo '<p align="center">'.$errortext.'</p>';
+            print_footer();
+            exit;
+    }               
+
+/// Load serialized IMS CP index to memory only once.
+    if (empty($items)) {
+        if (!$items = ims_load_serialized_file($deploydir.'/moodle_inx.ser')) {
+            error (get_string('errorreadingfile', 'error', 'moodle_inx.ser'));
+        }
+    }
+
+/// fast forward to first non-index page
+    while (empty($items[$page]->href)) $page++;
+    
+/// Select encoding
+    $encoding = current_charset();
+
+/// Select direction
+    if (get_string('thisdirection') == 'rtl') {
+        $direction = ' dir="rtl"';
+    } else {
+        $direction = ' dir="ltr"';
+    }
+
+/// The output here
+
+    echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n";
+    echo "<html$direction>\n";
+    echo '<head>';
+    echo '<meta http-equiv="content-type" content="text/html; charset='.$encoding.'" />';
+    echo "
+    <script type=\"text/javascript\" language=\"javascript\" src=\"dummy.js\"></script>
+    <script language=\"javascript\" type=\"text/javascript\">
+        function resizeiframe () {
+              var winWidth = 0, winHeight = 0;
+              if( typeof( window.innerWidth ) == 'number' ) {
+                //Non-IE
+                winWidth = window.innerWidth;
+                winHeight = window.innerHeight;
+              } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
+                //IE 6+ in 'standards compliant mode'
+                winWidth = document.documentElement.clientWidth;
+                winHeight = document.documentElement.clientHeight;
+              } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
+                //IE 4 compatible
+                winWidth = document.body.clientWidth;
+                winHeight = document.body.clientHeight;
+              }
+
+            document.getElementById('ims-preview-contentframe').style.width = (winWidth - 300)+'px';
+            document.getElementById('ims-preview-contentframe').style.height = (winHeight)+'px';
+            document.getElementById('ims-preview-menudiv').style.height = (winHeight)+'px';
+            
+        }
+        
+        window.onresize = resizeiframe;
+        window.onload = resizeiframe;
+
+    </script>
+    <style type='text/css'>
+        #ims-preview-menudiv {
+            position:absolute;
+            top:0px;
+            left:0px;
+            width:300px;
+            height:100%;
+            overflow:auto;
+        }
+        
+        #ims-preview-contentframe {
+            position:absolute;
+            top:0px;
+            left:300px;
+            height:100%;
+            border:0;
+        }
+    </style>
+    ";
+    echo "<title>Preview</title></head>\n";
+/// moodle header
+    print_header();
+/// content - this produces everything else
+
+/// adds side navigation bar if needed. must also adjust width of iframe to accomodate 
+    echo "<div id=\"ims-preview-menudiv\">";  preview_buttons($directory, $items['title']); echo preview_ims_generate_toc($items, $directory); echo "</div>";
+    
+    $fullurl = "$CFG->repositorywebroot/$directory/".$items[$page]->href;
+/// prints iframe filled with $fullurl ;width:".$iframewidth." missing also height=\"420px\"
+    echo "<iframe id=\"ims-preview-contentframe\" name=\"ims-preview-contentframe\" src=\"{$fullurl}\"></iframe>"; //Content frame 
+/// moodle footer
+    echo "</div></div></body></html>";
+    
+    
+    /*** This function will generate the TOC file for the package
+     *   from an specified parent to be used in the view of the IMS
+     */
+    function preview_ims_generate_toc($items, $directory, $page=0) {
+        global $CFG;
+
+        $contents = '';
+
+    /// Configure links behaviour
+        $fullurl = '?directory='.$directory.'&page=';
+
+    /// Iterate over items to build the menu
+        $currlevel = 0;
+        $currorder = 0;
+        $endlevel  = 0;
+        foreach ($items as $item) {
+        /// Convert text from UTF-8 to current charset if needed
+            if (empty($CFG->unicodedb)) {
+////                $textlib = textlib_get_instance();
+////                $item->title = $textlib->convert($item->title, 'UTF-8', current_charset());
+            }
+        /// Skip pages until we arrive to $page
+            if ($item->id < $page) {
+                continue;
+            }
+        /// Arrive to page, we store its level
+            if ($item->id == $page) {
+                $endlevel = $item->level;
+                continue;
+            }
+        /// We are after page and inside it (level > endlevel)
+            if ($item->id > $page && $item->level > $endlevel) {
+            /// Start Level 
+                if ($item->level > $currlevel) {
+                    $contents .= '<ol class="listlevel_'.$item->level.'">';
+                }
+            /// End Level
+                if ($item->level < $currlevel) {
+                    $contents .= '</ol>';
+                }
+            /// Add item
+                $contents .= '<li>';
+                if (!empty($item->href)) {
+                    $contents .= '<a href="'.$fullurl.$item->id.'" target="_parent">'.$item->title.'</a>';
+                } else {
+                    $contents .= $item->title;
+                }
+                $contents .= '</li>';
+                $currlevel = $item->level;
+                continue;
+            }
+        /// We have reached endlevel, exit
+            if ($item->id > $page && $item->level <= $endlevel) {
+                break;
+            }
+        }
+        $contents .= '</ol>';
+
+        return $contents;
+    }
+    
+    function preview_buttons($directory, $name) {
+        $strchoose = get_string('choose','resource');
+        $strback = get_string('back','resource');
+        
+        $path = $directory;
+        $arr = explode('/', $directory);
+        array_pop($arr);
+        $directory = implode('/', $arr);
+        echo "<div id=\"ims_preview_buttons\" style=\"padding:10px;\">
+              (<a href='finder.php?directory=$directory'>$strback</a>) 
+              (<a href=\"javascript:
+                        opener.document.forms['form'].reference.value = '#$path'; 
+                        opener.document.forms['form'].name.value = '$name'; 
+                        window.close();
+              \">$strchoose</a>)</div>";
+    }
+    
+?>
\ No newline at end of file
diff --git a/mod/resource/type/ims/repository_config.php b/mod/resource/type/ims/repository_config.php
new file mode 100644 (file)
index 0000000..76e1ed6
--- /dev/null
@@ -0,0 +1,5 @@
+<?php
+    $CFG->repositoryactivate = false;
+    $CFG->repository = "C:/public/www/html/ims_repository";
+    $CFG->repositorywebroot = "/ims_repository";
+?>
\ No newline at end of file
diff --git a/mod/resource/type/ims/repository_deploy.php b/mod/resource/type/ims/repository_deploy.php
new file mode 100644 (file)
index 0000000..824b88a
--- /dev/null
@@ -0,0 +1,434 @@
+<?php // $Id$
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 2001-3001 Martin Dougiamas        http://dougiamas.com  //
+//           (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com  //
+//                                                                       //
+// This program 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 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program 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:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+    /***
+     * This page will deploy an IMS Content Package from repository.
+     * Just adds hash file.
+     * Arguments:
+     *   - file   directory containing CP to deploy
+     *   - all    if not set, will deploy 1 package
+     *            if = true, will recursively deploy all packages
+     *             found in directory file.
+     *            if = force, same as above but will redeploy too.
+     */
+
+/// Required stuff
+    require_once('../../../../config.php');
+    require_once('../../lib.php');
+    require_once('resource.class.php');
+    require_once('../../../../backup/lib.php');
+    require_once('../../../../lib/filelib.php');
+    require_once('../../../../lib/xmlize.php');
+    
+    require_once('repository_config.php');
+    
+    /// Security - Admin Only  
+    if (!isadmin()) {
+        error("Not admin!");    
+    }
+        
+    $file       = required_param ('file', PARAM_PATH);
+    $all        = optional_param ('all', '', PARAM_STR);
+    
+    if ($all == '') {
+        print_header();
+        ims_deploy_file($file);
+        print_footer();
+    }
+    else {
+        print_header();
+        ims_deploy_folder($file, $all);
+        print_footer();
+    }
+
+/// Deploys all packages found in the folder recursively.
+    function ims_deploy_folder($file, $all='') {
+        global $CFG;
+        
+        $dirpath = "$CFG->repository/$file";
+        $dir = opendir($dirpath);
+        while (false != ($filename = readdir($dir))) {
+            if ($filename != '.' && $filename != '..') {
+                $path = $dirpath.'/'.$filename;
+                if (is_dir($path) && file_exists("$path/imsmanifest.xml")) {
+                    if ($all == 'force' || !file_exists("$path/moodle_inx.ser")) {
+                        echo "DEPLOYING $path<br>";
+                        ims_deploy_file($file.'/'.$filename, $all);
+                    }
+                }
+                else if (is_dir($path)) {
+                    echo "DEPLOYING $path<br>";
+                    ims_deploy_folder($file.'/'.$filename, $all); 
+                }
+                else {
+                    echo "WONT DEPLOY $path<br>";
+                }
+            }
+        }
+        closedir($dir);     
+    }
+
+    function ims_deploy_file($file, $all='') {   
+        global $CFG;
+    
+    /// Load request parameters 
+        $resourcedir = "$CFG->repository/$file";
+        
+    /// Get some needed strings
+        $strdeploy = get_string('deploy','resource');
+    
+    ///
+    /// Main process, where everything is deployed
+    ///
+
+    /// Load imsmanifest to memory (instead of using a full parser,
+    /// we are going to use xmlize intensively (because files aren't too big)
+        if (!$imsmanifest = ims_file2var ($resourcedir.'/imsmanifest.xml')) {
+            error (get_string ('errorreadingfile', 'error', 'imsmanifest.xml'));
+        }
+            
+    /// Check if the first line is a proper one, because I've seen some
+    /// packages with some control characters at the beginning.
+        $inixml = strpos($imsmanifest, '<?xml ');
+        if ($inixml !== false) {
+            if ($inixml !== 0) {
+                //Strip strange chars before "<?xml "
+                $imsmanifest = substr($imsmanifest, $inixml);
+            }
+        } else {
+            if (
+                (ord($imsmanifest[0]) == 0xFF && ord($imsmanifest[1]) == 0xFE) || 
+                (ord($imsmanifest[0]) == 0xFE && ord($imsmanifest[1]) == 0xFF)) {
+                echo " UTF-16 - CAN'T DEPLOY.";
+                return;
+            }
+            else {
+                error (get_string ('invalidxmlfile', 'error', 'imsmanifest.xml'));
+            }
+        }
+    
+    /// xmlize the variable
+        $data = xmlize($imsmanifest, 0);
+
+    ///    traverse_xmlize($data);
+        $title = ims_get_cp_title($data);
+    ///    foreach ($GLOBALS['traverse_array'] as $line) echo $line;
+    
+    /// Extract every manifest present in the imsmanifest file.
+    /// Returns a tree structure.
+        if (!$manifests = ims_extract_manifests($data)) {
+            error (get_string('nonmeaningfulcontent', 'error'));
+        }
+    
+    /// Process every manifest found in inverse order so every one 
+    /// will be able to use its own submanifests. Not perfect because
+    /// teorically this will allow some manifests to use other non-childs
+    /// but this is supposed to be
+    
+    /// Detect if all the manifest share a common xml:base tag
+        $manifest_base = $data['manifest']['@']['xml:base'];
+
+    /// Parse XML-metadata
+        /// Skip this for now (until a proper METADATA container was created in Moodle).
+    
+    /// Parse XML-content package data
+    /// First we select an organization an load all the items
+
+        if (!$items = ims_process_organizations($data['manifest']['#']['organizations']['0'])) {
+            if ($all == 'force') return; else error (get_string('nonmeaningfulcontent', 'error'));
+        }
+    
+    /// Detect if all the resources share a common xml:base tag
+        $resources_base = $data['manifest']['#']['resources']['0']['@']['xml:base'];
+      
+    /// Now, we load all the resources available (keys are identifiers)
+        if (!$resources = ims_load_resources($data['manifest']['#']['resources']['0']['#']['resource'], $manifest_base, $resources_base)) {
+            error (get_string('nonmeaningfulcontent', 'error'));
+        }
+    ///Now we assign to each item, its resource (by identifier)
+        foreach ($items as $key=>$item) {
+            if (!empty($resources[$item->identifierref])) {
+                $items[$key]->href = $resources[$item->identifierref];
+            } else {
+                $items[$key]->href = '';
+            }
+        }
+    
+    /// Create the INDEX (moodle_inx.ser - where the order of the pages are stored serialized) file
+        $items['title'] = $title;
+        if (!ims_save_serialized_file($resourcedir.'/moodle_inx.ser', $items)) {
+            error (get_string('errorcreatingfile', 'error', 'moodle_inx.ser'));
+        }
+    
+    /// No zip so no HASH
+    
+    /// End button (go to view mode)
+        echo '<center>';
+        print_simple_box(get_string('imspackageloaded', 'resource'), 'center');
+        $link = $CFG->wwwroot.'/mod/resource/type/ims/preview.php';
+        $options['directory'] = $file;
+        $label = get_string('viewims', 'resource');
+        $method = 'get';
+        print_single_button($link, $options, $label, $method);
+        echo '</center>';
+    
+    ///
+    /// End of main process, where everything is deployed
+    ///
+    }
+///
+/// Common and useful functions used by the body of the script
+///
+
+    /*** This function will return a tree of manifests (xmlized) as they are
+     *   found and extracted from one manifest file. The first manifest in the
+     *   will be the main one, while the rest will be submanifests. In the
+     *   future (when IMS CP suppors it, external submanifest will be detected
+     *   and retrieved here too). See IMS specs for more info.
+     */
+    function ims_extract_manifests($data) {
+
+        $manifest = new stdClass;    //To store found manifests in a tree structure
+
+    /// If there are some manifests
+        if (!empty($data['manifest'])) {
+        /// Add manifest to results array
+            $manifest->data = $data['manifest'];
+        /// Look for submanifests
+            $submanifests = ims_extract_submanifests($data['manifest']['#']);
+        /// Add them as child
+            if (!empty($submanifests)) {
+                $manifest->childs = $submanifests;
+            }
+        }
+    /// Return tree of manifests found
+        return $manifest;
+    }
+
+    /* This function will search recursively for submanifests returning an array
+     * containing them (xmlized) following a tree structure.
+     */
+    function ims_extract_submanifests($data) {
+
+        $submanifests = array();  //To store found submanifests
+
+    /// If there are some manifests
+        if (!empty($data['manifest'])) {
+        /// Get them
+            foreach ($data['manifest'] as $submanifest) {
+            /// Create a new submanifest object
+                $submanifest_object = new stdClass;
+                $submanifest_object->data = $submanifest;
+            /// Look for more submanifests recursively
+                $moresubmanifests = ims_extract_submanifests($submanifest['#']);
+            /// Add them to results array
+                if (!empty($moresubmanifests)) {
+                    $submanifest_object->childs = moresubmanifests;
+                }
+            /// Add submanifest object to results array
+                $submanifests[] = $submanifest_object;
+            }
+        }
+    /// Return array of manifests found
+        return $submanifests;
+    }
+
+    /*** This function will return an ordered and nested array of items
+     *   that is a perfect representation of the prefered organization
+     */
+    function ims_process_organizations($data) {
+
+        global $CFG;
+        
+    /// Get the default organization
+        $default_organization = $data['@']['default'];
+        if ($CFG->debug) print_object('default_organization: '.$default_organization);
+
+    /// Iterate (reverse) over organizations until we find the default one
+        if (empty($data['#']['organization'])) {  /// Verify <organization> exists
+            return false;
+        }
+        $count_organizations = count($data['#']['organization']);
+        if ($CFG->debug) print_object('count_organizations: '.$count_organizations);
+
+        $current_organization = $count_organizations - 1;
+        while ($current_organization >= 0) {
+        /// Load organization and check it
+            $organization = $data['#']['organization'][$current_organization];
+            if ($organization['@']['identifier'] == $default_organization) {
+                    $current_organization = -1;   //Match, so exit.
+            }
+            $current_organization--;
+        }
+
+    /// At this point we MUST have the final organization
+        if ($CFG->debug) print_object('final organization: '.$organization['#']['title'][0]['#']);
+        if (empty($organization)) {
+            return false;    //Error, no organization found
+        }
+
+    /// Extract items map from organization
+        $items = $organization['#']['item'];
+        if (empty($organization['#']['item'])) {  /// Verify <item> exists
+            return false;
+        }
+        if (!$itemmap = ims_process_items($items)) {
+            return false;    //Error, no items found
+        }
+        return $itemmap;
+    }
+
+    /*** This function gets the xmlized representation of the items
+     *   and returns an array of items, ordered, with level and info
+     */
+    function ims_process_items($items, $level = 1, $id = 1, $parent = 0) {
+        global $CFG;
+
+        $itemmap = array();
+
+    /// Iterate over items from start to end
+        $count_items = count($items);
+        if ($CFG->debug) print_object('level '.$level.'-count_items: '.$count_items);
+
+        $current_item = 0;
+        while ($current_item < $count_items) {
+        /// Load item 
+            $item = $items[$current_item];
+            $obj_item = new stdClass;
+            $obj_item->title         = $item['#']['title'][0]['#'];
+            $obj_item->identifier    = $item['@']['identifier'];
+            $obj_item->identifierref = $item['@']['identifierref'];
+            $obj_item->id            = $id;
+            $obj_item->level         = $level;
+            $obj_item->parent        = $parent;
+        /// Only if the item has everything
+            if (!empty($obj_item->title) && 
+                !empty($obj_item->identifier)) {
+            /// Add to itemmap
+                $itemmap[$id] = $obj_item;
+                if ($CFG->debug) print_object('level '.$level.'-id '.$id.'-parent '.$parent.'-'.$obj_item->title);
+            /// Counters go up
+                $id++;
+            /// Check for subitems recursively
+                $subitems = $item['#']['item'];
+                if (count($subitems)) {
+                /// Recursive call
+                    $subitemmap = ims_process_items($subitems, $level+1, $id, $obj_item->id);
+                /// Add at the end and counters if necessary
+                    if ($count_subitems = count($subitemmap)) {
+                        foreach ($subitemmap as $subitem) {
+                        /// Add the subitem to the main items array
+                            $itemmap[$subitem->id] = $subitem;
+                        /// Counters go up
+                            $id++;
+                        }
+                    }
+                }
+            }
+            $current_item++;
+        }
+        return $itemmap;
+    }
+
+    /*** This function will load an array of resources to be used later. 
+     *   Keys are identifiers
+     */
+    function ims_load_resources($data, $manifest_base, $resources_base) {
+        global $CFG;
+
+        $resources = array();
+
+        if (empty($data)) {  /// Verify <resource> exists
+            return false;
+        }
+        $count_resources = count($data);
+        if ($CFG->debug) print_object('count_resources: '.$count_resources);
+
+        $current_resource = 0;
+        while ($current_resource < $count_resources) {
+        /// Load resource 
+            $resource = $data[$current_resource];
+
+        /// Create a new object resource
+            $obj_resource = new stdClass;
+            $obj_resource->identifier = $resource['@']['identifier'];
+            $obj_resource->resource_base = $resource['@']['xml:base'];
+            $obj_resource->href = $resource['@']['href'];
+            if (empty($obj_resource->href)) {
+                $obj_resource->href = $resource['#']['file']['0']['@']['href'];
+            }
+            
+        /// Some packages are poorly done and use \ in roots. This makes them 
+        /// not display since the URLs are not valid.
+            if (!empty($obj_resource->href)) {
+                $obj_resource->href = strtr($obj_resource->href, "\\", '/');    
+            }
+
+        /// Only if the resource has everything
+            if (!empty($obj_resource->identifier) &&
+                !empty($obj_resource->href)) {
+            /// Add to resources (identifier as key)
+            /// Depending of $manifest_base, $resources_base and the particular
+            /// $resource_base variable, concatenate them to build the correct href
+                $href_base = '';
+                if (!empty($manifest_base)) {
+                    $href_base = $manifest_base;
+                }
+                if (!empty($resources_base)) {
+                    $href_base .= $resources_base;
+                }
+                if (!empty($obj_resource->resource_base)) {
+                    $href_base .= $obj_resource->resource_base;
+                }
+                $resources[$obj_resource->identifier] = $href_base.$obj_resource->href;
+            }
+        /// Counters go up
+            $current_resource++;
+        }
+        return $resources;
+    }
+    
+    /*** This function finds out the title of the resource from the XML.
+     *   First 2 conditions cover nearly all cases. The third is a fair guess
+     *   if no metadata is supplied. This is eventually saved in the serialized
+     *   hash as $items['title'].
+     */    
+    function ims_get_cp_title($xmlobj) {
+        $md = $xmlobj['manifest']['#']['metadata']['0']['#'];
+        if (isset($md['imsmd:lom'])) {
+            return $md['imsmd:lom']['0']['#']['imsmd:general']['0']['#']['imsmd:title']['0']['#']['imsmd:langstring']['0']['#'];
+        }
+        else if (isset($md['imsmd:record'])) {
+            return $md['imsmd:record']['0']['#']['imsmd:general']['0']['#']['imsmd:title']['0']['#']['imsmd:langstring']['0']['#'];
+        }
+        else if ($title = $xmlobj['manifest']['#']['organizations']['0']['#']['organization']['0']['#']['title']['0']['#']) {
+            return $title;  
+        }
+        else {
+            return "NO TITLE FOUND";
+        }
+    }
+?>
\ No newline at end of file
diff --git a/mod/resource/type/ims/resize.js b/mod/resource/type/ims/resize.js
new file mode 100644 (file)
index 0000000..c181eda
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * This script resizes everything to fit the window. Maybe a fixed iframe
+ * would be better?
+ */
+
+function getElementStyle(obj, prop, cssProp) {
+    ret = '';
+    
+    if (obj.currentStyle) {
+        ret = obj.currentStyle[prop];
+    } else if (document.defaultView && document.defaultView.getComputedStyle) {
+        var compStyle = document.defaultView.getComputedStyle(obj, null);
+        ret = compStyle.getPropertyValue(cssProp);
+    }
+    
+    if (ret == 'auto') ret = '0';
+    return ret;
+}
+
+function resizeiframe (hasNav) {
+    var winWidth = 0, winHeight = 0;
+    if( typeof( window.innerWidth ) == 'number' ) {
+        //Non-IE
+        winWidth = window.innerWidth;
+        winHeight = window.innerHeight;
+    } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
+        //IE 6+ in 'standards compliant mode'
+        winWidth = document.documentElement.clientWidth;
+        winHeight = document.documentElement.clientHeight;
+    } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
+        //IE 4 compatible
+        winWidth = document.body.clientWidth;
+        winHeight = document.body.clientHeight;
+    }
+                          
+    var header = document.getElementById('header');
+    var divs = document.getElementsByTagName('div');
+    var n = divs.length;
+    
+    
+    var content = document.getElementById('content');
+    var headerHeight = 0;
+    if (content) {
+        headerHeight = content.offsetTop;
+    }
+    
+    var footer = document.getElementById('footer');
+    var imsnavbar = document.getElementById('ims-nav-bar');
+    var footerHeight = 0;
+    var imsnavHeight = 0;
+    if (footer) {
+        footerHeight = footer.offsetHeight + parseInt(getElementStyle(footer, 'marginTop', 'margin-top')) + parseInt(getElementStyle(footer, 'marginBottom', 'margin-bottom'));
+    }
+    if (imsnavbar) {
+        imsnavHeight = imsnavbar.offsetHeight;
+    }
+    
+    var topMargin = parseInt(getElementStyle(document.getElementsByTagName('body')[0], 'marginTop', 'margin-top'));
+    var bottomMargin = parseInt(getElementStyle(document.getElementsByTagName('body')[0], 'marginBottom', 'margin-bottom'));
+    
+    var totalHeight = headerHeight + 
+                        footerHeight + 
+                        imsnavHeight +
+                        topMargin +
+                        bottomMargin;
+
+    if (hasNav == true) {
+        var iframeWidth = (winWidth - 325)+'px';
+        document.getElementById('ims-menudiv').style.height = (winHeight - totalHeight)+'px';
+    }
+    else {
+        var iframeWidth = '99%';
+    }
+
+    document.getElementById('ims-contentframe').style.height = (winHeight - totalHeight)+'px';
+    document.getElementById('ims-containerdiv').style.height = (winHeight - totalHeight)+'px';
+    document.getElementById('ims-contentframe').style.width = iframeWidth;
+}
\ No newline at end of file
index d349fbb7a020f3e6bb3c435adc94beab838234f1..0d516c876c93724763622caad61d0635740cca5d 100644 (file)
@@ -37,6 +37,7 @@
 
 
 include_once ($CFG->libdir.'/filelib.php');
+require_once($CFG->dirroot.'/mod/resource/type/ims/repository_config.php');
 
 /**
 * Extend the base resource class for ims resources 
@@ -62,6 +63,17 @@ class resource_ims extends resource_base {
             unset($this->parameters->navigationuparrow);
             $this->parameters->skipsubmenus = 1;
         }
+        
+    /// Is it in the repository material or not?
+        $file = $this->resource->reference;
+        if ($file[0] == '#') {
+            $this->isrepository = true;
+            $file = ltrim($file, '#');
+            $this->resource->reference = $file;
+        }
+        else {
+            $this->isrepository = false;
+        }
     }
 
     /***
@@ -72,7 +84,7 @@ class resource_ims extends resource_base {
         /// set parameter defaults
         $alltextfield = new stdClass();
         $alltextfield->tableofcontents=0;
-        $alltextfield->navigationbuttons=1;
+        $alltextfield->navigationbuttons=0;
         $alltextfield->navigationmenu=1;
         $alltextfield->skipsubmenus=1;
         $alltextfield->navigationupbutton=1;
@@ -127,36 +139,52 @@ class resource_ims extends resource_base {
     * 2 = Zip file doesn't exist
     * 3 = Package not deployed.
     * 4 = Package has changed since deployed.
+    * If the IMS CP is one from the central repository, then we instead check 
+    * with the following codes:
+    * 5 = Not deployed. Since repository is central must be admin to deploy so terminate
     */
     function check4errors($file, $course, $resource) {
-
         global $CFG;
 
-        $mimetype = mimeinfo("type", $file);
-        if ($mimetype != "application/zip") {
-            return 1;    //Error
-        }
-
-    /// Check if the uploaded file exists
-        if (!file_exists($CFG->dataroot.'/'.$course->id.'/'.$file)) {
-            return 2;    //Error
-        }
-
-    /// Calculate the path were the IMS package must be deployed
-        $deploydir = $CFG->dataroot.'/'.$course->id.'/'.$CFG->moddata.'/resource/'.$resource->id;
-
-    /// Confirm that the IMS package has been deployed. These files must exist if
-    /// the package is deployed: moodle_index.ser and moodle_hash.ser
-        if (!file_exists($deploydir.'/moodle_inx.ser') ||
-            !file_exists($deploydir.'/moodle_hash.ser')) {
-            return 3;    //Error
+        if ($this->isrepository) {
+        /// Calculate the path were the IMS package must be deployed
+            $deploydir = $CFG->repository . $file;
+    
+        /// Confirm that the IMS package has been deployed. These files must exist if
+        /// the package is deployed: moodle_index.ser and moodle_hash.ser
+            if (!file_exists($deploydir.'/moodle_inx.ser')) {
+                return 5;    //Error
+            }               
         }
-
-    /// If teacheredit, make, hash check. It's the md5 of the name of the file 
-    /// plus its size and modification date
-        if (isteacheredit($course->id)) {
-            if (!$this->checkpackagehash($file, $course, $resource)) {
-                return 4;
+        else {
+        /// Check for zip file type
+            $mimetype = mimeinfo("type", $file);
+            if ($mimetype != "application/zip") {
+                return 1;    //Error
+            }
+    
+        /// Check if the uploaded file exists
+            if (!file_exists($CFG->dataroot.'/'.$course->id.'/'.$file)) {
+                return 2;    //Error
+            }
+                        
+        /// Calculate the path were the IMS package must be deployed
+            $deploydir = $CFG->dataroot.'/'.$course->id.'/'.$CFG->moddata.'/resource/'.$resource->id;
+    
+    
+        /// Confirm that the IMS package has been deployed. These files must exist if
+        /// the package is deployed: moodle_index.ser and moodle_hash.ser
+            if (!file_exists($deploydir.'/moodle_inx.ser') ||
+                !file_exists($deploydir.'/moodle_hash.ser')) {
+                return 3;    //Error
+            }           
+        
+        /// If teacheredit, make, hash check. It's the md5 of the name of the file 
+        /// plus its size and modification date
+            if (isteacheredit($course->id)) {
+                if (!$this->checkpackagehash($file, $course, $resource)) {
+                    return 4;
+                }
             }
         }
 
@@ -243,20 +271,22 @@ class resource_ims extends resource_base {
      * Delete all the moddata files for the resource
      * @param    resource object
      */
-     function delete_instance($resource) {
-
+    function delete_instance($resource) {
+        
          global $CFG;
+        
+    /// Delete moddata resource dir completely unless repository.
+        if (!$this->isrepository) {
+            $resource_dir = $CFG->dataroot.'/'.$resource->course.'/'.$CFG->moddata.'/resource/'.$resource->id;
+            if (file_exists($resource_dir)) {
+                if (!$status = fulldelete($resource_dir)) {
+                    return false;
+                }
+            }
+        }
 
-     /// Delete moddata resource dir completely
-         $resource_dir = $CFG->dataroot.'/'.$resource->course.'/'.$CFG->moddata.'/resource/'.$resource->id;
-         if (file_exists($resource_dir)) {
-             if (!$status = fulldelete($resource_dir)) {
-                 return false;
-             }
-         }
-
-         return parent::delete_instance($resource);
-     }
+        return parent::delete_instance($resource);
+    }
 
 
     /**
@@ -314,6 +344,8 @@ class resource_ims extends resource_base {
                     $errortext = get_string('packagenotdeplyed','resource');
                 } else if ($errorcode == 4) {
                     $errortext = get_string('packagechanged','resource');
+                } else if ($errorcode == 5) {
+                    $errortext = get_string('packagenotdeplyed','resource'); // no button though since from repository.
                 }
             }
         /// Display the error and exit
@@ -355,7 +387,12 @@ class resource_ims extends resource_base {
 
     /// Load serialized IMS CP index to memory only once.
         if (empty($items)) {
-            $resourcedir = $CFG->dataroot.'/'.$course->id.'/'.$CFG->moddata.'/resource/'.$resource->id;
+            if (!$this->isrepository) {
+                $resourcedir = $CFG->dataroot.'/'.$course->id.'/'.$CFG->moddata.'/resource/'.$resource->id;
+            }
+            else {
+                $resourcedir = $CFG->repository . $resource->reference;
+            }
             if (!$items = ims_load_serialized_file($resourcedir.'/moodle_inx.ser')) {
                 error (get_string('errorreadingfile', 'error', 'moodle_inx.ser'));
             }
@@ -414,19 +451,76 @@ class resource_ims extends resource_base {
             echo "<html$direction>\n";
             echo '<head>';
             echo '<meta http-equiv="content-type" content="text/html; charset='.$encoding.'" />';
+            if (!empty($this->parameters->navigationmenu)) {
+                $jsarg = 'true';
+            }
+            else {
+                $jsarg = 'false';
+            }
+            
+        /// The dummy LMS API hack to stop some SCORM packages giving errors.
+            echo "<script type=\"text/javascript\" language=\"javascript\" src=\"$CFG->wwwroot/mod/resource/type/ims/dummy.js\"></script>";            
+        
+        /// All this sets up script and style stuff to position and 
+        /// resize the menus and stuff. The CSS is here because it
+        /// differs depending on some php variables. The javascript
+        /// uses resize.js.
+            echo "
+            <script type=\"text/javascript\" language=\"javascript\" src=\"$CFG->wwwroot/mod/resource/type/ims/resize.js\"></script>
+            <script language=\"javascript\" type=\"text/javascript\">
+                window.onresize = function(){
+                    resizeiframe($jsarg);
+                };
+                window.onload = function(){
+                    resizeiframe($jsarg);
+                };
+            </script>
+            <style type='text/css'>
+                #ims-menudiv {
+                    position:absolute;
+                    left:5px;
+                    width:300px;
+                    overflow:auto;
+                    float:left;
+                }
+                
+                #ims-containerdiv {
+                    width:100%;
+                    
+                }
+                
+                #ims-contentframe {
+                    position:absolute;
+                    
+                   ";
+            if (!empty($this->parameters->navigationmenu)) {
+                echo "left:310px;";
+            }
+            echo "
+                    border:0px;
+                }
+                
+            </style>
+            ";
             echo "<title>{$course->shortname}: ".strip_tags(format_string($resource->name,true))."</title></head>\n";
         /// moodle header
             if ($resource->popup) {
-                print_header($pagetitle, $course->fullname.' : '.$resource->name);
+                //print_header($pagetitle, $course->fullname.' : '.$resource->name);
+                print_header();
             } else {
                 print_header($pagetitle, $course->fullname, "$this->navigation ".format_string($resource->name), "", "", true, update_module_button($cm->id, $course->id, $this->strresource), navmenu($course, $cm, "parent"));
             }
         /// content - this produces everything else
             $this->print_ims($cm, $course, $items, $resource, $page);
-        /// moodle footer
-            print_footer();
+        /// moodle footer. no footer if it's in a popup - save space.
+            if ($resource->popup) {
+               echo "</div></div></body></html>";
+            }
+            else {
+               print_footer();
+            }
 
-        /// log it. clearly only run once.
+        /// log it.
             add_to_log($course->id, "resource", "view", "view.php?id={$cm->id}", $resource->id, $cm->id);
             exit;
         }
@@ -444,12 +538,18 @@ class resource_ims extends resource_base {
         global $CFG;
         
     /// Calculate the file.php correct url
-        if ($CFG->slasharguments) {
-            $fileurl = "{$CFG->wwwroot}/file.php/{$course->id}/{$CFG->moddata}/resource/{$resource->id}";
-        } else {
-            $fileurl = "{$CFG->wwwroot}/file.php?file=/{$course->id}/{$CFG->moddata}/resource/{$resource->id}";
+        if (!$this->isrepository) {
+            if ($CFG->slasharguments) {
+                $fileurl = "{$CFG->wwwroot}/file.php/{$course->id}/{$CFG->moddata}/resource/{$resource->id}";
+            } else {
+                $fileurl = "{$CFG->wwwroot}/file.php?file=/{$course->id}/{$CFG->moddata}/resource/{$resource->id}";
+            }
+        }
+        else {
+            $fileurl = $CFG->repositorywebroot . $resource->reference;
         }
 
+
     /// Calculate the view.php correct url
         $viewurl = "view.php?id={$cm->id}&amp;type={$resource->type}&amp;frameset=toc&amp;page=";
 
@@ -493,17 +593,15 @@ class resource_ims extends resource_base {
             $this->print_nav($items, $resource, $page);
         }
         
-    /// adds side navigation bar if needed. must also adjust width of iframe to accomodate
+        echo '<div id="ims-containerdiv">';
+    /// adds side navigation bar if needed. must also adjust width of iframe to accomodate 
         if (!empty($this->parameters->navigationmenu)) {
-            echo "<div style=\"float:left;width:300px;height:420px;overflow:scroll\">"; $this->print_navmenu($items, $resource, $page); echo "</div>";
-            $iframewidth = "700px";
-        }
-        else {
-            $iframewidth = "100%";
+            echo "<div id=\"ims-menudiv\">"; $this->print_navmenu($items, $resource, $page); echo "</div>";
         }
         
     /// prints iframe filled with $fullurl
-        echo "<iframe src=\"{$fullurl}\" style=\"border:0;width:".$iframewidth."\" height=\"420px\"></iframe>"; //Content frame
+        echo "<iframe id=\"ims-contentframe\" name=\"ims-contentframe\" src=\"{$fullurl}\"></iframe>"; //Content frame
+        echo '</div>';
     }
 
 /// Prints TOC    
@@ -521,12 +619,12 @@ class resource_ims extends resource_base {
 
 /// Prints side navigation menu. This is just the full TOC with no surround.    
     function print_navmenu($items, $resource, $page=0) {
-        echo ims_generate_toc ($items, $resource, 0);
+        echo ims_generate_toc ($items, $resource, 0, $page);
     }
     
 /// Prints navigation bar at the top of the page.
     function print_nav($items, $resource, $page) {
-        echo '<div class="ims-nav-bar">';
+        echo '<div class="ims-nav-bar" id="ims-nav-bar">';
     /// Prev button
         echo ims_get_prev_nav_button ($items, $this, $page);
     /// Up button
@@ -536,7 +634,7 @@ class resource_ims extends resource_base {
     /// Main TOC button
         echo ims_get_toc_nav_button ($items, $this, $page);
     /// Footer
-        echo '</div>';      
+        echo '</div>';
     }        
         
 
@@ -690,8 +788,9 @@ class resource_ims extends resource_base {
 
     /*** This function will generate the TOC file for the package
      *   from an specified parent to be used in the view of the IMS
+     *   Now hilights 'selected page' also.
      */
-    function ims_generate_toc($items, $resource, $page=0) {
+    function ims_generate_toc($items, $resource, $page=0, $selected_page = -1) {
         global $CFG,$SESSION;
 
         $contents = '';
@@ -706,8 +805,8 @@ class resource_ims extends resource_base {
         foreach ($items as $item) {
         /// Convert text from UTF-8 to current charset if needed
             if (empty($CFG->unicodedb)) {
-                $textlib = textlib_get_instance();
-                $item->title = $textlib->convert($item->title, 'UTF-8', current_charset());
+////                $textlib = textlib_get_instance();
+////                $item->title = $textlib->convert($item->title, 'UTF-8', current_charset());
             }
         /// Skip pages until we arrive to $page
             if ($item->id < $page) {
@@ -731,7 +830,9 @@ class resource_ims extends resource_base {
             /// Add item
                 $contents .= '<li>';
                 if (!empty($item->href)) {
+                       if ($item->id == $selected_page) $contents .= '<div id="ims-toc-selected">';
                     $contents .= '<a href="'.$fullurl.$item->id.'" target="_parent">'.$item->title.'</a>';
+                    if ($item->id == $selected_page) $contents .= '</div>';
                 } else {
                     $contents .= $item->title;
                 }
@@ -753,6 +854,7 @@ class resource_ims extends resource_base {
      *   to show the previous button in the nav frame
      **/
     function ims_get_prev_nav_button ($items, $resource_obj, $page) {
+        $strprevious        = get_string("previous", "resource");
 
         $cm = $resource_obj->cm;
         $resource = $resource_obj->resource;
@@ -767,10 +869,10 @@ class resource_ims extends resource_base {
             }
         }
 
-        if ($page >= 0 ) {  //0 and 1 pages haven't previous
-            $contents .= "<span class=\"ims-nav-button\"><a href=\"view.php?id={$cm->id}&amp;type={$resource->type}&amp;page={$page}&amp;frameset=ims\" target=\"_parent\">&lt;&lt;</a></span>"; 
+        if ($page >= 1 ) {  //0 and 1 pages haven't previous
+            $contents .= "<span class=\"ims-nav-button\"><a href=\"view.php?id={$cm->id}&amp;type={$resource->type}&amp;page={$page}&amp;frameset=ims\" target=\"_parent\">$strprevious</a></span>"; 
         } else {
-            $contents .= '<span class="ims-nav-dimmed">&lt;&lt;</span>';
+            $contents .= '<span class="ims-nav-dimmed">'.$strprevious.'</span>';
         }
 
         return $contents;
@@ -780,6 +882,7 @@ class resource_ims extends resource_base {
      *   to show the next button in the nav frame
      **/
     function ims_get_next_nav_button ($items, $resource_obj, $page) {
+        $strnext        = get_string("next", "resource");
 
         $cm = $resource_obj->cm;
         $resource = $resource_obj->resource;
@@ -795,9 +898,9 @@ class resource_ims extends resource_base {
         }
         
         if (!empty($items[$page])) {  //If the next page exists
-            $contents .= "<span class=\"ims-nav-button\"><a href=\"view.php?id={$cm->id}&amp;type={$resource->type}&amp;page={$page}&amp;frameset=ims\" target=\"_parent\">&gt;&gt;</a></span>";
+            $contents .= "<span class=\"ims-nav-button\"><a href=\"view.php?id={$cm->id}&amp;type={$resource->type}&amp;page={$page}&amp;frameset=ims\" target=\"_parent\">$strnext</a></span>";
         } else {
-            $contents .= '<span class="ims-nav-dimmed">&gt;&gt;</span>';
+            $contents .= '<span class="ims-nav-dimmed">'.$strnext.'</span>';
         }
 
 
@@ -808,6 +911,7 @@ class resource_ims extends resource_base {
      *   to show the up button in the nav frame
      **/
     function ims_get_up_nav_button ($items, $resource_obj, $page) {
+        $strup        = get_string("upbutton", "resource");
 
         $cm = $resource_obj->cm;
         $resource = $resource_obj->resource;
@@ -817,9 +921,9 @@ class resource_ims extends resource_base {
         if (!empty($resource_obj->parameters->navigationupbutton)) {
             if ($page > 1 && $items[$page]->parent > 0) {  //If the page has parent
                 $page = $items[$page]->parent;
-                $contents .= "<span class=\"ims-nav-button\"><a href=\"view.php?id={$cm->id}&amp;type={$resource->type}&amp;page={$page}&amp;frameset=ims\" target=\"_parent\">&and;</a></span>";
+                $contents .= "<span class=\"ims-nav-button\"><a href=\"view.php?id={$cm->id}&amp;type={$resource->type}&amp;page={$page}&amp;frameset=ims\" target=\"_parent\">$strup</a></span>";
             } else {
-                $contents .= '<span class="ims-nav-dimmed">&and;</span>';
+                $contents .= "<span class=\"ims-nav-dimmed\">$strup</span>";
             }
         }
         return $contents;