- Testing... If you can read this.. I solved the problem (thanks to Martin)! :)
[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
6901fa79 35define("FORMAT_MOODLE", "0"); // Does all sorts of transformations and filtering
d342c763 36define("FORMAT_HTML", "1"); // Plain HTML (with some tags stripped)
37define("FORMAT_PLAIN", "2"); // Plain text (even tags are printed in full)
38define("FORMAT_WIKI", "3"); // Wiki-formatted text
0095d5cd 39
950cf403 40$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><em><sup><sub><address><cite><blockquote><pre><strike><embed><object><param><acronym>";
3fe3851d 41
42
0095d5cd 43/// Functions
44
3662bce5 45function s($var) {
c1d57101 46/// returns $var with HTML characters (like "<", ">", etc.) properly quoted,
f9903ed0 47
3662bce5 48 if (empty($var)) {
49 return "";
50 }
7d8f674d 51 return htmlSpecialChars(stripslashes_safe($var));
f9903ed0 52}
53
3662bce5 54function p($var) {
c1d57101 55/// prints $var with HTML characters (like "<", ">", etc.) properly quoted,
f9903ed0 56
3662bce5 57 if (empty($var)) {
58 echo "";
59 }
7d8f674d 60 echo htmlSpecialChars(stripslashes_safe($var));
f9903ed0 61}
62
8553b700 63function nvl(&$var, $default="") {
c1d57101 64/// if $var is undefined, return $default, otherwise return $var
8553b700 65
66 return isset($var) ? $var : $default;
67}
f9903ed0 68
69function strip_querystring($url) {
c1d57101 70/// takes a URL and returns it without the querystring portion
f9903ed0 71
b9b8ab69 72 if ($commapos = strpos($url, '?')) {
73 return substr($url, 0, $commapos);
74 } else {
75 return $url;
76 }
f9903ed0 77}
78
79function get_referer() {
c1d57101 80/// returns the URL of the HTTP_REFERER, less the querystring portion
f9903ed0 81
607809b3 82 return strip_querystring(nvl($_SERVER["HTTP_REFERER"]));
f9903ed0 83}
84
c1d57101 85
f9903ed0 86function me() {
c1d57101 87/// returns the name of the current script, WITH the querystring portion.
eaa50dbc 88/// this function is necessary because PHP_SELF and REQUEST_URI and SCRIPT_NAME
c1d57101 89/// return different things depending on a lot of things like your OS, Web
90/// server, and the way PHP is compiled (ie. as a CGI, module, ISAPI, etc.)
f9903ed0 91
607809b3 92 if (!empty($_SERVER["REQUEST_URI"])) {
93 return $_SERVER["REQUEST_URI"];
c1d57101 94
607809b3 95 } else if (!empty($_SERVER["PHP_SELF"])) {
fced815c 96 if (!empty($_SERVER["QUERY_STRING"])) {
97 return $_SERVER["PHP_SELF"]."?".$_SERVER["QUERY_STRING"];
98 }
607809b3 99 return $_SERVER["PHP_SELF"];
c1d57101 100
fced815c 101 } else if (!empty($_SERVER["SCRIPT_NAME"])) {
102 if (!empty($_SERVER["QUERY_STRING"])) {
103 return $_SERVER["SCRIPT_NAME"]."?".$_SERVER["QUERY_STRING"];
104 }
105 return $_SERVER["SCRIPT_NAME"];
106
b9b8ab69 107 } else {
fced815c 108 notify("Warning: Could not find any of these web server variables: \$REQUEST_URI, \$PHP_SELF or \$SCRIPT_NAME");
bcdfe14e 109 return false;
7fbd6b1c 110 }
f9903ed0 111}
112
113
f9903ed0 114function qualified_me() {
c1d57101 115/// like me() but returns a full URL
f9903ed0 116
39e018b3 117 if (!empty($_SERVER["HTTP_HOST"])) {
118 $hostname = $_SERVER["HTTP_HOST"];
119 } else if (!empty($_ENV["HTTP_HOST"])) {
120 $hostname = $_ENV["HTTP_HOST"];
df3fd249 121 } else if (!empty($_SERVER["SERVER_NAME"])) {
122 $hostname = $_SERVER["SERVER_NAME"];
39e018b3 123 } else if (!empty($_ENV["SERVER_NAME"])) {
124 $hostname = $_ENV["SERVER_NAME"];
125 } else {
126 notify("Warning: could not find the name of this server!");
bcdfe14e 127 return false;
c1d57101 128 }
f9903ed0 129
607809b3 130 $protocol = (isset($_SERVER["HTTPS"]) and $_SERVER["HTTPS"] == "on") ? "https://" : "http://";
39e018b3 131 $url_prefix = $protocol.$hostname;
b9b8ab69 132 return $url_prefix . me();
f9903ed0 133}
134
135
a0deb5db 136function match_referer($goodreferer = "") {
137/// returns true if the referer is the same as the goodreferer. If
138/// goodreferer is not specified, use qualified_me as the goodreferer
60f18531 139 global $CFG;
140
ae384ef1 141 if (empty($CFG->secureforms)) { // Don't bother checking referer
60f18531 142 return true;
143 }
f9903ed0 144
ae384ef1 145 if ($goodreferer == "nomatch") { // Don't bother checking referer
a0deb5db 146 return true;
147 }
148
149 if (empty($goodreferer)) {
150 $goodreferer = qualified_me();
c1d57101 151 }
a0deb5db 152 return $goodreferer == get_referer();
f9903ed0 153}
154
36b4f985 155function data_submitted($url="") {
156/// Used on most forms in Moodle to check for data
157/// Returns the data as an object, if it's found.
607809b3 158/// This object can be used in foreach loops without
159/// casting because it's cast to (array) automatically
36b4f985 160///
161/// Checks that submitted POST data exists, and also
162/// checks the referer against the given url (it uses
163/// the current page if none was specified.
164
37208cd2 165 global $CFG;
166
607809b3 167 if (empty($_POST)) {
36b4f985 168 return false;
607809b3 169
36b4f985 170 } else {
171 if (match_referer($url)) {
607809b3 172 return (object)$_POST;
36b4f985 173 } else {
174 if ($CFG->debug > 10) {
175 notice("The form did not come from this page! (referer = ".get_referer().")");
176 }
177 return false;
178 }
179 }
180}
181
7d8f674d 182function stripslashes_safe($string) {
183/// stripslashes() removes ALL backslashes even from strings
184/// so C:\temp becomes C:temp ... this isn't good.
185/// The following should work as a fairly safe replacement
186/// to be called on quoted AND unquoted strings (to be sure)
187
188 $string = str_replace("\\'", "'", $string);
189 $string = str_replace('\\"', '"', $string);
190 $string = str_replace('\\\\', '\\', $string);
191 return $string;
192}
f9903ed0 193
72e4eac6 194if (!function_exists('str_ireplace')) {
195 function str_ireplace($find, $replace, $string ) {
196 /// This does a search and replace, ignoring case
197 /// This function is only here because one doesn't exist yet in PHP
198 /// Unlike str_replace(), this only works on single values (not arrays)
199
200 $parts = explode(strtolower($find), strtolower($string));
201
202 $pos = 0;
203
204 foreach ($parts as $key => $part) {
205 $parts[$key] = substr($string, $pos, strlen($part));
206 $pos += strlen($part) + strlen($find);
207 }
208
209 return (join($replace, $parts));
3fe3851d 210 }
3fe3851d 211}
212
f9903ed0 213function read_template($filename, &$var) {
c1d57101 214/// return a (big) string containing the contents of a template file with all
215/// the variables interpolated. all the variables must be in the $var[] array or
216/// object (whatever you decide to use).
217///
218/// WARNING: do not use this on big files!!
f9903ed0 219
b9b8ab69 220 $temp = str_replace("\\", "\\\\", implode(file($filename), ""));
221 $temp = str_replace('"', '\"', $temp);
222 eval("\$template = \"$temp\";");
223 return $template;
f9903ed0 224}
225
226function checked(&$var, $set_value = 1, $unset_value = 0) {
c1d57101 227/// if variable is set, set it to the set_value otherwise set it to the
228/// unset_value. used to handle checkboxes when you are expecting them from
229/// a form
f9903ed0 230
b9b8ab69 231 if (empty($var)) {
232 $var = $unset_value;
233 } else {
234 $var = $set_value;
235 }
f9903ed0 236}
237
238function frmchecked(&$var, $true_value = "checked", $false_value = "") {
c1d57101 239/// prints the word "checked" if a variable is true, otherwise prints nothing,
240/// used for printing the word "checked" in a checkbox form input
f9903ed0 241
b9b8ab69 242 if ($var) {
243 echo $true_value;
244 } else {
245 echo $false_value;
246 }
f9903ed0 247}
248
249
86aa7ccf 250function link_to_popup_window ($url, $name="popup", $linkname="click here",
b48f834c 251 $height=400, $width=500, $title="Popup window", $options="none") {
c1d57101 252/// This will create a HTML link that will work on both
253/// Javascript and non-javascript browsers.
254/// Relies on the Javascript function openpopup in javascript.php
255/// $url must be relative to home page eg /mod/survey/stuff.php
f9903ed0 256
ff80e012 257 global $CFG;
258
b48f834c 259 if ($options == "none") {
260 $options = "menubar=0,location=0,scrollbars,resizable,width=$width,height=$height";
261 }
86aa7ccf 262 $fullscreen = 0;
f9903ed0 263
55e4b5f9 264 echo "<a target=\"$name\" title=\"$title\" href=\"$CFG->wwwroot$url\" ".
86aa7ccf 265 "onClick=\"return openpopup('$url', '$name', '$options', $fullscreen);\">$linkname</a>\n";
f9903ed0 266}
267
86aa7ccf 268
f9903ed0 269function close_window_button() {
c1d57101 270/// Prints a simple button to close a window
271
86aa7ccf 272 echo "<center>\n";
273 echo "<script>\n";
274 echo "<!--\n";
275 echo "document.write('<form>');\n";
66a51452 276 echo "document.write('<input type=\"button\" onClick=\"self.close();\" value=\"".get_string("closewindow")."\" />');\n";
86aa7ccf 277 echo "document.write('</form>');\n";
278 echo "-->\n";
279 echo "</script>\n";
280 echo "<noscript>\n";
281 echo "<a href=\"".$_SERVER['HTTP_REFERER']."\"><---</a>\n";
282 echo "</noscript>\n";
283 echo "</center>\n";
f9903ed0 284}
285
286
08056730 287function choose_from_menu ($options, $name, $selected="", $nothing="choose", $script="", $nothingvalue="0", $return=false) {
c1d57101 288/// Given an array of value, creates a popup menu to be part of a form
289/// $options["value"]["label"]
f9903ed0 290
618b22c5 291 if ($nothing == "choose") {
292 $nothing = get_string("choose")."...";
293 }
294
f9903ed0 295 if ($script) {
296 $javascript = "onChange=\"$script\"";
9c9f7d77 297 } else {
298 $javascript = "";
f9903ed0 299 }
9c9f7d77 300
66a51452 301 $output = "<select name=\"$name\" $javascript>\n";
bda8d43a 302 if ($nothing) {
76c1650d 303 $output .= " <option value=\"$nothingvalue\"\n";
bda8d43a 304 if ($nothingvalue == $selected) {
66a51452 305 $output .= " selected=\"true\"";
bda8d43a 306 }
76c1650d 307 $output .= ">$nothing</option>\n";
873960de 308 }
607809b3 309 if (!empty($options)) {
310 foreach ($options as $value => $label) {
76c1650d 311 $output .= " <option value=\"$value\"";
607809b3 312 if ($value == $selected) {
66a51452 313 $output .= " selected=\"true\"";
607809b3 314 }
a20c1090 315 if ($label === "") {
76c1650d 316 $output .= ">$value</option>\n";
a20c1090 317 } else {
318 $output .= ">$label</option>\n";
607809b3 319 }
f9903ed0 320 }
321 }
76c1650d 322 $output .= "</select>\n";
08056730 323
324 if ($return) {
325 return $output;
326 } else {
327 echo $output;
328 }
f9903ed0 329}
330
16ef5e78 331function popup_form ($common, $options, $formname, $selected="", $nothing="choose", $help="", $helptext="", $return=false, $targetwindow="self") {
c1d57101 332/// Implements a complete little popup form
333/// $common = the URL up to the point of the variable that changes
334/// $options = A list of value-label pairs for the popup list
335/// $formname = name must be unique on the page
336/// $selected = the option that is already selected
337/// $nothing = The label for the "no choice" option
e5dfd0f3 338/// $help = The name of a help page if help is required
339/// $helptext = The name of the label for the help button
5b472756 340/// $return = Boolean indicating whether the function should return the text
341/// as a string or echo it directly to the page being rendered
f9903ed0 342
0d0baabf 343 global $CFG;
344
618b22c5 345 if ($nothing == "choose") {
346 $nothing = get_string("choose")."...";
347 }
348
66a51452 349 $startoutput = "<form target=\"{$CFG->framename}\" name=\"$formname\">";
350 $output = "<select name=\"popup\" onchange=\"$targetwindow.location=document.$formname.popup.options[document.$formname.popup.selectedIndex].value\">\n";
f9903ed0 351
352 if ($nothing != "") {
dfec7b01 353 $output .= " <option value=\"javascript:void(0)\">$nothing</option>\n";
f9903ed0 354 }
355
356 foreach ($options as $value => $label) {
d897cae4 357 if (substr($label,0,1) == "-") {
dfec7b01 358 $output .= " <option value=\"\"";
d897cae4 359 } else {
dfec7b01 360 $output .= " <option value=\"$common$value\"";
d897cae4 361 if ($value == $selected) {
66a51452 362 $output .= " selected=\"true\"";
d897cae4 363 }
f9903ed0 364 }
365 if ($label) {
dfec7b01 366 $output .= ">$label</option>\n";
f9903ed0 367 } else {
dfec7b01 368 $output .= ">$value</option>\n";
f9903ed0 369 }
370 }
dfec7b01 371 $output .= "</select>";
372 $output .= "</form>\n";
d897cae4 373
374 if ($return) {
dfec7b01 375 return $startoutput.$output;
d897cae4 376 } else {
dfec7b01 377 echo $startoutput;
9c9f7d77 378 if ($help) {
379 helpbutton($help, $helptext);
380 }
d897cae4 381 echo $output;
382 }
f9903ed0 383}
384
385
386
387function formerr($error) {
c1d57101 388/// Prints some red text
f9903ed0 389 if (!empty($error)) {
66a51452 390 echo "<font color=\"#ff0000\">$error</font>";
f9903ed0 391 }
392}
393
394
395function validate_email ($address) {
66a51452 396/// Validates an email to make sure it makes sense.
f9903ed0 397 return (ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.
398 '@'.
399 '[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
400 '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$',
401 $address));
402}
403
6c8e8b5e 404function detect_munged_arguments($string) {
393c9b4f 405 if (ereg('\.\.', $string)) { // check for parent URLs
6c8e8b5e 406 return true;
407 }
393c9b4f 408 if (ereg('[\|\`]', $string)) { // check for other bad characters
6c8e8b5e 409 return true;
410 }
411 return false;
412}
413
6ed3da1d 414function get_slash_arguments($file="file.php") {
415/// Searches the current environment variables for some slash arguments
f9903ed0 416
eaa50dbc 417 if (!$string = me()) {
f9903ed0 418 return false;
419 }
eaa50dbc 420
6ed3da1d 421 $pathinfo = explode($file, $string);
422
bcdfe14e 423 if (!empty($pathinfo[1])) {
424 return $pathinfo[1];
6ed3da1d 425 } else {
426 return false;
427 }
428}
429
430function parse_slash_arguments($string, $i=0) {
431/// Extracts arguments from "/foo/bar/something"
432/// eg http://mysite.com/script.php/foo/bar/something
f9903ed0 433
6c8e8b5e 434 if (detect_munged_arguments($string)) {
780db230 435 return false;
436 }
6ed3da1d 437 $args = explode("/", $string);
f9903ed0 438
439 if ($i) { // return just the required argument
440 return $args[$i];
441
442 } else { // return the whole array
443 array_shift($args); // get rid of the empty first one
444 return $args;
445 }
446}
447
0095d5cd 448function format_text_menu() {
c1d57101 449/// Just returns an array of formats suitable for a popup menu
0095d5cd 450 return array (FORMAT_MOODLE => get_string("formattext"),
6901fa79 451 FORMAT_HTML => get_string("formathtml"),
d342c763 452 FORMAT_PLAIN => get_string("formatplain"),
453 FORMAT_WIKI => get_string("formatwiki"));
0095d5cd 454}
455
60f18531 456function format_text($text, $format=FORMAT_MOODLE, $options=NULL) {
c1d57101 457/// Given text in a variety of format codings, this function returns
458/// the text as safe HTML.
459///
460/// $text is raw text (originally from a user)
461/// $format is one of the format constants, defined above
0095d5cd 462
e67b9e31 463 global $CFG, $course;
a751a4e5 464
0095d5cd 465 switch ($format) {
73f8658c 466 case FORMAT_HTML:
5f350e8f 467 replace_smilies($text);
e67b9e31 468 return filter_text($text);
73f8658c 469 break;
470
6901fa79 471 case FORMAT_PLAIN:
472 $text = htmlentities($text);
3405b212 473 $text = str_replace(" ", "&nbsp; ", $text);
5f350e8f 474 replace_smilies($text);
6901fa79 475 $text = nl2br($text);
476 return $text;
477 break;
478
d342c763 479 case FORMAT_WIKI:
e67b9e31 480 $text = wiki_to_html($text);
481 return filter_text($text);
d342c763 482 break;
483
73f8658c 484 default: // FORMAT_MOODLE or anything else
c9dda990 485 if (!isset($options->smiley)) {
486 $options->smiley=true;
487 }
488 if (!isset($options->para)) {
1a072208 489 $options->para=true;
c9dda990 490 }
e67b9e31 491 $text = text_to_html($text, $options->smiley, $options->para);
492 return filter_text($text);
493
0095d5cd 494 break;
0095d5cd 495 }
496}
497
d342c763 498function format_text_email($text, $format) {
499/// Given text in a variety of format codings, this function returns
500/// the text as plain text suitable for plain email.
501///
502/// $text is raw text (originally from a user)
503/// $format is one of the format constants, defined above
504
505 switch ($format) {
506
507 case FORMAT_PLAIN:
508 return $text;
509 break;
510
511 case FORMAT_WIKI:
512 $text = wiki_to_html($text);
5b472756 513 /// This expression turns links into something nice in a text format. (Russell Jungwirth)
514 /// From: http://php.net/manual/en/function.eregi-replace.php and simplified
515 $text = eregi_replace('(<a [^<]*href=["|\']?([^ "\']*)["|\']?[^>]*>([^<]*)</a>)','\\3 [\\2]', $text);
7c55a29b 516 return strtr(strip_tags($text), array_flip(get_html_translation_table(HTML_ENTITIES)));
d342c763 517 break;
518
519 default: // FORMAT_MOODLE or anything else
5b472756 520 $text = eregi_replace('(<a [^<]*href=["|\']?([^ "\']*)["|\']?[^>]*>([^<]*)</a>)','\\3 [\\2]', $text);
7c55a29b 521 return strtr(strip_tags($text), array_flip(get_html_translation_table(HTML_ENTITIES)));
d342c763 522 break;
523 }
524}
0095d5cd 525
e67b9e31 526
527function filter_text($text) {
528/// Given some text in HTML format, this function will pass it
529/// through any filters that have been defined in $CFG->textfilterx
530/// The variable defines a filepath to a file containing the
531/// filter function. The file must contain a variable called
532/// $textfilter_function which contains the name of the function
533/// with $course->id and $text parameters
534
535 global $CFG, $course; // A dirty hack right now ... should not be assumed global
536
537 if (empty($course->id)) {
538 return $text;
539 }
540
541 for ($i=1; $i<=10; $i++) {
542 $variable = "textfilter$i";
543 if (empty($CFG->$variable)) { /// No more filters
544 return $text;
545 }
546 if (is_readable("$CFG->dirroot/".$CFG->$variable)) {
547 include("$CFG->dirroot/".$CFG->$variable);
548 $text = $textfilter_function($course->id, $text);
549 }
550 }
551 return $text;
552}
553
554
0095d5cd 555function clean_text($text, $format) {
c1d57101 556/// Given raw text (eg typed in by a user), this function cleans it up
557/// and removes any nasty tags that could mess up Moodle pages.
b7a3cf49 558
fc120758 559 global $ALLOWED_TAGS;
3fe3851d 560
d342c763 561 switch ($format) {
0095d5cd 562 case FORMAT_MOODLE:
0095d5cd 563 case FORMAT_HTML:
d342c763 564 case FORMAT_WIKI:
5b472756 565 /// Remove javascript: label
3fe3851d 566 $text = strip_tags($text, $ALLOWED_TAGS);
5b472756 567 /// Remove javascript/VBScript
568 $text = str_ireplace("javascript:", "xxx", $text);
569 /// Remove script events
570 $text = eregi_replace("([^a-z])language([[:space:]]*)=", "xxx", $text);
571 $text = eregi_replace("([^a-z])on([a-z]+)([[:space:]]*)=", "xxx", $text);
3fe3851d 572 return $text;
6901fa79 573
574 case FORMAT_PLAIN:
575 return $text;
0095d5cd 576 }
b7a3cf49 577}
f9903ed0 578
5f350e8f 579function replace_smilies(&$text) {
c1d57101 580/// Replaces all known smileys in the text with image equivalents
2ea9027b 581 global $CFG;
c1d57101 582
5b472756 583/// this builds the mapping array only once
617778f2 584 static $runonce = false;
69081931 585 static $e = array();
586 static $img = array();
617778f2 587 static $emoticons = array(
2ea9027b 588 ':-)' => 'smiley.gif',
589 ':)' => 'smiley.gif',
590 ':-D' => 'biggrin.gif',
591 ';-)' => 'wink.gif',
592 ':-/' => 'mixed.gif',
593 'V-.' => 'thoughtful.gif',
594 ':-P' => 'tongueout.gif',
595 'B-)' => 'cool.gif',
596 '^-)' => 'approve.gif',
597 '8-)' => 'wideeyes.gif',
598 ':o)' => 'clown.gif',
599 ':-(' => 'sad.gif',
600 ':(' => 'sad.gif',
601 '8-.' => 'shy.gif',
602 ':-I' => 'blush.gif',
603 ':-X' => 'kiss.gif',
604 '8-o' => 'surprise.gif',
605 'P-|' => 'blackeye.gif',
606 '8-[' => 'angry.gif',
607 'xx-P' => 'dead.gif',
608 '|-.' => 'sleepy.gif',
609 '}-]' => 'evil.gif',
610 );
611
5b472756 612 /// this is the meat of the code - this is run every time
613 if ($runonce == false){
617778f2 614 foreach ($emoticons as $emoticon => $image){
69081931 615 $e[] = $emoticon;
66a51452 616 $img[] = "<img alt=\"$emoticon\" width=\"15\" height=\"15\" src=\"$CFG->pixpath/s/$image\" />";
617778f2 617 }
618 $runonce = true;
c0f728ba 619 }
b7a3cf49 620
5f350e8f 621 $text = str_replace($e, $img, $text);
1a072208 622}
0095d5cd 623
909f539d 624function text_to_html($text, $smiley=true, $para=true) {
c1d57101 625/// Given plain text, makes it into HTML as nicely as possible.
626/// May contain HTML tags already
f9903ed0 627
27326a3e 628 global $CFG;
629
c1d57101 630/// Remove any whitespace that may be between HTML tags
7b3be1b1 631 $text = eregi_replace(">([[:space:]]+)<", "><", $text);
632
c1d57101 633/// Remove any returns that precede or follow HTML tags
0eae8049 634 $text = eregi_replace("([\n\r])<", " <", $text);
635 $text = eregi_replace(">([\n\r])", "> ", $text);
7b3be1b1 636
5f350e8f 637 convert_urls_into_links($text);
f9903ed0 638
c1d57101 639/// Make returns into HTML newlines.
f9903ed0 640 $text = nl2br($text);
641
c1d57101 642/// Turn smileys into images.
d69cb7f4 643 if ($smiley) {
5f350e8f 644 replace_smilies($text);
d69cb7f4 645 }
f9903ed0 646
c1d57101 647/// Wrap the whole thing in a paragraph tag if required
909f539d 648 if ($para) {
01d79966 649 return "<p>".$text."</p>";
909f539d 650 } else {
651 return $text;
652 }
f9903ed0 653}
654
3e9ca9fb 655function wiki_to_html($text) {
01d79966 656/// Given Wiki formatted text, make it into XHTML using external function
43373804 657 global $CFG;
3e9ca9fb 658
43373804 659 require_once("$CFG->libdir/wiki.php");
3e9ca9fb 660
01d79966 661 $wiki = new Wiki;
662 return $wiki->format($text);
3e9ca9fb 663}
664
5f350e8f 665function convert_urls_into_links(&$text) {
666/// Given some text, it converts any URLs it finds into HTML links.
667
668/// Make lone URLs into links. eg http://moodle.com/
3405b212 669 $text = eregi_replace("([[:space:]]|^|\(|\[)([[:alnum:]]+)://([^[:space:]]*)([[:alnum:]#?/&=])",
88438a58 670 "\\1<a href=\"\\2://\\3\\4\" target=\"newpage\">\\2://\\3\\4</a>", $text);
5f350e8f 671
672/// eg www.moodle.com
3405b212 673 $text = eregi_replace("([[:space:]]|^|\(|\[)www\.([^[:space:]]*)([[:alnum:]#?/&=])",
88438a58 674 "\\1<a href=\"http://www.\\2\\3\" target=\"newpage\">www.\\2\\3</a>", $text);
5f350e8f 675}
676
88438a58 677function highlight($needle, $haystack, $case=0,
678 $left_string="<span class=\"highlight\">", $right_string="</span>") {
679/// This function will highlight search words in a given string
680/// It cares about HTML and will not ruin links. It's best to use
681/// this function after performing any conversions to HTML.
682/// Function found here: http://forums.devshed.com/t67822/scdaa2d1c3d4bacb4671d075ad41f0854.html
683
684 $list_of_words = eregi_replace("[^-a-zA-Z0-9&']", " ", $needle);
685 $list_array = explode(" ", $list_of_words);
686 for ($i=0; $i<sizeof($list_array); $i++) {
687 if (strlen($list_array[$i]) == 1) {
688 $list_array[$i] = "";
689 }
690 }
691 $list_of_words = implode(" ", $list_array);
692 $list_of_words_cp = $list_of_words;
693 $final = array();
694 preg_match_all('/<(.+?)>/is',$haystack,$list_of_words);
695
696 foreach (array_unique($list_of_words[0]) as $key=>$value) {
697 $final['<|'.$key.'|>'] = $value;
698 }
699
700 $haystack = str_replace($final,array_keys($final),$haystack);
701 $list_of_words_cp = eregi_replace(" +", "|", $list_of_words_cp);
702
703 if ($list_of_words_cp{0}=="|") {
704 $list_of_words_cp{0} = "";
705 }
706 if ($list_of_words_cp{strlen($list_of_words_cp)-1}=="|") {
707 $list_of_words_cp{strlen($list_of_words_cp)-1}="";
708 }
709 $list_of_words_cp = "(".trim($list_of_words_cp).")";
710
711 if (!$case){
712 $haystack = eregi_replace("$list_of_words_cp", "$left_string"."\\1"."$right_string", $haystack);
713 } else {
714 $haystack = ereg_replace("$list_of_words_cp", "$left_string"."\\1"."$right_string", $haystack);
715 }
716 $haystack = str_replace(array_keys($final),$final,$haystack);
717
718 return stripslashes($haystack);
719}
720
721function highlightfast($needle, $haystack) {
c1d57101 722/// This function will highlight instances of $needle in $haystack
88438a58 723/// It's faster that the above function and doesn't care about
724/// HTML or anything.
5af78ed2 725
726 $parts = explode(strtolower($needle), strtolower($haystack));
727
728 $pos = 0;
729
730 foreach ($parts as $key => $part) {
731 $parts[$key] = substr($haystack, $pos, strlen($part));
732 $pos += strlen($part);
733
88438a58 734 $parts[$key] .= "<span class=\"highlight\">".substr($haystack, $pos, strlen($needle))."</span>";
5af78ed2 735 $pos += strlen($needle);
736 }
737
738 return (join('', $parts));
739}
740
f9903ed0 741
9fa49e22 742/// STANDARD WEB PAGE PARTS ///////////////////////////////////////////////////
743
66a51452 744function print_header ($title="", $heading="", $navigation="", $focus="", $meta="",
745 $cache=true, $button="&nbsp;", $menu="", $usexml=false) {
9fa49e22 746// $title - appears top of window
747// $heading - appears top of page
748// $navigation - premade navigation string
749// $focus - indicates form element eg inputform.password
750// $meta - meta tags in the header
751// $cache - should this page be cacheable?
752// $button - HTML code for a button (usually for module editing)
66a51452 753// $menu - HTML code for a popup menu
754// $usexml - use XML for this page
e825f279 755 global $USER, $CFG, $THEME, $SESSION;
9fa49e22 756
757 if (file_exists("$CFG->dirroot/theme/$CFG->theme/styles.php")) {
758 $styles = $CFG->stylesheet;
759 } else {
760 $styles = "$CFG->wwwroot/theme/standard/styles.php";
761 }
762
763 if ($navigation == "home") {
764 $home = true;
765 $navigation = "";
9d378732 766 } else {
767 $home = false;
9fa49e22 768 }
769
770 if ($button == "") {
771 $button = "&nbsp;";
772 }
773
774 if (!$menu and $navigation) {
775 if (isset($USER->id)) {
66a51452 776 $menu = "<font size=\"2\"><a target=\"$CFG->framename\" href=\"$CFG->wwwroot/login/logout.php\">".get_string("logout")."</a></font>";
9fa49e22 777 } else {
66a51452 778 $menu = "<font size=\"2\"><a target=\"$CFG->framename\" href=\"$CFG->wwwroot/login/index.php\">".get_string("login")."</a></font>";
9fa49e22 779 }
780 }
781
782 // Specify character set ... default is iso-8859-1 but some languages might need something else
783 // Could be optimised by carrying the charset variable around in $USER
784 if (current_language() == "en") {
66a51452 785 $meta = "<meta http-equiv=\"content-type\" content=\"text/html; charset=iso-8859-1\" />\n$meta\n";
9fa49e22 786 } else {
66a51452 787 $meta = "<meta http-equiv=\"content-type\" content=\"text/html; charset=".get_string("thischarset")."\" />\n$meta\n";
9fa49e22 788 }
789
d8152d04 790 if ( get_string("thisdirection") == "rtl" ) {
107b010b 791 $direction = " dir=\"rtl\"";
9fa49e22 792 } else {
107b010b 793 $direction = " dir=\"ltr\"";
9fa49e22 794 }
795
796 if (!$cache) { // Do everything we can to prevent clients and proxies caching
797 @header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
798 @header("Pragma: no-cache");
66a51452 799 $meta .= "\n<meta http-equiv=\"pragma\" content=\"no-cache\" />";
800 $meta .= "\n<meta http-equiv=\"expires\" content=\"0\" />";
801 }
802
803 if ($usexml) { // Added by Gustav Delius / Mad Alex for MathML output
804 $currentlanguage = current_language();
805
806 @header("Content-type: text/xml");
807 echo "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
808 if (!empty($CFG->xml_stylesheets)) {
809 $stylesheets = explode(";", $CFG->xml_stylesheets);
810 foreach ($stylesheets as $stylesheet) {
811 echo "<?xml-stylesheet type=\"text/xsl\" href=\"$CFG->wwwroot/$stylesheet\" ?>\n";
812 }
813 }
814 echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1";
e4576482 815 if (!empty($CFG->xml_doctype_extra)) {
66a51452 816 echo " plus $CFG->xml_doctype_extra";
e4576482 817 }
66a51452 818 echo "//" . strtoupper($currentlanguage) . "\" \"$CFG->xml_dtd\">\n";
819 $direction = " xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"$currentlanguage\" $direction";
9fa49e22 820 }
821
822 include ("$CFG->dirroot/theme/$CFG->theme/header.html");
823}
824
825function print_footer ($course=NULL) {
826// Can provide a course object to make the footer contain a link to
827// to the course home page, otherwise the link will go to the site home
828 global $USER, $CFG, $THEME;
829
830
831/// Course links
832 if ($course) {
833 if ($course == "home") { // special case for site home page - please do not remove
76c1650d 834 $homelink = "<p align=\"center\"><a title=\"moodle $CFG->release ($CFG->version)\" href=\"http://moodle.org/\" target=\"_blank\">";
66a51452 835 $homelink .= "<br /><img width=\"130\" height=\"19\" src=\"pix/madewithmoodle.gif\" border=\"0\" /></a></p>";
9fa49e22 836 $course = get_site();
837 $homepage = true;
838 } else {
76c1650d 839 $homelink = "<a target=\"{$CFG->framename}\" href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a>";
9fa49e22 840 }
841 } else {
c2cb4545 842 $homelink = "<a target=\"{$CFG->framename}\" href=\"$CFG->wwwroot/\">".get_string("home")."</a>";
9fa49e22 843 $course = get_site();
844 }
845
846/// User links
a282d0ff 847 $loggedinas = user_login_string($course, $USER);
848
849 include ("$CFG->dirroot/theme/$CFG->theme/footer.html");
850}
851
1ddf9329 852function style_sheet_setup($lastmodified=0, $lifetime=300, $themename="") {
853/// This function is called by stylesheets to set up the header
854/// approriately as well as the current path
6535be85 855
856 global $CFG;
857
858 header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT");
859 header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT");
860 header("Cache-control: max_age = $lifetime");
861 header("Pragma: ");
862 header("Content-type: text/css"); // Correct MIME type
863
864 if (!empty($themename)) {
865 $CFG->theme = $themename;
866 }
867
868 return "$CFG->wwwroot/theme/$CFG->theme";
869
870}
871
a282d0ff 872
873function user_login_string($course, $user=NULL) {
874 global $USER, $CFG;
875
8d2accb6 876 if (empty($user)) {
a282d0ff 877 $user = $USER;
878 }
879
880 if (isset($user->realuser)) {
881 if ($realuser = get_record("user", "id", $user->realuser)) {
66a51452 882 $realuserinfo = " [<a target=\"{$CFG->framename}\" href=\"$CFG->wwwroot/course/loginas.php?id=$course->id&amp;return=$realuser->id\">$realuser->firstname $realuser->lastname</a>] ";
9fa49e22 883 }
9d378732 884 } else {
885 $realuserinfo = "";
9fa49e22 886 }
887
a282d0ff 888 if (isset($user->id) and $user->id) {
66a51452 889 $username = "<a target=\"{$CFG->framename}\" href=\"$CFG->wwwroot/user/view.php?id=$user->id&amp;course=$course->id\">$user->firstname $user->lastname</a>";
9fa49e22 890 $loggedinas = $realuserinfo.get_string("loggedinas", "moodle", "$username").
ca16eaeb 891 " (<a target=\"{$CFG->framename}\" href=\"$CFG->wwwroot/login/logout.php\">".get_string("logout")."</a>)";
9fa49e22 892 } else {
893 $loggedinas = get_string("loggedinnot", "moodle").
ca16eaeb 894 " (<a target=\"{$CFG->framename}\" href=\"$CFG->wwwroot/login/index.php\">".get_string("login")."</a>)";
9fa49e22 895 }
a282d0ff 896 return $loggedinas;
9fa49e22 897}
898
899
9fa49e22 900function print_navigation ($navigation) {
901 global $CFG;
902
903 if ($navigation) {
904 if (! $site = get_site()) {
905 $site->shortname = get_string("home");;
906 }
eb347b6b 907 echo "<a target=\"{$CFG->framename}\" href=\"$CFG->wwwroot/\">$site->shortname</a> -> $navigation";
9fa49e22 908 }
909}
910
d4df9200 911function print_headline($text, $size=2) {
912 echo "<b><font size=\"$size\">$text</font></b><br />\n";
913}
914
76c1650d 915function print_heading($text, $align="center", $size=3) {
916 echo "<p align=\"$align\"><font size=\"$size\"><b>".stripslashes_safe($text)."</b></font></p>";
9fa49e22 917}
918
c9f6251e 919function print_heading_with_help($text, $helppage, $module="moodle", $icon="") {
9fa49e22 920// Centered heading with attached help button (same title text)
c9f6251e 921// and optional icon attached
922 echo "<p align=\"center\"><font size=\"3\">$icon<b>".stripslashes_safe($text);
9fa49e22 923 helpbutton($helppage, $text, $module);
eb347b6b 924 echo "</b></font></p>";
9fa49e22 925}
926
927function print_continue($link) {
9fa49e22 928
929 if (!$link) {
607809b3 930 $link = $_SERVER["HTTP_REFERER"];
9fa49e22 931 }
932
eb347b6b 933 print_heading("<a href=\"$link\">".get_string("continue")."</a>");
9fa49e22 934}
935
936
937function print_simple_box($message, $align="", $width="", $color="#FFFFFF", $padding=5, $class="generalbox") {
938 print_simple_box_start($align, $width, $color, $padding, $class);
7d8f674d 939 echo stripslashes_safe($message);
9fa49e22 940 print_simple_box_end();
941}
942
943function print_simple_box_start($align="", $width="", $color="#FFFFFF", $padding=5, $class="generalbox") {
944 global $THEME;
945
946 if ($align) {
76c1650d 947 $align = "align=\"$align\"";
9fa49e22 948 }
949 if ($width) {
76c1650d 950 $width = "width=\"$width\"";
9fa49e22 951 }
9d378732 952 echo "<table $align $width class=\"$class\" border=\"0\" cellpadding=\"$padding\" cellspacing=\"0\"><tr><td bgcolor=\"$color\" class=\"$class"."content\">";
9fa49e22 953}
954
955function print_simple_box_end() {
956 echo "</td></tr></table>";
957}
958
cc7fa0dc 959function print_single_button($link, $options, $label="OK", $method="get") {
960 echo "<form action=\"$link\" method=\"$method\">";
9fa49e22 961 if ($options) {
962 foreach ($options as $name => $value) {
66a51452 963 echo "<input type=\"hidden\" name=\"$name\" value=\"$value\" />";
9fa49e22 964 }
965 }
66a51452 966 echo "<input type=\"submit\" value=\"$label\" /></form>";
9fa49e22 967}
968
969function print_spacer($height=1, $width=1, $br=true) {
970 global $CFG;
66a51452 971 echo "<img height=\"$height\" width=\"$width\" src=\"$CFG->wwwroot/pix/spacer.gif\" alt=\"\" />";
9fa49e22 972 if ($br) {
76c1650d 973 echo "<br />\n";
9fa49e22 974 }
975}
976
977function print_file_picture($path, $courseid=0, $height="", $width="", $link="") {
978// Given the path to a picture file in a course, or a URL,
979// this function includes the picture in the page.
980 global $CFG;
981
982 if ($height) {
76c1650d 983 $height = "height=\"$height\"";
9fa49e22 984 }
985 if ($width) {
76c1650d 986 $width = "width=\"$width\"";
9fa49e22 987 }
988 if ($link) {
76c1650d 989 echo "<a href=\"$link\">";
9fa49e22 990 }
991 if (substr(strtolower($path), 0, 7) == "http://") {
66a51452 992 echo "<img border=\"0\" $height $width src=\"$path\" />";
9fa49e22 993
994 } else if ($courseid) {
66a51452 995 echo "<img border=\"0\" $height $width src=\"";
9fa49e22 996 if ($CFG->slasharguments) { // Use this method if possible for better caching
997 echo "$CFG->wwwroot/file.php/$courseid/$path";
998 } else {
3f396065 999 echo "$CFG->wwwroot/file.php?file=/$courseid/$path";
9fa49e22 1000 }
66a51452 1001 echo "\" />";
9fa49e22 1002 } else {
1003 echo "Error: must pass URL or course";
1004 }
1005 if ($link) {
76c1650d 1006 echo "</a>";
9fa49e22 1007 }
1008}
1009
1010function print_user_picture($userid, $courseid, $picture, $large=false, $returnstring=false, $link=true) {
67a63a30 1011 global $CFG, $THEME;
9fa49e22 1012
1013 if ($link) {
66a51452 1014 $output = "<a href=\"$CFG->wwwroot/user/view.php?id=$userid&amp;course=$courseid\">";
9fa49e22 1015 } else {
1016 $output = "";
1017 }
1018 if ($large) {
67a63a30 1019 $file = "f1";
9fa49e22 1020 $size = 100;
1021 } else {
67a63a30 1022 $file = "f2";
9fa49e22 1023 $size = 35;
1024 }
67a63a30 1025 if ($picture) { // Print custom user picture
9fa49e22 1026 if ($CFG->slasharguments) { // Use this method if possible for better caching
67a63a30 1027 $output .= "<img align=\"absmiddle\" src=\"$CFG->wwwroot/user/pix.php/$userid/$file.jpg\"".
66a51452 1028 " border=\"0\" width=\"$size\" height=\"$size\" alt=\"\" />";
9fa49e22 1029 } else {
67a63a30 1030 $output .= "<img align=\"absmiddle\" src=\"$CFG->wwwroot/user/pix.php?file=/$userid/$file.jpg\"".
66a51452 1031 " border=\"0\" width=\"$size\" height=\"$size\" alt=\"\" />";
9fa49e22 1032 }
67a63a30 1033 } else { // Print default user pictures (use theme version if available)
c9f6251e 1034 $output .= "<img align=\"absmiddle\" src=\"$CFG->pixpath/u/$file.png\"".
66a51452 1035 " border=\"0\" width=\"$size\" height=\"$size\" alt=\"\" />";
9fa49e22 1036 }
1037 if ($link) {
76c1650d 1038 $output .= "</a>";
9fa49e22 1039 }
1040
1041 if ($returnstring) {
1042 return $output;
1043 } else {
1044 echo $output;
1045 }
1046}
1047
1048function print_table($table) {
1049// Prints a nicely formatted table.
1050// $table is an object with several properties.
1051// $table->head is an array of heading names.
1052// $table->align is an array of column alignments
1053// $table->size is an array of column sizes
5867bfb5 1054// $table->wrap is an array of "nowrap"s or nothing
9fa49e22 1055// $table->data[] is an array of arrays containing the data.
1056// $table->width is an percentage of the page
1057// $table->cellpadding padding on each cell
1058// $table->cellspacing spacing between cells
1059
1060 if (isset($table->align)) {
1061 foreach ($table->align as $key => $aa) {
1062 if ($aa) {
76c1650d 1063 $align[$key] = " align=\"$aa\"";
9fa49e22 1064 } else {
1065 $align[$key] = "";
1066 }
1067 }
1068 }
1069 if (isset($table->size)) {
1070 foreach ($table->size as $key => $ss) {
1071 if ($ss) {
76c1650d 1072 $size[$key] = " width=\"$ss\"";
9fa49e22 1073 } else {
1074 $size[$key] = "";
1075 }
1076 }
1077 }
5867bfb5 1078 if (isset($table->wrap)) {
1079 foreach ($table->wrap as $key => $ww) {
1080 if ($ww) {
66a51452 1081 $wrap[$key] = " nowrap=\"nowrap\" ";
5867bfb5 1082 } else {
1083 $wrap[$key] = "";
1084 }
1085 }
1086 }
9fa49e22 1087
9d378732 1088 if (empty($table->width)) {
9fa49e22 1089 $table->width = "80%";
1090 }
1091
9d378732 1092 if (empty($table->cellpadding)) {
9fa49e22 1093 $table->cellpadding = "5";
1094 }
1095
9d378732 1096 if (empty($table->cellspacing)) {
9fa49e22 1097 $table->cellspacing = "1";
1098 }
1099
5867bfb5 1100 print_simple_box_start("center", "$table->width", "#ffffff", 0);
66a51452 1101 echo "<table width=\"100%\" border=\"0\" valign=\"top\" align=\"center\" ";
9fa49e22 1102 echo " cellpadding=\"$table->cellpadding\" cellspacing=\"$table->cellspacing\" class=\"generaltable\">\n";
1103
b79f41cd 1104 if (!empty($table->head)) {
5867bfb5 1105 echo "<tr>";
9fa49e22 1106 foreach ($table->head as $key => $heading) {
9d378732 1107 if (!isset($size[$key])) {
1108 $size[$key] = "";
1109 }
1110 if (!isset($align[$key])) {
1111 $align[$key] = "";
1112 }
66a51452 1113 echo "<th valign=\"top\" ".$align[$key].$size[$key]." nowrap=\"nowrap\" class=\"generaltableheader\">$heading</th>";
9fa49e22 1114 }
66a51452 1115 echo "</tr>\n";
9fa49e22 1116 }
1117
a1f8ff87 1118 if (!empty($table->data)) {
1119 foreach ($table->data as $row) {
1120 echo "<tr valign=\"top\">";
1121 foreach ($row as $key => $item) {
1122 if (!isset($size[$key])) {
1123 $size[$key] = "";
1124 }
1125 if (!isset($align[$key])) {
1126 $align[$key] = "";
1127 }
1128 if (!isset($wrap[$key])) {
1129 $wrap[$key] = "";
1130 }
1131 echo "<td ".$align[$key].$size[$key].$wrap[$key]." class=\"generaltablecell\">$item</td>";
1132 }
1133 echo "</tr>\n";
9fa49e22 1134 }
9fa49e22 1135 }
5867bfb5 1136 echo "</table>\n";
9fa49e22 1137 print_simple_box_end();
1138
1139 return true;
1140}
1141
2f4d324b 1142function make_table($table) {
1143// Creates a nicely formatted table and returns it
1144// $table is an object with several properties.
1145// $table->head is an array of heading names.
1146// $table->align is an array of column alignments
1147// $table->size is an array of column sizes
1148// $table->wrap is an array of "nowrap"s or nothing
1149// $table->data[] is an array of arrays containing the data.
1150// $table->width is an percentage of the page
1151// $table->class is a class
1152// $table->fontsize is the size of all the text
1153// $table->tablealign align the whole table
1154// $table->cellpadding padding on each cell
1155// $table->cellspacing spacing between cells
1156
1157 if (isset($table->align)) {
1158 foreach ($table->align as $key => $aa) {
1159 if ($aa) {
1160 $align[$key] = " align=\"$aa\"";
1161 } else {
1162 $align[$key] = "";
1163 }
1164 }
1165 }
1166 if (isset($table->size)) {
1167 foreach ($table->size as $key => $ss) {
1168 if ($ss) {
1169 $size[$key] = " width=\"$ss\"";
1170 } else {
1171 $size[$key] = "";
1172 }
1173 }
1174 }
1175 if (isset($table->wrap)) {
1176 foreach ($table->wrap as $key => $ww) {
1177 if ($ww) {
66a51452 1178 $wrap[$key] = " nowrap=\"nowrap\" ";
2f4d324b 1179 } else {
1180 $wrap[$key] = "";
1181 }
1182 }
1183 }
1184
1185 if (empty($table->width)) {
1186 $table->width = "80%";
1187 }
1188
1189 if (empty($table->tablealign)) {
1190 $table->tablealign = "center";
1191 }
1192
1193 if (empty($table->cellpadding)) {
1194 $table->cellpadding = "5";
1195 }
1196
1197 if (empty($table->cellspacing)) {
1198 $table->cellspacing = "1";
1199 }
1200
1201 if (empty($table->class)) {
1202 $table->class = "generaltable";
1203 }
1204
1205 if (empty($table->fontsize)) {
1206 $fontsize = "";
1207 } else {
1208 $fontsize = "<font size=\"$table->fontsize\">";
1209 }
1210
66a51452 1211 $output = "<table width=\"$table->width\" valign=\"top\" align=\"$table->tablealign\" ";
2f4d324b 1212 $output .= " cellpadding=\"$table->cellpadding\" cellspacing=\"$table->cellspacing\" class=\"$table->class\">\n";
1213
1214 if (!empty($table->head)) {
1215 $output .= "<tr>";
1216 foreach ($table->head as $key => $heading) {
1217 if (!isset($size[$key])) {
1218 $size[$key] = "";
1219 }
1220 if (!isset($align[$key])) {
1221 $align[$key] = "";
1222 }
66a51452 1223 $output .= "<th valign=\"top\" ".$align[$key].$size[$key]." nowrap=\"nowrap\" class=\"{$table->class}header\">$fontsize$heading</th>";
2f4d324b 1224 }
1225 $output .= "</tr>\n";
1226 }
1227
1228 foreach ($table->data as $row) {
66a51452 1229 $output .= "<tr valign=\"top\">";
2f4d324b 1230 foreach ($row as $key => $item) {
1231 if (!isset($size[$key])) {
1232 $size[$key] = "";
1233 }
1234 if (!isset($align[$key])) {
1235 $align[$key] = "";
1236 }
1237 if (!isset($wrap[$key])) {
1238 $wrap[$key] = "";
1239 }
1240 $output .= "<td ".$align[$key].$size[$key].$wrap[$key]." class=\"{$table->class}cell\">$fontsize$item</td>";
1241 }
1242 $output .= "</tr>\n";
1243 }
1244 $output .= "</table>\n";
1245
1246 return $output;
1247}
1248
50bdc74d 1249function print_textarea($richedit, $rows, $cols, $width, $height, $name, $value="", $courseid=0) {
7d8f674d 1250/// Prints a richtext field or a normal textarea
50bdc74d 1251 global $CFG, $THEME, $course;
1252
408e62f8 1253 if (empty($courseid)) {
50bdc74d 1254 if (!empty($course->id)) { // search for it in global context
1255 $courseid = $course->id;
1256 }
1257 }
9fa49e22 1258
1259 if ($richedit) {
408e62f8 1260 $richediturl = "$CFG->wwwroot/lib/rte/richedit.html";
1261 if (!empty($courseid) and isteacher($courseid)) {
c53be4c0 1262 $richediturl = "$CFG->wwwroot/lib/rte/richedit.php?id=$courseid";
50bdc74d 1263 }
1264
66a51452 1265 echo "<object id=\"richedit\" style=\"background-color: buttonface\"";
50bdc74d 1266 echo " data=\"$richediturl\"";
9fa49e22 1267 echo " width=\"$width\" height=\"$height\" ";
66a51452 1268 echo " type=\"text/x-scriptlet\" VIEWASTEXT=\"true\"></object>\n";
1269 echo "<textarea style=\"display:none\" name=\"$name\" rows=\"1\" cols=\"1\">";
9fa49e22 1270 p($value);
76c1650d 1271 echo "</textarea>\n";
9fa49e22 1272 } else {
66a51452 1273 echo "<textarea name=\"$name\" rows=\"$rows\" cols=\"$cols\" wrap=\"virtual\">";
9fa49e22 1274 p($value);
76c1650d 1275 echo "</textarea>\n";
9fa49e22 1276 }
1277}
1278
1279function print_richedit_javascript($form, $name, $source="no") {
76c1650d 1280 echo "<script language=\"javascript\" event=\"onload\" for=\"window\">\n";
9fa49e22 1281 echo " document.richedit.options = \"history=no;source=$source\";";
1282 echo " document.richedit.docHtml = $form.$name.innerText;";
76c1650d 1283 echo "</script>";
9fa49e22 1284}
1285
1286
1287function update_course_icon($courseid) {
1288// Used to be an icon, but it's now a simple form button
1289 global $CFG, $USER;
1290
b6c12732 1291 if (isteacheredit($courseid)) {
9c9f7d77 1292 if (!empty($USER->editing)) {
9fa49e22 1293 $string = get_string("turneditingoff");
1294 $edit = "off";
1295 } else {
1296 $string = get_string("turneditingon");
1297 $edit = "on";
1298 }
66a51452 1299 return "<form target=\"_parent\" method=\"get\" action=\"$CFG->wwwroot/course/view.php\">".
1300 "<input type=\"hidden\" name=\"id\" value=\"$courseid\" />".
1301 "<input type=\"hidden\" name=\"edit\" value=\"$edit\" />".
1302 "<input type=\"submit\" value=\"$string\" /></form>";
9fa49e22 1303 }
1304}
1305
1306function update_module_button($moduleid, $courseid, $string) {
1307// Prints the editing button on a module "view" page
1308 global $CFG;
1309
b6c12732 1310 if (isteacheredit($courseid)) {
9fa49e22 1311 $string = get_string("updatethis", "", $string);
66a51452 1312 return "<form target=\"_parent\" method=\"get\" action=\"$CFG->wwwroot/course/mod.php\">".
1313 "<input type=\"hidden\" name=\"update\" value=\"$moduleid\" />".
1314 "<input type=\"hidden\" name=\"return\" value=\"true\" />".
1315 "<input type=\"submit\" value=\"$string\" /></form>";
b6c12732 1316 } else {
1317 return "";
9fa49e22 1318 }
1319}
1320
c2cb4545 1321function update_category_button($categoryid) {
d2b6ba70 1322// Prints the editing button on a category page
1323 global $CFG, $USER;
c2cb4545 1324
d2b6ba70 1325 if (iscreator()) {
1326 if (!empty($USER->editing)) {
1327 $string = get_string("turneditingoff");
1328 $edit = "off";
1329 } else {
1330 $string = get_string("turneditingon");
1331 $edit = "on";
9b16d1ea 1332 }
66a51452 1333 return "<form method=\"get\" action=\"$CFG->wwwroot/course/category.php\">".
1334 "<input type=\"hidden\" name=\"id\" value=\"$categoryid\" />".
1335 "<input type=\"hidden\" name=\"edit\" value=\"$edit\" />".
1336 "<input type=\"submit\" value=\"$string\" /></form>";
d2b6ba70 1337 }
1338}
1339
1340function update_categories_button() {
1341// Prints the editing button on categories listing
1342 global $CFG, $USER;
1343
1344 if (isadmin()) {
1345 if (!empty($USER->editing)) {
1346 $string = get_string("turneditingoff");
1347 $edit = "off";
1348 } else {
1349 $string = get_string("turneditingon");
1350 $edit = "on";
1351 }
66a51452 1352 return "<form target=\"_parent\" method=\"get\" action=\"$CFG->wwwroot/course/index.php\">".
1353 "<input type=\"hidden\" name=\"edit\" value=\"$edit\" />".
1354 "<input type=\"submit\" value=\"$string\" /></form>";
c2cb4545 1355 }
1356}
9fa49e22 1357
16ef5e78 1358function navmenu($course, $cm=NULL, $targetwindow="self") {
9fa49e22 1359// Given a course and a (current) coursemodule
1360// This function returns a small popup menu with all the
1361// course activity modules in it, as a navigation menu
1362// The data is taken from the serialised array stored in
1363// the course record
1364
1365 global $CFG;
1366
1367 if ($cm) {
1368 $cm = $cm->id;
1369 }
1370
1371 if ($course->format == 'weeks') {
1372 $strsection = get_string("week");
1373 } else {
1374 $strsection = get_string("topic");
1375 }
1376
1377 if (!$modinfo = unserialize($course->modinfo)) {
1378 return "";
1379 }
1380 $section = -1;
1381 $selected = "";
1382 foreach ($modinfo as $mod) {
ab2df10c 1383 if ($mod->mod == "label") {
1384 continue;
1385 }
9fa49e22 1386 if ($mod->section > 0 and $section <> $mod->section) {
1387 $menu[] = "-------------- $strsection $mod->section --------------";
1388 }
1389 $section = $mod->section;
cf055081 1390 //Only add visible or teacher mods to jumpmenu
1391 if ($mod->visible or isteacher($course->id)) {
1392 $url = "$mod->mod/view.php?id=$mod->cm";
1393 if ($cm == $mod->cm) {
1394 $selected = $url;
1395 }
1396 $mod->name = urldecode($mod->name);
1397 if (strlen($mod->name) > 55) {
1398 $mod->name = substr($mod->name, 0, 50)."...";
1399 }
2a409368 1400 if (!$mod->visible) {
1401 $mod->name = "(".$mod->name.")";
1402 }
cf055081 1403 $menu[$url] = $mod->name;
9fa49e22 1404 }
9fa49e22 1405 }
1406
16ef5e78 1407 return popup_form("$CFG->wwwroot/mod/", $menu, "navmenu", $selected, get_string("jumpto"),
1408 "", "", true, $targetwindow);
9fa49e22 1409}
1410
1411
1412
1413function print_date_selector($day, $month, $year, $currenttime=0) {
1414// Currenttime is a default timestamp in GMT
1415// Prints form items with the names $day, $month and $year
1416
1417 if (!$currenttime) {
1418 $currenttime = time();
1419 }
1420 $currentdate = usergetdate($currenttime);
1421
1422 for ($i=1; $i<=31; $i++) {
1423 $days[$i] = "$i";
1424 }
1425 for ($i=1; $i<=12; $i++) {
39e018b3 1426 $months[$i] = userdate(gmmktime(12,0,0,$i,1,2000), "%B");
9fa49e22 1427 }
1428 for ($i=2000; $i<=2010; $i++) {
1429 $years[$i] = $i;
1430 }
47f1da80 1431 choose_from_menu($days, $day, $currentdate['mday'], "");
1432 choose_from_menu($months, $month, $currentdate['mon'], "");
1433 choose_from_menu($years, $year, $currentdate['year'], "");
9fa49e22 1434}
1435
1436function print_time_selector($hour, $minute, $currenttime=0) {
1437// Currenttime is a default timestamp in GMT
1438// Prints form items with the names $hour and $minute
1439
1440 if (!$currenttime) {
1441 $currenttime = time();
1442 }
1443 $currentdate = usergetdate($currenttime);
1444 for ($i=0; $i<=23; $i++) {
1445 $hours[$i] = sprintf("%02d",$i);
1446 }
1447 for ($i=0; $i<=59; $i++) {
1448 $minutes[$i] = sprintf("%02d",$i);
1449 }
47f1da80 1450 choose_from_menu($hours, $hour, $currentdate['hours'], "");
1451 choose_from_menu($minutes, $minute, $currentdate['minutes'], "");
9fa49e22 1452}
1453
d6bdd9d5 1454function print_grade_menu($courseid, $name, $current, $includenograde=true) {
62ca135d 1455/// Prints a grade menu (as part of an existing form) with help
1456/// Showing all possible numerical grades and scales
1457
c9f6251e 1458 global $CFG;
62ca135d 1459
1460 $strscale = get_string("scale");
1461 $strscales = get_string("scales");
1462
1f7deef6 1463 $scales = get_scales_menu($courseid);
62ca135d 1464 foreach ($scales as $i => $scalename) {
1465 $grades[-$i] = "$strscale: $scalename";
1466 }
d6bdd9d5 1467 if ($includenograde) {
1468 $grades[0] = get_string("nograde");
1469 }
62ca135d 1470 for ($i=100; $i>=1; $i--) {
1471 $grades[$i] = $i;
1472 }
1473 choose_from_menu($grades, "$name", "$current", "");
1474
c9f6251e 1475 $helpicon = "$CFG->pixpath/help.gif";
66a51452 1476 $linkobject = "<img align=\"absmiddle\" border=\"0\" height=\"17\" width=\"22\" alt=\"$strscales\" src=\"$helpicon\" />";
1477 link_to_popup_window ("/course/scales.php?id=$courseid&amp;list=true", "ratingscales",
62ca135d 1478 $linkobject, 400, 500, $strscales);
1479}
1480
02ebf404 1481function print_scale_menu($courseid, $name, $current) {
1482/// Prints a scale menu (as part of an existing form) including help button
62ca135d 1483/// Just like print_grade_menu but without the numerical grades
02ebf404 1484
c9f6251e 1485 global $CFG;
02ebf404 1486
1487 $strscales = get_string("scales");
1488 choose_from_menu(get_scales_menu($courseid), "$name", $current, "");
c9f6251e 1489 $helpicon = "$CFG->pixpath/help.gif";
66a51452 1490 $linkobject = "<img align=\"absmiddle\" border=\"0\" height=\"17\" width=\"22\" alt=\"$strscales\" src=\"$helpicon\" />";
1491 link_to_popup_window ("/course/scales.php?id=$courseid&amp;list=true", "ratingscales",
02ebf404 1492 $linkobject, 400, 500, $strscales);
1493}
1494
fdc47ee6 1495
02ebf404 1496function print_scale_menu_helpbutton($courseid, $scale) {
1497/// Prints a help button about a scale
1498/// scale is an object
1499
c9f6251e 1500 global $CFG;
02ebf404 1501
1502 $strscales = get_string("scales");
c9f6251e 1503 $helpicon = "$CFG->pixpath/help.gif";
66a51452 1504 $linkobject = "<img align=\"absmiddle\" border=\"0\" height=\"17\" width=\"22\" alt=\"$scale->name\" src=\"$helpicon\" />";
1505 link_to_popup_window ("/course/scales.php?id=$courseid&amp;list=true&amp;scale=$scale->id", "ratingscale",
02ebf404 1506 $linkobject, 400, 500, $scale->name);
1507}
1508
1509
9fa49e22 1510function error ($message, $link="") {
1511 global $CFG, $SESSION;
1512
1513 print_header(get_string("error"));
66a51452 1514 echo "<br />";
9fa49e22 1515 print_simple_box($message, "center", "", "#FFBBBB");
1516
1517 if (!$link) {
1518 if ( !empty($SESSION->fromurl) ) {
1519 $link = "$SESSION->fromurl";
1520 unset($SESSION->fromurl);
9fa49e22 1521 } else {
c2cb4545 1522 $link = "$CFG->wwwroot/";
9fa49e22 1523 }
1524 }
1525 print_continue($link);
1526 print_footer();
1527 die;
1528}
1529
1530function helpbutton ($page, $title="", $module="moodle", $image=true, $linktext=false, $text="") {
1531 // $page = the keyword that defines a help page
1532 // $title = the title of links, rollover tips, alt tags etc
1533 // $module = which module is the page defined in
1534 // $image = use a help image for the link? (true/false/"both")
1535 // $text = if defined then this text is used in the page, and
1536 // the $page variable is ignored.
dc0dc7d5 1537 global $CFG, $THEME;
9fa49e22 1538
1539 if ($module == "") {
1540 $module = "moodle";
1541 }
1542
1543 if ($image) {
c9f6251e 1544 $icon = "$CFG->pixpath/help.gif";
9fa49e22 1545 if ($linktext) {
66a51452 1546 $linkobject = "$title<img align=\"absmiddle\" border=\"0\" height=\"17\" width=\"22\" alt=\"\" src=\"$icon\" />";
9fa49e22 1547 } else {
66a51452 1548 $linkobject = "<img align=\"absmiddle\" border=\"0\" height=\"17\" width=\"22\" alt=\"$title\" src=\"$icon\" />";
9fa49e22 1549 }
1550 } else {
1551 $linkobject = $title;
1552 }
1553 if ($text) {
66a51452 1554 $url = "/help.php?module=$module&amp;text=".htmlentities(urlencode($text));
9fa49e22 1555 } else {
66a51452 1556 $url = "/help.php?module=$module&amp;file=$page.html";
9fa49e22 1557 }
1558 link_to_popup_window ($url, "popup", $linkobject, 400, 500, $title);
1559}
1560
e825f279 1561function emoticonhelpbutton($form, $field) {
1562/// Prints a special help button that is a link to the "live" emoticon popup
1563 global $CFG, $SESSION;
1564
1565 $SESSION->inserttextform = $form;
1566 $SESSION->inserttextfield = $field;
1567 helpbutton("emoticons", get_string("helpemoticons"), "moodle", false, true);
c9f6251e 1568 echo "&nbsp;";
66a51452 1569 link_to_popup_window ("/help.php?module=moodle&amp;file=emoticons.html", "popup",
1570 "<img src=\"$CFG->pixpath/s/smiley.gif\" border=\"0\" align=\"absmiddle\" width=\"15\" height=\"15\" />",
c9f6251e 1571 400, 500, get_string("helpemoticons"));
1572 echo "<br />";
e825f279 1573}
1574
9fa49e22 1575function notice ($message, $link="") {
750ab759 1576 global $CFG, $THEME;
9fa49e22 1577
1578 if (!$link) {
750ab759 1579 if (!empty($_SERVER["HTTP_REFERER"])) {
1580 $link = $_SERVER["HTTP_REFERER"];
1581 } else {
c2cb4545 1582 $link = "$CFG->wwwroot/";
750ab759 1583 }
9fa49e22 1584 }
1585
01d79966 1586 echo "<br />";
11a876e1 1587 print_simple_box($message, "center", "50%", "$THEME->cellheading", "20", "noticebox");
eb347b6b 1588 print_heading("<a href=\"$link\">".get_string("continue")."</a>");
9fa49e22 1589 print_footer(get_site());
1590 die;
1591}
1592
1593function notice_yesno ($message, $linkyes, $linkno) {
1594 global $THEME;
1595
eb347b6b 1596 print_simple_box_start("center", "60%", "$THEME->cellheading");
66a51452 1597 echo "<p align=\"center\"><font size=\"3\">$message</font></p>";
1598 echo "<p align=\"center\"><font size=\"3\"><b>";
eb347b6b 1599 echo "<a href=\"$linkyes\">".get_string("yes")."</a>";
9fa49e22 1600 echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
eb347b6b 1601 echo "<a href=\"$linkno\">".get_string("no")."</a>";
1602 echo "</b></font></p>";
9fa49e22 1603 print_simple_box_end();
1604}
1605
559573a2 1606function redirect($url, $message="", $delay="0") {
9fa49e22 1607// Uses META tags to redirect the user, after printing a notice
1608
c9082a8c 1609 if (empty($message)) {
66a51452 1610 echo "<meta http-equiv=\"refresh\" content=\"$delay; url=$url\" />";
c9082a8c 1611 } else {
05c19593 1612 if (empty($delay)) {
c9082a8c 1613 $delay = 3; // There's no point having a message with no delay
1614 }
66a51452 1615 echo "<meta http-equiv=\"refresh\" content=\"$delay; url=$url\" />";
9fa49e22 1616 print_header();
76c1650d 1617 echo "<center>";
1618 echo "<p>$message</p>";
1619 echo "<p>( <a href=\"$url\">".get_string("continue")."</a> )</p>";
1620 echo "</center>";
9fa49e22 1621 }
1622 die;
1623}
1624
99988d1a 1625function notify ($message, $color="red", $align="center") {
1626 echo "<p align=\"$align\"><b><font color=\"$color\">$message</font></b></p>\n";
9fa49e22 1627}
1628
43373804 1629function obfuscate_email($email) {
1630/// Given an email address, this function will return an obfuscated version of it
1631 $i = 0;
1632 $length = strlen($email);
1633 $obfuscated = "";
1634 while ($i < $length) {
1635 if (rand(0,2)) {
1636 $obfuscated.='%'.dechex(ord($email{$i}));
1637 } else {
1638 $obfuscated.=$email{$i};
1639 }
1640 $i++;
1641 }
1642 return $obfuscated;
1643}
1644
1645function obfuscate_text($plaintext) {
1646/// This function takes some text and replaces about half of the characters
1647/// with HTML entity equivalents. Return string is obviously longer.
1648 $i=0;
1649 $length = strlen($plaintext);
1650 $obfuscated="";
2b09e377 1651 $prev_obfuscated = false;
43373804 1652 while ($i < $length) {
2b09e377 1653 $c = ord($plaintext{$i});
1654 $numerical = ($c >= ord('0')) && ($c <= ord('9'));
1655 if ($prev_obfuscated and $numerical ) {
1656 $obfuscated.='&#'.ord($plaintext{$i});
1657 } else if (rand(0,2)) {
43373804 1658 $obfuscated.='&#'.ord($plaintext{$i});
2b09e377 1659 $prev_obfuscated = true;
43373804 1660 } else {
1661 $obfuscated.=$plaintext{$i};
2b09e377 1662 $prev_obfuscated = false;
43373804 1663 }
2b09e377 1664 $i++;
43373804 1665 }
1666 return $obfuscated;
1667}
1668
1669function obfuscate_mailto($email, $label="") {
1670/// This function uses the above two functions to generate a fully
1671/// obfuscated email link, ready to use.
1672
1673 if (empty($label)) {
1674 $label = $email;
1675 }
1676 return sprintf('<a href="%s:%s" title="%s">%s</a>', obfuscate_text('mailto'),
1677 obfuscate_email($email),
1678 obfuscate_text($email),
1679 obfuscate_text($label));
1680}
1681
8b9c7aa0 1682function print_paging_bar($totalcount, $page, $perpage, $baseurl) {
1683/// Prints a single paging bar to provide access to other pages (usually in a search)
1684
519d369f 1685 $maxdisplay = 18;
8ef9cb56 1686
8b9c7aa0 1687 if ($totalcount > $perpage) {
f04dc61d 1688 echo "<center>";
1689 echo "<p>".get_string("page").":";
be20753e 1690 $lastpage = ceil($totalcount / $perpage);
1691 if ($page > 15) {
1692 $startpage = $page - 10;
519d369f 1693 echo "&nbsp<a href=\"{$baseurl}page=0\">1</a>&nbsp;...";
be20753e 1694 } else {
1695 $startpage = 0;
1696 }
be20753e 1697 $currpage = $startpage;
1698 $displaycount = 0;
1699 while ($displaycount < $maxdisplay and $currpage < $lastpage) {
1700 $displaypage = $currpage+1;
1701 if ($page == $currpage) {
8b9c7aa0 1702 echo "&nbsp;&nbsp;$displaypage";
1703 } else {
be20753e 1704 echo "&nbsp;&nbsp;<a href=\"{$baseurl}page=$currpage\">$displaypage</a>";
e27dbcc8 1705 }
be20753e 1706 $displaycount++;
1707 $currpage++;
8b9c7aa0 1708 }
924cef21 1709 if ($currpage < $lastpage) {
519d369f 1710 $lastpageactual = $lastpage - 1;
1711 echo "&nbsp;...<a href=\"{$baseurl}page=$lastpageactual\">$lastpage</a>&nbsp;";
924cef21 1712 }
8b9c7aa0 1713 $pagenum = $page + 1;
be20753e 1714 if ($pagenum != $displaypage) {
8b9c7aa0 1715 echo "&nbsp;&nbsp;(<a href=\"{$baseurl}page=$pagenum\">".get_string("next")."</a>)";
1716 }
1717 echo "</p>";
be20753e 1718 echo "</center>";
8b9c7aa0 1719 }
1720}
9fa49e22 1721
9d5b689c 1722// vim:autoindent:expandtab:shiftwidth=4:tabstop=4:tw=140:
f9903ed0 1723?>