910f8c9f4e7c88691c60bdc487fce7b2a2207b30
[moodle.git] / mod / resource / type / ims / resource.class.php
1 <?php // $Id$
3 ///////////////////////////////////////////////////////////////////////////
4 //                                                                       //
5 // NOTICE OF COPYRIGHT                                                   //
6 //                                                                       //
7 // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
8 //          http://moodle.com                                            //
9 //                                                                       //
10 // Copyright (C) 2001-3001 Martin Dougiamas        http://dougiamas.com  //
11 //           (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com  //
12 //                                                                       //
13 // This program is free software; you can redistribute it and/or modify  //
14 // it under the terms of the GNU General Public License as published by  //
15 // the Free Software Foundation; either version 2 of the License, or     //
16 // (at your option) any later version.                                   //
17 //                                                                       //
18 // This program is distributed in the hope that it will be useful,       //
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of        //
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
21 // GNU General Public License for more details:                          //
22 //                                                                       //
23 //          http://www.gnu.org/copyleft/gpl.html                         //
24 //                                                                       //
25 ///////////////////////////////////////////////////////////////////////////
27 include_once ($CFG->libdir.'/filelib.php');
29 /**
30 * Extend the base resource class for ims resources
31 */
32 class resource_ims extends resource_base {
34     var $parameters;  //Attribute of this class where we'll store all the IMS deploy preferences
36     function resource_ims($cmid=0) {
37     /// super constructor
38         parent::resource_base($cmid);
40     /// prevent notice
41         if (empty($this->resource->alltext)) {
42             $this->resource->alltext='';
43         }
44     /// set own attributes
45         $this->parameters = $this->alltext2parameters($this->resource->alltext);
46     }
48     /***
49     * This function converts parameters stored in the alltext field to the proper 
50     * this->parameters object storing the special configuration of this resource type
51     */
52     function alltext2parameters($alltext) {
53         /// set parameter defaults
54         $alltextfield = new stdClass();
55         $alltextfield->tableofcontents=0;
56         $alltextfield->navigationbuttons=0;
58     /// load up any stored parameters
59         if (!empty($alltext)) {
60             $parray = explode(',', $alltext);
61             foreach ($parray as $key => $fieldstring) {
62                 $field = explode('=', $fieldstring);
63                 $alltextfield->$field[0] = $field[1];
64             }
65         }
67         return $alltextfield;
68     }
70     /***
71     * This function converts the this->parameters attribute (object) to the format
72     * needed to save them in the alltext field to store all the special configuration
73     * of this resource type
74     */
75     function parameters2alltext($parameters) {
76         $optionlist = array();
78         $optionlist[] = 'tableofcontents='.$parameters->tableofcontents;
79         $optionlist[] = 'navigationbuttons='.$parameters->navigationbuttons;
81         return implode(',', $optionlist);
82     }
84     /***
85     * This function will convert all the parameters configured in the resource form
86     * to a this->parameter attribute (object)
87     */
88     function form2parameters($resource) {
89         $parameters = new stdClass;
90         $parameters->tableofcontents = $resource->param_tableofcontents;
91         $parameters->navigationbuttons = $resource->param_navigationbuttons;
93         return $parameters;
94     }
96     /*** This function checks for errors in the status or deployment of the IMS
97     * Content Package returning an error code:
98     * 1 = Not a .zip file.
99     * 2 = Zip file doesn't exist
100     * 3 = Package not deployed.
101     * 4 = Package has changed since deployed.
102     */
103     function check4errors($file, $course, $resource) {
105         global $CFG;
107         $mimetype = mimeinfo("type", $file);
108         if ($mimetype != "application/zip") {
109             return 1;    //Error
110         }
112     /// Check if the uploaded file exists
113         if (!file_exists($CFG->dataroot.'/'.$course->id.'/'.$file)) {
114             return 2;    //Error
115         }
117     /// Calculate the path were the IMS package must be deployed
118         $deploydir = $CFG->dataroot.'/'.$course->id.'/'.$CFG->moddata.'/resource/'.$resource->id;
120     /// Confirm that the IMS package has been deployed. These files must exist if
121     /// the package is deployed: moodle_index.ser and moodle_hash.ser
122         if (!file_exists($deploydir.'/moodle_inx.ser') ||
123             !file_exists($deploydir.'/moodle_hash.ser')) {
124             return 3;    //Error
125         }
127     /// If teacheredit, make, hash check. It's the md5 of the name of the file 
128     /// plus its size and modification date
129         if (isteacheredit($course->id)) {
130             if (!$this->checkpackagehash($file, $course, $resource)) {
131                 return 4;
132             }
133         }
135     /// We've arrived here. Everything is ok
136         return 0;
137     }
139     /*** This function will check that the ims package (zip file) uploaded 
140     * isn't changed since it was deployed.
141     */
142     function checkpackagehash($file, $course, $resource) {
143         global $CFG;
145     /// Calculate paths
146         $zipfile = $CFG->dataroot.'/'.$course->id.'/'.$file;
147         $hashfile= $CFG->dataroot.'/'.$course->id.'/'.$CFG->moddata.'/resource/'.$resource->id.'/moodle_hash.ser';
148     /// Get deloyed hash value
149         $f = fopen ($hashfile,'r');
150         $deployedhash = fread($f, filesize($hashfile));
151         fclose ($f);
152     /// Unserialize the deployed hash
153         $deployedhash = unserialize($deployedhash);
154     /// Calculate uploaded file hash value
155         $uploadedhash = $this->calculatefilehash($zipfile);
157     /// Compare them
158         return ($deployedhash == $uploadedhash);
159     }
161     /*** This function will calculate the hash of any file passes as argument.
162     * It's based in a md5 of the filename, filesize and 20 first bytes (it includes
163     * the zip CRC at byte 15).
164     */
165     function calculatefilehash($filefullpath) {
167     /// Name and size
168         $filename = basename($filefullpath);
169         $filesize = filesize($filefullpath);
170     /// Read first 20cc
171         $f = fopen ($filefullpath,'r');
172         $data = fread($f, 20);
173         fclose ($f);
175         return md5($filename.'-'.$filesize.'-'.$data);
176     }
178     /**
179     * Add new instance of file resource
180     *
181     * Create alltext field before calling base class function.
182     *
183     * @param    resource object
184     */
185     function add_instance($resource) {
187     /// Load parameters to this->parameters
188         $this->parameters = $this->form2parameters($resource);
189     /// Save parameters into the alltext field
190         $resource->alltext = $this->parameters2alltext($this->parameters);
192         return parent::add_instance($resource);
193     }
196     /**
197     * Update instance of file resource
198     *
199     * Create alltext field before calling base class function.
200     *
201     * @param    resource object
202     */
203     function update_instance($resource) {
205     /// Load parameters to this->parameters
206         $this->parameters = $this->form2parameters($resource);
207     /// Save parameters into the alltext field
208         $resource->alltext = $this->parameters2alltext($this->parameters);
210         return parent::update_instance($resource);
211     }
213     /** Delete instance of IMS-CP resource
214      *
215      * Delete all the moddata files for the resource
216      * @param    resource object
217      */
218      function delete_instance($resource) {
220          global $CFG;
222      /// Delete moddata resource dir completely
223          $resource_dir = $CFG->dataroot.'/'.$resource->course.'/'.$CFG->moddata.'/resource/'.$resource->id;
224          if (file_exists($resource_dir)) {
225              if (!$status = fulldelete($resource_dir)) {
226                  return false;
227              }
228          }
230          return parent::delete_instance($resource);
231      }
234     /**
235      * Display the file resource
236      *
237      * Displays a file resource embedded, in a frame, or in a popup.
238      * Output depends on type of file resource.
239      *
240      * @param    CFG     global object
241      */
242     function display() {
243         global $CFG, $THEME, $USER;
245         require_once($CFG->libdir.'/filelib.php');
247     /// Set up generic stuff first, including checking for access
248         parent::display();
250     /// Set up some shorthand variables
251         $cm = $this->cm;
252         $course = $this->course;
253         $resource = $this->resource;
255     /// Fetch parameters
256         $inpopup = optional_param('inpopup', 0, PARAM_BOOL);
257         $page    = optional_param('page', 0, PARAM_INT);
258         $frameset= optional_param('frameset', '', PARAM_ALPHA);
260     /// Init some variables
261         $errorcode = 0;
262         $buttontext = 0;
263         $querystring = '';
264         $resourcetype = '';
265         $mimetype = mimeinfo("type", $resource->reference);
266         $pagetitle = strip_tags($course->shortname.': '.format_string($resource->name));
268     /// Cache this per request
269         static $items;
271     /// Check for errors
272         $errorcode = $this->check4errors($resource->reference, $course, $resource);
274     /// If there are any error, show it instead of the resource page
275         if ($errorcode) {
276             if (!isteacheredit($course->id)) {
277             /// Resource not available page
278                 $errortext = get_string('resourcenotavailable','resource');
279             } else {
280             /// Depending of the error, show different messages and pages
281                 if ($errorcode ==1) {
282                     $errortext = get_string('invalidfiletype','error', $resource->reference);
283                 } else if ($errorcode == 2) {
284                     $errortext = get_string('filenotfound','error', $resource->reference);
285                 } else if ($errorcode == 3) {
286                     $errortext = get_string('packagenotdeplyed','resource');
287                 } else if ($errorcode == 4) {
288                     $errortext = get_string('packagechanged','resource');
289                 }
290             }
291         /// Display the error and exit
292             if ($inpopup) {
293                 print_header($pagetitle, $course->fullname.' : '.$resource->name);
294             } else {
295                 print_header($pagetitle, $course->fullname, "$this->navigation ".format_string($resource->name), "", "", true, update_module_button($cm->id, $course->id, $this->strresource), navmenu($course, $cm));
296             }
297             print_simple_box_start('center', '60%');
298             echo '<p align="center">'.$errortext.'</p>';
299         /// If errors were 3 or 4 and isteacheredit(), show the deploy button
300             if (isteacheredit($course->id) && ($errorcode == 3 || $errorcode == 4)) {
301                 $link = 'type/ims/deploy.php';
302                 $options['courseid'] = $course->id;
303                 $options['cmid'] = $cm->id;
304                 $options['file'] = $resource->reference;
305                 $options['sesskey'] = $USER->sesskey;
306                 $options['inpopup'] = $inpopup;
307                 if ($errorcode == 3) {
308                     $label = get_string ('deploy', 'resource');
309                 } else if ($errorcode == 4) {
310                      $label = get_string ('redeploy', 'resource');
311                 }
312                 $method='post';
313             /// Let's go with the button
314                 echo '<center>';
315                 print_single_button($link, $options, $label, $method);
316                 echo '</center>';
317             }
318             print_simple_box_end();
319         /// Close button if inpopup
320             if ($inpopup) {
321                 close_window_button();
322             }
324             print_footer();
325             exit;
326         }
328     /// Load serialized IMS CP index to memory only once.
329         if (empty($items)) {
330             $resourcedir = $CFG->dataroot.'/'.$course->id.'/'.$CFG->moddata.'/resource/'.$resource->id;
331             if (!$items = ims_load_serialized_file($resourcedir.'/moodle_inx.ser')) {
332                 error (get_string('errorreadingfile', 'error', 'moodle_inx.ser'));
333             }
334         }
336     /// Check whether this is supposed to be a popup, but was called directly
338         if (empty($frameset) && $resource->popup && !$inpopup) {    /// Make a page and a pop-up window
340             print_header($pagetitle, $course->fullname, "$this->navigation ".format_string($resource->name), "", "", true, update_module_button($cm->id, $course->id, $this->strresource), navmenu($course, $cm));
342             echo "\n<script language=\"javascript\" type=\"text/javascript\">";
343             echo "\n<!--\n";
344             echo "openpopup('/mod/resource/view.php?inpopup=true&id={$cm->id}','resource{$resource->id}','{$resource->popup}');\n";
345             echo "\n-->\n";
346             echo '</script>';
348             if (trim(strip_tags($resource->summary))) {
349                 $formatoptions->noclean = true;
350                 print_simple_box(format_text($resource->summary, FORMAT_MOODLE, $formatoptions), "center");
351             }
353             $link = "<a href=\"$CFG->wwwroot/mod/resource/view.php?inpopup=true&amp;id={$cm->id}\" target=\"resource{$resource->id}\" onclick=\"return openpopup('/mod/resource/view.php?inpopup=true&amp;id={$cm->id}', 'resource{$resource->id}','{$resource->popup}');\">".format_string($resource->name,true)."</a>";
355             echo "<p>&nbsp;</p>";
356             echo '<p align="center">';
357             print_string('popupresource', 'resource');
358             echo '<br />';
359             print_string('popupresourcelink', 'resource', $link);
360             echo "</p>";
362             print_footer($course);
363             exit;
364         }
367     /// If we aren't in a frame, build it (the main one)
369         if (empty($frameset)) {
371         /// Select encoding
372             $encoding = current_charset();
374         /// Select direction
375             if (get_string('thisdirection') == 'rtl') {
376                 $direction = ' dir="rtl"';
377             } else {
378                 $direction = ' dir="ltr"';
379             }
381         /// The frameset output starts
383             echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n";
384             echo "<html$direction>\n";
385             echo '<head>';
386             echo '<meta http-equiv="content-type" content="text/html; charset='.$encoding.'" />';
387             echo "<title>{$course->shortname}: ".strip_tags(format_string($resource->name,true))."</title></head>\n";
388             echo "<frameset rows=\"$CFG->resource_framesize,*\">"; //Main frameset
389             echo "<frame src=\"view.php?id={$cm->id}&amp;type={$resource->type}&amp;frameset=top\" />"; //Top frame
390             echo "<frame src=\"view.php?id={$cm->id}&amp;type={$resource->type}&amp;frameset=ims\" />"; //Ims frame
391             echo "</frameset>";
392             echo "</html>";
393         /// We can only get here once per resource, so add an entry to the log
394             add_to_log($course->id, "resource", "view", "view.php?id={$cm->id}", $resource->id, $cm->id);
395             exit;
396         }
398     /// If required we print the ims frameset
400         if ($frameset == 'ims') {
402         /// Calculate the file.php correct url
403             if ($CFG->slasharguments) {
404                 $fileurl = "{$CFG->wwwroot}/file.php/{$course->id}/{$CFG->moddata}/resource/{$resource->id}";
405             } else {
406                 $fileurl = "{$CFG->wwwroot}/file.php?file=/{$course->id}/{$CFG->moddata}/resource/{$resource->id}";
407             }
409         /// Calculate the view.php correct url
410             $viewurl = "view.php?id={$cm->id}&amp;type={$resource->type}&amp;frameset=toc&amp;page=";
413         /// Decide what to show (full toc, partial toc or package file)
414             $fullurl = '';
415             if (empty($page) && !empty($this->parameters->tableofcontents)) {
416             /// Full toc contents
417                 $fullurl = $viewurl.$page;
418             } else {
419                 if (empty($page)) {
420                 /// If no page and no toc, set page 1
421                     $page = 1;
422                 }
423                 if (empty($items[$page]->href)) {
424                 /// The page hasn't href, then partial toc contents
425                     $fullurl = $viewurl.$page;
426                 } else {
427                 /// The page has href, then its own file contents
428                 /// but considering if it seems to be an external url or a internal one
429                     if (strpos($items[$page]->href, '//') !== false) {
430                     /// External URL
431                         $fullurl = $items[$page]->href;
432                     } else {
433                     /// Internal URL, use file.php
434                         $fullurl = $fileurl.'/'.$items[$page]->href;
435                     }
436                 }
437             }
439         /// Select encoding
440             $encoding = current_charset();
442         /// Select direction
443             if (get_string('thisdirection') == 'rtl') {
444                 $direction = ' dir="rtl"';
445             } else {
446                 $direction = ' dir="ltr"';
447             }
449         /// The frameset output starts
451             echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n";
452             echo "<html$direction>\n";
453             echo '<head>';
454             echo '<meta http-equiv="content-type" content="text/html; charset='.$encoding.'" />';
455             echo "<title>{$course->shortname}: ".strip_tags(format_string($resource->name,true))."</title></head>\n";
456             if (!empty($this->parameters->navigationbuttons)) {
457                 echo "<frameset rows=\"20,*\" border=\"0\">"; //Ims frameset with navigation buttons
458             } else {
459                 echo "<frameset rows=\"*\">";    //Ims frameset without navigation buttons
460             }
461             if (!empty($this->parameters->navigationbuttons)) {
462                 echo "<frame src=\"view.php?id={$cm->id}&amp;type={$resource->type}&amp;page={$page}&amp;frameset=nav\" scrolling=\"no\" noresize=\"noresize\" name=\"ims-nav\" />"; //Nav frame
463             }
464             echo "<frame src=\"{$fullurl}\" name=\"ims-content\" />"; //Content frame
465             echo "</frameset>";
466             echo "</html>";
467             exit;
468         }
470     /// If we are in the top frameset, just print it
472         if ($frameset == 'top') {
474         /// The header depends of the resource->popup
475             if ($resource->popup) {
476                 print_header($pagetitle, $course->fullname.' : '.$resource->name);
477             } else {
478                 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"));
479             }
480             echo '</body></html>';
481             exit;
482         }
484     /// If we are in the toc frameset, calculate and show the toc autobuilt page
486         if ($frameset == 'toc') {
487             print_header();
488             $table = new stdClass;
489             if (empty($page)) {
490                 $table->head[] = '<b>'.$resource->name.'</b>';
491             } else {
492                 $table->head[] = '<b>'.$items[$page]->title.'</b>';
493             }
494             $table->data[] = array(ims_generate_toc ($items, $resource, $page));
495             $table->width = '60%';
496             print_table($table);
497             print_footer();
498             exit;
499         }
500         
501     /// If we are in the nav frameset, just print it
503         if ($frameset == 'nav') {
504         /// Header
505             print_header();
506             echo '<div class="ims-nav-bar">';
507         /// Prev button
508             echo ims_get_prev_nav_button ($items, $this, $page);
509         /// Up button
510             echo ims_get_up_nav_button ($items, $this, $page);
511         /// Next button
512             echo ims_get_next_nav_button ($items, $this, $page);
513         /// Main TOC button
514             echo ims_get_toc_nav_button ($items, $this, $page);
515         /// Footer
516             echo '</div></div></div></body></html>';
517             exit;
518         }
519     }
522     /**
523     * Setup a new file resource
524     *
525     * Display a form to create a new or edit an existing file resource
526     *
527     * @param    form                    object
528     * @param    CFG                     global object
529     * @param    usehtmleditor           global integer
530     * @param    RESOURCE_WINDOW_OPTIONS global array
531     */
532     function setup($form) {
533         global $CFG, $usehtmleditor, $RESOURCE_WINDOW_OPTIONS;
535         parent::setup($form);
537         $strfilename = get_string("location");
538         $strnote     = get_string("note", "resource");
539         $strchooseafile = get_string("chooseafile", "resource");
540         $strnewwindow     = get_string("newwindow", "resource");
541         $strnewwindowopen = get_string("newwindowopen", "resource");
542         $strsearch        = get_string("searchweb", "resource");
544         foreach ($RESOURCE_WINDOW_OPTIONS as $optionname) {
545             $stringname = "str$optionname";
546             $$stringname = get_string("new$optionname", "resource");
547             $window->$optionname = "";
548             $jsoption[] = "\"$optionname\"";
549         }
551         $frameoption = "\"framepage\"";
552         $popupoptions = implode(",", $jsoption);
553         $jsoption[] = $frameoption;
554         $alloptions = implode(",", $jsoption);
556         if ($form->instance) {     // Re-editing
557             if (!$form->popup) {
558                 $windowtype = "page";   // No popup text => in page
559                 foreach ($RESOURCE_WINDOW_OPTIONS as $optionname) {
560                     $defaultvalue = "resource_popup$optionname";
561                     $window->$optionname = $CFG->$defaultvalue;
562                 }
563             } else {
564                 $windowtype = "popup";
565                 $rawoptions = explode(',', $form->popup);
566                 foreach ($rawoptions as $rawoption) {
567                     $option = explode('=', trim($rawoption));
568                     $optionname = $option[0];
569                     $optionvalue = $option[1];
570                     if ($optionname == 'height' or $optionname == 'width') {
571                         $window->$optionname = $optionvalue;
572                     } else if ($optionvalue) {
573                         $window->$optionname = 'checked="checked"';
574                     }
575                 }
576             }
577         } else {
578             foreach ($RESOURCE_WINDOW_OPTIONS as $optionname) {
579                 $defaultvalue = "resource_popup$optionname";
580     
581                 if ($optionname == 'height' or $optionname == 'width') {
582                     $window->$optionname = $CFG->$defaultvalue;
583                 } else if ($CFG->$defaultvalue) {
584                     $window->$optionname = 'checked="checked"';
585                 }
586             }
588             $windowtype = ($CFG->resource_popup) ? 'popup' : 'page';
589             if (empty($form->options)) {
590                 $form->options = 'frame';
591                 $form->reference = $CFG->resource_defaulturl;
592             }
593         }
594         if (empty($form->reference)) {
595             $form->reference = $CFG->resource_defaulturl;
596         }
598         //Converts the alltext to form fields
599         $parameters=$this->alltext2parameters($form->alltext);
600         $form->param_tableofcontents = $parameters->tableofcontents;
601         $form->param_navigationbuttons = $parameters->navigationbuttons;
603         //Show the setup form
604         include("$CFG->dirroot/mod/resource/type/ims/ims.html");
606         parent::setup_end();
607     }
609 } //End class
611 ///
612 /// General purpose functions
613 ///
614     /*** This function will serialize the variable passed and send it
615      *   to filesystem
616      */
617     function ims_save_serialized_file($destination, $var) {
618         $status = false;
619         if ($ser = serialize($var)) {
620             $status = ims_var2file($destination, $ser);
621         }
622         return $status;
623      }
625     /*** This function will unserialize the variable stored
626      *   in filesystem
627      */
628     function ims_load_serialized_file($file) {
629         $status = false;
630         if ($ser = ims_file2var($file)) {
631             $status = unserialize($ser);
632         }
633         return $status;
634     }
636     /*** This function will load all the contents of one file to one variable
637      *   Not suitable for BIG files
638      */
639     function ims_file2var ($file) {
640         $status = true;
641         $var = '';
642         $fp = fopen($file, 'r')
643             or $status = false;
644         if ($status) {
645            while ($data = fread($fp, 4096)) {
646                $var = $var.$data;
647            }
648            fclose($fp);
649         }
650         if (!$status) {
651             $var = false;
652         }
653         return $var;
654     }
656     /*** This file will write the contents of one variable to a file
657      *   Not suitable for BIG files
658      */
659     function ims_var2file ($file, $var) {
660         $status = false;
661         if ($out = fopen($file,"w")) {
662             $status = fwrite($out, $var);
663             fclose($out);
664         }
665         return $status;
666     }
668     /*** This function will generate the TOC file for the package
669      *   from an specified parent to be used in the view of the IMS
670      */
671     function ims_generate_toc($items, $resource, $page=0) {
672         global $CFG,$SESSION;
674         $contents = '';
676     /// Configure links behaviour
677         $fullurl = $CFG->wwwroot.'/mod/resource/view.php?r='.$resource->id.'&amp;frameset=ims&amp;page=';
679     /// Decide if we have to leave text in UTF-8, else convert to ISO-8859-1
680     /// (interim solution until everything was migrated to UTF-8). Then we'll
681     //  delete this hack.
682         $convert = true;
683         if ($SESSION->encoding == 'UTF-8') {
684             $convert = false;
685         }
687     /// Iterate over items to build the menu
688         $currlevel = 0;
689         $currorder = 0;
690         $endlevel  = 0;
691         foreach ($items as $item) {
692         /// Convert text to ISO-8859-1 if specified (will remove this once utf-8 migration was complete- 1.6)
693         if ($convert) {
694             $item->title = utf8_decode($item->title);
695         }
696         
697         /// Skip pages until we arrive to $page
698             if ($item->id < $page) {
699                 continue;
700             }
701         /// Arrive to page, we store its level
702             if ($item->id == $page) {
703                 $endlevel = $item->level;
704                 continue;
705             }
706         /// We are after page and inside it (level > endlevel)
707             if ($item->id > $page && $item->level > $endlevel) {
708             /// Start Level 
709                 if ($item->level > $currlevel) {
710                     $contents .= '<ol class="listlevel_'.$item->level.'">';
711                 }
712             /// End Level
713                 if ($item->level < $currlevel) {
714                     $contents .= '</ol>';
715                 }
716             /// Add item
717                 $contents .= '<li>';
718                 if (!empty($item->href)) {
719                     $contents .= '<a href="'.$fullurl.$item->id.'" target="_parent">'.$item->title.'</a>';
720                 } else {
721                     $contents .= $item->title;
722                 }
723                 $contents .= '</li>';
724                 $currlevel = $item->level;
725                 continue;
726             }
727         /// We have reached endlevel, exit
728             if ($item->id > $page && $item->level <= $endlevel) {
729                 break;
730             }
731         }
732         $contents .= '</ol>';
734         return $contents;
735     }
737     /*** This function will return the correct html code needed
738      *   to show the previous button in the nav frame
739      **/
740     function ims_get_prev_nav_button ($items, $resource_obj, $page) {
742         $cm = $resource_obj->cm;
743         $resource = $resource_obj->resource;
745         $contents = '';
747         if ($page > 1 ) {  //0 and 1 pages haven't previous
748             $page--;
749             $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>"; 
750         } else {
751             $contents .= '<span class="ims-nav-dimmed">&lt;&lt;</span>';
752         }
754         return $contents;
755     }
757     /*** This function will return the correct html code needed
758      *   to show the next button in the nav frame
759      **/
760     function ims_get_next_nav_button ($items, $resource_obj, $page) {
762         $cm = $resource_obj->cm;
763         $resource = $resource_obj->resource;
765         $contents = '';
767         if (!empty($items[$page+1])) {  //If the next page exists
768             $page++;
769             $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>";
770         } else {
771             $contents .= '<span class="ims-nav-dimmed">&gt;&gt;</span>';
772         }
775         return $contents;
776     }
778     /*** This function will return the correct html code needed
779      *   to show the up button in the nav frame
780      **/
781     function ims_get_up_nav_button ($items, $resource_obj, $page) {
783         $cm = $resource_obj->cm;
784         $resource = $resource_obj->resource;
786         $contents = '';
788         if ($page > 1 && $items[$page]->parent > 0 ) {  //If the page has parent
789             $page = $items[$page]->parent;
790             $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>";
791         } else {
792             $contents .= '<span class="ims-nav-dimmed">&and;</span>';
793         }
795         return $contents;
796     }
798     /*** This function will return the correct html code needed
799      *   to show the toc button in the nav frame
800      **/
801     function ims_get_toc_nav_button ($items, $resource_obj, $page) {
803         $cm = $resource_obj->cm;
804         $resource = $resource_obj->resource;
806         $strtoc = get_string('toc', 'resource');
808         $contents = '';
810         if (!empty($resource_obj->parameters->tableofcontents)) {  //The toc is enabled
811             $page = 0;
812             $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\">TOC</a></span>";
813         }
815         return $contents;
816     }
818 ?>