Modified
[moodle.git] / lib / weblib.php
CommitLineData
f9903ed0 1<?PHP // $Id$
2
9fa49e22 3///////////////////////////////////////////////////////////////////////////
4// weblib.php - functions for web output
f9903ed0 5//
9fa49e22 6// Library of all general-purpose Moodle PHP functions and constants
7// that produce HTML output
f9903ed0 8//
9fa49e22 9///////////////////////////////////////////////////////////////////////////
10// //
11// NOTICE OF COPYRIGHT //
12// //
13// Moodle - Modular Object-Oriented Dynamic Learning Environment //
14// http://moodle.com //
15// //
16// Copyright (C) 2001-2003 Martin Dougiamas http://dougiamas.com //
17// //
18// This program is free software; you can redistribute it and/or modify //
19// it under the terms of the GNU General Public License as published by //
20// the Free Software Foundation; either version 2 of the License, or //
21// (at your option) any later version. //
22// //
23// This program is distributed in the hope that it will be useful, //
24// but WITHOUT ANY WARRANTY; without even the implied warranty of //
25// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
26// GNU General Public License for more details: //
27// //
28// http://www.gnu.org/copyleft/gpl.html //
29// //
30///////////////////////////////////////////////////////////////////////////
f9903ed0 31
0095d5cd 32/// Constants
33
c1d57101 34/// Define text formatting types ... eventually we can add Wiki, BBcode etc
0095d5cd 35define("FORMAT_MOODLE", "0");
36define("FORMAT_HTML", "1");
37
c9dda990 38$SMILEY_TEXT[] = ":-)";
39$SMILEY_IMAGE[] = "<IMG ALT=\":-)\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/smiley.gif\">";
40$SMILEY_TEXT[] = ":)";
41$SMILEY_IMAGE[] = "<IMG ALT=\":-)\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/smiley.gif\">";
42$SMILEY_TEXT[] = ":-D";
43$SMILEY_IMAGE[] = "<IMG ALT=\":-D\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/biggrin.gif\">";
44$SMILEY_TEXT[] = ";-)";
45$SMILEY_IMAGE[] = "<IMG ALT=\";-)\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/wink.gif\">";
46$SMILEY_TEXT[] = ":-/";
47$SMILEY_IMAGE[] = "<IMG ALT=\":-/\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/mixed.gif\">";
48$SMILEY_TEXT[] = "V-.";
49$SMILEY_IMAGE[] = "<IMG ALT=\"V-.\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/thoughtful.gif\">";
50$SMILEY_TEXT[] = ":-P";
51$SMILEY_IMAGE[] = "<IMG ALT=\":-P\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/tongueout.gif\">";
52$SMILEY_TEXT[] = "B-)";
53$SMILEY_IMAGE[] = "<IMG ALT=\"B-)\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/cool.gif\">";
54$SMILEY_TEXT[] = "^-)";
55$SMILEY_IMAGE[] = "<IMG ALT=\"^-)\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/approve.gif\">";
56$SMILEY_TEXT[] = "8-)";
57$SMILEY_IMAGE[] = "<IMG ALT=\"8-)\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/wideeyes.gif\">";
58$SMILEY_TEXT[] = ":o)";
59$SMILEY_IMAGE[] = "<IMG ALT=\":o)\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/clown.gif\">";
60$SMILEY_TEXT[] = ":-(";
61$SMILEY_IMAGE[] = "<IMG ALT=\":-(\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/sad.gif\">";
62$SMILEY_TEXT[] = ":(";
63$SMILEY_IMAGE[] = "<IMG ALT=\":-(\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/sad.gif\">";
64$SMILEY_TEXT[] = "8-.";
65$SMILEY_IMAGE[] = "<IMG ALT=\"8-.\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/shy.gif\">";
66$SMILEY_TEXT[] = ":-I";
67$SMILEY_IMAGE[] = "<IMG ALT=\":-I\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/blush.gif\">";
68$SMILEY_TEXT[] = ":-X";
69$SMILEY_IMAGE[] = "<IMG ALT=\":-X\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/kiss.gif\">";
70$SMILEY_TEXT[] = "8-o";
71$SMILEY_IMAGE[] = "<IMG ALT=\"8-o\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/surprise.gif\">";
72$SMILEY_TEXT[] = "P-|";
73$SMILEY_IMAGE[] = "<IMG ALT=\"P-|\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/blackeye.gif\">";
74$SMILEY_TEXT[] = "8-[";
75$SMILEY_IMAGE[] = "<IMG ALT=\"8-[\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/angry.gif\">";
76$SMILEY_TEXT[] = "xx-P";
77$SMILEY_IMAGE[] = "<IMG ALT=\"xx-P\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/dead.gif\">";
78$SMILEY_TEXT[] = "|-.";
79$SMILEY_IMAGE[] = "<IMG ALT=\"|-.\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/sleepy.gif\">";
80$SMILEY_TEXT[] = "}-]";
81$SMILEY_IMAGE[] = "<IMG ALT=\"}-]\" WIDTH=15 HEIGHT=15 SRC=\"$CFG->wwwroot/pix/s/evil.gif\">";
0095d5cd 82
3fe3851d 83$JAVASCRIPT_TAGS = array("javascript:", "onclick=", "ondblclick=", "onkeydown=", "onkeypress=", "onkeyup=",
84 "onmouseover=", "onmouseout=", "onmousedown=", "onmouseup=",
85 "onblur=", "onfocus=", "onload=", "onselect=");
86
6dd38d46 87$ALLOWED_TAGS = "<p><br><b><i><u><font><table><tbody><span><div><tr><td><ol><ul><dl><li><dt><dd><h1><h2><h3><h4><h5><h6><hr><img><a><strong><emphasis><sup><sub><address><cite><blockquote><pre><strike>";
3fe3851d 88
89
0095d5cd 90/// Functions
91
8553b700 92function s($var) {
c1d57101 93/// returns $var with HTML characters (like "<", ">", etc.) properly quoted,
f9903ed0 94
b9b8ab69 95 return htmlSpecialChars(stripslashes($var));
f9903ed0 96}
97
98function p($var) {
c1d57101 99/// prints $var with HTML characters (like "<", ">", etc.) properly quoted,
f9903ed0 100
b9b8ab69 101 echo htmlSpecialChars(stripslashes($var));
f9903ed0 102}
103
8553b700 104function nvl(&$var, $default="") {
c1d57101 105/// if $var is undefined, return $default, otherwise return $var
8553b700 106
107 return isset($var) ? $var : $default;
108}
f9903ed0 109
110function strip_querystring($url) {
c1d57101 111/// takes a URL and returns it without the querystring portion
f9903ed0 112
b9b8ab69 113 if ($commapos = strpos($url, '?')) {
114 return substr($url, 0, $commapos);
115 } else {
116 return $url;
117 }
f9903ed0 118}
119
120function get_referer() {
c1d57101 121/// returns the URL of the HTTP_REFERER, less the querystring portion
f9903ed0 122
607809b3 123 return strip_querystring(nvl($_SERVER["HTTP_REFERER"]));
f9903ed0 124}
125
c1d57101 126
f9903ed0 127function me() {
c1d57101 128/// returns the name of the current script, WITH the querystring portion.
129/// this function is necessary because PHP_SELF and REQUEST_URI and PATH_INFO
130/// return different things depending on a lot of things like your OS, Web
131/// server, and the way PHP is compiled (ie. as a CGI, module, ISAPI, etc.)
f9903ed0 132
607809b3 133 if (!empty($_SERVER["REQUEST_URI"])) {
134 return $_SERVER["REQUEST_URI"];
c1d57101 135
607809b3 136 } else if (!empty($_SERVER["PATH_INFO"])) {
137 return $_SERVER["PATH_INFO"];
c1d57101 138
607809b3 139 } else if (!empty($_SERVER["PHP_SELF"])) {
140 return $_SERVER["PHP_SELF"];
c1d57101 141
b9b8ab69 142 } else {
c1d57101 143 notify("Error: Could not find any of these web server variables: \$REQUEST_URI, \$PATH_INFO or \$PHP_SELF");
7fbd6b1c 144 }
f9903ed0 145}
146
147
f9903ed0 148function qualified_me() {
c1d57101 149/// like me() but returns a full URL
f9903ed0 150
607809b3 151 if (empty($_SERVER["HTTP_HOST"])) {
c1d57101 152 notify("Error: could not find web server variable: \$HTTP_HOST");
153 }
f9903ed0 154
607809b3 155 $protocol = (isset($_SERVER["HTTPS"]) and $_SERVER["HTTPS"] == "on") ? "https://" : "http://";
156 $url_prefix = "$protocol".$_SERVER["HTTP_HOST"];
b9b8ab69 157 return $url_prefix . me();
f9903ed0 158}
159
160
161function match_referer($good_referer = "") {
c1d57101 162/// returns true if the referer is the same as the good_referer. If
87a2fa03 163/// good_referer is not specified, use qualified_me as the good_referer
60f18531 164 global $CFG;
165
ce78926d 166 if (!empty($CFG->buggy_referer)) {
60f18531 167 return true;
168 }
f9903ed0 169
ce78926d 170 if (empty($good_referer)) {
c1d57101 171 $good_referer = qualified_me();
172 }
b9b8ab69 173 return $good_referer == get_referer();
f9903ed0 174}
175
36b4f985 176function data_submitted($url="") {
177/// Used on most forms in Moodle to check for data
178/// Returns the data as an object, if it's found.
607809b3 179/// This object can be used in foreach loops without
180/// casting because it's cast to (array) automatically
36b4f985 181///
182/// Checks that submitted POST data exists, and also
183/// checks the referer against the given url (it uses
184/// the current page if none was specified.
185
607809b3 186 if (empty($_POST)) {
36b4f985 187 return false;
607809b3 188
36b4f985 189 } else {
190 if (match_referer($url)) {
607809b3 191 return (object)$_POST;
36b4f985 192 } else {
193 if ($CFG->debug > 10) {
194 notice("The form did not come from this page! (referer = ".get_referer().")");
195 }
196 return false;
197 }
198 }
199}
200
f9903ed0 201
3fe3851d 202function stri_replace($find, $replace, $string ) {
c1d57101 203/// This does a search and replace, ignoring case
204/// This function is only here because one doesn't exist yet in PHP
205/// Unlike str_replace(), this only works on single values (not arrays)
3fe3851d 206
207 $parts = explode(strtolower($find), strtolower($string));
208
209 $pos = 0;
210
211 foreach ($parts as $key => $part) {
212 $parts[$key] = substr($string, $pos, strlen($part));
213 $pos += strlen($part) + strlen($find);
214 }
215
216 return (join($replace, $parts));
217}
218
f9903ed0 219function read_template($filename, &$var) {
c1d57101 220/// return a (big) string containing the contents of a template file with all
221/// the variables interpolated. all the variables must be in the $var[] array or
222/// object (whatever you decide to use).
223///
224/// WARNING: do not use this on big files!!
f9903ed0 225
b9b8ab69 226 $temp = str_replace("\\", "\\\\", implode(file($filename), ""));
227 $temp = str_replace('"', '\"', $temp);
228 eval("\$template = \"$temp\";");
229 return $template;
f9903ed0 230}
231
232function checked(&$var, $set_value = 1, $unset_value = 0) {
c1d57101 233/// if variable is set, set it to the set_value otherwise set it to the
234/// unset_value. used to handle checkboxes when you are expecting them from
235/// a form
f9903ed0 236
b9b8ab69 237 if (empty($var)) {
238 $var = $unset_value;
239 } else {
240 $var = $set_value;
241 }
f9903ed0 242}
243
244function frmchecked(&$var, $true_value = "checked", $false_value = "") {
c1d57101 245/// prints the word "checked" if a variable is true, otherwise prints nothing,
246/// used for printing the word "checked" in a checkbox form input
f9903ed0 247
b9b8ab69 248 if ($var) {
249 echo $true_value;
250 } else {
251 echo $false_value;
252 }
f9903ed0 253}
254
255
65cf9fc3 256function link_to_popup_window ($url, $name="popup", $linkname="click here", $height=400, $width=500, $title="Popup window") {
c1d57101 257/// This will create a HTML link that will work on both
258/// Javascript and non-javascript browsers.
259/// Relies on the Javascript function openpopup in javascript.php
260/// $url must be relative to home page eg /mod/survey/stuff.php
f9903ed0 261
ff80e012 262 global $CFG;
263
b9b8ab69 264 echo "\n<SCRIPT language=\"Javascript\">";
f9903ed0 265 echo "\n<!--";
b9b8ab69 266 echo "\ndocument.write('<A TITLE=\"$title\" HREF=javascript:openpopup(\"$url\",\"$name\",\"$height\",\"$width\") >$linkname</A>');";
f9903ed0 267 echo "\n//-->";
b9b8ab69 268 echo "\n</SCRIPT>";
269 echo "\n<NOSCRIPT>\n<A TARGET=\"$name\" TITLE=\"$title\" HREF=\"$CFG->wwwroot/$url\">$linkname</A>\n</NOSCRIPT>\n";
f9903ed0 270
271}
272
273function close_window_button() {
c1d57101 274/// Prints a simple button to close a window
275
f9903ed0 276 echo "<FORM><CENTER>";
e5dfd0f3 277 echo "<INPUT TYPE=button onClick=\"self.close();\" VALUE=\"".get_string("closewindow")."\">";
f9903ed0 278 echo "</CENTER></FORM>";
279}
280
281
08056730 282function choose_from_menu ($options, $name, $selected="", $nothing="choose", $script="", $nothingvalue="0", $return=false) {
c1d57101 283/// Given an array of value, creates a popup menu to be part of a form
284/// $options["value"]["label"]
f9903ed0 285
618b22c5 286 if ($nothing == "choose") {
287 $nothing = get_string("choose")."...";
288 }
289
f9903ed0 290 if ($script) {
291 $javascript = "onChange=\"$script\"";
9c9f7d77 292 } else {
293 $javascript = "";
f9903ed0 294 }
9c9f7d77 295
08056730 296 $output = "<SELECT NAME=$name $javascript>\n";
bda8d43a 297 if ($nothing) {
08056730 298 $output .= " <OPTION VALUE=\"$nothingvalue\"\n";
bda8d43a 299 if ($nothingvalue == $selected) {
08056730 300 $output .= " SELECTED";
bda8d43a 301 }
08056730 302 $output .= ">$nothing</OPTION>\n";
873960de 303 }
607809b3 304 if (!empty($options)) {
305 foreach ($options as $value => $label) {
306 $output .= " <OPTION VALUE=\"$value\"";
307 if ($value == $selected) {
308 $output .= " SELECTED";
309 }
310 if ($label) {
311 $output .= ">$label</OPTION>\n";
312 } else {
313 $output .= ">$value</OPTION>\n";
314 }
f9903ed0 315 }
316 }
08056730 317 $output .= "</SELECT>\n";
318
319 if ($return) {
320 return $output;
321 } else {
322 echo $output;
323 }
f9903ed0 324}
325
d897cae4 326function popup_form ($common, $options, $formname, $selected="", $nothing="choose", $help="", $helptext="", $return=false) {
c1d57101 327/// Implements a complete little popup form
328/// $common = the URL up to the point of the variable that changes
329/// $options = A list of value-label pairs for the popup list
330/// $formname = name must be unique on the page
331/// $selected = the option that is already selected
332/// $nothing = The label for the "no choice" option
e5dfd0f3 333/// $help = The name of a help page if help is required
334/// $helptext = The name of the label for the help button
f9903ed0 335
618b22c5 336 if ($nothing == "choose") {
337 $nothing = get_string("choose")."...";
338 }
339
3e50a139 340 $output = "<FORM TARGET=_top NAME=$formname>";
341 $output .= "<SELECT NAME=popup onChange=\"top.location=document.$formname.popup.options[document.$formname.popup.selectedIndex].value\">\n";
f9903ed0 342
343 if ($nothing != "") {
d897cae4 344 $output .= " <OPTION VALUE=\"javascript:void(0)\">$nothing</OPTION>\n";
f9903ed0 345 }
346
347 foreach ($options as $value => $label) {
d897cae4 348 if (substr($label,0,1) == "-") {
349 $output .= " <OPTION VALUE=\"\"";
350 } else {
351 $output .= " <OPTION VALUE=\"$common$value\"";
352 if ($value == $selected) {
353 $output .= " SELECTED";
354 }
f9903ed0 355 }
356 if ($label) {
d897cae4 357 $output .= ">$label</OPTION>\n";
f9903ed0 358 } else {
d897cae4 359 $output .= ">$value</OPTION>\n";
f9903ed0 360 }
361 }
d897cae4 362 $output .= "</SELECT>";
d897cae4 363 $output .= "</FORM>\n";
364
365 if ($return) {
366 return $output;
367 } else {
9c9f7d77 368 if ($help) {
369 helpbutton($help, $helptext);
370 }
d897cae4 371 echo $output;
372 }
f9903ed0 373}
374
375
376
377function formerr($error) {
c1d57101 378/// Prints some red text
f9903ed0 379 if (!empty($error)) {
380 echo "<font color=#ff0000>$error</font>";
381 }
382}
383
384
385function validate_email ($address) {
c1d57101 386/// Validates an email to make it makes sense.
f9903ed0 387 return (ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.
388 '@'.
389 '[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
390 '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$',
391 $address));
392}
393
394
395function get_slash_arguments($i=0) {
c1d57101 396/// Extracts arguments from "/foo/bar/something"
397/// eg http://mysite.com/script.php/foo/bar/something
398/// Might only work on Apache
f9903ed0 399
400 global $PATH_INFO;
401
402 if (!isset($PATH_INFO)) {
403 return false;
404 }
405
780db230 406 if (strpos($PATH_INFO, "..")) { // check for parent URLs
407 return false;
408 }
409 if (strpos($PATH_INFO, "|")) { // check for pipes
410 return false;
411 }
412 if (strpos($PATH_INFO, "`")) { // check for backquotes
e2d89725 413 return false;
414 }
415
f9903ed0 416 $args = explode("/", $PATH_INFO);
417
418 if ($i) { // return just the required argument
419 return $args[$i];
420
421 } else { // return the whole array
422 array_shift($args); // get rid of the empty first one
423 return $args;
424 }
425}
426
0095d5cd 427function format_text_menu() {
c1d57101 428/// Just returns an array of formats suitable for a popup menu
0095d5cd 429 return array (FORMAT_MOODLE => get_string("formattext"),
430 FORMAT_HTML => get_string("formathtml") );
431}
432
60f18531 433function format_text($text, $format=FORMAT_MOODLE, $options=NULL) {
c1d57101 434/// Given text in a variety of format codings, this function returns
435/// the text as safe HTML.
436///
437/// $text is raw text (originally from a user)
438/// $format is one of the format constants, defined above
0095d5cd 439
440 switch ($format) {
441 case FORMAT_MOODLE:
c9dda990 442 if (!isset($options->smiley)) {
443 $options->smiley=true;
444 }
445 if (!isset($options->para)) {
1a072208 446 $options->para=true;
c9dda990 447 }
0095d5cd 448 return text_to_html($text, $options->smiley, $options->para);
449 break;
f9903ed0 450
0095d5cd 451 case FORMAT_HTML:
1a072208 452 $text = replace_smilies($text);
3fe3851d 453 return $text;
0095d5cd 454 break;
455 }
456}
457
458
459function clean_text($text, $format) {
c1d57101 460/// Given raw text (eg typed in by a user), this function cleans it up
461/// and removes any nasty tags that could mess up Moodle pages.
b7a3cf49 462
3fe3851d 463 global $JAVASCRIPT_TAGS, $ALLOWED_TAGS;
464
465 switch ($format) { // Does the same thing, currently, but it's nice to have the option
0095d5cd 466 case FORMAT_MOODLE:
3fe3851d 467 $text = strip_tags($text, $ALLOWED_TAGS);
468 foreach ($JAVASCRIPT_TAGS as $tag) {
469 $text = stri_replace($tag, "", $text);
470 }
471 return $text;
0095d5cd 472
473 case FORMAT_HTML:
3fe3851d 474 $text = strip_tags($text, $ALLOWED_TAGS);
475 foreach ($JAVASCRIPT_TAGS as $tag) {
476 $text = stri_replace($tag, "", $text);
477 }
478 return $text;
0095d5cd 479 }
b7a3cf49 480}
f9903ed0 481
1a072208 482function replace_smilies($text) {
c1d57101 483/// Replaces all known smileys in the text with image equivalents
484
1a072208 485 global $CFG, $SMILEY_TEXT, $SMILEY_IMAGE;
b7a3cf49 486
1a072208 487 return str_replace($SMILEY_TEXT, $SMILEY_IMAGE, $text);
488}
0095d5cd 489
909f539d 490function text_to_html($text, $smiley=true, $para=true) {
c1d57101 491/// Given plain text, makes it into HTML as nicely as possible.
492/// May contain HTML tags already
f9903ed0 493
c1d57101 494/// Remove any whitespace that may be between HTML tags
7b3be1b1 495 $text = eregi_replace(">([[:space:]]+)<", "><", $text);
496
c1d57101 497/// Remove any returns that precede or follow HTML tags
0eae8049 498 $text = eregi_replace("([\n\r])<", " <", $text);
499 $text = eregi_replace(">([\n\r])", "> ", $text);
7b3be1b1 500
c1d57101 501/// Make lone URLs into links. eg http://moodle.com/
0be05df0 502 $text = eregi_replace("([\n\r ([])([[:alnum:]]+)://([^[:space:]]*)([[:alnum:]#?/&=])",
3fe3851d 503 "\\1<A HREF=\"\\2://\\3\\4\" TARGET=\"newpage\">\\2://\\3\\4</A>", $text);
f9903ed0 504
c1d57101 505/// eg www.moodle.com
e1bf736f 506 $text = eregi_replace("([[:space:]])www\.([^[:space:]]*)([[:alnum:]#?/&=])",
f9903ed0 507 "\\1<A HREF=\"http://www.\\2\\3\" TARGET=\"newpage\">www.\\2\\3</A>", $text);
508
c1d57101 509/// Make returns into HTML newlines.
f9903ed0 510 $text = nl2br($text);
511
c1d57101 512/// Turn smileys into images.
d69cb7f4 513 if ($smiley) {
1a072208 514 $text = replace_smilies($text);
d69cb7f4 515 }
f9903ed0 516
c1d57101 517/// Wrap the whole thing in a paragraph tag if required
909f539d 518 if ($para) {
519 return "<P>".$text."</P>";
520 } else {
521 return $text;
522 }
f9903ed0 523}
524
5af78ed2 525function highlight($needle, $haystack) {
c1d57101 526/// This function will highlight instances of $needle in $haystack
5af78ed2 527
528 $parts = explode(strtolower($needle), strtolower($haystack));
529
530 $pos = 0;
531
532 foreach ($parts as $key => $part) {
533 $parts[$key] = substr($haystack, $pos, strlen($part));
534 $pos += strlen($part);
535
536 $parts[$key] .= "<SPAN CLASS=highlight>".substr($haystack, $pos, strlen($needle))."</SPAN>";
537 $pos += strlen($needle);
538 }
539
540 return (join('', $parts));
541}
542
f9903ed0 543
9fa49e22 544
545/// STANDARD WEB PAGE PARTS ///////////////////////////////////////////////////
546
547function print_header ($title="", $heading="", $navigation="", $focus="", $meta="", $cache=true, $button="&nbsp;", $menu="") {
548// $title - appears top of window
549// $heading - appears top of page
550// $navigation - premade navigation string
551// $focus - indicates form element eg inputform.password
552// $meta - meta tags in the header
553// $cache - should this page be cacheable?
554// $button - HTML code for a button (usually for module editing)
555// $menu - HTML code for a popup menu
556 global $USER, $CFG, $THEME;
557
558 if (file_exists("$CFG->dirroot/theme/$CFG->theme/styles.php")) {
559 $styles = $CFG->stylesheet;
560 } else {
561 $styles = "$CFG->wwwroot/theme/standard/styles.php";
562 }
563
564 if ($navigation == "home") {
565 $home = true;
566 $navigation = "";
9d378732 567 } else {
568 $home = false;
9fa49e22 569 }
570
571 if ($button == "") {
572 $button = "&nbsp;";
573 }
574
575 if (!$menu and $navigation) {
576 if (isset($USER->id)) {
577 $menu = "<FONT SIZE=2><A TARGET=_parent HREF=\"$CFG->wwwroot/login/logout.php\">".get_string("logout")."</A></FONT>";
578 } else {
579 $menu = "<FONT SIZE=2><A TARGET=_parent HREF=\"$CFG->wwwroot/login/index.php\">".get_string("login")."</A></FONT>";
580 }
581 }
582
583 // Specify character set ... default is iso-8859-1 but some languages might need something else
584 // Could be optimised by carrying the charset variable around in $USER
585 if (current_language() == "en") {
586 $meta = "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-1\">\n$meta\n";
587 } else {
588 $meta = "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=".get_string("thischarset")."\">\n$meta\n";
589 }
590
591 if ($CFG->langdir == "RTL") {
592 $direction = " DIR=\"RTL\"";
593 } else {
594 $direction = " DIR=\"LTR\"";
595 }
596
597 if (!$cache) { // Do everything we can to prevent clients and proxies caching
598 @header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
599 @header("Pragma: no-cache");
600 $meta .= "\n<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">";
601 $meta .= "\n<META HTTP-EQUIV=\"Expires\" CONTENT=\"0\">";
602 }
603
604 include ("$CFG->dirroot/theme/$CFG->theme/header.html");
605}
606
607function print_footer ($course=NULL) {
608// Can provide a course object to make the footer contain a link to
609// to the course home page, otherwise the link will go to the site home
610 global $USER, $CFG, $THEME;
611
612
613/// Course links
614 if ($course) {
615 if ($course == "home") { // special case for site home page - please do not remove
616 $homelink = "<P ALIGN=center><A TITLE=\"Moodle $CFG->release ($CFG->version)\" HREF=\"http://moodle.com/\">";
617 $homelink .= "<BR><IMG WIDTH=130 HEIGHT=19 SRC=\"pix/madewithmoodle2.gif\" BORDER=0></A></P>";
618 $course = get_site();
619 $homepage = true;
620 } else {
621 $homelink = "<A TARGET=_top HREF=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</A>";
622 }
623 } else {
624 $homelink = "<A TARGET=_top HREF=\"$CFG->wwwroot\">".get_string("home")."</A>";
625 $course = get_site();
626 }
627
628/// User links
9d378732 629 if (isset($USER->realuser)) {
9fa49e22 630 if ($realuser = get_record("user", "id", $USER->realuser)) {
631 $realuserinfo = " [<A HREF=\"$CFG->wwwroot/course/loginas.php?id=$course->id&return=$realuser->id\">$realuser->firstname $realuser->lastname</A>] ";
632 }
9d378732 633 } else {
634 $realuserinfo = "";
9fa49e22 635 }
636
9c9f7d77 637 if (isset($USER->id) and $USER->id) {
9fa49e22 638 $username = "<A HREF=\"$CFG->wwwroot/user/view.php?id=$USER->id&course=$course->id\">$USER->firstname $USER->lastname</A>";
639 $loggedinas = $realuserinfo.get_string("loggedinas", "moodle", "$username").
640 " (<A HREF=\"$CFG->wwwroot/login/logout.php\">".get_string("logout")."</A>)";
641 } else {
642 $loggedinas = get_string("loggedinnot", "moodle").
643 " (<A HREF=\"$CFG->wwwroot/login/index.php\">".get_string("login")."</A>)";
644 }
645
646 include ("$CFG->dirroot/theme/$CFG->theme/footer.html");
647}
648
649
650
651function print_navigation ($navigation) {
652 global $CFG;
653
654 if ($navigation) {
655 if (! $site = get_site()) {
656 $site->shortname = get_string("home");;
657 }
658 echo "<A TARGET=_top HREF=\"$CFG->wwwroot/\">$site->shortname</A> -> $navigation";
659 }
660}
661
662function print_heading($text, $align="CENTER", $size=3) {
663 echo "<P ALIGN=\"$align\"><FONT SIZE=\"$size\"><B>".stripslashes($text)."</B></FONT></P>";
664}
665
666function print_heading_with_help($text, $helppage, $module="moodle") {
667// Centered heading with attached help button (same title text)
668 echo "<P ALIGN=\"CENTER\"><FONT SIZE=\"3\"><B>".stripslashes($text);
669 helpbutton($helppage, $text, $module);
670 echo "</B></FONT></P>";
671}
672
673function print_continue($link) {
9fa49e22 674
675 if (!$link) {
607809b3 676 $link = $_SERVER["HTTP_REFERER"];
9fa49e22 677 }
678
679 print_heading("<A HREF=\"$link\">".get_string("continue")."</A>");
680}
681
682
683function print_simple_box($message, $align="", $width="", $color="#FFFFFF", $padding=5, $class="generalbox") {
684 print_simple_box_start($align, $width, $color, $padding, $class);
685 echo stripslashes($message);
686 print_simple_box_end();
687}
688
689function print_simple_box_start($align="", $width="", $color="#FFFFFF", $padding=5, $class="generalbox") {
690 global $THEME;
691
692 if ($align) {
9d378732 693 $align = "ALIGN=\"$align\"";
9fa49e22 694 }
695 if ($width) {
9d378732 696 $width = "WIDTH=\"$width\"";
9fa49e22 697 }
9d378732 698 echo "<table $align $width class=\"$class\" border=\"0\" cellpadding=\"$padding\" cellspacing=\"0\"><tr><td bgcolor=\"$color\" class=\"$class"."content\">";
9fa49e22 699}
700
701function print_simple_box_end() {
702 echo "</td></tr></table>";
703}
704
705function print_single_button($link, $options, $label="OK") {
706 echo "<FORM ACTION=\"$link\" METHOD=GET>";
707 if ($options) {
708 foreach ($options as $name => $value) {
709 echo "<INPUT TYPE=hidden NAME=\"$name\" VALUE=\"$value\">";
710 }
711 }
712 echo "<INPUT TYPE=submit VALUE=\"$label\"></FORM>";
713}
714
715function print_spacer($height=1, $width=1, $br=true) {
716 global $CFG;
717 echo "<IMG HEIGHT=\"$height\" WIDTH=\"$width\" SRC=\"$CFG->wwwroot/pix/spacer.gif\" ALT=\"\">";
718 if ($br) {
719 echo "<BR \>\n";
720 }
721}
722
723function print_file_picture($path, $courseid=0, $height="", $width="", $link="") {
724// Given the path to a picture file in a course, or a URL,
725// this function includes the picture in the page.
726 global $CFG;
727
728 if ($height) {
729 $height = "HEIGHT=\"$height\"";
730 }
731 if ($width) {
732 $width = "WIDTH=\"$width\"";
733 }
734 if ($link) {
735 echo "<A HREF=\"$link\">";
736 }
737 if (substr(strtolower($path), 0, 7) == "http://") {
738 echo "<IMG BORDER=0 $height $width SRC=\"$path\">";
739
740 } else if ($courseid) {
741 echo "<IMG BORDER=0 $height $width SRC=\"";
742 if ($CFG->slasharguments) { // Use this method if possible for better caching
743 echo "$CFG->wwwroot/file.php/$courseid/$path";
744 } else {
745 echo "$CFG->wwwroot/file.php?file=$courseid/$path";
746 }
747 echo "\">";
748 } else {
749 echo "Error: must pass URL or course";
750 }
751 if ($link) {
752 echo "</A>";
753 }
754}
755
756function print_user_picture($userid, $courseid, $picture, $large=false, $returnstring=false, $link=true) {
757 global $CFG;
758
759 if ($link) {
760 $output = "<A HREF=\"$CFG->wwwroot/user/view.php?id=$userid&course=$courseid\">";
761 } else {
762 $output = "";
763 }
764 if ($large) {
765 $file = "f1.jpg";
766 $size = 100;
767 } else {
768 $file = "f2.jpg";
769 $size = 35;
770 }
771 if ($picture) {
772 if ($CFG->slasharguments) { // Use this method if possible for better caching
773 $output .= "<IMG SRC=\"$CFG->wwwroot/user/pix.php/$userid/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
774 } else {
775 $output .= "<IMG SRC=\"$CFG->wwwroot/user/pix.php?file=/$userid/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
776 }
777 } else {
778 $output .= "<IMG SRC=\"$CFG->wwwroot/user/default/$file\" BORDER=0 WIDTH=$size HEIGHT=$size ALT=\"\">";
779 }
780 if ($link) {
781 $output .= "</A>";
782 }
783
784 if ($returnstring) {
785 return $output;
786 } else {
787 echo $output;
788 }
789}
790
791function print_table($table) {
792// Prints a nicely formatted table.
793// $table is an object with several properties.
794// $table->head is an array of heading names.
795// $table->align is an array of column alignments
796// $table->size is an array of column sizes
797// $table->data[] is an array of arrays containing the data.
798// $table->width is an percentage of the page
799// $table->cellpadding padding on each cell
800// $table->cellspacing spacing between cells
801
802 if (isset($table->align)) {
803 foreach ($table->align as $key => $aa) {
804 if ($aa) {
805 $align[$key] = " ALIGN=\"$aa\"";
806 } else {
807 $align[$key] = "";
808 }
809 }
810 }
811 if (isset($table->size)) {
812 foreach ($table->size as $key => $ss) {
813 if ($ss) {
814 $size[$key] = " WIDTH=\"$ss\"";
815 } else {
816 $size[$key] = "";
817 }
818 }
819 }
820
9d378732 821 if (empty($table->width)) {
9fa49e22 822 $table->width = "80%";
823 }
824
9d378732 825 if (empty($table->cellpadding)) {
9fa49e22 826 $table->cellpadding = "5";
827 }
828
9d378732 829 if (empty($table->cellspacing)) {
9fa49e22 830 $table->cellspacing = "1";
831 }
832
833 print_simple_box_start("CENTER", "$table->width", "#FFFFFF", 0);
834 echo "<TABLE WIDTH=100% BORDER=0 valign=top align=center ";
835 echo " cellpadding=\"$table->cellpadding\" cellspacing=\"$table->cellspacing\" class=\"generaltable\">\n";
836
b79f41cd 837 if (!empty($table->head)) {
9fa49e22 838 echo "<TR>";
839 foreach ($table->head as $key => $heading) {
9d378732 840 if (!isset($size[$key])) {
841 $size[$key] = "";
842 }
843 if (!isset($align[$key])) {
844 $align[$key] = "";
845 }
9fa49e22 846 echo "<TH VALIGN=top ".$align[$key].$size[$key]." NOWRAP class=\"generaltableheader\">$heading</TH>";
847 }
848 echo "</TR>\n";
849 }
850
851 foreach ($table->data as $row) {
852 echo "<TR VALIGN=TOP>";
853 foreach ($row as $key => $item) {
9d378732 854 if (!isset($size[$key])) {
855 $size[$key] = "";
856 }
857 if (!isset($align[$key])) {
858 $align[$key] = "";
859 }
9fa49e22 860 echo "<TD ".$align[$key].$size[$key]." class=\"generaltablecell\">$item</TD>";
861 }
862 echo "</TR>\n";
863 }
864 echo "</TABLE>\n";
865 print_simple_box_end();
866
867 return true;
868}
869
870function print_editing_switch($courseid) {
871 global $CFG, $USER;
872
873 if (isteacher($courseid)) {
874 if ($USER->editing) {
875 echo "<A HREF=\"$CFG->wwwroot/course/view.php?id=$courseid&edit=off\">Turn editing off</A>";
876 } else {
877 echo "<A HREF=\"$CFG->wwwroot/course/view.php?id=$courseid&edit=on\">Turn editing on</A>";
878 }
879 }
880}
881
882function print_textarea($richedit, $rows, $cols, $width, $height, $name, $value="") {
883 global $CFG, $THEME;
884
885 if ($richedit) {
886 echo "<object id=richedit style=\"BACKGROUND-COLOR: buttonface\"";
887 echo " data=\"$CFG->wwwroot/lib/rte/richedit.html\"";
888 echo " width=\"$width\" height=\"$height\" ";
889 echo " type=\"text/x-scriptlet\" VIEWASTEXT></object>\n";
890 echo "<TEXTAREA style=\"display:none\" NAME=\"$name\" ROWS=1 COLS=1>";
891 p($value);
892 echo "</TEXTAREA>\n";
893 } else {
894 echo "<TEXTAREA name=\"$name\" rows=\"$rows\" cols=\"$cols\" wrap=virtual>";
895 p($value);
896 echo "</TEXTAREA>\n";
897 }
898}
899
900function print_richedit_javascript($form, $name, $source="no") {
901 echo "<SCRIPT language=\"JavaScript\" event=\"onload\" for=\"window\">\n";
902 echo " document.richedit.options = \"history=no;source=$source\";";
903 echo " document.richedit.docHtml = $form.$name.innerText;";
904 echo "</SCRIPT>";
905}
906
907
908function update_course_icon($courseid) {
909// Used to be an icon, but it's now a simple form button
910 global $CFG, $USER;
911
912 if (isteacher($courseid)) {
9c9f7d77 913 if (!empty($USER->editing)) {
9fa49e22 914 $string = get_string("turneditingoff");
915 $edit = "off";
916 } else {
917 $string = get_string("turneditingon");
918 $edit = "on";
919 }
920 return "<FORM TARGET=_parent METHOD=GET ACTION=\"$CFG->wwwroot/course/view.php\">".
921 "<INPUT TYPE=hidden NAME=id VALUE=\"$courseid\">".
922 "<INPUT TYPE=hidden NAME=edit VALUE=\"$edit\">".
923 "<INPUT TYPE=submit VALUE=\"$string\"></FORM>";
924 }
925}
926
927function update_module_button($moduleid, $courseid, $string) {
928// Prints the editing button on a module "view" page
929 global $CFG;
930
931 if (isteacher($courseid)) {
932 $string = get_string("updatethis", "", $string);
933 return "<FORM TARGET=_parent METHOD=GET ACTION=\"$CFG->wwwroot/course/mod.php\">".
934 "<INPUT TYPE=hidden NAME=update VALUE=\"$moduleid\">".
935 "<INPUT TYPE=hidden NAME=return VALUE=\"true\">".
936 "<INPUT TYPE=submit VALUE=\"$string\"></FORM>";
937 }
938}
939
940
941function navmenu($course, $cm=NULL) {
942// Given a course and a (current) coursemodule
943// This function returns a small popup menu with all the
944// course activity modules in it, as a navigation menu
945// The data is taken from the serialised array stored in
946// the course record
947
948 global $CFG;
949
950 if ($cm) {
951 $cm = $cm->id;
952 }
953
954 if ($course->format == 'weeks') {
955 $strsection = get_string("week");
956 } else {
957 $strsection = get_string("topic");
958 }
959
960 if (!$modinfo = unserialize($course->modinfo)) {
961 return "";
962 }
963 $section = -1;
964 $selected = "";
965 foreach ($modinfo as $mod) {
966 if ($mod->section > 0 and $section <> $mod->section) {
967 $menu[] = "-------------- $strsection $mod->section --------------";
968 }
969 $section = $mod->section;
970 $url = "$mod->mod/view.php?id=$mod->cm";
971 if ($cm == $mod->cm) {
972 $selected = $url;
973 }
974 $mod->name = urldecode($mod->name);
975 if (strlen($mod->name) > 55) {
976 $mod->name = substr($mod->name, 0, 50)."...";
977 }
978 $menu[$url] = $mod->name;
979 }
980
981 return popup_form("$CFG->wwwroot/mod/", $menu, "navmenu", $selected, get_string("jumpto"), "", "", true);
982}
983
984
985
986function print_date_selector($day, $month, $year, $currenttime=0) {
987// Currenttime is a default timestamp in GMT
988// Prints form items with the names $day, $month and $year
989
990 if (!$currenttime) {
991 $currenttime = time();
992 }
993 $currentdate = usergetdate($currenttime);
994
995 for ($i=1; $i<=31; $i++) {
996 $days[$i] = "$i";
997 }
998 for ($i=1; $i<=12; $i++) {
8663bfdb 999 $months[$i] = userdate(mktime(0,0,0,$i,1,2000), "%B");
9fa49e22 1000 }
1001 for ($i=2000; $i<=2010; $i++) {
1002 $years[$i] = $i;
1003 }
47f1da80 1004 choose_from_menu($days, $day, $currentdate['mday'], "");
1005 choose_from_menu($months, $month, $currentdate['mon'], "");
1006 choose_from_menu($years, $year, $currentdate['year'], "");
9fa49e22 1007}
1008
1009function print_time_selector($hour, $minute, $currenttime=0) {
1010// Currenttime is a default timestamp in GMT
1011// Prints form items with the names $hour and $minute
1012
1013 if (!$currenttime) {
1014 $currenttime = time();
1015 }
1016 $currentdate = usergetdate($currenttime);
1017 for ($i=0; $i<=23; $i++) {
1018 $hours[$i] = sprintf("%02d",$i);
1019 }
1020 for ($i=0; $i<=59; $i++) {
1021 $minutes[$i] = sprintf("%02d",$i);
1022 }
47f1da80 1023 choose_from_menu($hours, $hour, $currentdate['hours'], "");
1024 choose_from_menu($minutes, $minute, $currentdate['minutes'], "");
9fa49e22 1025}
1026
1027function error ($message, $link="") {
1028 global $CFG, $SESSION;
1029
1030 print_header(get_string("error"));
1031 echo "<BR>";
1032 print_simple_box($message, "center", "", "#FFBBBB");
1033
1034 if (!$link) {
1035 if ( !empty($SESSION->fromurl) ) {
1036 $link = "$SESSION->fromurl";
1037 unset($SESSION->fromurl);
1038 save_session("SESSION");
1039 } else {
1040 $link = "$CFG->wwwroot";
1041 }
1042 }
1043 print_continue($link);
1044 print_footer();
1045 die;
1046}
1047
1048function helpbutton ($page, $title="", $module="moodle", $image=true, $linktext=false, $text="") {
1049 // $page = the keyword that defines a help page
1050 // $title = the title of links, rollover tips, alt tags etc
1051 // $module = which module is the page defined in
1052 // $image = use a help image for the link? (true/false/"both")
1053 // $text = if defined then this text is used in the page, and
1054 // the $page variable is ignored.
1055 global $CFG;
1056
1057 if ($module == "") {
1058 $module = "moodle";
1059 }
1060
1061 if ($image) {
1062 if ($linktext) {
1063 $linkobject = "$title<IMG align=\"absmiddle\" BORDER=0 HEIGHT=17 WIDTH=22 ALT=\"\" SRC=\"$CFG->wwwroot/pix/help.gif\">";
1064 } else {
1065 $linkobject = "<IMG align=\"absmiddle\" BORDER=0 HEIGHT=17 WIDTH=22 ALT=\"$title\" SRC=\"$CFG->wwwroot/pix/help.gif\">";
1066 }
1067 } else {
1068 $linkobject = $title;
1069 }
1070 if ($text) {
1071 $url = "/help.php?module=$module&text=".htmlentities(urlencode($text));
1072 } else {
1073 $url = "/help.php?module=$module&file=$page.html";
1074 }
1075 link_to_popup_window ($url, "popup", $linkobject, 400, 500, $title);
1076}
1077
1078function notice ($message, $link="") {
607809b3 1079 global $THEME;
9fa49e22 1080
1081 if (!$link) {
607809b3 1082 $link = $_SERVER["HTTP_REFERER"];
9fa49e22 1083 }
1084
1085 echo "<BR>";
1086 print_simple_box($message, "center", "", "$THEME->cellheading");
1087 print_heading("<A HREF=\"$link\">".get_string("continue")."</A>");
1088 print_footer(get_site());
1089 die;
1090}
1091
1092function notice_yesno ($message, $linkyes, $linkno) {
1093 global $THEME;
1094
1095 print_simple_box_start("center", "", "$THEME->cellheading");
1096 echo "<P ALIGN=CENTER><FONT SIZE=3>$message</FONT></P>";
1097 echo "<P ALIGN=CENTER><FONT SIZE=3><B>";
1098 echo "<A HREF=\"$linkyes\">".get_string("yes")."</A>";
1099 echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
1100 echo "<A HREF=\"$linkno\">".get_string("no")."</A>";
1101 echo "</B></FONT></P>";
1102 print_simple_box_end();
1103}
1104
1105function redirect($url, $message="", $delay=0) {
1106// Uses META tags to redirect the user, after printing a notice
1107
1108 echo "<META HTTP-EQUIV='Refresh' CONTENT='$delay; URL=$url'>";
1109
1110 if (!empty($message)) {
1111 print_header();
1112 echo "<CENTER>";
1113 echo "<P>$message</P>";
1114 echo "<P>( <A HREF=\"$url\">".get_string("continue")."</A> )</P>";
1115 echo "</CENTER>";
1116 }
1117 die;
1118}
1119
99988d1a 1120function notify ($message, $color="red", $align="center") {
1121 echo "<p align=\"$align\"><b><font color=\"$color\">$message</font></b></p>\n";
9fa49e22 1122}
1123
1124
f9903ed0 1125?>