improved handling of Hot Potatoes navigation buttons

This commit is contained in:
gbateson 2005-09-19 06:29:14 +00:00
parent 7b2523bdba
commit 7882cdaf79
4 changed files with 99 additions and 65 deletions

View File

@ -1386,11 +1386,11 @@ class hotpot_xml_quiz extends hotpot_xml_tree {
}
return;
}
// read in the XML source and close the file
$this->source = fread($fp, filesize($this->filepath));
fclose($fp);
// convert relative URLs to absolute URLs
if ($this->convert_urls) {
$this->hotpot_convert_relative_urls($this->source);
@ -1404,10 +1404,10 @@ class hotpot_xml_quiz extends hotpot_xml_tree {
$this->source = '<html>'.$this->source;
}
}
// encode "gap fill" text in JCloze exercise
$this->encode_cdata($this->source, 'gap-fill');
// convert source to xml tree
$this->hotpot_xml_tree($this->source);
@ -1416,25 +1416,30 @@ class hotpot_xml_quiz extends hotpot_xml_tree {
$this->filetype = '';
$this->quiztype = '';
$this->outputformat = 0; // undefined
// link <HTML> tag to <html>, if necessary
if (isset($this->xml['HTML'])) {
$this->xml['html'] = &$this->xml['HTML'];
}
if (isset($this->xml['html'])) {
$this->filetype = 'html';
$this->quiztype = '';
// relative URLs in "PreloadImages(...);"
$search = '%'.'(?<='.'PreloadImages'.'\('.')'."([^)]+?)".'(?='.'\);'.')'.'%se';
$replace = "hotpot_convert_preloadimages_urls('".$this->get_baseurl()."','".$this->reference."','\\1')";
$this->source = preg_replace($search, $replace, $this->source);
// relative URLs in <button class="NavButton" ... onclick="location='...'">
$search = '%'.'(?<='.'onclick="'."location='".')'."([^']*)".'(?='."'; return false;".'")'.'%ise';
$replace = "hotpot_convert_navbutton_url('".$this->get_baseurl()."','".$this->reference."','\\1','".$this->course."')";
$this->source = preg_replace($search, $replace, $this->source);
} else {
$this->filetype = 'xml';
$keys = array_keys($this->xml);
foreach ($keys as $key) {
if (preg_match('/^(hotpot|textoys)-(\w+)-file$/i', $key, $matches)) {
@ -1529,12 +1534,11 @@ class hotpot_xml_quiz extends hotpot_xml_tree {
$quoteopen = '("|&quot;|&amp;quot;)'; // open quote
$quoteclose = '\\5'; // close quote (to match open quote)
$url = '\S+?\.\S+?';
$url = '\S+?\.\S+?'; // '.*?'
$replace = "hotpot_convert_relative_url('".$this->get_baseurl()."', '".$this->reference."', '\\1', '\\6', '\\7')";
$tags = array('script'=>'src', 'link'=>'href', 'a'=>'href','img'=>'src','param'=>'value');
foreach ($tags as $tag=>$attribute) {
$search = "%($tagopen$tag$space$anychar$attribute=$quoteopen)($url)($quoteclose$anychar$tagclose)%ise";
$str = preg_replace($search, $replace, $str);
}
@ -1607,51 +1611,51 @@ class hotpot_xml_quiz extends hotpot_xml_tree {
// make sure the Moodle media plugin is available
global $CFG;
include_once "$CFG->dirroot/filter/mediaplugin/filter.php";
// exclude swf files from the filter
$CFG->filter_mediaplugin_ignore_swf = true;
$s = '\s+'; // at least one space
$n = '[^>]*'; // any character inside a tag
$q = '["'."']?"; // single, double, or no quote
$Q = '[^"'."' >]*"; // any charater inside a quoted string
// patterns to media files types and paths
$filetype = "avi|mpeg|mpg|mp3|mov|wmv";
$filepath = "$Q\.($filetype)";
// pattern to match <param> tags which contain the file path
// wmp : url
// quicktime : src
// realplayer : src
// flash : movie (doesn't need replacing)
$url_param = "/<param$s{$n}name=$q(src|url)$q$s{$n}value=$q($filepath)$q$n>/is";
// pattern to match <a> tags which link to multimedia files (not swf)
$link = "/<a$s{$n}href=$q($filepath)$q$n>(.*?)<\/a>/is";
// extract <object> tags
preg_match_all("|<object$n>(.*?)</object>|is", $this->html, $objects);
$i_max = count($objects[0]);
for ($i=0; $i<$i_max; $i++) {
$url = '';
if (preg_match($url_param, $objects[1][$i], $matches)) {
$url = $matches[2];
} else if (preg_match($link, $objects[1][$i], $matches)) {
$url = $matches[1];
}
if ($url) {
$txt = trim(strip_tags($objects[1][$i]));
// if url is in the query string, remove the leading characters
$url = preg_replace('/^[^?]*\?([^=]+=[^&]*&)*[^=]+=([^&]*)$/', '$2', $url, 1);
$new_object = mediaplugin_filter($this->filedir, '<a href="'.$url.'">'.$txt.'</a>');
$new_object = preg_replace("|(<a$n>.*<\/a>)(.*<object$n>.*<embed$n>.*)(</embed>.*</object>.*)$|is", '$2$1$3', $new_object);
$this->html = str_replace($objects[0][$i], $new_object, $this->html);
}
}
@ -1668,10 +1672,24 @@ function hotpot_convert_preloadimages_urls($baseurl, $reference, $urls) {
}
return implode(',',$urls);
}
function hotpot_convert_navbutton_url($baseurl, $reference, $url, $course) {
global $CFG;
$url = hotpot_convert_url($baseurl, $reference, $url);
// is this a $url for another hotpot in this course ?
if (preg_match("|^$baseurl(.*)$|", $url, $matches)) {
if ($records = get_records_select('hotpot', "course='$course' AND reference='".$matches[1]."'")) {
$ids = array_keys($records);
$url = "$CFG->wwwroot/mod/hotpot/view.php?hp=".$ids[0];
}
}
return $url;
}
function hotpot_convert_relative_url($baseurl, $reference, $opentag, $url, $closetag) {
// match a series of "name=value" pairs in a <PARAM ...> tag
if (preg_match('|^'.'\w+=[^&]+'.'([&]\w+=[^&]+)*'.'$|', $url)) {
$query = $url;
$url = '';
@ -1740,9 +1758,9 @@ function hotpot_convert_url($baseurl, $reference, $url) {
if (preg_match('%^(http://|/|javascript:)%i', $url)) {
// do nothing
// has this url already been converted?
} else if (isset($HOTPOT_CONVERTED_URLS[$url])) {
$url = $HOTPOT_CONVERTED_URLS[$url];
// has this relative url already been converted?
} else if (isset($HOTPOT_RELATIVE_URLS[$url])) {
$url = $HOTPOT_RELATIVE_URLS[$url];
} else {
$relativeurl = $url;
@ -1767,7 +1785,7 @@ function hotpot_convert_url($baseurl, $reference, $url) {
$url = "$baseurl$url";
// add url to cache
$HOTPOT_CONVERTED_URLS[$relativeurl] = $url;
$HOTPOT_RELATIVE_URLS[$relativeurl] = $url;
}
return $url;
}

View File

@ -593,28 +593,42 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
// nav bar
function v6_expand_NavBar() {
function v6_expand_NavBar($navbarid='') {
$this->navbarid = $navbarid;
$tag = 'navbar';
$this->read_template('hp6navbar.ht_', $tag);
unset($this->navbarid);
return $this->$tag;
}
function v6_expand_TopNavBar() {
return $this->v6_expand_NavBar();
return $this->v6_expand_NavBar('TopNavBar');
}
function v6_expand_BottomNavBar() {
return $this->v6_expand_NavBar();
}
function v6_expand_NextExURL() {
return $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',next-ex-url');
return $this->v6_expand_NavBar('BottomNavBar');
}
// hp6navbar.ht_
function v6_expand_NavBarID() {
return ''; // what's this?;
// $this->navbarid is set in "$this->v6_expand_NavBar"
return empty($this->navbarid) ? '' : $this->navbarid;
}
function v6_expand_ContentsURL() {
return $this->parent->xml_value('hotpot-config-file,global,contents-url');
$url = $this->parent->xml_value('hotpot-config-file,global,contents-url');
if ($url) {
$url = hotpot_convert_navbutton_url($this->parent->get_baseurl(), $this->parent->reference, $url, $this->parent->course);
}
return $url;
}
function v6_expand_NextExURL() {
$url = $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',next-ex-url');
if ($url) {
$url = hotpot_convert_navbutton_url($this->parent->get_baseurl(), $this->parent->reference, $url, $this->parent->course);
}
return $url;
}
// conditional blocks

View File

@ -5,8 +5,8 @@
/// This fragment is called by moodle_needs_upgrading() and /admin/index.php
/////////////////////////////////////////////////////////////////////////////////
$module->version = 2005090700; // release date of this version (see note below)
$module->release = 'v2.1.0'; // human-friendly version name (used in mod/hotpot/lib.php)
$module->version = 2005090701; // release date of this version (see note below)
$module->release = 'v2.1.1'; // human-friendly version name (used in mod/hotpot/lib.php)
$module->cron = 0; // period for cron to check this module (secs)
// interpretation of YYYYMMDDXY version numbers

View File

@ -155,13 +155,13 @@
if (empty($frameset)) {
// HP v6
if ($hotpot->navigation==HOTPOT_NAVIGATION_FRAME || $hotpot->navigation==HOTPOT_NAVIGATION_IFRAME) {
$get_html = ($framename=='main');
$get_html = ($framename=='main') ? true : false;
} else {
$get_html = true;
}
} else {
// HP5 v5
$get_html = empty($framename);
$get_html = empty($framename) ? true : false;
}
if ($get_html) {
@ -176,7 +176,9 @@
if (empty($frameset)) {
// HP6 v6
if ($hotpot->navigation!=HOTPOT_NAVIGATION_BUTTONS) {
if ($hotpot->navigation==HOTPOT_NAVIGATION_BUTTONS) {
// convert URLs in nav buttons
} else {
$hp->remove_nav_buttons();
}
if ($hotpot->navigation==HOTPOT_NAVIGATION_GIVEUP) {
@ -186,7 +188,10 @@
} else {
// HP5 v5
if ($hotpot->navigation!=HOTPOT_NAVIGATION_BUTTONS) {
if ($hotpot->navigation==HOTPOT_NAVIGATION_BUTTONS) {
// convert URLs in nav buttons
} else {
// remove navigation buttons
$hp->html = preg_replace('#NavBar\+=(.*);#', '', $hp->html);
}
if ($hotpot->navigation==HOTPOT_NAVIGATION_GIVEUP) {
@ -285,9 +290,8 @@
// extract <head> and <body> tags
$head = '';
$pattern = '|<head([^>]*)>(.*?)</head>|is';
if (preg_match_all($pattern, $hp->html, $matches)) {
$last = count($matches[0])-1;
$head = $matches[2][$last];
if (preg_match($pattern, $hp->html, $matches)) {
$head = $matches[2]; // first <head>...</head> block
// remove <title>
$head = preg_replace('|<title[^>]*>(.*?)</title>|is', '', $head);
@ -347,33 +351,31 @@
} // end switch $frameset
exit;
// is there a <body> (HP6 and HP5: v6 and v4)
} else if (preg_match_all('|<body([^>]*)>(.*?)</body>|is', $hp->html, $matches)) {
$last = count($matches[0])-1;
$body = $matches[2][$last];
$body_tags = $matches[1][$last];
// is there a <body> (HP6 and HP5: v6 and v4)
} else if (preg_match('|<body'.'([^>]*'.'onLoad=(["\'])(.*?)(\\2)'.'[^>]*)'.'>(.*)</body>|is', $hp->html, $matches)) {
$body = $matches[5]; // contents of first <body onload="StartUp()">...</body> block
$body_tags = $matches[1];
// workaround to ensure javascript onload routine for quiz is always executed
// $body_tags will only be inserted into the <body ...> tag
// if it is included in the theme/$CFG->theme/header.html,
// so some old or modified themes may not insert $body_tags
if (preg_match('/onload=("|\')(.*?)(\\1)/i', $body_tags, $matches)) {
$body .= ""
.'<SCRIPT type="text/javascript">'."\n"
."<!--\n"
." var s = (typeof(window.onload)=='function') ? onload.toString() : '';\n"
." if (s.indexOf('".$matches[2]."')<0) {\n"
." if (s=='') {\n" // no previous onload
." window.onload = new Function('".$matches[2]."');\n"
." } else {\n"
." window.onload_hotpot = onload;\n"
." window.onload = new Function('window.onload_hotpot();' + '".$matches[2]."');\n"
." }\n"
." }\n"
."//-->\n"
."</SCRIPT>\n"
;
}
$body .= ""
. '<SCRIPT type="text/javascript">'."\n"
. "<!--\n"
. " var s = (typeof(window.onload)=='function') ? onload.toString() : '';\n"
. " if (s.indexOf('".$matches[3]."')<0) {\n"
. " if (s=='') {\n" // no previous onload
. " window.onload = new Function('".$matches[3]."');\n"
. " } else {\n"
. " window.onload_hotpot = onload;\n"
. " window.onload = new Function('window.onload_hotpot();'+'".$matches[3]."');\n"
. " }\n"
. " }\n"
. "//-->\n"
. "</SCRIPT>\n"
;
$footer = '</body>'.$footer;
}