2009-05-22 03:26:07 +00:00
< ? php
2009-05-26 06:26:11 +00:00
// This file is part of Moodle - http://moodle.org/
//
2009-05-22 03:26:07 +00:00
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
2009-05-26 06:26:11 +00:00
//
2009-05-22 03:26:07 +00:00
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
2001-11-22 06:23:56 +00:00
2004-09-23 02:48:41 +00:00
/**
* Library of functions for web output
*
* Library of all general - purpose Moodle PHP functions and constants
* that produce HTML output
*
* Other main libraries :
* - datalib . php - functions that access the database .
* - moodlelib . php - general - purpose Moodle functions .
2009-05-22 03:26:07 +00:00
*
2009-05-26 06:26:11 +00:00
* @ package moodlecore
2009-05-22 03:26:07 +00:00
* @ copyright 1999 onwards Martin Dougiamas { @ link http :// moodle . com }
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2004-09-23 02:48:41 +00:00
*/
2005-01-26 15:57:00 +00:00
2002-10-10 07:26:10 +00:00
/// Constants
2002-10-19 04:58:14 +00:00
/// Define text formatting types ... eventually we can add Wiki, BBcode etc
2004-09-23 02:48:41 +00:00
/**
* Does all sorts of transformations and filtering
*/
2004-09-22 14:39:15 +00:00
define ( 'FORMAT_MOODLE' , '0' ); // Does all sorts of transformations and filtering
2004-09-23 02:48:41 +00:00
/**
* Plain HTML ( with some tags stripped )
*/
2004-09-22 14:39:15 +00:00
define ( 'FORMAT_HTML' , '1' ); // Plain HTML (with some tags stripped)
2004-09-23 02:48:41 +00:00
/**
* Plain text ( even tags are printed in full )
*/
2004-09-22 14:39:15 +00:00
define ( 'FORMAT_PLAIN' , '2' ); // Plain text (even tags are printed in full)
2004-09-23 02:48:41 +00:00
/**
* Wiki - formatted text
2005-04-11 13:46:06 +00:00
* Deprecated : left here just to note that '3' is not used ( at the moment )
* and to catch any latent wiki - like text ( which generates an error )
2004-09-23 02:48:41 +00:00
*/
2004-09-22 14:39:15 +00:00
define ( 'FORMAT_WIKI' , '3' ); // Wiki-formatted text
2004-09-23 02:48:41 +00:00
/**
* Markdown - formatted text http :// daringfireball . net / projects / markdown /
*/
2004-09-22 14:39:15 +00:00
define ( 'FORMAT_MARKDOWN' , '4' ); // Markdown-formatted text http://daringfireball.net/projects/markdown/
2002-10-10 07:26:10 +00:00
2006-08-26 13:00:07 +00:00
/**
* TRUSTTEXT marker - if present in text , text cleaning should be bypassed
*/
define ( 'TRUSTTEXT' , '#####TRUSTTEXT#####' );
2009-08-10 03:04:01 +00:00
/**
* A moodle_url comparison using this flag will return true if the base URLs match , params are ignored
*/
define ( 'URL_MATCH_BASE' , 0 );
/**
* A moodle_url comparison using this flag will return true if the base URLs match and the params of url1 are part of url2
*/
define ( 'URL_MATCH_PARAMS' , 1 );
/**
2009-08-10 04:58:02 +00:00
* A moodle_url comparison using this flag will return true if the two URLs are identical , except for the order of the params
2009-08-10 03:04:01 +00:00
*/
define ( 'URL_MATCH_EXACT' , 2 );
2004-09-23 02:48:41 +00:00
/**
* Allowed tags - string of html tags that can be tested against for safe html tags
* @ global string $ALLOWED_TAGS
2009-05-22 03:26:07 +00:00
* @ name $ALLOWED_TAGS
2004-09-23 02:48:41 +00:00
*/
2007-04-24 17:09:12 +00:00
global $ALLOWED_TAGS ;
2003-10-16 14:25:36 +00:00
$ALLOWED_TAGS =
2008-07-26 11:29:00 +00:00
'<p><br><b><i><u><font><table><tbody><thead><tfoot><span><div><tr><td><th><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><param><acronym><nolink><lang><tex><algebra><math><mi><mn><mo><mtext><mspace><ms><mrow><mfrac><msqrt><mroot><mstyle><merror><mpadded><mphantom><mfenced><msub><msup><msubsup><munder><mover><munderover><mmultiscripts><mtable><mtr><mtd><maligngroup><malignmark><maction><cn><ci><apply><reln><fn><interval><inverse><sep><condition><declare><lambda><compose><ident><quotient><exp><factorial><divide><max><min><minus><plus><power><rem><times><root><gcd><and><or><xor><not><implies><forall><exists><abs><conjugate><eq><neq><gt><lt><geq><leq><ln><log><int><diff><partialdiff><lowlimit><uplimit><bvar><degree><set><list><union><intersect><in><notin><subset><prsubset><notsubset><notprsubset><setdiff><sum><product><limit><tendsto><mean><sdev><variance><median><mode><moment><vector><matrix><matrixrow><determinant><transpose><selector><annotation><semantics><annotation-xml><tt><code>' ;
2005-06-05 05:40:24 +00:00
2004-09-29 14:00:35 +00:00
/**
* Allowed protocols - array of protocols that are safe to use in links and so on
* @ global string $ALLOWED_PROTOCOLS
2009-05-22 03:26:07 +00:00
* @ name $ALLOWED_PROTOCOLS
2004-09-29 14:00:35 +00:00
*/
2005-05-28 13:28:20 +00:00
$ALLOWED_PROTOCOLS = array ( 'http' , 'https' , 'ftp' , 'news' , 'mailto' , 'rtsp' , 'teamspeak' , 'gopher' , 'mms' ,
2008-08-07 22:38:46 +00:00
'color' , 'callto' , 'cursor' , 'text-align' , 'font-size' , 'font-weight' , 'font-style' , 'font-family' ,
2008-12-03 16:31:49 +00:00
'border' , 'margin' , 'padding' , 'background' , 'background-color' , 'text-decoration' ); // CSS as well to get through kses
2004-09-29 14:00:35 +00:00
2002-10-10 07:26:10 +00:00
/// Functions
2004-09-23 02:48:41 +00:00
/**
* Add quotes to HTML characters
*
* Returns $var with HTML characters ( like " < " , " > " , etc . ) properly quoted .
* This function is very similar to { @ link p ()}
*
2009-05-22 03:26:07 +00:00
* @ todo Remove obsolete param $obsolete if not used anywhere
*
2004-09-23 02:48:41 +00:00
* @ param string $var the string potentially containing HTML characters
2009-04-01 00:39:17 +00:00
* @ param boolean $obsolete no longer used .
2004-09-23 02:48:41 +00:00
* @ return string
*/
2009-04-01 00:39:17 +00:00
function s ( $var , $obsolete = false ) {
2006-04-12 17:39:23 +00:00
2005-07-09 07:20:52 +00:00
if ( $var == '0' ) { // for integer 0, boolean false, string '0'
return '0' ;
2003-05-26 14:43:19 +00:00
}
2006-04-12 17:39:23 +00:00
2009-04-02 02:42:11 +00:00
return preg_replace ( " /&(# \ d+);/i " , " & $ 1; " , htmlspecialchars ( $var ));
2001-11-22 06:23:56 +00:00
}
2004-09-23 02:48:41 +00:00
/**
* Add quotes to HTML characters
*
2004-09-23 04:36:43 +00:00
* Prints $var with HTML characters ( like " < " , " > " , etc . ) properly quoted .
2009-05-22 03:26:07 +00:00
* This function simply calls { @ link s ()}
* @ see s ()
*
* @ todo Remove obsolete param $obsolete if not used anywhere
2004-09-23 02:48:41 +00:00
*
* @ param string $var the string potentially containing HTML characters
2009-04-01 00:39:17 +00:00
* @ param boolean $obsolete no longer used .
2004-09-23 02:48:41 +00:00
* @ return string
*/
2009-04-01 00:39:17 +00:00
function p ( $var , $obsolete = false ) {
echo s ( $var , $obsolete );
2001-11-22 06:23:56 +00:00
}
2006-12-30 22:45:40 +00:00
/**
* Does proper javascript quoting .
2009-05-22 03:26:07 +00:00
*
2007-01-04 10:23:06 +00:00
* Do not use addslashes anymore , because it does not work when magic_quotes_sybase is enabled .
*
2009-05-22 03:26:07 +00:00
* @ param mixed $var String , Array , or Object to add slashes to
2006-12-30 22:45:40 +00:00
* @ return mixed quoted result
*/
function addslashes_js ( $var ) {
if ( is_string ( $var )) {
$var = str_replace ( '\\' , '\\\\' , $var );
$var = str_replace ( array ( '\'' , '"' , " \n " , " \r " , " \0 " ), array ( '\\\'' , '\\"' , '\\n' , '\\r' , '\\0' ), $var );
2007-01-01 13:26:20 +00:00
$var = str_replace ( '</' , '<\/' , $var ); // XHTML compliance
2006-12-30 22:45:40 +00:00
} else if ( is_array ( $var )) {
$var = array_map ( 'addslashes_js' , $var );
} else if ( is_object ( $var )) {
$a = get_object_vars ( $var );
foreach ( $a as $key => $value ) {
$a [ $key ] = addslashes_js ( $value );
}
$var = ( object ) $a ;
}
return $var ;
}
2004-09-23 02:48:41 +00:00
/**
* Remove query string from url
*
* Takes in a URL and returns it without the querystring portion
*
* @ param string $url the url which may have a query string attached
2009-05-22 03:26:07 +00:00
* @ return string The remaining URL
2004-09-23 02:48:41 +00:00
*/
function strip_querystring ( $url ) {
2001-11-22 06:23:56 +00:00
2002-12-30 03:39:42 +00:00
if ( $commapos = strpos ( $url , '?' )) {
return substr ( $url , 0 , $commapos );
} else {
return $url ;
}
2001-11-22 06:23:56 +00:00
}
2004-09-23 02:48:41 +00:00
/**
2007-03-05 05:47:27 +00:00
* Returns the URL of the HTTP_REFERER , less the querystring portion if required
2009-05-22 03:26:07 +00:00
*
* @ uses $_SERVER
2008-01-16 08:41:30 +00:00
* @ param boolean $stripquery if true , also removes the query part of the url .
2009-05-22 03:26:07 +00:00
* @ return string The resulting referer or emtpy string
2004-09-23 02:48:41 +00:00
*/
2007-03-05 05:47:27 +00:00
function get_referer ( $stripquery = true ) {
2006-12-30 21:25:13 +00:00
if ( isset ( $_SERVER [ 'HTTP_REFERER' ])) {
2007-03-05 05:47:27 +00:00
if ( $stripquery ) {
return strip_querystring ( $_SERVER [ 'HTTP_REFERER' ]);
} else {
return $_SERVER [ 'HTTP_REFERER' ];
}
2006-12-30 21:25:13 +00:00
} else {
2007-01-04 10:23:06 +00:00
return '' ;
2006-12-30 21:25:13 +00:00
}
2001-11-22 06:23:56 +00:00
}
2002-10-19 04:58:14 +00:00
2004-09-23 02:48:41 +00:00
/**
* Returns the name of the current script , WITH the querystring portion .
2009-05-22 03:26:07 +00:00
*
* This function is necessary because PHP_SELF and REQUEST_URI and SCRIPT_NAME
2004-09-23 02:48:41 +00:00
* return different things depending on a lot of things like your OS , Web
* server , and the way PHP is compiled ( ie . as a CGI , module , ISAPI , etc . )
2004-09-23 04:36:43 +00:00
* < b > NOTE :</ b > This function returns false if the global variables needed are not set .
*
2009-05-22 03:26:07 +00:00
* @ global string
* @ return mixed String , or false if the global variables needed are not set
2004-09-23 02:48:41 +00:00
*/
2009-06-17 08:50:16 +00:00
function me () {
global $ME ;
return $ME ;
2001-11-22 06:23:56 +00:00
}
2004-09-23 02:48:41 +00:00
/**
2009-05-22 03:26:07 +00:00
* Returns the name of the current script , WITH the full URL .
*
* This function is necessary because PHP_SELF and REQUEST_URI and SCRIPT_NAME
* return different things depending on a lot of things like your OS , Web
* server , and the way PHP is compiled ( ie . as a CGI , module , ISAPI , etc .
* < b > NOTE :</ b > This function returns false if the global variables needed are not set .
*
2004-09-23 04:36:43 +00:00
* Like { @ link me ()} but returns a full URL
2004-09-23 02:48:41 +00:00
* @ see me ()
2009-05-22 03:26:07 +00:00
*
* @ global string
* @ return mixed String , or false if the global variables needed are not set
2004-09-23 02:48:41 +00:00
*/
2001-11-22 06:23:56 +00:00
function qualified_me () {
2009-01-05 21:37:20 +00:00
global $FULLME ;
return $FULLME ;
2001-11-22 06:23:56 +00:00
}
2007-05-03 04:34:53 +00:00
/**
* Class for creating and manipulating urls .
2007-06-19 14:44:02 +00:00
*
2009-05-22 03:26:07 +00:00
* It can be used in moodle pages where config . php has been included without any further includes .
*
2009-08-04 02:05:32 +00:00
* It is useful for manipulating urls with long lists of params .
* One situation where it will be useful is a page which links to itself to perfrom various actions
2009-05-22 03:26:07 +00:00
* and / or to process form data . A moodle_url object :
2009-08-04 02:05:32 +00:00
* can be created for a page to refer to itself with all the proper get params being passed from page call to
* page call and methods can be used to output a url including all the params , optionally adding and overriding
2009-05-22 03:26:07 +00:00
* params and can also be used to
* - output the url without any get params
2009-08-04 02:05:32 +00:00
* - and output the params as hidden fields to be output within a form
2009-05-22 03:26:07 +00:00
*
* One important usage note is that data passed to methods out , out_action , get_query_string and
2009-08-04 02:05:32 +00:00
* hidden_params_out affect what is returned by the function and do not change the data stored in the object .
* This is to help with typical usage of these objects where one object is used to output urls
* in many places in a page .
2009-05-22 03:26:07 +00:00
*
* @ link http :// docs . moodle . org / en / Development : lib / weblib . php_moodle_url See short write up here
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ package moodlecore
2007-05-03 04:34:53 +00:00
*/
class moodle_url {
2009-05-22 03:26:07 +00:00
/**
* @ var string
* @ access protected
*/
2009-05-06 08:49:12 +00:00
protected $scheme = '' ; // e.g. http
protected $host = '' ;
protected $port = '' ;
protected $user = '' ;
protected $pass = '' ;
protected $path = '' ;
protected $fragment = '' ;
2009-05-22 03:26:07 +00:00
/**
2009-08-04 02:05:32 +00:00
* @ var array
2009-05-22 03:26:07 +00:00
* @ access protected
*/
2009-05-06 08:49:12 +00:00
protected $params = array (); // Associative array of query string params
2007-06-19 14:44:02 +00:00
2007-05-03 04:34:53 +00:00
/**
2009-08-04 02:05:32 +00:00
* Pass no arguments to create a url that refers to this page .
2009-05-22 03:26:07 +00:00
* Use empty string to create empty url .
2007-06-19 14:44:02 +00:00
*
2009-05-22 03:26:07 +00:00
* @ global string
2009-05-06 08:50:32 +00:00
* @ param mixed $url a number of different forms are accespted :
* null - create a URL that is the same as the URL used to load this page , but with no query string
* '' - and empty URL
* string - a URL , will be parsed into it ' s bits , including query string
* array - as returned from the PHP function parse_url
* moodle_url - make a copy of another moodle_url
2009-05-06 08:49:12 +00:00
* @ param array $params these params override anything in the query string
* where params have the same name .
2007-05-03 04:34:53 +00:00
*/
2009-05-06 08:49:12 +00:00
public function __construct ( $url = null , $params = array ()) {
2009-05-06 08:50:32 +00:00
if ( $url === '' ) {
// Leave URL blank.
} else if ( is_a ( $url , 'moodle_url' )) {
$this -> scheme = $url -> scheme ;
$this -> host = $url -> host ;
$this -> port = $url -> port ;
$this -> user = $url -> user ;
$this -> pass = $url -> pass ;
2009-05-06 08:55:53 +00:00
$this -> path = $url -> path ;
2009-05-06 08:50:32 +00:00
$this -> fragment = $url -> fragment ;
$this -> params = $url -> params ;
} else {
2009-05-06 08:49:12 +00:00
if ( $url === null ) {
2009-05-06 08:50:32 +00:00
global $ME ;
2009-01-05 21:37:20 +00:00
$url = $ME ;
2007-05-03 04:34:53 +00:00
}
2009-05-06 08:50:32 +00:00
if ( is_string ( $url )) {
$url = parse_url ( $url );
}
$parts = $url ;
2009-05-06 08:49:12 +00:00
if ( $parts === FALSE ) {
2009-05-06 08:50:32 +00:00
throw new moodle_exception ( 'invalidurl' );
2007-05-03 04:34:53 +00:00
}
2009-05-06 08:49:12 +00:00
if ( isset ( $parts [ 'query' ])) {
2007-05-29 06:14:09 +00:00
parse_str ( str_replace ( '&' , '&' , $parts [ 'query' ]), $this -> params );
2007-05-03 04:34:53 +00:00
}
unset ( $parts [ 'query' ]);
2009-05-06 08:49:12 +00:00
foreach ( $parts as $key => $value ) {
2007-05-03 04:34:53 +00:00
$this -> $key = $value ;
}
}
2009-05-06 08:50:32 +00:00
$this -> params ( $params );
2007-06-19 14:44:02 +00:00
}
2009-05-06 08:49:12 +00:00
2007-05-03 04:34:53 +00:00
/**
2009-08-04 02:05:32 +00:00
* Add an array of params to the params for this page .
2009-05-22 03:26:07 +00:00
*
* The added params override existing ones if they have the same name .
2007-05-03 04:34:53 +00:00
*
2009-07-27 10:33:00 +00:00
* @ param array $params Defaults to null . If null then returns all params .
2009-05-22 03:26:07 +00:00
* @ return array Array of Params for url .
2007-05-03 04:34:53 +00:00
*/
2009-05-06 08:49:12 +00:00
public function params ( $params = null ) {
if ( ! is_null ( $params )) {
2008-07-24 15:22:31 +00:00
return $this -> params = $params + $this -> params ;
} else {
return $this -> params ;
}
2007-05-03 04:34:53 +00:00
}
2007-06-19 14:44:02 +00:00
2007-05-03 04:34:53 +00:00
/**
2009-08-04 02:05:32 +00:00
* Remove all params if no arguments passed .
* Remove selected params if arguments are passed .
2009-05-22 03:26:07 +00:00
*
* Can be called as either remove_params ( 'param1' , 'param2' )
2009-05-06 08:50:32 +00:00
* or remove_params ( array ( 'param1' , 'param2' )) .
2007-05-03 04:34:53 +00:00
*
2009-05-06 08:50:32 +00:00
* @ param mixed $params either an array of param names , or a string param name ,
* @ param string $params , ... any number of additional param names .
2007-05-03 04:34:53 +00:00
*/
2009-05-06 08:51:23 +00:00
public function remove_params ( $params = NULL ) {
2009-05-06 08:50:32 +00:00
if ( empty ( $params )) {
2007-05-03 04:34:53 +00:00
$this -> params = array ();
2009-05-06 08:50:32 +00:00
return ;
}
if ( ! is_array ( $params )) {
$params = func_get_args ();
}
foreach ( $params as $param ) {
if ( isset ( $this -> params [ $param ])) {
unset ( $this -> params [ $param ]);
}
2007-05-03 04:34:53 +00:00
}
}
/**
2009-08-04 02:05:32 +00:00
* Add a param to the params for this page .
2009-05-22 03:26:07 +00:00
*
* The added param overrides existing one if theyhave the same name .
2007-05-03 04:34:53 +00:00
*
* @ param string $paramname name
2009-05-22 03:26:07 +00:00
* @ param string $param Param value . Defaults to null . If null then return value of param 'name'
* @ return void | string If $param was null then the value of $paramname was returned
ajaxlib/require_js: MDL-16693 $PAGE->requires->... deprecates require_js etc.
There is a new implementation of require_js in lib/deprecatedlib.php,
based on $PAGE->requires.
There were a few other recently introduced functions in lib/weblib.php,
namely print_js_call, print_delayed_js_call, print_js_config and
standard_js_config. These have been removed, since they were never in
a stable branch, and all the places that used them have been changed
to use the newer $PAGE->requires->... methods.
get_require_js_code is also gone, and the evil places that were calling
it, even though it is an internal function, have been fixed.
Also, I made some minor improvements to the code I committed yesterday
for MDL-16695.
All that remains is to update all the places in core code that are
still using require_js.
(This commit also fixes the problem where the admin tree would not
start with the right categories expanded.)
2009-06-12 12:13:07 +00:00
* ( null is returned if that param does not exist ) .
2007-05-03 04:34:53 +00:00
*/
2009-05-06 08:49:12 +00:00
public function param ( $paramname , $param = null ) {
if ( ! is_null ( $param )) {
2008-07-24 15:22:31 +00:00
$this -> params = array ( $paramname => $param ) + $this -> params ;
ajaxlib/require_js: MDL-16693 $PAGE->requires->... deprecates require_js etc.
There is a new implementation of require_js in lib/deprecatedlib.php,
based on $PAGE->requires.
There were a few other recently introduced functions in lib/weblib.php,
namely print_js_call, print_delayed_js_call, print_js_config and
standard_js_config. These have been removed, since they were never in
a stable branch, and all the places that used them have been changed
to use the newer $PAGE->requires->... methods.
get_require_js_code is also gone, and the evil places that were calling
it, even though it is an internal function, have been fixed.
Also, I made some minor improvements to the code I committed yesterday
for MDL-16695.
All that remains is to update all the places in core code that are
still using require_js.
(This commit also fixes the problem where the admin tree would not
start with the right categories expanded.)
2009-06-12 12:13:07 +00:00
} else if ( array_key_exists ( $paramname , $this -> params )) {
2008-07-25 16:20:46 +00:00
return $this -> params [ $paramname ];
ajaxlib/require_js: MDL-16693 $PAGE->requires->... deprecates require_js etc.
There is a new implementation of require_js in lib/deprecatedlib.php,
based on $PAGE->requires.
There were a few other recently introduced functions in lib/weblib.php,
namely print_js_call, print_delayed_js_call, print_js_config and
standard_js_config. These have been removed, since they were never in
a stable branch, and all the places that used them have been changed
to use the newer $PAGE->requires->... methods.
get_require_js_code is also gone, and the evil places that were calling
it, even though it is an internal function, have been fixed.
Also, I made some minor improvements to the code I committed yesterday
for MDL-16695.
All that remains is to update all the places in core code that are
still using require_js.
(This commit also fixes the problem where the admin tree would not
start with the right categories expanded.)
2009-06-12 12:13:07 +00:00
} else {
return null ;
2008-07-24 15:22:31 +00:00
}
2007-05-03 04:34:53 +00:00
}
2009-05-06 08:49:12 +00:00
/**
* Get the params as as a query string .
2009-05-22 03:26:07 +00:00
*
2009-05-06 08:49:12 +00:00
* @ param array $overrideparams params to add to the output params , these
* override existing ones with the same name .
2009-07-05 14:31:58 +00:00
* @ param boolean $escaped Use & amp ; as params separator instead of plain &
2009-05-06 08:49:12 +00:00
* @ return string query string that can be added to a url .
*/
2009-07-05 14:31:58 +00:00
public function get_query_string ( $overrideparams = array (), $escaped = true ) {
2007-05-03 04:34:53 +00:00
$arr = array ();
$params = $overrideparams + $this -> params ;
2009-05-06 08:49:12 +00:00
foreach ( $params as $key => $val ) {
2007-05-03 04:34:53 +00:00
$arr [] = urlencode ( $key ) . " = " . urlencode ( $val );
}
2009-07-05 14:31:58 +00:00
if ( $escaped ) {
return implode ( '&' , $arr );
} else {
return implode ( '&' , $arr );
}
2007-05-03 04:34:53 +00:00
}
2009-05-06 08:49:12 +00:00
2007-05-03 04:34:53 +00:00
/**
* Outputs params as hidden form elements .
2007-05-03 10:03:59 +00:00
*
2009-05-22 03:26:07 +00:00
* @ param array $exclude params to ignore
2007-05-20 14:05:49 +00:00
* @ param integer $indent indentation
2008-05-22 13:29:19 +00:00
* @ param array $overrideparams params to add to the output params , these
2009-05-06 08:49:12 +00:00
* override existing ones with the same name .
2007-05-03 04:34:53 +00:00
* @ return string html for form elements .
*/
2009-05-06 08:49:12 +00:00
public function hidden_params_out ( $exclude = array (), $indent = 0 , $overrideparams = array ()) {
2007-05-03 04:34:53 +00:00
$tabindent = str_repeat ( " \t " , $indent );
$str = '' ;
2008-05-22 13:29:19 +00:00
$params = $overrideparams + $this -> params ;
2009-05-06 08:49:12 +00:00
foreach ( $params as $key => $val ) {
2007-05-03 10:03:59 +00:00
if ( FALSE === array_search ( $key , $exclude )) {
2007-05-20 17:05:27 +00:00
$val = s ( $val );
2007-05-03 10:03:59 +00:00
$str .= " $tabindent <input type= \" hidden \" name= \" $key\ " value = \ " $val\ " /> \n " ;
}
2007-05-03 04:34:53 +00:00
}
return $str ;
}
2009-05-06 08:49:12 +00:00
2007-05-03 04:34:53 +00:00
/**
* Output url
2007-06-19 14:44:02 +00:00
*
2009-07-05 14:31:58 +00:00
* If you use the returned URL in HTML code , you want the escaped ampersands . If you use
* the returned URL in HTTP headers , you want $escaped = false .
*
2009-05-08 03:30:58 +00:00
* @ param boolean $omitquerystring whether to output page params as a query string in the url .
2007-05-03 04:34:53 +00:00
* @ param array $overrideparams params to add to the output url , these override existing ones with the same name .
2009-07-05 14:31:58 +00:00
* @ param boolean $escaped Use & amp ; as params separator instead of plain &
2009-05-22 03:26:07 +00:00
* @ return string Resulting URL
2007-05-03 04:34:53 +00:00
*/
2009-07-05 14:31:58 +00:00
public function out ( $omitquerystring = false , $overrideparams = array (), $escaped = true ) {
2007-05-03 04:34:53 +00:00
$uri = $this -> scheme ? $this -> scheme . ':' . (( strtolower ( $this -> scheme ) == 'mailto' ) ? '' : '//' ) : '' ;
$uri .= $this -> user ? $this -> user . ( $this -> pass ? ':' . $this -> pass : '' ) . '@' : '' ;
$uri .= $this -> host ? $this -> host : '' ;
$uri .= $this -> port ? ':' . $this -> port : '' ;
$uri .= $this -> path ? $this -> path : '' ;
2009-05-08 03:30:58 +00:00
if ( ! $omitquerystring ) {
2009-07-05 14:31:58 +00:00
$querystring = $this -> get_query_string ( $overrideparams , $escaped );
2009-05-08 03:30:58 +00:00
if ( $querystring ) {
$uri .= '?' . $querystring ;
}
2007-05-03 04:34:53 +00:00
}
$uri .= $this -> fragment ? '#' . $this -> fragment : '' ;
2007-06-19 14:44:02 +00:00
return $uri ;
2007-05-03 04:34:53 +00:00
}
2009-05-06 08:49:12 +00:00
2009-07-09 07:35:03 +00:00
/**
* Return a URL relative to $CFG -> wwwroot .
*
* Throws an exception if this URL does not start with $CFG -> wwwroot .
*
* The main use for this is when you want to pass a returnurl from one script to another .
* In this case the returnurl should be relative to $CFG -> wwwroot for two reasons .
* First , it is shorter . More imporatantly , some web servers ( e . g . IIS by default )
* give a 'security' error if you try to pass a full URL as a GET parameter in another URL .
*
* @ return string the URL relative to $CFG -> wwwroot . Note , you will need to urlencode
* this result if you are outputting a URL manually ( but not if you are adding
* it to another moodle_url ) .
*/
public function out_returnurl () {
global $CFG ;
$fulluri = $this -> out ( false , array (), false );
$uri = str_replace ( $CFG -> wwwroot . '/' , '' , $fulluri );
if ( $uri == $fulluri ) {
throw new coding_exception ( 'This URL (' . $fulluri . ') is not relative to $CFG->wwwroot.' );
}
return $uri ;
}
2007-05-03 04:34:53 +00:00
/**
* Output action url with sesskey
2007-06-19 14:44:02 +00:00
*
2009-05-22 03:26:07 +00:00
* Adds sesskey and overriderparams then calls { @ link out ()}
* @ see out ()
*
* @ param array $overrideparams Allows you to override params
2007-05-03 04:34:53 +00:00
* @ return string url
*/
2009-05-06 08:49:12 +00:00
public function out_action ( $overrideparams = array ()) {
2007-05-03 04:34:53 +00:00
$overrideparams = array ( 'sesskey' => sesskey ()) + $overrideparams ;
2007-05-29 06:27:38 +00:00
return $this -> out ( false , $overrideparams );
2007-05-03 04:34:53 +00:00
}
2009-08-10 03:04:01 +00:00
/**
* Compares this moodle_url with another
* See documentation of constants for an explanation of the comparison flags .
* @ param moodle_url $url The moodle_url object to compare
* @ param int $matchtype The type of comparison ( URL_MATCH_BASE , URL_MATCH_PARAMS , URL_MATCH_EXACT )
* @ return boolean
*/
public function compare ( moodle_url $url , $matchtype = URL_MATCH_EXACT ) {
2009-10-01 02:31:42 +00:00
2009-09-23 06:05:36 +00:00
$baseself = $this -> out ( true );
$baseother = $url -> out ( true );
// Append index.php if there is no specific file
if ( substr ( $baseself , - 1 ) == '/' ) {
$baseself .= 'index.php' ;
}
if ( substr ( $baseother , - 1 ) == '/' ) {
$baseother .= 'index.php' ;
}
// Compare the two base URLs
if ( $baseself != $baseother ) {
2009-08-10 03:04:01 +00:00
return false ;
}
if ( $matchtype == URL_MATCH_BASE ) {
return true ;
}
$urlparams = $url -> params ();
foreach ( $this -> params () as $param => $value ) {
if ( $param == 'sesskey' ) {
continue ;
}
if ( ! array_key_exists ( $param , $urlparams ) || $urlparams [ $param ] != $value ) {
return false ;
}
}
if ( $matchtype == URL_MATCH_PARAMS ) {
return true ;
}
foreach ( $urlparams as $param => $value ) {
if ( $param == 'sesskey' ) {
continue ;
}
if ( ! array_key_exists ( $param , $this -> params ()) || $this -> param ( $param ) != $value ) {
return false ;
}
}
return true ;
}
2007-05-03 04:34:53 +00:00
}
2009-07-27 10:33:00 +00:00
/**
* Given an unknown $url type ( string or moodle_url ), returns a string URL .
* A relative URL is handled with $PAGE -> url but gives a debugging error .
*
* @ param mixed $url The URL ( moodle_url or string )
* @ param bool $stripformparams Whether or not to strip the query params from the URL
2009-07-29 08:52:49 +00:00
* @ return string the URL . & s are unescaped . You must use s ( ... ) to output this to XHTML . ( $OUTPUT normally does this automatically . )
2009-07-27 10:33:00 +00:00
*/
function prepare_url ( $url , $stripformparams = false ) {
global $CFG , $PAGE ;
$output = $url ;
if ( $url instanceof moodle_url ) {
2009-07-29 08:52:49 +00:00
$output = $url -> out ( $stripformparams , array (), false );
2009-07-27 10:33:00 +00:00
}
// Handle relative URLs
if ( substr ( $output , 0 , 4 ) != 'http' && substr ( $output , 0 , 1 ) != '/' ) {
if ( preg_match ( '/(.*)\/([A-Za-z0-9-_]*\.php)$/' , $PAGE -> url -> out ( true ), $matches )) {
return $matches [ 1 ] . " / $output " ;
2009-08-13 01:15:58 +00:00
} else if ( $output == '' ) {
return $PAGE -> url -> out ( false , array (), false ) . '#' ;
2009-07-27 10:33:00 +00:00
} else {
2009-09-16 02:43:58 +00:00
throw new coding_exception ( 'Unrecognied URL scheme. Please check the formatting of the URL passed to this function. Absolute URLs are the preferred scheme.' );
2009-07-27 10:33:00 +00:00
}
}
2009-09-16 09:17:25 +00:00
// Add wwwroot only if the URL does not already start with http:// or https://
if ( ! preg_match ( '|https?://|' , $output ) ) {
$output = $CFG -> wwwroot . $output ;
}
2009-07-27 10:33:00 +00:00
return $output ;
}
2004-09-23 02:48:41 +00:00
/**
* Determine if there is data waiting to be processed from a form
*
* Used on most forms in Moodle to check for data
* Returns the data as an object , if it ' s found .
* This object can be used in foreach loops without
* casting because it ' s cast to ( array ) automatically
2005-01-26 15:57:00 +00:00
*
2006-12-04 09:13:51 +00:00
* Checks that submitted POST data exists and returns it as object .
2004-09-23 04:36:43 +00:00
*
2009-05-22 03:26:07 +00:00
* @ uses $_POST
2006-12-04 09:13:51 +00:00
* @ return mixed false or object
2004-09-23 02:48:41 +00:00
*/
2008-06-09 16:53:30 +00:00
function data_submitted () {
2004-09-23 04:36:43 +00:00
2003-01-05 06:45:20 +00:00
if ( empty ( $_POST )) {
2003-01-02 14:49:23 +00:00
return false ;
} else {
2008-06-09 16:53:30 +00:00
return ( object ) $_POST ;
2003-01-02 14:49:23 +00:00
}
}
2004-09-23 02:48:41 +00:00
/**
2004-09-23 04:36:43 +00:00
* Given some normal text this function will break up any
* long words to a given size by inserting the given character
*
2006-01-04 08:23:42 +00:00
* It 's multibyte savvy and doesn' t change anything inside html tags .
*
2004-09-23 02:48:41 +00:00
* @ param string $string the string to be modified
2004-09-25 05:29:21 +00:00
* @ param int $maxsize maximum length of the string to be returned
2004-09-23 02:48:41 +00:00
* @ param string $cutchar the string used to represent word breaks
* @ return string
*/
2004-03-10 02:19:17 +00:00
function break_up_long_words ( $string , $maxsize = 20 , $cutchar = ' ' ) {
2005-04-03 12:15:45 +00:00
2006-01-04 08:23:42 +00:00
/// Loading the textlib singleton instance. We are going to need it.
$textlib = textlib_get_instance ();
2005-03-10 13:30:57 +00:00
2006-01-04 08:23:42 +00:00
/// First of all, save all the tags inside the text to skip them
$tags = array ();
filter_save_tags ( $string , $tags );
2004-07-07 17:45:42 +00:00
2006-01-04 08:23:42 +00:00
/// Process the string adding the cut when necessary
2004-03-10 02:19:17 +00:00
$output = '' ;
2006-11-11 17:23:20 +00:00
$length = $textlib -> strlen ( $string );
2004-03-10 02:19:17 +00:00
$wordlength = 0 ;
for ( $i = 0 ; $i < $length ; $i ++ ) {
2006-11-11 17:23:20 +00:00
$char = $textlib -> substr ( $string , $i , 1 );
2006-01-04 08:23:42 +00:00
if ( $char == ' ' or $char == " \t " or $char == " \n " or $char == " \r " or $char == " < " or $char == " > " ) {
2004-03-10 02:19:17 +00:00
$wordlength = 0 ;
} else {
$wordlength ++ ;
if ( $wordlength > $maxsize ) {
$output .= $cutchar ;
$wordlength = 0 ;
}
}
$output .= $char ;
}
2006-01-04 08:23:42 +00:00
/// Finally load the tags back again
if ( ! empty ( $tags )) {
$output = str_replace ( array_keys ( $tags ), $tags , $output );
}
2004-03-10 02:19:17 +00:00
return $output ;
}
2009-09-03 06:59:25 +00:00
/**
2008-12-10 08:57:50 +00:00
* Try and close the current window using JavaScript , either immediately , or after a delay .
2009-05-22 03:26:07 +00:00
*
* Echo ' s out the resulting XHTML & javascript
*
* @ global object
* @ global object
2008-12-10 08:57:50 +00:00
* @ param integer $delay a delay in seconds before closing the window . Default 0.
* @ param boolean $reloadopener if true , we will see if this window was a pop - up , and try
* to reload the parent window before this one closes .
2005-03-22 17:31:04 +00:00
*/
2008-12-10 08:57:50 +00:00
function close_window ( $delay = 0 , $reloadopener = false ) {
2009-08-06 14:21:34 +00:00
global $THEME , $PAGE , $OUTPUT ;
2005-03-22 17:31:04 +00:00
2009-05-06 08:29:22 +00:00
if ( ! $PAGE -> headerprinted ) {
2009-09-03 06:59:25 +00:00
$PAGE -> set_title ( get_string ( 'closewindow' ));
echo $OUTPUT -> header ();
2008-12-10 08:57:50 +00:00
} else {
print_container_end_all ( false , $THEME -> open_header_containers );
}
if ( $reloadopener ) {
$function = 'close_window_reloading_opener' ;
} else {
$function = 'close_window' ;
}
echo '<p class="centerpara">' . get_string ( 'windowclosing' ) . '</p>' ;
ajaxlib/require_js: MDL-16693 $PAGE->requires->... deprecates require_js etc.
There is a new implementation of require_js in lib/deprecatedlib.php,
based on $PAGE->requires.
There were a few other recently introduced functions in lib/weblib.php,
namely print_js_call, print_delayed_js_call, print_js_config and
standard_js_config. These have been removed, since they were never in
a stable branch, and all the places that used them have been changed
to use the newer $PAGE->requires->... methods.
get_require_js_code is also gone, and the evil places that were calling
it, even though it is an internal function, have been fixed.
Also, I made some minor improvements to the code I committed yesterday
for MDL-16695.
All that remains is to update all the places in core code that are
still using require_js.
(This commit also fixes the problem where the admin tree would not
start with the right categories expanded.)
2009-06-12 12:13:07 +00:00
$PAGE -> requires -> js_function_call ( $function ) -> after_delay ( $delay );
2008-12-10 08:57:50 +00:00
2009-08-06 14:21:34 +00:00
echo $OUTPUT -> footer ();
2008-12-10 08:57:50 +00:00
exit ;
}
2005-03-22 17:31:04 +00:00
2009-08-05 08:49:56 +00:00
/**
* Returns a string containing a link to the user documentation for the current
* page . Also contains an icon by default . Shown to teachers and admin only .
*
* @ global object
* @ global object
* @ param string $text The text to be displayed for the link
* @ param string $iconpath The path to the icon to be displayed
* @ return string The link to user documentation for this current page
*/
function page_doc_link ( $text = '' , $iconpath = '' ) {
global $CFG , $PAGE , $OUTPUT ;
if ( empty ( $CFG -> docroot ) || during_initial_install ()) {
return '' ;
}
if ( ! has_capability ( 'moodle/site:doclinks' , $PAGE -> context )) {
return '' ;
}
$path = $PAGE -> docspath ;
if ( ! $path ) {
return '' ;
}
return $OUTPUT -> doc_link ( $path , $text , $iconpath );
}
2006-01-11 02:22:16 +00:00
2004-09-23 04:36:43 +00:00
/**
* Validates an email to make sure it makes sense .
*
* @ param string $address The email address to validate .
* @ return boolean
*/
2004-09-25 05:29:21 +00:00
function validate_email ( $address ) {
2004-09-23 04:36:43 +00:00
2006-04-20 22:32:00 +00:00
return ( ereg ( '^[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+' .
'(\.[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+)*' .
2001-11-22 06:23:56 +00:00
'@' .
'[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.' .
'[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$' ,
$address ));
}
2004-11-30 19:44:08 +00:00
/**
* Extracts file argument either from file parameter or PATH_INFO
2009-01-05 21:37:20 +00:00
* Note : $scriptname parameter is not needed anymore
2004-11-30 19:44:08 +00:00
*
2009-05-22 03:26:07 +00:00
* @ global string
* @ uses $_SERVER
* @ uses PARAM_PATH
2004-11-30 19:44:08 +00:00
* @ return string file path ( only safe characters )
*/
2009-01-05 21:37:20 +00:00
function get_file_argument () {
global $SCRIPT ;
2004-11-30 19:44:08 +00:00
$relativepath = optional_param ( 'file' , FALSE , PARAM_PATH );
// then try extract file from PATH_INFO (slasharguments method)
2009-01-05 21:37:20 +00:00
if ( $relativepath === false and isset ( $_SERVER [ 'PATH_INFO' ]) and $_SERVER [ 'PATH_INFO' ] !== '' ) {
2004-11-30 19:44:08 +00:00
// check that PATH_INFO works == must not contain the script name
2009-01-05 21:37:20 +00:00
if ( strpos ( $_SERVER [ 'PATH_INFO' ], $SCRIPT ) === false ) {
$relativepath = clean_param ( urldecode ( $_SERVER [ 'PATH_INFO' ]), PARAM_PATH );
2004-11-30 19:44:08 +00:00
}
}
2009-01-05 21:37:20 +00:00
// note: we are not using any other way because they are not compatible with unicode file names ;-)
2004-11-30 19:44:08 +00:00
return $relativepath ;
}
2004-09-23 04:36:43 +00:00
/**
2004-09-25 05:29:21 +00:00
* Just returns an array of text formats suitable for a popup menu
2004-09-23 04:36:43 +00:00
*
2004-09-25 05:29:21 +00:00
* @ uses FORMAT_MOODLE
* @ uses FORMAT_HTML
* @ uses FORMAT_PLAIN
* @ uses FORMAT_MARKDOWN
* @ return array
2004-09-23 04:36:43 +00:00
*/
2002-10-10 07:26:10 +00:00
function format_text_menu () {
2004-09-23 04:36:43 +00:00
2004-09-22 14:39:15 +00:00
return array ( FORMAT_MOODLE => get_string ( 'formattext' ),
FORMAT_HTML => get_string ( 'formathtml' ),
FORMAT_PLAIN => get_string ( 'formatplain' ),
FORMAT_MARKDOWN => get_string ( 'formatmarkdown' ));
2002-10-10 07:26:10 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* Given text in a variety of format codings , this function returns
2005-01-26 15:57:00 +00:00
* the text as safe HTML .
2004-09-23 04:36:43 +00:00
*
2008-01-13 08:30:39 +00:00
* This function should mainly be used for long strings like posts ,
2007-12-15 18:42:49 +00:00
* answers , glossary items etc . For short strings @ see format_string () .
*
2009-05-22 03:26:07 +00:00
* @ todo Finish documenting this function
*
* @ global object
* @ global object
* @ global object
* @ global object
2004-09-25 05:29:21 +00:00
* @ uses FORMAT_MOODLE
* @ uses FORMAT_HTML
* @ uses FORMAT_PLAIN
* @ uses FORMAT_WIKI
* @ uses FORMAT_MARKDOWN
2009-05-22 03:26:07 +00:00
* @ uses CLI_SCRIPT
* @ staticvar array $croncache
2004-09-25 05:29:21 +00:00
* @ param string $text The text to be formatted . This is raw text originally from user input .
2005-01-26 15:57:00 +00:00
* @ param int $format Identifier of the text format to be used
2009-05-22 03:26:07 +00:00
* [ FORMAT_MOODLE , FORMAT_HTML , FORMAT_PLAIN , FORMAT_WIKI , FORMAT_MARKDOWN ]
* @ param object $options ?
* @ param int $courseid The courseid to use , defaults to $COURSE -> courseid
2004-09-25 05:29:21 +00:00
* @ return string
2004-09-23 04:36:43 +00:00
*/
2006-08-26 13:00:07 +00:00
function format_text ( $text , $format = FORMAT_MOODLE , $options = NULL , $courseid = NULL ) {
2009-05-06 08:31:30 +00:00
global $CFG , $COURSE , $DB , $PAGE ;
2004-01-16 10:49:07 +00:00
2008-02-03 10:57:07 +00:00
static $croncache = array ();
2009-01-31 20:07:32 +00:00
2008-12-19 02:16:00 +00:00
$hashstr = '' ;
2008-02-03 10:57:07 +00:00
2006-10-24 22:19:41 +00:00
if ( $text === '' ) {
return '' ; // no need to do any filters and cleaning
}
2009-07-24 02:44:44 +00:00
if ( ! empty ( $options -> comments ) && ! empty ( $CFG -> usecomments )) {
require_once ( $CFG -> libdir . '/commentlib.php' );
$comment = new comment ( $options -> comments );
$cmt = $comment -> init ( true );
} else {
$cmt = '' ;
}
2006-10-24 22:19:41 +00:00
2009-04-20 10:05:50 +00:00
if ( ! isset ( $options -> trusted )) {
$options -> trusted = false ;
2006-08-26 13:00:07 +00:00
}
2005-10-29 21:32:09 +00:00
if ( ! isset ( $options -> noclean )) {
2009-04-20 10:05:50 +00:00
if ( $options -> trusted and trusttext_active ()) {
// no cleaning if text trusted and noclean not specified
$options -> noclean = true ;
} else {
$options -> noclean = false ;
}
2005-10-29 21:32:09 +00:00
}
2006-09-22 18:08:53 +00:00
if ( ! isset ( $options -> nocache )) {
$options -> nocache = false ;
}
2005-10-29 21:32:09 +00:00
if ( ! isset ( $options -> smiley )) {
$options -> smiley = true ;
}
if ( ! isset ( $options -> filter )) {
$options -> filter = true ;
}
if ( ! isset ( $options -> para )) {
$options -> para = true ;
}
if ( ! isset ( $options -> newlines )) {
$options -> newlines = true ;
2004-02-09 12:33:44 +00:00
}
2004-01-16 10:49:07 +00:00
if ( empty ( $courseid )) {
2007-01-27 19:56:08 +00:00
$courseid = $COURSE -> id ;
2004-01-16 10:49:07 +00:00
}
2003-08-26 18:44:09 +00:00
2009-04-13 06:56:32 +00:00
if ( $options -> filter ) {
$filtermanager = filter_manager :: instance ();
} else {
$filtermanager = new null_filter_manager ();
2008-12-19 02:16:00 +00:00
}
2009-05-06 08:31:30 +00:00
$context = $PAGE -> context ;
2009-04-13 06:56:32 +00:00
2006-09-22 18:08:53 +00:00
if ( ! empty ( $CFG -> cachetext ) and empty ( $options -> nocache )) {
2009-04-13 06:56:32 +00:00
$hashstr .= $text . '-' . $filtermanager -> text_filtering_hash ( $context , $courseid ) . '-' . ( int ) $courseid . '-' . current_language () . '-' .
2009-04-20 10:05:50 +00:00
( int ) $format . ( int ) $options -> trusted . ( int ) $options -> noclean . ( int ) $options -> smiley .
2009-04-13 06:56:32 +00:00
( int ) $options -> filter . ( int ) $options -> para . ( int ) $options -> newlines ;
2008-02-03 10:57:07 +00:00
2008-12-19 02:16:00 +00:00
$time = time () - $CFG -> cachetext ;
2009-01-31 20:07:32 +00:00
$md5key = md5 ( $hashstr );
2009-01-03 14:28:02 +00:00
if ( CLI_SCRIPT ) {
2008-02-03 10:57:07 +00:00
if ( isset ( $croncache [ $md5key ])) {
2009-07-24 02:44:44 +00:00
return $croncache [ $md5key ] . $cmt ;
2008-02-03 10:57:07 +00:00
}
}
2009-07-04 09:35:03 +00:00
if ( $oldcacheitem = $DB -> get_record ( 'cache_text' , array ( 'md5key' => $md5key ), '*' , IGNORE_MULTIPLE )) {
2006-03-20 02:33:41 +00:00
if ( $oldcacheitem -> timemodified >= $time ) {
2009-01-03 14:28:02 +00:00
if ( CLI_SCRIPT ) {
2008-02-03 10:57:07 +00:00
if ( count ( $croncache ) > 150 ) {
2008-02-25 20:22:59 +00:00
reset ( $croncache );
$key = key ( $croncache );
unset ( $croncache [ $key ]);
2008-02-03 10:57:07 +00:00
}
$croncache [ $md5key ] = $oldcacheitem -> formattedtext ;
}
2009-07-24 02:44:44 +00:00
return $oldcacheitem -> formattedtext . $cmt ;
2006-03-20 02:33:41 +00:00
}
2005-10-29 21:32:09 +00:00
}
}
2002-10-10 07:26:10 +00:00
switch ( $format ) {
2003-02-05 12:41:59 +00:00
case FORMAT_HTML :
2006-08-26 13:00:07 +00:00
if ( $options -> smiley ) {
2005-10-29 21:32:09 +00:00
replace_smilies ( $text );
}
2006-08-26 13:00:07 +00:00
if ( ! $options -> noclean ) {
2007-01-20 13:36:03 +00:00
$text = clean_text ( $text , FORMAT_HTML );
2004-08-09 14:54:39 +00:00
}
2009-04-13 06:56:32 +00:00
$text = $filtermanager -> filter_text ( $text , $context , $courseid );
2003-02-05 12:41:59 +00:00
break ;
2003-04-27 10:46:16 +00:00
case FORMAT_PLAIN :
2007-01-20 13:36:03 +00:00
$text = s ( $text ); // cleans dangerous JS
2004-05-11 23:17:25 +00:00
$text = rebuildnolinktag ( $text );
2004-09-22 14:39:15 +00:00
$text = str_replace ( ' ' , ' ' , $text );
2003-04-27 10:46:16 +00:00
$text = nl2br ( $text );
break ;
2003-05-04 04:07:36 +00:00
case FORMAT_WIKI :
2005-04-11 13:46:06 +00:00
// this format is deprecated
2005-04-20 19:12:28 +00:00
$text = ' < p > NOTICE : Wiki - like formatting has been removed from Moodle . You should not be seeing
this message as all texts should have been converted to Markdown format instead .
2005-04-12 03:14:29 +00:00
Please post a bug report to http :// moodle . org / bugs with information about where you
2005-10-29 21:32:09 +00:00
saw this message .</ p > ' . s ( $text );
2003-05-04 04:07:36 +00:00
break ;
2004-07-30 04:02:58 +00:00
case FORMAT_MARKDOWN :
$text = markdown_to_html ( $text );
2006-08-26 13:00:07 +00:00
if ( $options -> smiley ) {
2005-10-29 21:32:09 +00:00
replace_smilies ( $text );
}
2006-08-26 13:00:07 +00:00
if ( ! $options -> noclean ) {
2007-01-20 13:36:03 +00:00
$text = clean_text ( $text , FORMAT_HTML );
2004-08-09 14:54:39 +00:00
}
2009-04-13 06:56:32 +00:00
$text = $filtermanager -> filter_text ( $text , $context , $courseid );
2004-07-30 04:02:58 +00:00
break ;
2003-02-05 12:41:59 +00:00
default : // FORMAT_MOODLE or anything else
2004-03-09 06:44:27 +00:00
$text = text_to_html ( $text , $options -> smiley , $options -> para , $options -> newlines );
2006-08-26 13:00:07 +00:00
if ( ! $options -> noclean ) {
2007-01-20 13:36:03 +00:00
$text = clean_text ( $text , FORMAT_HTML );
2004-08-09 14:54:39 +00:00
}
2009-04-13 06:56:32 +00:00
$text = $filtermanager -> filter_text ( $text , $context , $courseid );
2002-10-10 07:26:10 +00:00
break ;
}
2004-02-09 12:33:44 +00:00
2009-04-13 06:56:32 +00:00
// Warn people that we have removed this old mechanism, just in case they
// were stupid enough to rely on it.
if ( isset ( $CFG -> currenttextiscacheable )) {
debugging ( 'Once upon a time, Moodle had a truly evil use of global variables ' .
'called $CFG->currenttextiscacheable. The good news is that this no ' .
'longer exists. The bad news is that you seem to be using a filter that ' .
'relies on it. Please seek out and destroy that filter code.' , DEBUG_DEVELOPER );
}
if ( empty ( $options -> nocache ) and ! empty ( $CFG -> cachetext )) {
2009-01-03 14:28:02 +00:00
if ( CLI_SCRIPT ) {
2008-02-03 10:57:07 +00:00
// special static cron cache - no need to store it in db if its not already there
if ( count ( $croncache ) > 150 ) {
2008-02-25 20:22:59 +00:00
reset ( $croncache );
$key = key ( $croncache );
unset ( $croncache [ $key ]);
2008-02-03 10:57:07 +00:00
}
$croncache [ $md5key ] = $text ;
2009-07-24 02:44:44 +00:00
return $text . $cmt ;
2008-02-03 10:57:07 +00:00
}
2006-10-04 21:22:57 +00:00
$newcacheitem = new object ();
2006-03-20 02:33:41 +00:00
$newcacheitem -> md5key = $md5key ;
2008-05-15 21:40:00 +00:00
$newcacheitem -> formattedtext = $text ;
2006-03-20 02:33:41 +00:00
$newcacheitem -> timemodified = time ();
if ( $oldcacheitem ) { // See bug 4677 for discussion
$newcacheitem -> id = $oldcacheitem -> id ;
2009-04-17 08:05:55 +00:00
try {
$DB -> update_record ( 'cache_text' , $newcacheitem ); // Update existing record in the cache table
} catch ( dml_exception $e ) {
// It's unlikely that the cron cache cleaner could have
// deleted this entry in the meantime, as it allows
// some extra time to cover these cases.
}
2006-03-20 02:33:41 +00:00
} else {
2009-04-17 08:05:55 +00:00
try {
$DB -> insert_record ( 'cache_text' , $newcacheitem ); // Insert a new record in the cache table
} catch ( dml_exception $e ) {
// Again, it's possible that another user has caused this
// record to be created already in the time that it took
// to traverse this function. That's OK too, as the
// call above handles duplicate entries, and eventually
// the cron cleaner will delete them.
}
2006-03-20 02:33:41 +00:00
}
2004-02-09 12:33:44 +00:00
}
2009-07-24 02:44:44 +00:00
return $text . $cmt ;
2009-08-04 02:05:32 +00:00
2002-10-10 07:26:10 +00:00
}
2009-05-22 03:26:07 +00:00
/**
* Converts the text format from the value to the 'internal'
2009-08-04 02:05:32 +00:00
* name or vice versa .
2006-03-04 16:04:48 +00:00
*
2009-05-22 03:26:07 +00:00
* $key can either be the value or the name and you get the other back .
*
* @ uses FORMAT_MOODLE
* @ uses FORMAT_HTML
* @ uses FORMAT_PLAIN
* @ uses FORMAT_MARKDOWN
* @ param mixed $key int 0 - 4 or string one of 'moodle' , 'html' , 'plain' , 'markdown'
* @ return mixed as above but the other way around !
2005-05-16 10:08:18 +00:00
*/
function text_format_name ( $key ) {
$lookup = array ();
$lookup [ FORMAT_MOODLE ] = 'moodle' ;
$lookup [ FORMAT_HTML ] = 'html' ;
$lookup [ FORMAT_PLAIN ] = 'plain' ;
$lookup [ FORMAT_MARKDOWN ] = 'markdown' ;
$value = " error " ;
if ( ! is_numeric ( $key )) {
$key = strtolower ( $key );
$value = array_search ( $key , $lookup );
}
else {
if ( isset ( $lookup [ $key ] )) {
$value = $lookup [ $key ];
}
}
return $value ;
}
2007-12-25 10:03:59 +00:00
/**
* Resets all data related to filters , called during upgrade or when filter settings change .
2009-05-22 03:26:07 +00:00
*
* @ global object
* @ global object
2007-12-25 10:03:59 +00:00
* @ return void
*/
function reset_text_filters_cache () {
2008-06-02 21:52:27 +00:00
global $CFG , $DB ;
2007-12-25 10:03:59 +00:00
2008-06-02 21:52:27 +00:00
$DB -> delete_records ( 'cache_text' );
2007-12-25 10:03:59 +00:00
$purifdir = $CFG -> dataroot . '/cache/htmlpurifier' ;
remove_dir ( $purifdir , true );
}
2007-02-23 20:10:11 +00:00
2009-08-04 02:05:32 +00:00
/**
2009-05-22 03:26:07 +00:00
* Given a simple string , this function returns the string
* processed by enabled string filters if $CFG -> filterall is enabled
2007-12-15 18:42:49 +00:00
*
2009-05-22 03:26:07 +00:00
* This function should be used to print short strings ( non html ) that
* need filter processing e . g . activity titles , post subjects ,
* glossary concepts .
2005-03-25 16:24:43 +00:00
*
2009-05-22 03:26:07 +00:00
* @ global object
* @ global object
* @ global object
* @ staticvar bool $strcache
* @ param string $string The string to be filtered .
* @ param boolean $striplinks To strip any link in the result text .
Moodle 1.8 default changed from false to true ! MDL - 8713
* @ param int $courseid Current course as filters can , potentially , use it
* @ return string
2005-03-25 16:24:43 +00:00
*/
2009-04-13 06:56:32 +00:00
function format_string ( $string , $striplinks = true , $courseid = NULL ) {
2009-05-06 08:31:30 +00:00
global $CFG , $COURSE , $PAGE ;
2007-03-04 22:52:33 +00:00
2005-03-27 20:57:50 +00:00
//We'll use a in-memory cache here to speed up repeated strings
2007-02-23 20:10:11 +00:00
static $strcache = false ;
2007-03-04 22:52:33 +00:00
if ( $strcache === false or count ( $strcache ) > 2000 ) { // this number might need some tuning to limit memory usage in cron
2007-02-23 20:10:11 +00:00
$strcache = array ();
}
2007-06-19 14:44:02 +00:00
2007-03-04 22:52:33 +00:00
//init course id
2007-03-04 22:58:29 +00:00
if ( empty ( $courseid )) {
2007-03-04 22:52:33 +00:00
$courseid = $COURSE -> id ;
}
2005-03-27 20:57:50 +00:00
//Calculate md5
2007-03-04 22:52:33 +00:00
$md5 = md5 ( $string . '<+>' . $striplinks . '<+>' . $courseid . '<+>' . current_language ());
2005-03-27 20:57:50 +00:00
//Fetch from cache if possible
2007-03-04 22:52:33 +00:00
if ( isset ( $strcache [ $md5 ])) {
2005-03-27 20:57:50 +00:00
return $strcache [ $md5 ];
}
2007-03-06 02:59:25 +00:00
// First replace all ampersands not followed by html entity code
2009-06-22 01:22:37 +00:00
// Regular expression moved to its own method for easier unit testing
$string = replace_ampersands_not_followed_by_entity ( $string );
2007-03-19 04:26:45 +00:00
2009-04-16 09:13:30 +00:00
if ( ! empty ( $CFG -> filterall ) && $CFG -> version >= 2009040600 ) { // Avoid errors during the upgrade to the new system.
2009-05-06 08:31:30 +00:00
$context = $PAGE -> context ;
2009-04-13 06:56:32 +00:00
$string = filter_manager :: instance () -> filter_string ( $string , $context , $courseid );
2005-03-25 16:24:43 +00:00
}
2007-06-19 14:44:02 +00:00
2007-03-16 05:36:24 +00:00
// If the site requires it, strip ALL tags from this string
if ( ! empty ( $CFG -> formatstringstriptags )) {
$string = strip_tags ( $string );
2008-07-25 22:44:17 +00:00
} else {
// Otherwise strip just links if that is required (default)
if ( $striplinks ) { //strip links in string
2009-06-22 06:07:56 +00:00
$string = strip_links ( $string );
2008-07-25 22:44:17 +00:00
}
$string = clean_text ( $string );
2005-03-26 01:07:23 +00:00
}
2005-03-27 20:57:50 +00:00
//Store to cache
$strcache [ $md5 ] = $string ;
2007-06-19 14:44:02 +00:00
2005-03-25 16:24:43 +00:00
return $string ;
}
2009-06-22 01:22:37 +00:00
/**
* Given a string , performs a negative lookahead looking for any ampersand character
* that is not followed by a proper HTML entity . If any is found , it is replaced
* by & amp ; . The string is then returned .
*
* @ param string $string
* @ return string
*/
function replace_ampersands_not_followed_by_entity ( $string ) {
return preg_replace ( " / \ &(?![a-zA-Z0-9#] { 1,8};)/ " , " & " , $string );
}
2009-06-22 06:07:56 +00:00
/**
* Given a string , replaces all < a >.*</ a > by .* and returns the string .
2009-08-04 02:05:32 +00:00
*
2009-06-22 06:07:56 +00:00
* @ param string $string
* @ return string
*/
function strip_links ( $string ) {
return preg_replace ( '/(<a\s[^>]+?>)(.+?)(<\/a>)/is' , '$2' , $string );
}
/**
* This expression turns links into something nice in a text format . ( Russell Jungwirth )
*
* @ param string $string
* @ return string
*/
function wikify_links ( $string ) {
return preg_replace ( '~(<a [^<]*href=["|\']?([^ "\']*)["|\']?[^>]*>([^<]*)</a>)~i' , '$3 [ $2 ]' , $string );
}
/**
* Replaces non - standard HTML entities
2009-08-04 02:05:32 +00:00
*
2009-06-22 06:07:56 +00:00
* @ param string $string
* @ return string
*/
function fix_non_standard_entities ( $string ) {
$text = preg_replace ( '/(&#[0-9]+)(;?)/' , '$1;' , $string );
2009-08-04 02:05:32 +00:00
$text = preg_replace ( '/(&#x[0-9a-fA-F]+)(;?)/' , '$1;' , $text );
2009-06-22 06:07:56 +00:00
return $text ;
}
2004-09-23 04:36:43 +00:00
/**
* Given text in a variety of format codings , this function returns
* the text as plain text suitable for plain email .
*
2004-09-25 05:29:21 +00:00
* @ uses FORMAT_MOODLE
* @ uses FORMAT_HTML
* @ uses FORMAT_PLAIN
* @ uses FORMAT_WIKI
* @ uses FORMAT_MARKDOWN
* @ param string $text The text to be formatted . This is raw text originally from user input .
2005-01-26 15:57:00 +00:00
* @ param int $format Identifier of the text format to be used
2009-05-22 03:26:07 +00:00
* [ FORMAT_MOODLE , FORMAT_HTML , FORMAT_PLAIN , FORMAT_WIKI , FORMAT_MARKDOWN ]
2004-09-25 05:29:21 +00:00
* @ return string
2004-09-23 04:36:43 +00:00
*/
2003-05-04 04:07:36 +00:00
function format_text_email ( $text , $format ) {
switch ( $format ) {
case FORMAT_PLAIN :
return $text ;
break ;
case FORMAT_WIKI :
$text = wiki_to_html ( $text );
2009-06-22 06:07:56 +00:00
$text = wikify_links ( $text );
2003-07-15 02:06:51 +00:00
return strtr ( strip_tags ( $text ), array_flip ( get_html_translation_table ( HTML_ENTITIES )));
2003-05-04 04:07:36 +00:00
break ;
2003-11-07 03:27:21 +00:00
case FORMAT_HTML :
return html_to_text ( $text );
break ;
2004-07-30 04:02:58 +00:00
case FORMAT_MOODLE :
case FORMAT_MARKDOWN :
2004-08-21 14:21:09 +00:00
default :
2009-06-22 06:07:56 +00:00
$text = wikify_links ( $text );
2003-07-15 02:06:51 +00:00
return strtr ( strip_tags ( $text ), array_flip ( get_html_translation_table ( HTML_ENTITIES )));
2003-05-04 04:07:36 +00:00
break ;
}
}
2002-10-10 07:26:10 +00:00
2004-09-23 04:36:43 +00:00
/**
* Given some text in HTML format , this function will pass it
2009-04-13 06:56:32 +00:00
* through any filters that have been configured for this context .
2004-09-23 04:36:43 +00:00
*
2009-05-22 03:26:07 +00:00
* @ global object
* @ global object
* @ global object
2004-09-25 05:29:21 +00:00
* @ param string $text The text to be passed through format filters
2009-04-13 06:56:32 +00:00
* @ param int $courseid The current course .
* @ return string the filtered string .
2004-09-23 04:36:43 +00:00
*/
2004-01-16 10:49:07 +00:00
function filter_text ( $text , $courseid = NULL ) {
2009-05-06 08:31:30 +00:00
global $CFG , $COURSE , $PAGE ;
2007-01-27 19:56:08 +00:00
if ( empty ( $courseid )) {
$courseid = $COURSE -> id ; // (copied from format_text)
}
2003-10-13 14:11:17 +00:00
2009-05-06 08:31:30 +00:00
$context = $PAGE -> context ;
2007-03-16 05:36:24 +00:00
2009-04-13 06:56:32 +00:00
return filter_manager :: instance () -> filter_text ( $text , $context , $courseid );
2007-03-15 06:08:46 +00:00
}
2009-04-21 21:17:21 +00:00
/**
* Formats activity intro text
2009-05-22 03:26:07 +00:00
*
* @ global object
* @ uses CONTEXT_MODULE
2009-04-21 21:17:21 +00:00
* @ param string $module name of module
* @ param object $activity instance of activity
* @ param int $cmid course module id
2009-04-22 07:14:19 +00:00
* @ param bool $filter filter resulting html text
2009-04-21 21:17:21 +00:00
* @ return text
*/
2009-04-22 07:14:19 +00:00
function format_module_intro ( $module , $activity , $cmid , $filter = true ) {
2009-04-22 05:10:08 +00:00
global $CFG ;
require_once ( " $CFG->libdir /filelib.php " );
2009-04-22 07:14:19 +00:00
$options = ( object ) array ( 'noclean' => true , 'para' => false , 'filter' => false );
2009-04-21 21:17:21 +00:00
$context = get_context_instance ( CONTEXT_MODULE , $cmid );
2009-04-22 07:19:56 +00:00
$intro = file_rewrite_pluginfile_urls ( $activity -> intro , 'pluginfile.php' , $context -> id , $module . '_intro' , null );
2009-04-22 05:10:08 +00:00
return trim ( format_text ( $intro , $activity -> introformat , $options ));
2009-04-21 21:17:21 +00:00
}
2007-03-15 06:08:46 +00:00
2006-08-26 13:00:07 +00:00
/**
2009-04-20 10:05:50 +00:00
* Legacy function , used for cleaning of old forum and glossary text only .
2009-05-22 03:26:07 +00:00
*
* @ global object
2007-01-04 10:23:06 +00:00
* @ param string $text text that may contain TRUSTTEXT marker
2006-08-26 13:00:07 +00:00
* @ return text without any TRUSTTEXT marker
*/
function trusttext_strip ( $text ) {
global $CFG ;
while ( true ) { //removing nested TRUSTTEXT
2007-01-04 10:23:06 +00:00
$orig = $text ;
2009-04-20 10:05:50 +00:00
$text = str_replace ( '#####TRUSTTEXT#####' , '' , $text );
2006-08-26 13:00:07 +00:00
if ( strcmp ( $orig , $text ) === 0 ) {
return $text ;
}
}
}
2009-04-20 10:05:50 +00:00
/**
* Must be called before editing of all texts
* with trust flag . Removes all XSS nasties
* from texts stored in database if needed .
2009-05-22 03:26:07 +00:00
*
2009-04-20 10:05:50 +00:00
* @ param object $object data object with xxx , xxxformat and xxxtrust fields
* @ param string $field name of text field
* @ param object $context active context
* @ return object updated $object
*/
function trusttext_pre_edit ( $object , $field , $context ) {
$trustfield = $field . 'trust' ;
2009-08-04 02:05:32 +00:00
$formatfield = $field . 'format' ;
2009-04-20 10:05:50 +00:00
if ( ! $object -> $trustfield or ! trusttext_trusted ( $context )) {
$object -> $field = clean_text ( $object -> $field , $object -> $formatfield );
}
return $object ;
}
/**
2009-05-22 03:26:07 +00:00
* Is current user trusted to enter no dangerous XSS in this context ?
*
2009-04-20 10:05:50 +00:00
* Please note the user must be in fact trusted everywhere on this server !!
2009-05-22 03:26:07 +00:00
*
* @ param object $context
2009-04-20 10:05:50 +00:00
* @ return bool true if user trusted
*/
function trusttext_trusted ( $context ) {
2009-08-04 02:05:32 +00:00
return ( trusttext_active () and has_capability ( 'moodle/site:trustcontent' , $context ));
2009-04-20 10:05:50 +00:00
}
/**
* Is trusttext feature active ?
2009-05-22 03:26:07 +00:00
*
* @ global object
* @ param object $context
2009-04-20 10:05:50 +00:00
* @ return bool
*/
function trusttext_active () {
global $CFG ;
2009-08-04 02:05:32 +00:00
return ! empty ( $CFG -> enabletrusttext );
2009-04-20 10:05:50 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* Given raw text ( eg typed in by a user ), this function cleans it up
* and removes any nasty tags that could mess up Moodle pages .
*
2004-09-25 05:29:21 +00:00
* @ uses FORMAT_MOODLE
* @ uses FORMAT_PLAIN
2009-05-22 03:26:07 +00:00
* @ global string
* @ global object
2004-09-25 05:29:21 +00:00
* @ param string $text The text to be cleaned
2005-01-26 15:57:00 +00:00
* @ param int $format Identifier of the text format to be used
2009-05-22 03:26:07 +00:00
* [ FORMAT_MOODLE , FORMAT_HTML , FORMAT_PLAIN , FORMAT_WIKI , FORMAT_MARKDOWN ]
2004-09-25 05:29:21 +00:00
* @ return string The cleaned up text
2004-09-23 04:36:43 +00:00
*/
2004-01-15 07:17:47 +00:00
function clean_text ( $text , $format = FORMAT_MOODLE ) {
2002-03-26 12:58:54 +00:00
2007-04-19 12:18:44 +00:00
global $ALLOWED_TAGS , $CFG ;
2007-04-18 21:52:03 +00:00
if ( empty ( $text ) or is_numeric ( $text )) {
2007-06-19 14:44:02 +00:00
return ( string ) $text ;
2007-04-18 21:52:03 +00:00
}
2002-10-18 09:09:19 +00:00
2004-05-21 13:07:11 +00:00
switch ( $format ) {
2004-07-30 04:02:58 +00:00
case FORMAT_PLAIN :
2007-04-15 21:54:34 +00:00
case FORMAT_MARKDOWN :
2004-07-30 04:02:58 +00:00
return $text ;
default :
2007-04-18 21:52:03 +00:00
if ( ! empty ( $CFG -> enablehtmlpurifier )) {
$text = purify_html ( $text );
} else {
/// Fix non standard entity notations
2009-06-22 06:07:56 +00:00
$text = fix_non_standard_entities ( $text );
2007-06-19 14:44:02 +00:00
2007-04-18 21:52:03 +00:00
/// Remove tags that are not allowed
$text = strip_tags ( $text , $ALLOWED_TAGS );
2007-06-19 14:44:02 +00:00
2007-04-18 21:52:03 +00:00
/// Clean up embedded scripts and , using kses
$text = cleanAttributes ( $text );
2007-06-27 11:58:33 +00:00
/// Again remove tags that are not allowed
$text = strip_tags ( $text , $ALLOWED_TAGS );
2007-04-18 21:52:03 +00:00
}
2005-01-29 13:02:28 +00:00
2007-04-18 21:52:03 +00:00
/// Remove potential script events - some extra protection for undiscovered bugs in our code
2009-06-22 01:22:37 +00:00
$text = preg_replace ( " ~([^a-z])language([[:space:]]*)=~i " , " $ 1Xlanguage= " , $text );
$text = preg_replace ( " ~([^a-z])on([a-z]+)([[:space:]]*)=~i " , " $ 1Xon $ 2= " , $text );
2003-04-27 10:46:16 +00:00
return $text ;
2002-10-10 07:26:10 +00:00
}
2002-03-26 12:58:54 +00:00
}
2001-11-22 06:23:56 +00:00
2007-04-18 21:52:03 +00:00
/**
* KSES replacement cleaning function - uses HTML Purifier .
2009-05-22 03:26:07 +00:00
*
* @ global object
* @ param string $text The ( X ) HTML string to purify
2007-04-18 21:52:03 +00:00
*/
function purify_html ( $text ) {
global $CFG ;
2007-12-25 10:03:59 +00:00
// this can not be done only once because we sometimes need to reset the cache
2008-06-16 16:39:09 +00:00
$cachedir = $CFG -> dataroot . '/cache/htmlpurifier' ;
2007-12-25 10:03:59 +00:00
$status = check_dir_exists ( $cachedir , true , true );
2007-04-18 21:52:03 +00:00
static $purifier = false ;
2008-06-16 16:39:09 +00:00
static $config ;
2007-12-25 10:03:59 +00:00
if ( $purifier === false ) {
2008-06-16 16:39:09 +00:00
require_once $CFG -> libdir . '/htmlpurifier/HTMLPurifier.safe-includes.php' ;
2007-04-18 21:52:03 +00:00
$config = HTMLPurifier_Config :: createDefault ();
2009-07-19 12:17:48 +00:00
$config -> set ( 'Core.ConvertDocumentToFragment' , true );
$config -> set ( 'Core.Encoding' , 'UTF-8' );
$config -> set ( 'HTML.Doctype' , 'XHTML 1.0 Transitional' );
$config -> set ( 'Cache.SerializerPath' , $cachedir );
$config -> set ( 'URI.AllowedSchemes' , array ( 'http' => 1 , 'https' => 1 , 'ftp' => 1 , 'irc' => 1 , 'nntp' => 1 , 'news' => 1 , 'rtsp' => 1 , 'teamspeak' => 1 , 'gopher' => 1 , 'mms' => 1 ));
$config -> set ( 'Attr.AllowedFrameTargets' , array ( '_blank' ));
2007-04-18 21:52:03 +00:00
$purifier = new HTMLPurifier ( $config );
}
return $purifier -> purify ( $text );
}
2004-09-23 04:36:43 +00:00
/**
2004-09-25 05:29:21 +00:00
* This function takes a string and examines it for HTML tags .
2009-05-22 03:26:07 +00:00
*
2004-09-23 04:36:43 +00:00
* If tags are detected it passes the string to a helper function { @ link cleanAttributes2 ()}
2009-05-22 03:26:07 +00:00
* which checks for attributes and filters them for malicious content
2004-09-23 04:36:43 +00:00
*
* @ param string $str The string to be examined for html tags
* @ return string
*/
2004-08-21 04:34:06 +00:00
function cleanAttributes ( $str ){
2005-05-04 23:09:43 +00:00
$result = preg_replace_callback (
'%(<[^>]*(>|$)|>)%m' , #search for html tags
" cleanAttributes2 " ,
2004-08-21 04:34:06 +00:00
$str
2004-08-21 14:21:09 +00:00
);
2004-08-21 04:34:06 +00:00
return $result ;
2004-08-21 14:21:09 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* This function takes a string with an html tag and strips out any unallowed
* protocols e . g . javascript :
2009-05-22 03:26:07 +00:00
*
2004-09-23 04:36:43 +00:00
* It calls ancillary functions in kses which are prefixed by kses
*
2009-05-22 03:26:07 +00:00
* @ global object
* @ global string
2005-05-04 23:09:43 +00:00
* @ param array $htmlArray An array from { @ link cleanAttributes ()}, containing in its 1 st
* element the html to be cleared
2004-09-23 04:36:43 +00:00
* @ return string
*/
2005-05-04 23:09:43 +00:00
function cleanAttributes2 ( $htmlArray ){
2004-08-21 04:34:06 +00:00
2004-09-29 14:00:35 +00:00
global $CFG , $ALLOWED_PROTOCOLS ;
2004-09-22 14:39:15 +00:00
require_once ( $CFG -> libdir . '/kses.php' );
2004-08-21 04:34:06 +00:00
2005-05-04 23:09:43 +00:00
$htmlTag = $htmlArray [ 1 ];
2004-09-29 14:00:35 +00:00
if ( substr ( $htmlTag , 0 , 1 ) != '<' ) {
2004-08-21 04:34:06 +00:00
return '>' ; //a single character ">" detected
}
2004-09-29 14:00:35 +00:00
if ( ! preg_match ( '%^<\s*(/\s*)?([a-zA-Z0-9]+)([^>]*)>?$%' , $htmlTag , $matches )) {
2004-08-21 14:21:09 +00:00
return '' ; // It's seriously malformed
}
2004-08-21 04:34:06 +00:00
$slash = trim ( $matches [ 1 ]); //trailing xhtml slash
2004-08-21 14:21:09 +00:00
$elem = $matches [ 2 ]; //the element name
2004-08-21 04:34:06 +00:00
$attrlist = $matches [ 3 ]; // the list of attributes as a string
2004-09-29 14:00:35 +00:00
$attrArray = kses_hair ( $attrlist , $ALLOWED_PROTOCOLS );
2004-08-21 04:34:06 +00:00
2004-08-21 14:21:09 +00:00
$attStr = '' ;
2004-09-29 14:00:35 +00:00
foreach ( $attrArray as $arreach ) {
2006-03-02 21:38:20 +00:00
$arreach [ 'name' ] = strtolower ( $arreach [ 'name' ]);
if ( $arreach [ 'name' ] == 'style' ) {
$value = $arreach [ 'value' ];
while ( true ) {
$prevvalue = $value ;
$value = kses_no_null ( $value );
$value = preg_replace ( " / \ / \ *.* \ * \ //Us " , '' , $value );
$value = kses_decode_entities ( $value );
$value = preg_replace ( '/(&#[0-9]+)(;?)/' , " \\ 1; " , $value );
$value = preg_replace ( '/(&#x[0-9a-fA-F]+)(;?)/' , " \\ 1; " , $value );
if ( $value === $prevvalue ) {
$arreach [ 'value' ] = $value ;
break ;
}
}
$arreach [ 'value' ] = preg_replace ( " /j \ s*a \ s*v \ s*a \ s*s \ s*c \ s*r \ s*i \ s*p \ s*t/i " , " Xjavascript " , $arreach [ 'value' ]);
$arreach [ 'value' ] = preg_replace ( " /e \ s*x \ s*p \ s*r \ s*e \ s*s \ s*s \ s*i \ s*o \ s*n/i " , " Xexpression " , $arreach [ 'value' ]);
2008-02-28 21:17:52 +00:00
$arreach [ 'value' ] = preg_replace ( " /b \ s*i \ s*n \ s*d \ s*i \ s*n \ s*g/i " , " Xbinding " , $arreach [ 'value' ]);
2007-01-03 23:35:03 +00:00
} else if ( $arreach [ 'name' ] == 'href' ) {
2007-01-06 15:22:23 +00:00
//Adobe Acrobat Reader XSS protection
2008-12-29 21:18:02 +00:00
$arreach [ 'value' ] = preg_replace ( '/(\.(pdf|fdf|xfdf|xdp|xfd)[^#]*)#.*$/i' , '$1' , $arreach [ 'value' ]);
2006-03-02 21:38:20 +00:00
}
2006-12-11 22:07:53 +00:00
$attStr .= ' ' . $arreach [ 'name' ] . '="' . $arreach [ 'value' ] . '"' ;
2004-08-21 04:34:06 +00:00
}
2005-01-31 20:09:17 +00:00
2004-08-21 04:34:06 +00:00
$xhtml_slash = '' ;
2004-09-29 14:00:35 +00:00
if ( preg_match ( '%/\s*$%' , $attrlist )) {
2004-08-21 14:21:09 +00:00
$xhtml_slash = ' /' ;
2004-08-21 04:34:06 +00:00
}
2004-09-22 14:39:15 +00:00
return '<' . $slash . $elem . $attStr . $xhtml_slash . '>' ;
2004-08-21 04:34:06 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* Replaces all known smileys in the text with image equivalents
*
2009-05-22 03:26:07 +00:00
* @ global object
* @ staticvar array $e
* @ staticvar array $img
* @ staticvar array $emoticons
2004-09-23 04:36:43 +00:00
* @ param string $text Passed by reference . The string to search for smily strings .
* @ return string
*/
2003-05-05 16:40:46 +00:00
function replace_smilies ( & $text ) {
2009-07-02 10:26:02 +00:00
global $CFG , $OUTPUT ;
2008-05-11 23:34:29 +00:00
if ( empty ( $CFG -> emoticons )) { /// No emoticons defined, nothing to process here
return ;
}
2007-03-20 20:47:57 +00:00
$lang = current_language ();
2007-12-03 06:27:21 +00:00
$emoticonstring = $CFG -> emoticons ;
2003-03-12 21:37:05 +00:00
static $e = array ();
static $img = array ();
2007-12-03 06:27:21 +00:00
static $emoticons = null ;
if ( is_null ( $emoticons )) {
$emoticons = array ();
if ( $emoticonstring ) {
$items = explode ( '{;}' , $CFG -> emoticons );
foreach ( $items as $item ) {
$item = explode ( '{:}' , $item );
2008-01-13 08:30:39 +00:00
$emoticons [ $item [ 0 ]] = $item [ 1 ];
2007-12-03 06:27:21 +00:00
}
}
}
2007-03-20 20:47:57 +00:00
if ( empty ( $img [ $lang ])) { /// After the first time this is not run again
$e [ $lang ] = array ();
$img [ $lang ] = array ();
2003-03-12 20:36:55 +00:00
foreach ( $emoticons as $emoticon => $image ){
2003-11-07 14:55:44 +00:00
$alttext = get_string ( $image , 'pix' );
2008-11-24 01:05:55 +00:00
$alttext = preg_replace ( '/^\[\[(.*)\]\]$/' , '$1' , $alttext ); /// Clean alttext in case there isn't lang string for it.
2007-03-20 20:47:57 +00:00
$e [ $lang ][] = $emoticon ;
2009-07-02 10:26:02 +00:00
$img [ $lang ][] = '<img alt="' . $alttext . '" width="15" height="15" src="' . $OUTPUT -> old_icon_url ( 's/' . $image ) . '" />' ;
2003-03-12 20:36:55 +00:00
}
2003-03-12 21:40:47 +00:00
}
2002-03-26 12:58:54 +00:00
2004-03-25 06:31:44 +00:00
// Exclude from transformations all the code inside <script> tags
// Needed to solve Bug 1185. Thanks to jouse 2001 detecting it. :-)
// Based on code from glossary fiter by Williams Castillo.
// - Eloy
// Detect all the <script> zones to take out
$excludes = array ();
preg_match_all ( '/<script language(.+?)<\/script>/is' , $text , $list_of_excludes );
// Take out all the <script> zones from text
foreach ( array_unique ( $list_of_excludes [ 0 ]) as $key => $value ) {
$excludes [ '<+' . $key . '+>' ] = $value ;
}
if ( $excludes ) {
$text = str_replace ( $excludes , array_keys ( $excludes ), $text );
}
2003-11-07 14:55:44 +00:00
/// this is the meat of the code - this is run every time
2007-03-20 20:47:57 +00:00
$text = str_replace ( $e [ $lang ], $img [ $lang ], $text );
2004-03-25 06:31:44 +00:00
// Recover all the <script> zones to text
if ( $excludes ) {
$text = str_replace ( array_keys ( $excludes ), $excludes , $text );
}
2002-10-12 05:09:49 +00:00
}
2002-10-10 07:26:10 +00:00
2008-09-25 10:07:11 +00:00
/**
* This code is called from help . php to inject a list of smilies into the
* emoticons help file .
*
2009-05-22 03:26:07 +00:00
* @ global object
* @ global object
2008-09-25 10:07:11 +00:00
* @ return string HTML for a list of smilies .
*/
ajaxlib/require_js: MDL-16693 $PAGE->requires->... deprecates require_js etc.
There is a new implementation of require_js in lib/deprecatedlib.php,
based on $PAGE->requires.
There were a few other recently introduced functions in lib/weblib.php,
namely print_js_call, print_delayed_js_call, print_js_config and
standard_js_config. These have been removed, since they were never in
a stable branch, and all the places that used them have been changed
to use the newer $PAGE->requires->... methods.
get_require_js_code is also gone, and the evil places that were calling
it, even though it is an internal function, have been fixed.
Also, I made some minor improvements to the code I committed yesterday
for MDL-16695.
All that remains is to update all the places in core code that are
still using require_js.
(This commit also fixes the problem where the admin tree would not
start with the right categories expanded.)
2009-06-12 12:13:07 +00:00
function get_emoticons_list_for_help_file () {
2009-07-03 06:19:25 +00:00
global $CFG , $SESSION , $PAGE , $OUTPUT ;
2008-09-25 10:07:11 +00:00
if ( empty ( $CFG -> emoticons )) {
return '' ;
}
$items = explode ( '{;}' , $CFG -> emoticons );
$output = '<ul id="emoticonlist">' ;
foreach ( $items as $item ) {
$item = explode ( '{:}' , $item );
2009-07-03 06:19:25 +00:00
$output .= '<li><img src="' . $OUTPUT -> old_icon_url ( 's/' . $item [ 1 ]) . '" alt="' .
2008-09-25 10:07:11 +00:00
$item [ 0 ] . '" /><code>' . $item [ 0 ] . '</code></li>' ;
}
$output .= '</ul>' ;
if ( ! empty ( $SESSION -> inserttextform )) {
$formname = $SESSION -> inserttextform ;
$fieldname = $SESSION -> inserttextfield ;
} else {
$formname = 'theform' ;
$fieldname = 'message' ;
}
2008-11-20 06:59:11 +00:00
ajaxlib/require_js: MDL-16693 $PAGE->requires->... deprecates require_js etc.
There is a new implementation of require_js in lib/deprecatedlib.php,
based on $PAGE->requires.
There were a few other recently introduced functions in lib/weblib.php,
namely print_js_call, print_delayed_js_call, print_js_config and
standard_js_config. These have been removed, since they were never in
a stable branch, and all the places that used them have been changed
to use the newer $PAGE->requires->... methods.
get_require_js_code is also gone, and the evil places that were calling
it, even though it is an internal function, have been fixed.
Also, I made some minor improvements to the code I committed yesterday
for MDL-16695.
All that remains is to update all the places in core code that are
still using require_js.
(This commit also fixes the problem where the admin tree would not
start with the right categories expanded.)
2009-06-12 12:13:07 +00:00
$PAGE -> requires -> yui_lib ( 'event' );
$PAGE -> requires -> js_function_call ( 'emoticons_help.init' , array ( $formname , $fieldname , 'emoticonlist' ));
2008-09-25 10:07:11 +00:00
return $output ;
}
2004-09-25 05:29:21 +00:00
/**
* Given plain text , makes it into HTML as nicely as possible .
* May contain HTML tags already
*
2009-05-22 03:26:07 +00:00
* @ global object
2004-09-25 05:29:21 +00:00
* @ param string $text The string to convert .
* @ param boolean $smiley Convert any smiley characters to smiley images ?
* @ param boolean $para If true then the returned string will be wrapped in paragraph tags
* @ param boolean $newlines If true then lines newline breaks will be converted to HTML newline breaks .
* @ return string
*/
2004-03-09 06:44:27 +00:00
function text_to_html ( $text , $smiley = true , $para = true , $newlines = true ) {
2005-01-26 15:57:00 +00:00
///
2001-11-22 06:23:56 +00:00
2003-08-27 06:08:34 +00:00
global $CFG ;
2002-10-19 04:58:14 +00:00
/// Remove any whitespace that may be between HTML tags
2009-06-22 01:22:37 +00:00
$text = preg_replace ( " ~>([[:space:]]+)<~i " , " >< " , $text );
2002-08-22 08:31:29 +00:00
2002-10-19 04:58:14 +00:00
/// Remove any returns that precede or follow HTML tags
2009-06-22 01:22:37 +00:00
$text = preg_replace ( " ~([ \n \r ])<~i " , " < " , $text );
$text = preg_replace ( " ~>([ \n \r ])~i " , " > " , $text );
2002-08-22 08:31:29 +00:00
2003-05-05 16:40:46 +00:00
convert_urls_into_links ( $text );
2001-11-22 06:23:56 +00:00
2002-10-19 04:58:14 +00:00
/// Make returns into HTML newlines.
2004-03-09 06:44:27 +00:00
if ( $newlines ) {
$text = nl2br ( $text );
}
2001-11-22 06:23:56 +00:00
2002-10-19 04:58:14 +00:00
/// Turn smileys into images.
2002-05-18 05:22:48 +00:00
if ( $smiley ) {
2003-05-05 16:40:46 +00:00
replace_smilies ( $text );
2002-05-18 05:22:48 +00:00
}
2001-11-22 06:23:56 +00:00
2002-10-19 04:58:14 +00:00
/// Wrap the whole thing in a paragraph tag if required
2002-08-12 13:45:41 +00:00
if ( $para ) {
2004-09-22 14:39:15 +00:00
return '<p>' . $text . '</p>' ;
2002-08-12 13:45:41 +00:00
} else {
return $text ;
}
2001-11-22 06:23:56 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* Given Markdown formatted text , make it into XHTML using external function
*
2009-05-22 03:26:07 +00:00
* @ global object
2004-09-25 05:29:21 +00:00
* @ param string $text The markdown formatted text to be converted .
* @ return string Converted text
2004-09-23 04:36:43 +00:00
*/
2004-07-30 04:02:58 +00:00
function markdown_to_html ( $text ) {
global $CFG ;
2004-09-22 14:39:15 +00:00
require_once ( $CFG -> libdir . '/markdown.php' );
2004-07-30 04:02:58 +00:00
return Markdown ( $text );
}
2004-09-23 04:36:43 +00:00
/**
2004-09-25 05:29:21 +00:00
* Given HTML text , make it into plain text using external function
2004-09-23 04:36:43 +00:00
*
2009-05-22 03:26:07 +00:00
* @ global object
2004-09-23 04:36:43 +00:00
* @ param string $html The text to be converted .
* @ return string
*/
2003-11-07 03:27:21 +00:00
function html_to_text ( $html ) {
2004-09-25 05:29:21 +00:00
2003-11-07 04:14:38 +00:00
global $CFG ;
2003-11-07 03:27:21 +00:00
2004-09-22 14:39:15 +00:00
require_once ( $CFG -> libdir . '/html2text.php' );
2003-11-07 03:27:21 +00:00
2008-12-17 02:55:33 +00:00
$h2t = new html2text ( $html );
$result = $h2t -> get_text ();
2008-07-14 02:32:59 +00:00
2008-06-16 14:07:47 +00:00
return $result ;
2003-11-07 03:27:21 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* Given some text this function converts any URLs it finds into HTML links
*
* @ param string $text Passed in by reference . The string to be searched for urls .
*/
2003-05-05 16:40:46 +00:00
function convert_urls_into_links ( & $text ) {
/// Make lone URLs into links. eg http://moodle.com/
2009-06-22 01:22:37 +00:00
$text = preg_replace ( " ~([[:space:]]|^| \ (| \ [)([[:alnum:]]+)://([^[:space:]]*)([[:alnum:]#?/&=])~i " ,
2009-06-22 06:07:56 +00:00
'$1<a href="$2://$3$4">$2://$3$4</a>' , $text );
2003-05-05 16:40:46 +00:00
/// eg www.moodle.com
2009-06-22 01:22:37 +00:00
$text = preg_replace ( " ~([[:space:]]|^| \ (| \ [)www \ .([^[:space:]]*)([[:alnum:]#?/&=])~i " ,
2009-06-22 06:07:56 +00:00
'$1<a href="http://www.$2$3">www.$2$3</a>' , $text );
2003-05-05 16:40:46 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* This function will highlight search words in a given string
2009-05-22 03:26:07 +00:00
*
2004-09-23 04:36:43 +00:00
* It cares about HTML and will not ruin links . It ' s best to use
* this function after performing any conversions to HTML .
*
2008-12-11 10:33:57 +00:00
* @ param string $needle The search string . Syntax like " word1 +word2 -word3 " is dealt with correctly .
* @ param string $haystack The string ( HTML ) within which to highlight the search terms .
* @ param boolean $matchcase whether to do case - sensitive . Default case - insensitive .
* @ param string $prefix the string to put before each search term found .
* @ param string $suffix the string to put after each search term found .
* @ return string The highlighted HTML .
2004-09-23 04:36:43 +00:00
*/
2008-12-11 10:33:57 +00:00
function highlight ( $needle , $haystack , $matchcase = false ,
$prefix = '<span class="highlight">' , $suffix = '</span>' ) {
2008-01-01 15:51:54 +00:00
2008-12-11 10:33:57 +00:00
/// Quick bail-out in trivial cases.
2008-01-01 15:51:54 +00:00
if ( empty ( $needle ) or empty ( $haystack )) {
2003-12-13 06:27:25 +00:00
return $haystack ;
}
2008-12-11 10:33:57 +00:00
/// Break up the search term into words, discard any -words and build a regexp.
$words = preg_split ( '/ +/' , trim ( $needle ));
foreach ( $words as $index => $word ) {
if ( strpos ( $word , '-' ) === 0 ) {
unset ( $words [ $index ]);
} else if ( strpos ( $word , '+' ) === 0 ) {
$words [ $index ] = '\b' . preg_quote ( ltrim ( $word , '+' ), '/' ) . '\b' ; // Match only as a complete word.
} else {
$words [ $index ] = preg_quote ( $word , '/' );
2003-08-09 03:57:46 +00:00
}
}
2008-12-11 10:33:57 +00:00
$regexp = '/(' . implode ( '|' , $words ) . ')/u' ; // u is do UTF-8 matching.
if ( ! $matchcase ) {
$regexp .= 'i' ;
2003-08-09 03:57:46 +00:00
}
2008-12-11 10:33:57 +00:00
/// Another chance to bail-out if $search was only -words
if ( empty ( $words )) {
return $haystack ;
2003-08-09 03:57:46 +00:00
}
2008-12-11 10:33:57 +00:00
/// Find all the HTML tags in the input, and store them in a placeholders array.
$placeholders = array ();
$matches = array ();
preg_match_all ( '/<[^>]*>/' , $haystack , $matches );
foreach ( array_unique ( $matches [ 0 ]) as $key => $htmltag ) {
$placeholders [ '<|' . $key . '|>' ] = $htmltag ;
}
2004-12-31 15:23:50 +00:00
2008-12-11 10:33:57 +00:00
/// In $hastack, replace each HTML tag with the corresponding placeholder.
$haystack = str_replace ( $placeholders , array_keys ( $placeholders ), $haystack );
2004-12-31 15:23:50 +00:00
2008-12-11 10:33:57 +00:00
/// In the resulting string, Do the highlighting.
$haystack = preg_replace ( $regexp , $prefix . '$1' . $suffix , $haystack );
2004-12-31 15:23:50 +00:00
2008-12-11 10:33:57 +00:00
/// Turn the placeholders back into HTML tags.
$haystack = str_replace ( array_keys ( $placeholders ), $placeholders , $haystack );
2003-08-09 03:57:46 +00:00
2004-09-23 07:41:37 +00:00
return $haystack ;
2003-08-09 03:57:46 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* This function will highlight instances of $needle in $haystack
2009-05-22 03:26:07 +00:00
*
* It 's faster that the above function {@link highlight()} and doesn' t care about
2004-09-23 04:36:43 +00:00
* HTML or anything .
*
* @ param string $needle The string to search for
* @ param string $haystack The string to search for $needle in
2009-05-22 03:26:07 +00:00
* @ return string The highlighted HTML
2004-09-23 04:36:43 +00:00
*/
2003-08-09 03:57:46 +00:00
function highlightfast ( $needle , $haystack ) {
2002-06-11 07:01:51 +00:00
2008-01-01 15:51:54 +00:00
if ( empty ( $needle ) or empty ( $haystack )) {
return $haystack ;
}
2006-10-07 20:47:54 +00:00
$parts = explode ( moodle_strtolower ( $needle ), moodle_strtolower ( $haystack ));
2002-06-11 07:01:51 +00:00
2008-01-01 15:51:54 +00:00
if ( count ( $parts ) === 1 ) {
return $haystack ;
}
2002-06-11 07:01:51 +00:00
$pos = 0 ;
foreach ( $parts as $key => $part ) {
$parts [ $key ] = substr ( $haystack , $pos , strlen ( $part ));
$pos += strlen ( $part );
2004-09-22 14:39:15 +00:00
$parts [ $key ] .= '<span class="highlight">' . substr ( $haystack , $pos , strlen ( $needle )) . '</span>' ;
2002-06-11 07:01:51 +00:00
$pos += strlen ( $needle );
2004-05-21 13:07:11 +00:00
}
2002-06-11 07:01:51 +00:00
2008-01-01 15:51:54 +00:00
return str_replace ( '<span class="highlight"></span>' , '' , join ( '' , $parts ));
2002-06-11 07:01:51 +00:00
}
2007-02-21 10:42:50 +00:00
/**
* Return a string containing 'lang' , xml : lang and optionally 'dir' HTML attributes .
* Internationalisation , for print_header and backup / restorelib .
2009-05-22 03:26:07 +00:00
*
* @ param bool $dir Default false
* @ return string Attributes
2007-02-21 10:42:50 +00:00
*/
function get_html_lang ( $dir = false ) {
$direction = '' ;
if ( $dir ) {
if ( get_string ( 'thisdirection' ) == 'rtl' ) {
$direction = ' dir="rtl"' ;
} else {
$direction = ' dir="ltr"' ;
}
}
//Accessibility: added the 'lang' attribute to $direction, used in theme <html> tag.
$language = str_replace ( '_' , '-' , str_replace ( '_utf8' , '' , current_language ()));
2007-03-05 15:38:10 +00:00
@ header ( 'Content-Language: ' . $language );
2007-06-19 14:44:02 +00:00
return ( $direction . ' lang="' . $language . '" xml:lang="' . $language . '"' );
2007-02-21 10:42:50 +00:00
}
2009-06-26 09:06:16 +00:00
/// STANDARD WEB PAGE PARTS ///////////////////////////////////////////////////
2007-10-22 06:43:00 +00:00
/**
2009-06-26 09:06:16 +00:00
* Send the HTTP headers that Moodle requires .
* @ param $cacheable Can this page be cached on back ?
2007-10-22 06:43:00 +00:00
*/
2009-06-26 09:06:16 +00:00
function send_headers ( $contenttype , $cacheable = true ) {
@ header ( 'Content-Type: ' . $contenttype );
@ header ( 'Content-Script-Type: text/javascript' );
@ header ( 'Content-Style-Type: text/css' );
2001-11-22 06:23:56 +00:00
2009-06-26 09:06:16 +00:00
if ( $cacheable ) {
// Allow caching on "back" (but not on normal clicks)
@ header ( 'Cache-Control: private, pre-check=0, post-check=0, max-age=0' );
@ header ( 'Pragma: no-cache' );
@ header ( 'Expires: ' );
} else {
// Do everything we can to always prevent clients and proxies caching
@ header ( 'Cache-Control: no-store, no-cache, must-revalidate' );
@ header ( 'Cache-Control: post-check=0, pre-check=0' , false );
@ header ( 'Pragma: no-cache' );
@ header ( 'Expires: Mon, 20 Aug 1969 09:23:00 GMT' );
@ header ( 'Last-Modified: ' . gmdate ( 'D, d M Y H:i:s' ) . ' GMT' );
}
@ header ( 'Accept-Ranges: none' );
}
2002-12-20 14:44:14 +00:00
2004-09-23 04:36:43 +00:00
/**
* Returns text to be displayed to the user which reflects their login status
*
2009-05-22 03:26:07 +00:00
* @ global object
* @ global object
* @ global object
* @ global object
* @ uses CONTEXT_COURSE
2004-09-25 05:29:21 +00:00
* @ param course $course { @ link $COURSE } object containing course information
* @ param user $user { @ link $USER } object containing user information
2009-05-22 03:26:07 +00:00
* @ return string HTML
2004-09-23 04:36:43 +00:00
*/
2005-03-03 04:41:46 +00:00
function user_login_string ( $course = NULL , $user = NULL ) {
2008-05-15 21:40:00 +00:00
global $USER , $CFG , $SITE , $DB ;
2003-04-25 06:40:30 +00:00
2009-06-26 09:06:16 +00:00
if ( during_initial_install ()) {
return '' ;
}
2006-09-02 11:44:04 +00:00
if ( empty ( $user ) and ! empty ( $USER -> id )) {
2003-04-25 06:40:30 +00:00
$user = $USER ;
}
2005-03-03 04:41:46 +00:00
if ( empty ( $course )) {
$course = $SITE ;
}
2009-01-02 20:32:05 +00:00
if ( session_is_loggedinas ()) {
$realuser = session_get_realuser ();
2009-01-02 15:15:26 +00:00
$fullname = fullname ( $realuser , true );
$realuserinfo = " [<a $CFG->frametarget
href = \ " $CFG->wwwroot /course/loginas.php?id= $course->id &return=1&sesskey= " . sesskey () . " \" > $fullname </a>] " ;
2002-12-29 04:17:32 +00:00
} else {
2004-09-22 14:39:15 +00:00
$realuserinfo = '' ;
2002-12-20 14:44:14 +00:00
}
2009-01-02 22:56:48 +00:00
$loginurl = get_login_url ();
2004-06-22 18:35:59 +00:00
2006-09-17 17:53:20 +00:00
if ( empty ( $course -> id )) {
// $course->id is not defined during installation
return '' ;
2007-03-19 18:54:58 +00:00
} else if ( ! empty ( $user -> id )) {
2006-09-21 15:58:59 +00:00
$context = get_context_instance ( CONTEXT_COURSE , $course -> id );
2003-11-28 11:00:46 +00:00
$fullname = fullname ( $user , true );
2007-01-04 18:23:55 +00:00
$username = " <a $CFG->frametarget href= \" $CFG->wwwroot /user/view.php?id= $user->id &course= $course->id\ " > $fullname </ a > " ;
2008-05-15 21:40:00 +00:00
if ( is_mnet_remote_user ( $user ) and $idprovider = $DB -> get_record ( 'mnet_host' , array ( 'id' => $user -> mnethostid ))) {
2007-01-04 18:23:55 +00:00
$username .= " from <a $CFG->frametarget href= \" { $idprovider -> wwwroot } \" > { $idprovider -> name } </a> " ;
2007-01-04 02:52:44 +00:00
}
2006-09-14 09:39:23 +00:00
if ( isset ( $user -> username ) && $user -> username == 'guest' ) {
2005-05-05 04:22:26 +00:00
$loggedinas = $realuserinfo . get_string ( 'loggedinasguest' ) .
2009-01-02 22:56:48 +00:00
" (<a $CFG->frametarget href= \" $loginurl\ " > " .get_string('login').'</a>)';
2007-09-19 07:06:17 +00:00
} else if ( ! empty ( $user -> access [ 'rsw' ][ $context -> path ])) {
2006-09-21 14:42:45 +00:00
$rolename = '' ;
2008-05-15 21:40:00 +00:00
if ( $role = $DB -> get_record ( 'role' , array ( 'id' => $user -> access [ 'rsw' ][ $context -> path ]))) {
2006-09-21 14:42:45 +00:00
$rolename = ': ' . format_string ( $role -> name );
}
$loggedinas = get_string ( 'loggedinas' , 'moodle' , $username ) . $rolename .
2007-01-04 18:23:55 +00:00
" (<a $CFG->frametarget
2006-09-21 14:42:45 +00:00
href = \ " $CFG->wwwroot /course/view.php?id= $course->id &switchrole=0&sesskey= " . sesskey () . " \" > " . get_string ( 'switchrolereturn' ) . '</a>)' ;
2004-05-30 00:55:48 +00:00
} else {
2006-09-03 08:10:51 +00:00
$loggedinas = $realuserinfo . get_string ( 'loggedinas' , 'moodle' , $username ) . ' ' .
2007-03-02 16:47:38 +00:00
" (<a $CFG->frametarget href= \" $CFG->wwwroot /login/logout.php?sesskey= " . sesskey () . " \" > " . get_string ( 'logout' ) . '</a>)' ;
2004-05-30 00:55:48 +00:00
}
2002-12-20 14:44:14 +00:00
} else {
2004-09-22 14:39:15 +00:00
$loggedinas = get_string ( 'loggedinnot' , 'moodle' ) .
2009-01-02 22:56:48 +00:00
" (<a $CFG->frametarget href= \" $loginurl\ " > " .get_string('login').'</a>)';
2002-12-20 14:44:14 +00:00
}
2009-06-26 09:06:16 +00:00
$loggedinas = '<div class="logininfo">' . $loggedinas . '</div>' ;
if ( isset ( $SESSION -> justloggedin )) {
unset ( $SESSION -> justloggedin );
if ( ! empty ( $CFG -> displayloginfailures )) {
if ( ! empty ( $USER -> username ) and $USER -> username != 'guest' ) {
if ( $count = count_login_failures ( $CFG -> displayloginfailures , $USER -> username , $USER -> lastlogin )) {
$loggedinas .= ' <div class="loginfailures">' ;
if ( empty ( $count -> accounts )) {
$loggedinas .= get_string ( 'failedloginattempts' , '' , $count );
} else {
$loggedinas .= get_string ( 'failedloginattemptsall' , '' , $count );
}
if ( has_capability ( 'coursereport/log:view' , get_context_instance ( CONTEXT_SYSTEM ))) {
$loggedinas .= ' (<a href="' . $CFG -> wwwroot . '/course/report/log/index.php' .
'?chooselog=1&id=1&modid=site_errors">' . get_string ( 'logs' ) . '</a>)' ;
}
$loggedinas .= '</div>' ;
}
}
}
}
return $loggedinas ;
2002-12-20 14:44:14 +00:00
}
2004-09-23 04:36:43 +00:00
/**
2006-09-19 11:36:21 +00:00
* Tests whether $THEME -> rarrow , $THEME -> larrow have been set ( theme /-/ config . php ) .
* If not it applies sensible defaults .
2004-09-23 04:36:43 +00:00
*
2006-09-19 11:36:21 +00:00
* Accessibility : right and left arrow Unicode characters for breadcrumb , calendar ,
2007-01-04 10:23:06 +00:00
* search forum block , etc . Important : these are 'silent' in a screen - reader
2006-09-19 11:36:21 +00:00
* ( unlike & gt ; & raquo ;), and must be accompanied by text .
2009-05-22 03:26:07 +00:00
*
* @ global object
* @ uses $_SERVER
2004-09-23 04:36:43 +00:00
*/
2006-09-19 11:36:21 +00:00
function check_theme_arrows () {
global $THEME ;
2007-01-04 10:23:06 +00:00
2006-09-19 11:36:21 +00:00
if ( ! isset ( $THEME -> rarrow ) and ! isset ( $THEME -> larrow )) {
2006-11-28 15:26:40 +00:00
// Default, looks good in Win XP/IE 6, Win/Firefox 1.5, Win/Netscape 8...
// Also OK in Win 9x/2K/IE 5.x
2006-09-19 11:36:21 +00:00
$THEME -> rarrow = '►' ;
$THEME -> larrow = '◄' ;
2008-07-10 08:50:43 +00:00
if ( empty ( $_SERVER [ 'HTTP_USER_AGENT' ])) {
$uagent = '' ;
} else {
$uagent = $_SERVER [ 'HTTP_USER_AGENT' ];
}
2006-11-28 15:26:40 +00:00
if ( false !== strpos ( $uagent , 'Opera' )
|| false !== strpos ( $uagent , 'Mac' )) {
// Looks good in Win XP/Mac/Opera 8/9, Mac/Firefox 2, Camino, Safari.
// Not broken in Mac/IE 5, Mac/Netscape 7 (?).
2006-09-19 11:36:21 +00:00
$THEME -> rarrow = '▶' ;
$THEME -> larrow = '◀' ;
2006-11-28 15:26:40 +00:00
}
elseif ( false !== strpos ( $uagent , 'Konqueror' )) {
$THEME -> rarrow = '→' ;
$THEME -> larrow = '←' ;
}
elseif ( isset ( $_SERVER [ 'HTTP_ACCEPT_CHARSET' ])
&& false === stripos ( $_SERVER [ 'HTTP_ACCEPT_CHARSET' ], 'utf-8' )) {
// (Win/IE 5 doesn't set ACCEPT_CHARSET, but handles Unicode.)
// To be safe, non-Unicode browsers!
$THEME -> rarrow = '>' ;
$THEME -> larrow = '<' ;
}
2008-01-13 08:30:39 +00:00
2007-08-09 08:40:02 +00:00
/// RTL support - in RTL languages, swap r and l arrows
2008-01-13 08:30:39 +00:00
if ( right_to_left ()) {
$t = $THEME -> rarrow ;
$THEME -> rarrow = $THEME -> larrow ;
$THEME -> larrow = $t ;
}
2006-09-19 11:36:21 +00:00
}
}
2006-08-10 06:41:38 +00:00
2007-08-09 08:40:02 +00:00
2007-05-09 14:15:33 +00:00
/**
2007-05-14 13:28:21 +00:00
* Return the right arrow with text ( 'next' ), and optionally embedded in a link .
* See function above , check_theme_arrows .
2009-05-22 03:26:07 +00:00
*
* @ global object
2007-05-22 08:59:56 +00:00
* @ param string $text HTML / plain text label ( set to blank only for breadcrumb separator cases ) .
2007-05-14 13:28:21 +00:00
* @ param string $url An optional link to use in a surrounding HTML anchor .
* @ param bool $accesshide True if text should be hidden ( for screen readers only ) .
* @ param string $addclass Additional class names for the link , or the arrow character .
* @ return string HTML string .
2007-05-09 14:15:33 +00:00
*/
2007-05-14 13:28:21 +00:00
function link_arrow_right ( $text , $url = '' , $accesshide = false , $addclass = '' ) {
2007-05-09 14:15:33 +00:00
global $THEME ;
check_theme_arrows ();
2007-05-14 13:28:21 +00:00
$arrowclass = 'arrow ' ;
if ( ! $url ) {
$arrowclass .= $addclass ;
}
$arrow = '<span class="' . $arrowclass . '">' . $THEME -> rarrow . '</span>' ;
$htmltext = '' ;
if ( $text ) {
2008-05-13 12:36:16 +00:00
$htmltext = '<span class="arrow_text">' . $text . '</span> ' ;
2007-05-14 13:28:21 +00:00
if ( $accesshide ) {
2007-09-25 11:33:30 +00:00
$htmltext = get_accesshide ( $htmltext );
2007-05-14 13:28:21 +00:00
}
2007-05-09 14:15:33 +00:00
}
2007-05-14 13:28:21 +00:00
if ( $url ) {
2008-05-13 12:36:16 +00:00
$class = 'arrow_link' ;
2007-05-14 13:28:21 +00:00
if ( $addclass ) {
2008-05-13 12:36:16 +00:00
$class .= ' ' . $addclass ;
2007-05-14 13:28:21 +00:00
}
2008-05-13 12:36:16 +00:00
return '<a class="' . $class . '" href="' . $url . '" title="' . preg_replace ( '/<.*?>/' , '' , $text ) . '">' . $htmltext . $arrow . '</a>' ;
2007-05-14 13:28:21 +00:00
}
return $htmltext . $arrow ;
2007-05-09 14:15:33 +00:00
}
/**
2007-05-14 13:28:21 +00:00
* Return the left arrow with text ( 'previous' ), and optionally embedded in a link .
* See function above , check_theme_arrows .
2009-05-22 03:26:07 +00:00
*
* @ global object
2007-05-22 08:59:56 +00:00
* @ param string $text HTML / plain text label ( set to blank only for breadcrumb separator cases ) .
2007-05-14 13:28:21 +00:00
* @ param string $url An optional link to use in a surrounding HTML anchor .
* @ param bool $accesshide True if text should be hidden ( for screen readers only ) .
* @ param string $addclass Additional class names for the link , or the arrow character .
* @ return string HTML string .
2007-05-09 14:15:33 +00:00
*/
2007-05-14 13:28:21 +00:00
function link_arrow_left ( $text , $url = '' , $accesshide = false , $addclass = '' ) {
2007-05-09 14:15:33 +00:00
global $THEME ;
check_theme_arrows ();
2007-05-14 13:28:21 +00:00
$arrowclass = 'arrow ' ;
if ( ! $url ) {
$arrowclass .= $addclass ;
}
$arrow = '<span class="' . $arrowclass . '">' . $THEME -> larrow . '</span>' ;
$htmltext = '' ;
if ( $text ) {
2008-05-13 12:36:16 +00:00
$htmltext = ' <span class="arrow_text">' . $text . '</span>' ;
2007-05-14 13:28:21 +00:00
if ( $accesshide ) {
2007-09-25 11:33:30 +00:00
$htmltext = get_accesshide ( $htmltext );
2007-05-14 13:28:21 +00:00
}
2007-05-09 14:15:33 +00:00
}
2007-05-14 13:28:21 +00:00
if ( $url ) {
2008-05-13 12:36:16 +00:00
$class = 'arrow_link' ;
2007-05-14 13:28:21 +00:00
if ( $addclass ) {
2008-05-13 12:36:16 +00:00
$class .= ' ' . $addclass ;
2007-05-14 13:28:21 +00:00
}
2008-05-13 12:36:16 +00:00
return '<a class="' . $class . '" href="' . $url . '" title="' . preg_replace ( '/<.*?>/' , '' , $text ) . '">' . $arrow . $htmltext . '</a>' ;
2007-05-14 13:28:21 +00:00
}
return $arrow . $htmltext ;
}
2007-09-25 11:33:30 +00:00
/**
* Return a HTML element with the class " accesshide " , for accessibility.
2009-05-22 03:26:07 +00:00
* Please use cautiously - where possible , text should be visible !
*
2007-09-25 11:33:30 +00:00
* @ param string $text Plain text .
* @ param string $elem Lowercase element name , default " span " .
* @ param string $class Additional classes for the element .
* @ param string $attrs Additional attributes string in the form , " name='value' name2='value2' "
* @ return string HTML string .
*/
function get_accesshide ( $text , $elem = 'span' , $class = '' , $attrs = '' ) {
return " < $elem class= \" accesshide $class\ " $attrs > $text </ $elem > " ;
}
2007-05-14 13:28:21 +00:00
/**
* Return the breadcrumb trail navigation separator .
2009-05-22 03:26:07 +00:00
*
2007-05-14 13:28:21 +00:00
* @ return string HTML string .
*/
function get_separator () {
//Accessibility: the 'hidden' slash is preferred for screen readers.
return ' ' . link_arrow_right ( $text = '/' , $url = '' , $accesshide = true , 'sep' ) . ' ' ;
2007-05-09 14:15:33 +00:00
}
2008-11-03 05:27:10 +00:00
/**
* Print ( or return ) a collapisble region , that has a caption that can
2009-05-22 03:26:07 +00:00
* be clicked to expand or collapse the region .
2009-08-04 02:05:32 +00:00
*
2009-05-22 03:26:07 +00:00
* If JavaScript is off , then the region will always be exanded .
2008-11-03 05:27:10 +00:00
*
* @ param string $contents the contents of the box .
* @ param string $classes class names added to the div that is output .
* @ param string $id id added to the div that is output . Must not be blank .
* @ param string $caption text displayed at the top . Clicking on this will cause the region to expand or contract .
* @ param string $userpref the name of the user preference that stores the user ' s preferred deafault state .
* ( May be blank if you do not wish the state to be persisted .
* @ param boolean $default Inital collapsed state to use if the user_preference it not set .
* @ param boolean $return if true , return the HTML as a string , rather than printing it .
2009-05-22 03:26:07 +00:00
* @ return string | void If $return is false , returns nothing , otherwise returns a string of HTML .
2008-11-03 05:27:10 +00:00
*/
2008-11-03 05:04:23 +00:00
function print_collapsible_region ( $contents , $classes , $id , $caption , $userpref = '' , $default = false , $return = false ) {
$output = print_collapsible_region_start ( $classes , $id , $caption , $userpref , true );
$output .= $contents ;
$output .= print_collapsible_region_end ( true );
if ( $return ) {
return $output ;
} else {
echo $output ;
}
}
2008-11-03 05:27:10 +00:00
/**
* Print ( or return ) the start of a collapisble region , that has a caption that can
* be clicked to expand or collapse the region . If JavaScript is off , then the region
* will always be exanded .
*
2009-05-22 03:26:07 +00:00
* @ global object
2008-11-03 05:27:10 +00:00
* @ param string $classes class names added to the div that is output .
* @ param string $id id added to the div that is output . Must not be blank .
* @ param string $caption text displayed at the top . Clicking on this will cause the region to expand or contract .
2009-05-22 03:26:07 +00:00
* @ param boolean $userpref the name of the user preference that stores the user ' s preferred deafault state .
2008-11-03 05:27:10 +00:00
* ( May be blank if you do not wish the state to be persisted .
* @ param boolean $default Inital collapsed state to use if the user_preference it not set .
* @ param boolean $return if true , return the HTML as a string , rather than printing it .
2009-05-22 03:26:07 +00:00
* @ return string | void if $return is false , returns nothing , otherwise returns a string of HTML .
2008-11-03 05:27:10 +00:00
*/
2008-11-03 05:04:23 +00:00
function print_collapsible_region_start ( $classes , $id , $caption , $userpref = false , $default = false , $return = false ) {
2009-07-03 06:38:41 +00:00
global $CFG , $PAGE , $OUTPUT ;
2008-11-03 05:04:23 +00:00
// Include required JavaScript libraries.
ajaxlib/require_js: MDL-16693 $PAGE->requires->... deprecates require_js etc.
There is a new implementation of require_js in lib/deprecatedlib.php,
based on $PAGE->requires.
There were a few other recently introduced functions in lib/weblib.php,
namely print_js_call, print_delayed_js_call, print_js_config and
standard_js_config. These have been removed, since they were never in
a stable branch, and all the places that used them have been changed
to use the newer $PAGE->requires->... methods.
get_require_js_code is also gone, and the evil places that were calling
it, even though it is an internal function, have been fixed.
Also, I made some minor improvements to the code I committed yesterday
for MDL-16695.
All that remains is to update all the places in core code that are
still using require_js.
(This commit also fixes the problem where the admin tree would not
start with the right categories expanded.)
2009-06-12 12:13:07 +00:00
$PAGE -> requires -> yui_lib ( 'animation' );
2008-11-03 05:04:23 +00:00
// Work out the initial state.
if ( is_string ( $userpref )) {
user_preference_allow_ajax_update ( $userpref , PARAM_BOOL );
$collapsed = get_user_preferences ( $userpref , $default );
} else {
$collapsed = $default ;
$userpref = false ;
}
2008-11-04 05:12:12 +00:00
if ( $collapsed ) {
$classes .= ' collapsed' ;
}
2008-11-03 05:04:23 +00:00
$output = '' ;
$output .= '<div id="' . $id . '" class="collapsibleregion ' . $classes . '">' ;
2008-11-04 05:12:12 +00:00
$output .= '<div id="' . $id . '_sizer">' ;
2008-11-03 05:04:23 +00:00
$output .= '<div id="' . $id . '_caption" class="collapsibleregioncaption">' ;
$output .= $caption . ' ' ;
2008-11-04 05:12:12 +00:00
$output .= '</div><div id="' . $id . '_inner" class="collapsibleregioninner">' ;
ajaxlib/require_js: MDL-16693 $PAGE->requires->... deprecates require_js etc.
There is a new implementation of require_js in lib/deprecatedlib.php,
based on $PAGE->requires.
There were a few other recently introduced functions in lib/weblib.php,
namely print_js_call, print_delayed_js_call, print_js_config and
standard_js_config. These have been removed, since they were never in
a stable branch, and all the places that used them have been changed
to use the newer $PAGE->requires->... methods.
get_require_js_code is also gone, and the evil places that were calling
it, even though it is an internal function, have been fixed.
Also, I made some minor improvements to the code I committed yesterday
for MDL-16695.
All that remains is to update all the places in core code that are
still using require_js.
(This commit also fixes the problem where the admin tree would not
start with the right categories expanded.)
2009-06-12 12:13:07 +00:00
$PAGE -> requires -> js_function_call ( 'new collapsible_region' ,
2009-07-03 06:38:41 +00:00
array ( $id , $userpref , get_string ( 'clicktohideshow' ),
$OUTPUT -> old_icon_url ( 't/collapsed' ), $OUTPUT -> old_icon_url ( 't/expanded' )));
2008-11-03 05:04:23 +00:00
if ( $return ) {
return $output ;
} else {
echo $output ;
}
}
2008-11-03 05:27:10 +00:00
/**
* Close a region started with print_collapsible_region_start .
*
* @ param boolean $return if true , return the HTML as a string , rather than printing it .
2009-05-22 03:26:07 +00:00
* @ return string | void if $return is false , returns nothing , otherwise returns a string of HTML .
2008-11-03 05:27:10 +00:00
*/
2008-11-03 05:04:23 +00:00
function print_collapsible_region_end ( $return = false ) {
2008-11-04 05:12:12 +00:00
$output = '</div></div></div>' ;
2008-11-03 05:04:23 +00:00
if ( $return ) {
return $output ;
} else {
echo $output ;
}
}
2007-11-23 20:26:16 +00:00
/**
* Returns number of currently open containers
2009-05-22 03:26:07 +00:00
*
* @ global object
2007-11-23 20:26:16 +00:00
* @ return int number of open containers
*/
function open_containers () {
global $THEME ;
if ( ! isset ( $THEME -> open_containers )) {
$THEME -> open_containers = array ();
}
return count ( $THEME -> open_containers );
}
2007-11-23 16:49:51 +00:00
/**
2007-12-14 21:22:38 +00:00
* Force closing of open containers
2009-05-22 03:26:07 +00:00
*
2007-11-23 16:49:51 +00:00
* @ param boolean $return , return as string or just print it
2007-12-14 21:22:38 +00:00
* @ param int $keep number of containers to be kept open - usually theme or page containers
* @ return mixed string or void
2007-11-23 16:49:51 +00:00
*/
2007-12-14 21:22:38 +00:00
function print_container_end_all ( $return = false , $keep = 0 ) {
2009-09-25 06:17:38 +00:00
global $OUTPUT ;
2007-11-23 16:49:51 +00:00
$output = '' ;
2007-12-14 21:22:38 +00:00
while ( open_containers () > $keep ) {
2009-09-25 06:17:38 +00:00
$output .= $OUTPUT -> container_end ();
2007-11-23 16:49:51 +00:00
}
2007-11-16 13:33:51 +00:00
if ( $return ) {
return $output ;
} else {
echo $output ;
}
}
2007-11-23 16:49:51 +00:00
/**
* Internal function - do not use directly !
* Starting part of the surrounding divs for custom corners
*
* @ param boolean $clearfix , add CLASS " clearfix " to the inner div against collapsing
2007-12-14 21:22:38 +00:00
* @ param string $classes
* @ param mixed $idbase , optionally , define one idbase to be added to all the elements in the corners
* @ return string
2007-11-23 16:49:51 +00:00
*/
function _print_custom_corners_start ( $clearfix = false , $classes = '' , $idbase = '' ) {
/// Analise if we want ids for the custom corner elements
$id = '' ;
$idbt = '' ;
$idi1 = '' ;
$idi2 = '' ;
$idi3 = '' ;
if ( $idbase ) {
$id = 'id="' . $idbase . '" ' ;
$idbt = 'id="' . $idbase . '-bt" ' ;
$idi1 = 'id="' . $idbase . '-i1" ' ;
$idi2 = 'id="' . $idbase . '-i2" ' ;
$idi3 = 'id="' . $idbase . '-i3" ' ;
}
2007-11-28 18:14:38 +00:00
/// Calculate current level
$level = open_containers ();
2007-11-23 16:49:51 +00:00
/// Output begins
2007-11-28 18:14:38 +00:00
$output = '<div ' . $id . 'class="wrap wraplevel' . $level . ' ' . $classes . '">' . " \n " ;
2007-11-23 16:49:51 +00:00
$output .= '<div ' . $idbt . 'class="bt"><div> </div></div>' ;
$output .= " \n " ;
$output .= '<div ' . $idi1 . 'class="i1"><div ' . $idi2 . 'class="i2">' ;
$output .= ( ! empty ( $clearfix )) ? '<div ' . $idi3 . 'class="i3 clearfix">' : '<div ' . $idi3 . 'class="i3">' ;
return $output ;
}
/**
* Internal function - do not use directly !
* Ending part of the surrounding divs for custom corners
2009-05-22 03:26:07 +00:00
*
2007-12-14 21:22:38 +00:00
* @ param string $idbase
2009-05-22 03:26:07 +00:00
* @ return string HTML sttring
2007-11-23 16:49:51 +00:00
*/
function _print_custom_corners_end ( $idbase ) {
/// Analise if we want ids for the custom corner elements
$idbb = '' ;
if ( $idbase ) {
$idbb = 'id="' . $idbase . '-bb" ' ;
}
/// Output begins
$output = '</div></div></div>' ;
$output .= " \n " ;
$output .= '<div ' . $idbb . 'class="bb"><div> </div></div>' . " \n " ;
$output .= '</div>' ;
return $output ;
}
2007-11-16 13:33:51 +00:00
2004-09-23 04:36:43 +00:00
/**
* Print a specified group ' s avatar .
*
2009-05-22 03:26:07 +00:00
* @ global object
* @ uses CONTEXT_COURSE
* @ param array $group A single { @ link group } object OR array of groups .
2007-05-09 14:15:33 +00:00
* @ param int $courseid The course ID .
* @ param boolean $large Default small picture , or large .
* @ param boolean $return If false print picture , otherwise return the output as string
* @ param boolean $link Enclose image in a link to view specified course ?
2009-05-22 03:26:07 +00:00
* @ return string | void Depending on the setting of $return
2004-09-23 04:36:43 +00:00
*/
2006-08-10 06:41:38 +00:00
function print_group_picture ( $group , $courseid , $large = false , $return = false , $link = true ) {
2003-12-30 17:18:06 +00:00
global $CFG ;
2006-05-23 19:18:25 +00:00
if ( is_array ( $group )) {
$output = '' ;
foreach ( $group as $g ) {
$output .= print_group_picture ( $g , $courseid , $large , true , $link );
}
2006-08-10 06:41:38 +00:00
if ( $return ) {
2006-05-23 19:18:25 +00:00
return $output ;
} else {
echo $output ;
return ;
}
}
2006-09-07 08:57:56 +00:00
$context = get_context_instance ( CONTEXT_COURSE , $courseid );
2004-02-15 07:37:48 +00:00
2006-09-07 08:57:56 +00:00
if ( $group -> hidepicture and ! has_capability ( 'moodle/course:managegroups' , $context )) {
2004-02-15 07:29:55 +00:00
return '' ;
}
2004-02-15 07:13:08 +00:00
2006-09-07 08:57:56 +00:00
if ( $link or has_capability ( 'moodle/site:accessallgroups' , $context )) {
2005-05-05 02:15:21 +00:00
$output = '<a href="' . $CFG -> wwwroot . '/user/index.php?id=' . $courseid . '&group=' . $group -> id . '">' ;
2004-02-15 07:29:55 +00:00
} else {
$output = '' ;
}
if ( $large ) {
2004-09-22 14:39:15 +00:00
$file = 'f1' ;
2004-02-15 07:29:55 +00:00
} else {
2004-09-22 14:39:15 +00:00
$file = 'f2' ;
2004-02-15 07:29:55 +00:00
}
if ( $group -> picture ) { // Print custom group picture
2008-07-10 09:55:11 +00:00
require_once ( $CFG -> libdir . '/filelib.php' );
$grouppictureurl = get_file_url ( $group -> id . '/' . $file . '.jpg' , null , 'usergroup' );
$output .= '<img class="grouppicture" src="' . $grouppictureurl . '"' .
2008-09-12 06:56:11 +00:00
' alt="' . s ( get_string ( 'group' ) . ' ' . $group -> name ) . '" title="' . s ( $group -> name ) . '"/>' ;
2003-12-30 17:18:06 +00:00
}
2006-09-07 08:57:56 +00:00
if ( $link or has_capability ( 'moodle/site:accessallgroups' , $context )) {
2004-09-22 14:39:15 +00:00
$output .= '</a>' ;
2004-02-15 07:29:55 +00:00
}
2003-12-30 17:18:06 +00:00
2006-08-10 06:41:38 +00:00
if ( $return ) {
2003-12-30 17:18:06 +00:00
return $output ;
} else {
echo $output ;
}
}
2002-12-20 14:44:14 +00:00
2009-05-22 03:26:07 +00:00
/**
* Display a recent activity note
2009-08-04 02:05:32 +00:00
*
2009-05-22 03:26:07 +00:00
* @ uses CONTEXT_SYSTEM
* @ staticvar string $strftimerecent
* @ param object A time object
* @ param object A user object
* @ param string $text Text for display for the note
* @ param string $link The link to wrap around the text
* @ param bool $return If set to true the HTML is returned rather than echo ' d
* @ param string $viewfullnames
*/
2008-01-24 20:33:50 +00:00
function print_recent_activity_note ( $time , $user , $text , $link , $return = false , $viewfullnames = null ) {
static $strftimerecent = null ;
2006-08-10 06:41:38 +00:00
$output = '' ;
2008-01-24 20:33:50 +00:00
if ( is_null ( $viewfullnames )) {
2008-05-01 06:07:24 +00:00
$context = get_context_instance ( CONTEXT_SYSTEM );
2008-01-24 20:33:50 +00:00
$viewfullnames = has_capability ( 'moodle/site:viewfullnames' , $context );
}
2006-09-24 14:35:48 +00:00
2008-01-24 20:33:50 +00:00
if ( is_null ( $strftimerecent )) {
2005-03-10 13:30:57 +00:00
$strftimerecent = get_string ( 'strftimerecent' );
}
2006-08-10 06:41:38 +00:00
$output .= '<div class="head">' ;
2008-01-24 20:33:50 +00:00
$output .= '<div class="date">' . userdate ( $time , $strftimerecent ) . '</div>' ;
$output .= '<div class="name">' . fullname ( $user , $viewfullnames ) . '</div>' ;
2006-08-10 06:41:38 +00:00
$output .= '</div>' ;
$output .= '<div class="info"><a href="' . $link . '">' . format_string ( $text , true ) . '</a></div>' ;
if ( $return ) {
return $output ;
} else {
echo $output ;
}
2005-03-10 13:30:57 +00:00
}
2006-09-21 09:16:41 +00:00
/**
* Returns a little popup menu for switching roles
*
2009-05-22 03:26:07 +00:00
* @ global object
* @ global object
* @ uses CONTEXT_COURSE
2006-09-21 09:16:41 +00:00
* @ param int $courseid The course to update by id as found in 'course' table
* @ return string
*/
function switchroles_form ( $courseid ) {
2009-08-10 03:04:01 +00:00
global $CFG , $USER , $OUTPUT ;
2006-09-21 09:16:41 +00:00
if ( ! $context = get_context_instance ( CONTEXT_COURSE , $courseid )) {
return '' ;
}
2007-10-08 05:11:15 +00:00
if ( ! empty ( $USER -> access [ 'rsw' ][ $context -> path ])){ // Just a button to return to normal
2006-09-21 14:04:32 +00:00
$options = array ();
$options [ 'id' ] = $courseid ;
$options [ 'sesskey' ] = sesskey ();
$options [ 'switchrole' ] = 0 ;
2006-09-21 09:16:41 +00:00
2009-08-20 08:50:50 +00:00
return $OUTPUT -> button ( html_form :: make_button ( $CFG -> wwwroot . '/course/view.php' , $options , get_string ( 'switchrolereturn' )));
2006-09-21 14:04:32 +00:00
}
2007-03-16 20:21:27 +00:00
if ( has_capability ( 'moodle/role:switchroles' , $context )) {
2009-03-23 08:15:21 +00:00
if ( ! $roles = get_switchable_roles ( $context )) {
2007-03-16 20:21:27 +00:00
return '' ; // Nothing to show!
}
// unset default user role - it would not work
unset ( $roles [ $CFG -> guestroleid ]);
2009-08-10 03:04:01 +00:00
$popupurl = $CFG -> wwwroot . '/course/view.php?id=' . $courseid . '&sesskey=' . sesskey ();
2009-08-10 08:38:45 +00:00
$select = html_select :: make_popup_form ( $popupurl , 'switchrole' , $roles , 'switchrole' , '' );
2009-08-10 03:04:01 +00:00
$select -> nothinglabel = get_string ( 'switchroleto' );
$select -> set_help_icon ( 'switchrole' , get_string ( 'switchroleto' ));
return $OUTPUT -> select ( $select );
2007-03-16 20:21:27 +00:00
}
return '' ;
2006-09-21 09:16:41 +00:00
}
2005-03-29 13:37:08 +00:00
/**
2009-05-22 03:26:07 +00:00
* Returns a popup menu with course activity modules
*
2005-04-03 12:15:45 +00:00
* Given a course
2005-03-29 13:37:08 +00:00
* This function returns a small popup menu with all the
* course activity modules in it , as a navigation menu
2005-04-03 12:15:45 +00:00
* outputs a simple list structure in XHTML
2005-03-29 13:37:08 +00:00
* The data is taken from the serialised array stored in
* the course record
*
* @ todo Finish documenting this function
2009-05-22 03:26:07 +00:00
*
* @ global object
* @ uses CONTEXT_COURSE
* @ param course $course A { @ link $COURSE } object .
* @ param string $sections
* @ param string $modinfo
* @ param string $strsection
* @ param string $strjumpto
* @ param int $width
* @ param string $cmid
* @ return string The HTML block
2005-03-29 13:37:08 +00:00
*/
2006-10-02 14:57:00 +00:00
function navmenulist ( $course , $sections , $modinfo , $strsection , $strjumpto , $width = 50 , $cmid = 0 ) {
2005-03-29 13:37:08 +00:00
global $CFG ;
$section = - 1 ;
$url = '' ;
$menu = array ();
2008-01-24 20:33:50 +00:00
$doneheading = false ;
2005-03-29 13:37:08 +00:00
2006-10-02 14:57:00 +00:00
$coursecontext = get_context_instance ( CONTEXT_COURSE , $course -> id );
2005-03-30 12:31:00 +00:00
$menu [] = '<ul class="navmenulist"><li class="jumpto section"><span>' . $strjumpto . '</span><ul>' ;
2008-01-24 20:33:50 +00:00
foreach ( $modinfo -> cms as $mod ) {
if ( $mod -> modname == 'label' ) {
2005-03-29 13:37:08 +00:00
continue ;
}
2008-02-01 14:10:49 +00:00
if ( $mod -> sectionnum > $course -> numsections ) { /// Don't show excess hidden sections
2005-03-29 13:37:08 +00:00
break ;
}
2008-01-24 20:33:50 +00:00
if ( ! $mod -> uservisible ) { // do not icnlude empty sections at all
continue ;
}
2008-02-01 14:10:49 +00:00
if ( $mod -> sectionnum >= 0 and $section != $mod -> sectionnum ) {
$thissection = $sections [ $mod -> sectionnum ];
2005-03-29 13:37:08 +00:00
2007-01-04 10:23:06 +00:00
if ( $thissection -> visible or ! $course -> hiddensections or
2006-10-02 14:57:00 +00:00
has_capability ( 'moodle/course:viewhiddensections' , $coursecontext )) {
2005-03-29 13:37:08 +00:00
$thissection -> summary = strip_tags ( format_string ( $thissection -> summary , true ));
2008-01-24 20:33:50 +00:00
if ( ! $doneheading ) {
2005-03-29 13:46:20 +00:00
$menu [] = '</ul></li>' ;
2005-03-29 13:37:08 +00:00
}
if ( $course -> format == 'weeks' or empty ( $thissection -> summary )) {
2008-02-01 14:10:49 +00:00
$item = $strsection . " " . $mod -> sectionnum ;
2005-03-29 13:37:08 +00:00
} else {
if ( strlen ( $thissection -> summary ) < ( $width - 3 )) {
2005-03-30 11:54:58 +00:00
$item = $thissection -> summary ;
2005-03-29 13:37:08 +00:00
} else {
2005-03-30 11:54:58 +00:00
$item = substr ( $thissection -> summary , 0 , $width ) . '...' ;
2005-03-29 13:37:08 +00:00
}
}
2005-03-30 12:31:00 +00:00
$menu [] = '<li class="section"><span>' . $item . '</span>' ;
2005-03-29 13:37:08 +00:00
$menu [] = '<ul>' ;
$doneheading = true ;
2008-01-24 20:33:50 +00:00
2008-02-01 14:10:49 +00:00
$section = $mod -> sectionnum ;
2008-01-24 20:33:50 +00:00
} else {
// no activities from this hidden section shown
continue ;
2005-03-29 13:37:08 +00:00
}
}
2008-01-24 20:33:50 +00:00
$url = $mod -> modname . '/view.php?id=' . $mod -> id ;
$mod -> name = strip_tags ( format_string ( urldecode ( $mod -> name ), true ));
if ( strlen ( $mod -> name ) > ( $width + 5 )) {
$mod -> name = substr ( $mod -> name , 0 , $width ) . '...' ;
2005-03-29 13:37:08 +00:00
}
2008-01-24 20:33:50 +00:00
if ( ! $mod -> visible ) {
$mod -> name = '(' . $mod -> name . ')' ;
}
$class = 'activity ' . $mod -> modname ;
2009-02-03 07:47:24 +00:00
$class .= ( $cmid == $mod -> id ) ? ' selected' : '' ;
2008-01-24 20:33:50 +00:00
$menu [] = '<li class="' . $class . '">' .
2009-07-02 12:07:58 +00:00
'<img src="' . $OUTPUT -> mod_icon_url ( 'icon' , $mod -> modname ) . '" alt="" />' .
2008-01-24 20:33:50 +00:00
'<a href="' . $CFG -> wwwroot . '/mod/' . $url . '">' . $mod -> name . '</a></li>' ;
2005-03-29 13:37:08 +00:00
}
2008-01-24 20:33:50 +00:00
2005-03-29 13:46:20 +00:00
if ( $doneheading ) {
2005-03-29 13:48:25 +00:00
$menu [] = '</ul></li>' ;
2005-03-29 13:46:20 +00:00
}
2005-03-29 21:08:17 +00:00
$menu [] = '</ul></li></ul>' ;
2005-03-29 13:37:08 +00:00
return implode ( " \n " , $menu );
}
2004-09-23 04:36:43 +00:00
/**
* Prints a grade menu ( as part of an existing form ) with help
* Showing all possible numerical grades and scales
*
* @ todo Finish documenting this function
2009-07-27 10:33:00 +00:00
* @ todo Deprecate : this is only used in a few contrib modules
2009-05-22 03:26:07 +00:00
*
* @ global object
* @ param int $courseid The course ID
2009-08-04 02:05:32 +00:00
* @ param string $name
* @ param string $current
2009-05-22 03:26:07 +00:00
* @ param boolean $includenograde Include those with no grades
* @ param boolean $return If set to true returns rather than echo ' s
* @ return string | bool Depending on value of $return
2004-09-23 04:36:43 +00:00
*/
2006-08-10 06:41:38 +00:00
function print_grade_menu ( $courseid , $name , $current , $includenograde = true , $return = false ) {
2003-08-18 05:28:30 +00:00
2009-07-02 12:07:58 +00:00
global $CFG , $OUTPUT ;
2003-08-18 05:28:30 +00:00
2006-08-10 06:41:38 +00:00
$output = '' ;
2004-09-22 14:39:15 +00:00
$strscale = get_string ( 'scale' );
$strscales = get_string ( 'scales' );
2003-08-18 05:28:30 +00:00
2003-08-18 11:58:07 +00:00
$scales = get_scales_menu ( $courseid );
2003-08-18 05:28:30 +00:00
foreach ( $scales as $i => $scalename ) {
2004-09-22 14:39:15 +00:00
$grades [ - $i ] = $strscale . ': ' . $scalename ;
2003-08-18 05:28:30 +00:00
}
2003-08-25 12:47:36 +00:00
if ( $includenograde ) {
2004-09-22 14:39:15 +00:00
$grades [ 0 ] = get_string ( 'nograde' );
2003-08-25 12:47:36 +00:00
}
2003-08-18 05:28:30 +00:00
for ( $i = 100 ; $i >= 1 ; $i -- ) {
$grades [ $i ] = $i ;
}
2009-08-18 00:18:19 +00:00
$output .= $OUTPUT -> select ( html_select :: make ( $grades , $name , $current , false ));
2003-08-18 05:28:30 +00:00
2009-07-02 12:07:58 +00:00
$linkobject = '<span class="helplink"><img class="iconhelp" alt="' . $strscales . '" src="' . $OUTPUT -> old_icon_url ( 'help' ) . '" /></span>' ;
2009-08-20 13:18:08 +00:00
$link = html_link :: make ( '/course/scales.php?id=' . $courseid . '&list=true' , $linkobject );
$link -> add_action ( new popup_action ( 'click' , $link -> url , 'ratingscales' , array ( 'height' => 400 , 'width' => 500 )));
$link -> title = $strscales ;
$output .= $OUTPUT -> link ( $link );
2006-08-10 06:41:38 +00:00
if ( $return ) {
return $output ;
} else {
echo $output ;
}
2003-08-18 05:28:30 +00:00
}
2008-02-27 02:52:28 +00:00
/**
* Print an error to STDOUT and exit with a non - zero code . For commandline scripts .
* Default errorcode is 1.
*
* Very useful for perl - like error - handling :
2008-05-21 14:59:33 +00:00
*
2008-02-27 02:52:28 +00:00
* do_somethting () or mdie ( " Something went wrong " );
*
* @ param string $msg Error message
2008-05-21 14:59:33 +00:00
* @ param integer $errorcode Error code to emit
2008-02-27 02:52:28 +00:00
*/
function mdie ( $msg = '' , $errorcode = 1 ) {
trigger_error ( $msg );
exit ( $errorcode );
}
2007-01-05 04:51:46 +00:00
/**
* Returns a string of html with an image of a help icon linked to a help page on a number of help topics .
* Should be used only with htmleditor or textarea .
2009-05-22 03:26:07 +00:00
*
* @ global object
* @ global object
2007-01-05 04:51:46 +00:00
* @ param mixed $helptopics variable amount of params accepted . Each param may be a string or an array of arguments for
* helpbutton .
2009-05-22 03:26:07 +00:00
* @ return string Link to help button
2007-01-05 04:51:46 +00:00
*/
2007-01-04 10:23:06 +00:00
function editorhelpbutton (){
2009-07-02 12:07:58 +00:00
global $CFG , $SESSION , $OUTPUT ;
2007-01-04 10:23:06 +00:00
$items = func_get_args ();
$i = 1 ;
$urlparams = array ();
$titles = array ();
foreach ( $items as $item ){
if ( is_array ( $item )){
$urlparams [] = " keyword $i = " . urlencode ( $item [ 0 ]);
$urlparams [] = " title $i = " . urlencode ( $item [ 1 ]);
if ( isset ( $item [ 2 ])){
$urlparams [] = " module $i = " . urlencode ( $item [ 2 ]);
}
$titles [] = trim ( $item [ 1 ], " . \t " );
2008-09-25 10:07:11 +00:00
} else if ( is_string ( $item )) {
2007-01-04 10:23:06 +00:00
$urlparams [] = " button $i = " . urlencode ( $item );
2008-09-25 10:07:11 +00:00
switch ( $item ) {
2007-01-04 10:23:06 +00:00
case 'reading' :
$titles [] = get_string ( " helpreading " );
break ;
case 'writing' :
$titles [] = get_string ( " helpwriting " );
break ;
case 'questions' :
$titles [] = get_string ( " helpquestions " );
break ;
2008-09-25 10:07:11 +00:00
case 'emoticons2' :
2007-01-04 10:23:06 +00:00
$titles [] = get_string ( " helpemoticons " );
break ;
2008-09-25 10:07:11 +00:00
case 'richtext2' :
2007-01-05 04:51:46 +00:00
$titles [] = get_string ( 'helprichtext' );
break ;
2008-09-25 10:07:11 +00:00
case 'text2' :
2007-01-05 04:51:46 +00:00
$titles [] = get_string ( 'helptext' );
2007-01-04 10:23:06 +00:00
break ;
default :
2008-05-15 03:07:21 +00:00
print_error ( 'unknownhelp' , '' , '' , $item );
2007-01-04 10:23:06 +00:00
}
}
$i ++ ;
}
if ( count ( $titles ) > 1 ){
//join last two items with an 'and'
$a = new object ();
$a -> one = $titles [ count ( $titles ) - 2 ];
$a -> two = $titles [ count ( $titles ) - 1 ];
$titles [ count ( $titles ) - 2 ] = get_string ( 'and' , '' , $a );
unset ( $titles [ count ( $titles ) - 1 ]);
}
$alttag = join ( ', ' , $titles );
2005-03-18 12:10:00 +00:00
2007-01-04 10:23:06 +00:00
$paramstring = join ( '&' , $urlparams );
2009-07-02 12:07:58 +00:00
$linkobject = '<img alt="' . $alttag . '" class="iconhelp" src="' . $OUTPUT -> old_icon_url ( 'help' ) . '" />' ;
2009-08-20 13:18:08 +00:00
$link = html_link :: make ( s ( '/lib/form/editorhelp.php?' . $paramstring ), $linkobject );
$link -> add_action ( new popup_action ( 'click' , $link -> url , 'popup' , array ( 'height' => 400 , 'width' => 500 )));
$link -> title = $alttag ;
return $OUTPUT -> link ( $link );
2007-01-05 04:51:46 +00:00
}
2005-03-18 12:10:00 +00:00
2004-09-23 04:36:43 +00:00
/**
* Print a help button .
*
2004-09-25 05:29:21 +00:00
* Prints a special help button that is a link to the " live " emoticon popup
2009-05-22 03:26:07 +00:00
*
* @ todo Finish documenting this function
*
* @ global object
* @ global object
2004-09-25 05:29:21 +00:00
* @ param string $form ?
* @ param string $field ?
2009-05-22 03:26:07 +00:00
* @ param boolean $return If true then the output is returned as a string , if false it is printed to the current page .
* @ return string | void Depending on value of $return
2004-09-23 04:36:43 +00:00
*/
2007-01-04 10:23:06 +00:00
function emoticonhelpbutton ( $form , $field , $return = false ) {
2004-09-25 05:29:21 +00:00
2009-07-02 11:09:15 +00:00
global $SESSION , $OUTPUT ;
2003-05-08 16:09:30 +00:00
$SESSION -> inserttextform = $form ;
$SESSION -> inserttextfield = $field ;
2009-08-18 05:20:12 +00:00
$helpicon = moodle_help_icon :: make ( 'emoticons2' , get_string ( 'helpemoticons' ), 'moodle' , true );
$helpicon -> image -> src = $OUTPUT -> old_icon_url ( 's/smiley' );
$helpicon -> image -> add_class ( 'emoticon' );
$helpicon -> style = " margin-left:3px; padding-right:1px;width:15px;height:15px; " ;
$help = $OUTPUT -> help_icon ( $helpicon );
2007-01-04 10:23:06 +00:00
if ( ! $return ){
echo $help ;
} else {
return $help ;
}
2003-05-08 16:09:30 +00:00
}
2006-11-30 08:30:46 +00:00
/**
* Print a help button .
*
* Prints a special help button for html editors ( htmlarea in this case )
2009-05-22 03:26:07 +00:00
*
* @ todo Write code into this function ! detect current editor and print correct info
* @ global object
* @ return string Only returns an empty string at the moment
2006-11-30 08:30:46 +00:00
*/
function editorshortcutshelpbutton () {
global $CFG ;
2008-09-23 14:51:55 +00:00
//TODO: detect current editor and print correct info
/* $imagetext = '<img src="' . $CFG -> httpswwwroot . '/lib/editor/htmlarea/images/kbhelp.gif" alt="' .
2007-05-08 15:07:25 +00:00
get_string ( 'editorshortcutkeys' ) . '" class="iconkbhelp" />' ;
2006-11-30 08:30:46 +00:00
2008-09-23 14:51:55 +00:00
return helpbutton ( 'editorshortcuts' , get_string ( 'editorshortcutkeys' ), 'moodle' , true , false , '' , true , $imagetext ); */
return '' ;
2006-11-30 08:30:46 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* Print a message and exit .
*
2009-05-22 03:26:07 +00:00
* @ param string $message The message to print in the notice
* @ param string $link The link to use for the continue button
* @ param object $course A course object
* @ return void This function simply exits
2004-09-23 04:36:43 +00:00
*/
2007-04-30 17:08:34 +00:00
function notice ( $message , $link = '' , $course = NULL ) {
2009-08-06 14:21:34 +00:00
global $CFG , $SITE , $THEME , $COURSE , $PAGE , $OUTPUT ;
2002-12-20 14:44:14 +00:00
2007-12-14 21:22:38 +00:00
$message = clean_text ( $message ); // In case nasties are in here
2007-11-23 16:49:51 +00:00
2009-01-03 14:28:02 +00:00
if ( CLI_SCRIPT ) {
2009-05-25 17:33:28 +00:00
echo ( " !! $message !! \n " );
2009-05-27 08:34:04 +00:00
exit ( 1 ); // no success
2007-12-14 21:22:38 +00:00
}
2009-05-06 08:29:22 +00:00
if ( ! $PAGE -> headerprinted ) {
2007-12-14 21:22:38 +00:00
//header not yet printed
2009-09-03 06:59:25 +00:00
$PAGE -> set_title ( get_string ( 'notice' ));
echo $OUTPUT -> header ();
2007-12-14 21:22:38 +00:00
} else {
print_container_end_all ( false , $THEME -> open_header_containers );
}
2002-12-20 14:44:14 +00:00
2009-08-10 04:58:02 +00:00
echo $OUTPUT -> box ( $message , 'generalbox' , 'notice' );
2009-08-18 05:20:12 +00:00
echo $OUTPUT -> continue_button ( $link );
2007-01-04 10:23:06 +00:00
2009-08-06 14:21:34 +00:00
echo $OUTPUT -> footer ();
2009-05-27 08:34:04 +00:00
exit ( 1 ); // general error code
2002-12-20 14:44:14 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* Redirects the user to another page , after printing a notice
*
2009-06-29 07:19:05 +00:00
* This function calls the OUTPUT redirect method , echo ' s the output
* and then dies to ensure nothing else happens .
*
* < strong > Good practice :</ strong > You should call this method before starting page
* output by using any of the OUTPUT methods .
2009-05-22 03:26:07 +00:00
*
2009-08-04 02:05:32 +00:00
* @ param moodle_url $url A moodle_url to redirect to . Strings are not to be trusted !
2009-06-29 07:19:05 +00:00
* @ param string $message The message to display to the user
* @ param int $delay The delay before redirecting
* @ return void
2004-09-23 04:36:43 +00:00
*/
2007-04-30 17:08:34 +00:00
function redirect ( $url , $message = '' , $delay =- 1 ) {
2009-10-13 06:45:38 +00:00
global $OUTPUT , $PAGE , $SESSION , $CFG ;
2006-01-05 07:08:10 +00:00
2009-07-15 04:05:05 +00:00
if ( $url instanceof moodle_url ) {
$url = $url -> out ( false , array (), false );
}
2006-01-05 07:08:10 +00:00
if ( ! empty ( $CFG -> usesid ) && ! isset ( $_COOKIE [ session_name ()])) {
2008-06-22 16:51:55 +00:00
$url = $SESSION -> sid_process_url ( $url );
2005-12-05 02:24:45 +00:00
}
2009-07-03 09:03:29 +00:00
$lasterror = error_get_last ();
$debugdisableredirect = defined ( 'DEBUGGING_PRINTED' ) ||
( ! empty ( $CFG -> debugdisplay ) && ! empty ( $lasterror ) && ( $lasterror [ 'type' ] & DEBUG_DEVELOPER ));
2009-06-29 07:19:05 +00:00
$usingmsg = false ;
2009-07-03 09:03:29 +00:00
if ( ! empty ( $message )) {
if ( $delay === - 1 || ! is_numeric ( $delay )) {
2009-06-29 07:19:05 +00:00
$delay = 3 ;
2007-09-12 02:57:08 +00:00
}
2009-06-29 07:19:05 +00:00
$message = clean_text ( $message );
} else {
2009-07-03 09:03:29 +00:00
$message = get_string ( 'pageshouldredirect' );
2009-06-29 07:19:05 +00:00
$delay = 0 ;
2009-07-03 09:03:29 +00:00
// We are going to try to use a HTTP redirect, so we need a full URL.
2007-01-04 10:23:06 +00:00
if ( ! preg_match ( '|^[a-z]+:|' , $url )) {
2006-09-22 10:48:37 +00:00
// Get host name http://www.wherever.com
2006-09-24 19:10:13 +00:00
$hostpart = preg_replace ( '|^(.*?[^:/])/.*$|' , '$1' , $CFG -> wwwroot );
if ( preg_match ( '|^/|' , $url )) {
// URLs beginning with / are relative to web server root so we just add them in
$url = $hostpart . $url ;
2006-09-22 10:48:37 +00:00
} else {
2006-09-24 19:10:13 +00:00
// URLs not beginning with / are relative to path of current script, so add that on.
2006-09-25 11:23:15 +00:00
$url = $hostpart . preg_replace ( '|\?.*$|' , '' , me ()) . '/../' . $url ;
2006-09-22 10:48:37 +00:00
}
2006-09-21 15:13:27 +00:00
// Replace all ..s
2006-09-24 19:10:13 +00:00
while ( true ) {
2006-11-27 16:42:16 +00:00
$newurl = preg_replace ( '|/(?!\.\.)[^/]*/\.\./|' , '/' , $url );
2006-09-24 19:10:13 +00:00
if ( $newurl == $url ) {
2006-09-21 15:13:27 +00:00
break ;
}
2006-09-24 19:10:13 +00:00
$url = $newurl ;
2006-09-21 15:13:27 +00:00
}
}
2006-05-16 20:31:22 +00:00
}
2005-11-17 06:45:40 +00:00
2009-06-29 07:19:05 +00:00
if ( defined ( 'MDL_PERF' ) || ( ! empty ( $CFG -> perfdebug ) and $CFG -> perfdebug > 7 )) {
if ( defined ( 'MDL_PERFTOLOG' ) && ! function_exists ( 'register_shutdown_function' )) {
$perf = get_performance_info ();
error_log ( " PERF: " . $perf [ 'txt' ]);
}
2006-05-16 20:31:22 +00:00
}
2007-03-14 15:29:46 +00:00
2009-06-29 07:19:05 +00:00
$encodedurl = preg_replace ( " / \ &(?![a-zA-Z0-9#] { 1,8};)/ " , " & " , $url );
$encodedurl = preg_replace ( '/^.*href="([^"]*)".*$/' , " \\ 1 " , clean_text ( '<a href="' . $encodedurl . '" />' ));
2007-03-14 15:29:46 +00:00
2009-07-03 09:03:29 +00:00
if ( $delay == 0 && ! $debugdisableredirect && ! headers_sent ()) {
//302 might not work for POST requests, 303 is ignored by obsolete clients.
@ header ( $_SERVER [ 'SERVER_PROTOCOL' ] . ' 303 See Other' );
@ header ( 'Location: ' . $url );
2009-07-10 08:44:01 +00:00
echo bootstrap_renderer :: plain_redirect_message ( $encodedurl );
exit ;
2009-07-03 09:03:29 +00:00
}
2009-07-01 05:54:26 +00:00
2009-07-03 09:03:29 +00:00
// Include a redirect message, even with a HTTP redirect, because that is recommended practice.
2009-10-13 06:45:38 +00:00
$PAGE -> set_generaltype ( 'embedded' ); // No header and footer needed
2008-03-19 08:19:31 +00:00
$CFG -> docroot = false ; // to prevent the link to moodle docs from being displayed on redirect page.
2009-07-03 09:03:29 +00:00
echo $OUTPUT -> redirect_message ( $encodedurl , $message , $delay , $debugdisableredirect );
exit ;
2002-12-20 14:44:14 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* Given an email address , this function will return an obfuscated version of it
*
2004-09-25 05:29:21 +00:00
* @ param string $email The email address to obfuscate
2009-05-22 03:26:07 +00:00
* @ return string The obfuscated email address
2004-09-23 04:36:43 +00:00
*/
function obfuscate_email ( $email ) {
2003-07-11 08:38:39 +00:00
$i = 0 ;
$length = strlen ( $email );
2004-09-22 14:39:15 +00:00
$obfuscated = '' ;
2003-07-11 08:38:39 +00:00
while ( $i < $length ) {
if ( rand ( 0 , 2 )) {
$obfuscated .= '%' . dechex ( ord ( $email { $i }));
} else {
$obfuscated .= $email { $i };
}
$i ++ ;
}
return $obfuscated ;
}
2004-09-23 04:36:43 +00:00
/**
* This function takes some text and replaces about half of the characters
* with HTML entity equivalents . Return string is obviously longer .
*
2004-09-25 05:29:21 +00:00
* @ param string $plaintext The text to be obfuscated
2009-05-22 03:26:07 +00:00
* @ return string The obfuscated text
2004-09-23 04:36:43 +00:00
*/
2003-07-11 08:38:39 +00:00
function obfuscate_text ( $plaintext ) {
2005-01-26 15:57:00 +00:00
2003-07-11 08:38:39 +00:00
$i = 0 ;
$length = strlen ( $plaintext );
2004-09-22 14:39:15 +00:00
$obfuscated = '' ;
2003-09-09 02:22:36 +00:00
$prev_obfuscated = false ;
2003-07-11 08:38:39 +00:00
while ( $i < $length ) {
2003-09-09 02:22:36 +00:00
$c = ord ( $plaintext { $i });
$numerical = ( $c >= ord ( '0' )) && ( $c <= ord ( '9' ));
if ( $prev_obfuscated and $numerical ) {
2004-09-23 12:09:19 +00:00
$obfuscated .= '&#' . ord ( $plaintext { $i }) . ';' ;
2003-09-09 02:22:36 +00:00
} else if ( rand ( 0 , 2 )) {
2004-09-23 12:09:19 +00:00
$obfuscated .= '&#' . ord ( $plaintext { $i }) . ';' ;
2003-09-09 02:22:36 +00:00
$prev_obfuscated = true ;
2003-07-11 08:38:39 +00:00
} else {
$obfuscated .= $plaintext { $i };
2003-09-09 02:22:36 +00:00
$prev_obfuscated = false ;
2003-07-11 08:38:39 +00:00
}
2003-09-09 02:22:36 +00:00
$i ++ ;
2003-07-11 08:38:39 +00:00
}
return $obfuscated ;
}
2004-09-23 04:36:43 +00:00
/**
2004-09-25 05:29:21 +00:00
* This function uses the { @ link obfuscate_email ()} and { @ link obfuscate_text ()}
* to generate a fully obfuscated email link , ready to use .
2004-09-23 04:36:43 +00:00
*
2004-09-25 05:29:21 +00:00
* @ param string $email The email address to display
* @ param string $label The text to dispalyed as hyperlink to $email
* @ param boolean $dimmed If true then use css class ' dimmed ' for hyperlink
2009-05-22 03:26:07 +00:00
* @ return string The obfuscated mailto link
2004-09-23 04:36:43 +00:00
*/
2004-09-22 14:39:15 +00:00
function obfuscate_mailto ( $email , $label = '' , $dimmed = false ) {
2003-07-11 08:38:39 +00:00
if ( empty ( $label )) {
$label = $email ;
}
2004-02-20 10:27:24 +00:00
if ( $dimmed ) {
$title = get_string ( 'emaildisable' );
$dimmed = ' class="dimmed"' ;
} else {
$title = '' ;
$dimmed = '' ;
}
2004-05-21 13:07:11 +00:00
return sprintf ( " <a href= \" %s:%s \" $dimmed title= \" $title\ " >% s </ a > " ,
2004-02-20 10:27:24 +00:00
obfuscate_text ( 'mailto' ), obfuscate_email ( $email ),
obfuscate_text ( $label ));
2003-07-11 08:38:39 +00:00
}
2004-09-23 04:36:43 +00:00
/**
* This function is used to rebuild the < nolink > tag because some formats ( PLAIN and WIKI )
* will transform it to html entities
*
2004-09-25 05:29:21 +00:00
* @ param string $text Text to search for nolink tag in
* @ return string
2004-09-23 04:36:43 +00:00
*/
2004-05-11 23:17:25 +00:00
function rebuildnolinktag ( $text ) {
2004-05-21 13:07:11 +00:00
2004-05-11 23:17:25 +00:00
$text = preg_replace ( '/<(\/*nolink)>/i' , '<$1>' , $text );
return $text ;
}
2005-02-10 05:11:34 +00:00
/**
2009-05-31 14:42:29 +00:00
* Prints a maintenance message from $CFG -> maintenance_message or default if empty
2009-08-04 02:05:32 +00:00
* @ return void
2005-02-10 05:11:34 +00:00
*/
2009-05-31 14:42:29 +00:00
function print_maintenance_message () {
2009-08-06 08:19:21 +00:00
global $CFG , $SITE , $PAGE , $OUTPUT ;
2005-04-03 12:15:45 +00:00
2009-05-06 08:43:51 +00:00
$PAGE -> set_pagetype ( 'maintenance-message' );
2009-07-09 07:35:03 +00:00
$PAGE -> set_generaltype ( 'maintenance' );
2009-09-03 06:59:25 +00:00
$PAGE -> set_title ( strip_tags ( $SITE -> fullname ));
$PAGE -> set_heading ( $SITE -> fullname );
echo $OUTPUT -> header ();
2009-08-06 08:19:21 +00:00
echo $OUTPUT -> heading ( get_string ( 'sitemaintenance' , 'admin' ));
2009-05-31 14:42:29 +00:00
if ( isset ( $CFG -> maintenance_message ) and ! html_is_blank ( $CFG -> maintenance_message )) {
2009-08-10 04:58:02 +00:00
echo $OUTPUT -> box_start ( 'maintenance_message generalbox boxwidthwide boxaligncenter' );
2009-05-31 14:42:29 +00:00
echo $CFG -> maintenance_message ;
2009-08-10 04:58:02 +00:00
echo $OUTPUT -> box_end ();
2009-05-31 14:42:29 +00:00
}
2009-08-06 14:21:34 +00:00
echo $OUTPUT -> footer ();
2009-05-31 14:42:29 +00:00
die ;
2005-02-10 05:11:34 +00:00
}
2005-06-25 15:42:44 +00:00
/**
* Adjust the list of allowed tags based on $CFG -> allowobjectembed and user roles ( admin )
2009-05-22 03:26:07 +00:00
*
* @ global object
* @ global string
* @ return void
2005-06-25 15:42:44 +00:00
*/
function adjust_allowed_tags () {
2005-02-10 05:11:34 +00:00
2005-06-25 15:42:44 +00:00
global $CFG , $ALLOWED_TAGS ;
2005-06-29 16:17:11 +00:00
if ( ! empty ( $CFG -> allowobjectembed )) {
2005-06-25 15:42:44 +00:00
$ALLOWED_TAGS .= '<embed><object>' ;
}
}
2005-03-15 08:49:14 +00:00
2009-05-22 03:26:07 +00:00
/**
* A class for tabs , Some code to print tabs
*
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ package moodlecore
*/
2005-03-15 08:49:14 +00:00
class tabobject {
2009-05-22 03:26:07 +00:00
/**
* @ var string
*/
2005-03-15 08:49:14 +00:00
var $id ;
var $link ;
var $text ;
2009-05-22 03:26:07 +00:00
/**
* @ var bool
*/
2006-03-08 04:53:48 +00:00
var $linkedwhenselected ;
2005-03-15 08:49:14 +00:00
2009-08-04 02:05:32 +00:00
/**
2009-05-22 03:26:07 +00:00
* A constructor just because I like constructors
2009-08-04 02:05:32 +00:00
*
2009-05-22 03:26:07 +00:00
* @ param string $id
* @ param string $link
* @ param string $text
* @ param string $title
* @ param bool $linkedwhenselected
*/
2006-03-08 04:53:48 +00:00
function tabobject ( $id , $link = '' , $text = '' , $title = '' , $linkedwhenselected = false ) {
2005-03-15 08:49:14 +00:00
$this -> id = $id ;
$this -> link = $link ;
$this -> text = $text ;
2006-02-09 13:38:04 +00:00
$this -> title = $title ? $title : $text ;
2006-03-08 04:53:48 +00:00
$this -> linkedwhenselected = $linkedwhenselected ;
2005-03-15 08:49:14 +00:00
}
}
/**
2007-01-26 06:28:43 +00:00
* Returns a string containing a nested list , suitable for formatting into tabs with CSS .
2005-03-15 08:49:14 +00:00
*
2009-05-22 03:26:07 +00:00
* @ global object
2005-03-15 08:49:14 +00:00
* @ param array $tabrows An array of rows where each row is an array of tab objects
2007-01-26 06:28:43 +00:00
* @ param string $selected The id of the selected tab ( whatever row it ' s on )
* @ param array $inactive An array of ids of inactive tabs that are not selectable .
* @ param array $activated An array of ids of other tabs that are currently activated
2009-05-22 03:26:07 +00:00
* @ param bool $return If true output is returned rather then echo ' d
**/
2007-01-26 06:28:43 +00:00
function print_tabs ( $tabrows , $selected = NULL , $inactive = NULL , $activated = NULL , $return = false ) {
2005-03-15 08:49:14 +00:00
global $CFG ;
/// $inactive must be an array
if ( ! is_array ( $inactive )) {
$inactive = array ();
}
2006-03-04 16:04:48 +00:00
2007-01-26 06:28:43 +00:00
/// $activated must be an array
if ( ! is_array ( $activated )) {
$activated = array ();
2005-05-05 09:32:33 +00:00
}
2005-03-15 08:49:14 +00:00
2007-01-11 06:54:23 +00:00
/// Convert the tab rows into a tree that's easier to process
2007-01-26 06:28:43 +00:00
if ( ! $tree = convert_tabrows_to_tree ( $tabrows , $selected , $inactive , $activated )) {
2007-01-11 06:54:23 +00:00
return false ;
}
2005-04-03 12:15:45 +00:00
2007-01-11 06:54:23 +00:00
/// Print out the current tree of tabs (this function is recursive)
2007-06-19 14:44:02 +00:00
2007-01-11 06:54:23 +00:00
$output = convert_tree_to_html ( $tree );
$output = " \n \n " . '<div class="tabtree">' . $output . '</div><div class="clearer"> </div>' . " \n \n " ;
/// We're done!
if ( $return ) {
return $output ;
}
echo $output ;
}
2005-03-27 15:28:35 +00:00
2009-05-22 03:26:07 +00:00
/**
* Converts a nested array tree into HTML ul : li [ recursive ]
*
* @ param array $tree A tree array to convert
* @ param int $row Used in identifing the iteration level and in ul classes
* @ return string HTML structure
*/
2007-01-11 06:54:23 +00:00
function convert_tree_to_html ( $tree , $row = 0 ) {
2005-04-03 12:15:45 +00:00
2007-01-11 06:54:23 +00:00
$str = " \n " . '<ul class="tabrow' . $row . '">' . " \n " ;
2005-04-03 12:15:45 +00:00
2007-01-25 04:43:26 +00:00
$first = true ;
$count = count ( $tree );
2007-01-11 06:54:23 +00:00
foreach ( $tree as $tab ) {
2007-01-25 04:43:26 +00:00
$count -- ; // countdown to zero
2007-03-04 17:16:00 +00:00
$liclass = '' ;
2007-01-26 06:23:53 +00:00
if ( $first && ( $count == 0 )) { // Just one in the row
2007-03-04 17:16:00 +00:00
$liclass = 'first last' ;
2007-01-26 06:23:53 +00:00
$first = false ;
} else if ( $first ) {
2007-03-04 17:16:00 +00:00
$liclass = 'first' ;
2007-01-25 04:43:26 +00:00
$first = false ;
} else if ( $count == 0 ) {
2007-03-04 17:16:00 +00:00
$liclass = 'last' ;
2007-01-25 04:43:26 +00:00
}
2005-04-03 12:15:45 +00:00
2007-03-04 17:16:00 +00:00
if (( empty ( $tab -> subtree )) && ( ! empty ( $tab -> selected ))) {
$liclass .= ( empty ( $liclass )) ? 'onerow' : ' onerow' ;
2007-01-11 06:54:23 +00:00
}
2005-03-15 08:49:14 +00:00
2008-02-25 11:58:12 +00:00
if ( $tab -> inactive || $tab -> active || $tab -> selected ) {
2007-06-19 14:44:02 +00:00
if ( $tab -> selected ) {
2007-03-04 17:16:00 +00:00
$liclass .= ( empty ( $liclass )) ? 'here selected' : ' here selected' ;
2007-06-19 14:44:02 +00:00
} else if ( $tab -> active ) {
2007-03-04 17:16:00 +00:00
$liclass .= ( empty ( $liclass )) ? 'here active' : ' here active' ;
}
}
$str .= ( ! empty ( $liclass )) ? '<li class="' . $liclass . '">' : '<li>' ;
if ( $tab -> inactive || $tab -> active || ( $tab -> selected && ! $tab -> linkedwhenselected )) {
2007-10-09 16:56:00 +00:00
// The a tag is used for styling
$str .= '<a class="nolink"><span>' . $tab -> text . '</span></a>' ;
2007-01-11 06:54:23 +00:00
} else {
2007-03-04 17:16:00 +00:00
$str .= '<a href="' . $tab -> link . '" title="' . $tab -> title . '"><span>' . $tab -> text . '</span></a>' ;
2005-03-15 08:49:14 +00:00
}
2005-04-03 12:15:45 +00:00
2007-06-19 14:44:02 +00:00
if ( ! empty ( $tab -> subtree )) {
2007-01-11 06:54:23 +00:00
$str .= convert_tree_to_html ( $tab -> subtree , $row + 1 );
2007-01-25 04:43:26 +00:00
} else if ( $tab -> selected ) {
2007-03-04 17:16:00 +00:00
$str .= '<div class="tabrow' . ( $row + 1 ) . ' empty"> </div>' . " \n " ;
2007-01-11 06:54:23 +00:00
}
2007-07-03 20:17:54 +00:00
$str .= ' </li>' . " \n " ;
2005-03-15 08:49:14 +00:00
}
2007-01-11 06:54:23 +00:00
$str .= '</ul>' . " \n " ;
2005-04-03 12:15:45 +00:00
2007-01-11 06:54:23 +00:00
return $str ;
}
2009-05-22 03:26:07 +00:00
/**
* Convert nested tabrows to a nested array
*
* @ param array $tabrows A [ nested ] array of tab row objects
* @ param string $selected The tabrow to select ( by id )
* @ param array $inactive An array of tabrow id ' s to make inactive
* @ param array $activated An array of tabrow id ' s to make active
2009-08-04 02:05:32 +00:00
* @ return array The nested array
2009-05-22 03:26:07 +00:00
*/
2007-01-26 06:28:43 +00:00
function convert_tabrows_to_tree ( $tabrows , $selected , $inactive , $activated ) {
2007-01-11 06:54:23 +00:00
/// Work backwards through the rows (bottom to top) collecting the tree as we go.
$tabrows = array_reverse ( $tabrows );
$subtree = array ();
foreach ( $tabrows as $row ) {
$tree = array ();
foreach ( $row as $tab ) {
2007-02-01 07:02:28 +00:00
$tab -> inactive = in_array (( string ) $tab -> id , $inactive );
$tab -> active = in_array (( string ) $tab -> id , $activated );
$tab -> selected = ( string ) $tab -> id == $selected ;
2007-01-11 06:54:23 +00:00
if ( $tab -> active || $tab -> selected ) {
if ( $subtree ) {
$tab -> subtree = $subtree ;
}
}
$tree [] = $tab ;
}
$subtree = $tree ;
2005-03-15 09:47:41 +00:00
}
2007-01-11 06:54:23 +00:00
2007-03-14 15:29:46 +00:00
return $subtree ;
2005-03-15 08:49:14 +00:00
}
2008-11-05 08:17:30 +00:00
/**
2009-05-22 03:26:07 +00:00
* Returns the Moodle Docs URL in the users language
*
* @ global object
2008-11-05 08:17:30 +00:00
* @ param string $path the end of the URL .
2009-05-22 03:26:07 +00:00
* @ return string The MoodleDocs URL in the user ' s language . for example { @ link http :// docs . moodle . org / en / http :// docs . moodle . org / en / $path }
2008-11-05 08:17:30 +00:00
*/
function get_docs_url ( $path ) {
global $CFG ;
return $CFG -> docroot . '/' . str_replace ( '_utf8' , '' , current_language ()) . '/' . $path ;
}
2007-08-09 08:40:02 +00:00
2006-09-14 04:25:17 +00:00
/**
2009-05-22 03:26:07 +00:00
* Standard Debugging Function
*
2006-09-23 09:38:39 +00:00
* Returns true if the current site debugging settings are equal or above specified level .
2006-12-21 04:03:21 +00:00
* If passed a parameter it will emit a debugging notice similar to trigger_error () . The
* routing of notices is controlled by $CFG -> debugdisplay
2006-09-14 04:25:17 +00:00
* eg use like this :
*
2006-09-23 09:38:39 +00:00
* 1 ) debugging ( 'a normal debug notice' );
* 2 ) debugging ( 'something really picky' , DEBUG_ALL );
* 3 ) debugging ( 'annoying debug message only for develpers' , DEBUG_DEVELOPER );
2006-12-21 04:03:21 +00:00
* 4 ) if ( debugging ()) { perform extra debugging operations ( do not use print or echo ) }
*
* In code blocks controlled by debugging () ( such as example 4 )
* any output should be routed via debugging () itself , or the lower - level
* trigger_error () or error_log () . Using echo or print will break XHTML
* JS and HTTP headers .
*
2006-09-14 04:25:17 +00:00
*
2009-05-22 03:26:07 +00:00
* @ global object
* @ uses DEBUG_NORMAL
2006-09-14 04:31:05 +00:00
* @ param string $message a message to print
2006-09-14 04:25:17 +00:00
* @ param int $level the level at which this debugging statement should show
2008-06-22 16:51:55 +00:00
* @ param array $backtrace use different backtrace
2006-09-14 04:25:17 +00:00
* @ return bool
*/
2009-06-26 09:06:16 +00:00
function debugging ( $message = '' , $level = DEBUG_NORMAL , $backtrace = null ) {
2009-09-30 18:06:45 +00:00
global $CFG , $UNITTEST ;
2006-09-14 04:25:17 +00:00
2009-06-26 09:06:16 +00:00
if ( empty ( $CFG -> debug ) || $CFG -> debug < $level ) {
2006-09-14 04:25:17 +00:00
return false ;
}
2009-06-26 09:06:16 +00:00
if ( ! isset ( $CFG -> debugdisplay )) {
$CFG -> debugdisplay = ini_get_bool ( 'display_errors' );
2009-01-31 20:07:32 +00:00
}
2009-06-26 09:06:16 +00:00
if ( $message ) {
if ( ! $backtrace ) {
$backtrace = debug_backtrace ();
2008-06-13 17:51:34 +00:00
}
2009-06-26 09:06:16 +00:00
$from = format_backtrace ( $backtrace , CLI_SCRIPT );
2009-09-30 18:13:27 +00:00
if ( $CFG -> debugdisplay || isset ( $UNITTEST -> running )) {
2009-09-30 18:06:45 +00:00
// When the unit tests are running, any call to trigger_error
// is intercepted by the test framework and reported as an exception.
// Therefore, we cannot use trigger_error during unit tests.
// At the same time I do not think we should just discard those messages,
// so displaying them on-screen seems like the only option. (MDL-20398)
2009-06-26 09:06:16 +00:00
if ( ! defined ( 'DEBUGGING_PRINTED' )) {
define ( 'DEBUGGING_PRINTED' , 1 ); // indicates we have printed something
2008-06-13 17:51:34 +00:00
}
2009-07-13 06:16:48 +00:00
echo '<div class="notifytiny">' . $message . $from . '</div>' ;
2009-06-26 09:06:16 +00:00
} else {
trigger_error ( $message . $from , E_USER_NOTICE );
2008-06-13 17:51:34 +00:00
}
}
2009-06-26 09:06:16 +00:00
return true ;
2008-06-13 17:51:34 +00:00
}
2006-09-23 09:38:39 +00:00
/**
* Disable debug messages from debugging (), while keeping PHP error reporting level as is .
2009-05-22 03:26:07 +00:00
*
* @ global object
2006-09-23 09:38:39 +00:00
*/
function disable_debugging () {
global $CFG ;
$CFG -> debug = $CFG -> debug | 0x80000000 ; // switch the sign bit in integer number ;-)
}
2007-01-04 04:57:50 +00:00
2007-01-05 04:51:46 +00:00
/**
2007-01-04 04:57:50 +00:00
* Returns string to add a frame attribute , if required
2009-05-22 03:26:07 +00:00
*
* @ global object
* @ return bool
2007-01-04 04:57:50 +00:00
*/
function frametarget () {
global $CFG ;
if ( empty ( $CFG -> framename ) or ( $CFG -> framename == '_top' )) {
return '' ;
} else {
return ' target="' . $CFG -> framename . '" ' ;
}
}
2007-03-23 08:01:01 +00:00
/**
* Outputs a HTML comment to the browser . This is used for those hard - to - debug
* pages that use bits from many different files in very confusing ways ( e . g . blocks ) .
2009-05-22 03:26:07 +00:00
*
* < code > print_location_comment ( __FILE__ , __LINE__ ); </ code >
*
2007-03-23 08:01:01 +00:00
* @ param string $file
* @ param integer $line
* @ param boolean $return Whether to return or print the comment
2009-05-22 03:26:07 +00:00
* @ return string | void Void unless true given as third parameter
2007-03-23 08:01:01 +00:00
*/
function print_location_comment ( $file , $line , $return = false )
{
if ( $return ) {
return " <!-- $file at line $line --> \n " ;
} else {
echo " <!-- $file at line $line --> \n " ;
}
}
2007-05-09 15:03:01 +00:00
2007-07-04 10:01:20 +00:00
2007-08-17 07:25:47 +00:00
/**
2009-07-01 05:54:26 +00:00
* @ return boolean true if the current language is right - to - left ( Hebrew , Arabic etc )
2007-08-09 08:40:02 +00:00
*/
function right_to_left () {
static $result ;
2009-07-01 05:54:26 +00:00
if ( ! isset ( $result )) {
$result = get_string ( 'thisdirection' ) == 'rtl' ;
2007-08-09 08:40:02 +00:00
}
2009-07-01 05:54:26 +00:00
return $result ;
2007-08-09 08:40:02 +00:00
}
/**
* Returns swapped left <=> right if in RTL environment .
* part of RTL support
*
* @ param string $align align to check
* @ return string
*/
function fix_align_rtl ( $align ) {
2008-01-13 08:30:39 +00:00
if ( ! right_to_left ()) {
2007-08-17 07:25:47 +00:00
return $align ;
2007-08-09 08:40:02 +00:00
}
2008-01-13 08:30:39 +00:00
if ( $align == 'left' ) { return 'right' ; }
if ( $align == 'right' ) { return 'left' ; }
return $align ;
2007-08-09 08:40:02 +00:00
}
2007-11-10 14:53:54 +00:00
/**
* Returns true if the page is displayed in a popup window .
* Gets the information from the URL parameter inpopup .
*
2009-05-22 03:26:07 +00:00
* @ todo Use a central function to create the popup calls allover Moodle and
* In the moment only works with resources and probably questions .
2007-11-10 14:53:54 +00:00
*
2009-05-22 03:26:07 +00:00
* @ return boolean
2007-11-10 14:53:54 +00:00
*/
2007-11-12 11:17:24 +00:00
function is_in_popup () {
2007-11-10 14:53:54 +00:00
$inpopup = optional_param ( 'inpopup' , '' , PARAM_BOOL );
2008-01-13 08:30:39 +00:00
2007-11-10 14:53:54 +00:00
return ( $inpopup );
}
2009-01-10 20:44:45 +00:00
2009-04-08 11:46:19 +00:00
/**
* To use this class .
* - construct
* - call create ( or use the 3 rd param to the constructor )
* - call update or update_full repeatedly
2009-05-22 03:26:07 +00:00
*
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ package moodlecore
2009-04-08 11:46:19 +00:00
*/
2008-07-04 10:15:00 +00:00
class progress_bar {
2009-09-18 03:50:46 +00:00
/** @var string html id */
2008-07-04 10:15:00 +00:00
private $html_id ;
2009-09-18 03:50:46 +00:00
/** @var int */
2008-07-04 10:15:00 +00:00
private $percent ;
2009-09-18 03:50:46 +00:00
/** @var int */
2008-07-04 10:15:00 +00:00
private $width ;
2009-09-18 03:50:46 +00:00
/** @var int */
2008-07-04 10:15:00 +00:00
private $lastcall ;
2009-09-18 03:50:46 +00:00
/** @var int */
2008-07-04 10:15:00 +00:00
private $time_start ;
private $minimum_time = 2 ; //min time between updates.
2009-05-22 03:26:07 +00:00
/**
* Contructor
*
* @ param string $html_id
* @ param int $width
* @ param bool $autostart Default to false
*/
2009-09-18 03:50:46 +00:00
public function __construct ( $html_id = '' , $width = 500 , $autostart = false ){
if ( ! empty ( $html_id )) {
$this -> html_id = $html_id ;
} else {
$this -> html_id = uniqid ();
}
2008-07-04 10:15:00 +00:00
$this -> width = $width ;
$this -> restart ();
if ( $autostart ){
$this -> create ();
}
}
/**
2009-05-22 03:26:07 +00:00
* Create a new progress bar , this function will output html .
2009-08-04 02:05:32 +00:00
*
2009-05-22 03:26:07 +00:00
* @ return void Echo ' s output
2008-07-04 10:15:00 +00:00
*/
2009-09-18 03:50:46 +00:00
public function create (){
2008-07-04 10:15:00 +00:00
flush ();
$this -> lastcall -> pt = 0 ;
$this -> lastcall -> time = microtime ( true );
2009-05-26 17:44:25 +00:00
if ( CLI_SCRIPT ) {
return ; // temporary solution for cli scripts
}
2008-07-04 10:15:00 +00:00
$htmlcode = <<< EOT
< div style = " text-align:center;width: { $this -> width } px;clear:both;padding:0;margin:0 auto; " >
< h2 id = " status_ { $this -> html_id } " style = " text-align: center;margin:0 auto " ></ h2 >
< p id = " time_ { $this -> html_id } " ></ p >
< div id = " bar_ { $this -> html_id } " style = " border-style:solid;border-width:1px;width:500px;height:50px; " >
< div id = " progress_ { $this -> html_id } "
2009-09-18 03:50:46 +00:00
style = " text-align:center;background:#FFCC66;width:4px;border:1px
2008-07-04 10:15:00 +00:00
solid gray ; height : 38 px ; padding - top : 10 px ; " > <span id= " pt_ { $this -> html_id } " ></span>
</ div >
</ div >
</ div >
EOT ;
echo $htmlcode ;
flush ();
}
2009-05-22 03:26:07 +00:00
/**
* Update the progress bar
*
* @ param int $percent from 1 - 100
* @ param string $msg
* @ param mixed $es
* @ return void Echo ' s output
*/
2009-09-18 03:50:46 +00:00
private function _update ( $percent , $msg , $es ){
2009-07-02 03:47:05 +00:00
global $PAGE ;
2008-07-04 10:15:00 +00:00
if ( empty ( $this -> time_start )){
$this -> time_start = microtime ( true );
}
$this -> percent = $percent ;
$this -> lastcall -> time = microtime ( true );
$this -> lastcall -> pt = $percent ;
$w = $this -> percent * $this -> width ;
2009-05-26 17:44:25 +00:00
if ( CLI_SCRIPT ) {
return ; // temporary solution for cli scripts
}
2008-07-04 10:15:00 +00:00
if ( $es === null ){
$es = " Infinity " ;
}
2009-09-18 03:50:46 +00:00
echo $PAGE -> requires -> js_function_call ( 'update_progress_bar' , Array ( $this -> html_id , $w , $this -> percent , $msg , $es )) -> asap ();
2008-07-04 10:15:00 +00:00
flush ();
}
/**
* estimate time
2008-07-14 02:32:59 +00:00
*
2009-05-22 03:26:07 +00:00
* @ param int $curtime the time call this function
* @ param int $percent from 1 - 100
* @ return mixed Null , or int
2008-07-04 10:15:00 +00:00
*/
2009-09-18 03:50:46 +00:00
private function estimate ( $curtime , $pt ){
2008-07-04 10:15:00 +00:00
$consume = $curtime - $this -> time_start ;
$one = $curtime - $this -> lastcall -> time ;
$this -> percent = $pt ;
2008-07-14 02:32:59 +00:00
$percent = $pt - $this -> lastcall -> pt ;
2009-04-08 11:46:19 +00:00
if ( $percent != 0 ) {
2008-07-04 10:15:00 +00:00
$left = ( $one / $percent ) - $consume ;
2009-04-08 11:46:19 +00:00
} else {
2008-07-04 10:15:00 +00:00
return null ;
2009-04-08 11:46:19 +00:00
}
if ( $left < 0 ) {
2008-07-04 10:15:00 +00:00
return 0 ;
2009-04-08 11:46:19 +00:00
} else {
2008-07-04 10:15:00 +00:00
return $left ;
2009-04-08 11:46:19 +00:00
}
2008-07-04 10:15:00 +00:00
}
/**
* Update progress bar according percent
2008-07-14 02:32:59 +00:00
*
2009-05-22 03:26:07 +00:00
* @ param int $percent from 1 - 100
* @ param string $msg the message needed to be shown
2008-07-04 10:15:00 +00:00
*/
2009-09-18 03:50:46 +00:00
public function update_full ( $percent , $msg ){
2008-07-04 10:15:00 +00:00
$percent = max ( min ( $percent , 100 ), 0 );
if ( $percent != 100 && ( $this -> lastcall -> time + $this -> minimum_time ) > microtime ( true )){
return ;
}
$this -> _update ( $percent / 100 , $msg );
}
/**
* Update progress bar according the nubmer of tasks
2008-07-14 02:32:59 +00:00
*
2009-05-22 03:26:07 +00:00
* @ param int $cur current task number
* @ param int $total total task number
* @ param string $msg message
2008-07-04 10:15:00 +00:00
*/
2009-09-18 03:50:46 +00:00
public function update ( $cur , $total , $msg ){
2008-07-04 10:15:00 +00:00
$cur = max ( $cur , 0 );
if ( $cur >= $total ){
2008-07-14 02:32:59 +00:00
$percent = 1 ;
2008-07-04 10:15:00 +00:00
} else {
$percent = $cur / $total ;
}
2008-09-17 07:02:08 +00:00
/**
2008-07-04 10:15:00 +00:00
if ( $percent != 1 && ( $this -> lastcall -> time + $this -> minimum_time ) > microtime ( true )){
return ;
}
2008-09-17 07:02:08 +00:00
*/
2008-07-04 10:15:00 +00:00
$es = $this -> estimate ( microtime ( true ), $percent );
$this -> _update ( $percent , $msg , $es );
}
/**
* Restart the progress bar .
*/
2009-09-18 03:50:46 +00:00
public function restart (){
2008-07-04 10:15:00 +00:00
$this -> percent = 0 ;
$this -> lastcall = new stdClass ;
$this -> lastcall -> pt = 0 ;
$this -> lastcall -> time = microtime ( true );
$this -> time_start = 0 ;
}
}
2007-11-10 14:53:54 +00:00
2009-02-12 08:33:42 +00:00
/**
* Use this class from long operations where you want to output occasional information about
* what is going on , but don ' t know if , or in what format , the output should be .
2009-05-22 03:26:07 +00:00
*
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ package moodlecore
2009-02-12 08:33:42 +00:00
*/
abstract class moodle_progress_trace {
/**
* Ouput an progress message in whatever format .
* @ param string $message the message to output .
* @ param integer $depth indent depth for this message .
*/
abstract public function output ( $message , $depth = 0 );
/**
* Called when the processing is finished .
*/
public function finished () {
}
}
/**
* This subclass of moodle_progress_trace does not ouput anything .
2009-05-22 03:26:07 +00:00
*
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ package moodlecore
2009-02-12 08:33:42 +00:00
*/
class null_progress_trace extends moodle_progress_trace {
2009-05-22 03:26:07 +00:00
/**
* Does Nothing
*
* @ param string $message
* @ param int $depth
* @ return void Does Nothing
*/
2009-02-12 08:33:42 +00:00
public function output ( $message , $depth = 0 ) {
}
}
/**
* This subclass of moodle_progress_trace outputs to plain text .
2009-05-22 03:26:07 +00:00
*
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ package moodlecore
2009-02-12 08:33:42 +00:00
*/
class text_progress_trace extends moodle_progress_trace {
2009-05-22 03:26:07 +00:00
/**
* Output the trace message
*
* @ param string $message
* @ param int $depth
* @ return void Output is echo ' d
*/
2009-02-12 08:33:42 +00:00
public function output ( $message , $depth = 0 ) {
echo str_repeat ( ' ' , $depth ), $message , " \n " ;
flush ();
}
}
/**
* This subclass of moodle_progress_trace outputs as HTML .
2009-05-22 03:26:07 +00:00
*
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ package moodlecore
2009-02-12 08:33:42 +00:00
*/
class html_progress_trace extends moodle_progress_trace {
2009-05-22 03:26:07 +00:00
/**
* Output the trace message
*
* @ param string $message
* @ param int $depth
* @ return void Output is echo ' d
*/
2009-02-12 08:33:42 +00:00
public function output ( $message , $depth = 0 ) {
echo '<p>' , str_repeat ( '  ' , $depth ), htmlspecialchars ( $message ), " </p> \n " ;
flush ();
}
}
2009-05-22 03:26:07 +00:00
/**
* HTML List Progress Tree
*
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ package moodlecore
*/
2009-02-12 08:33:42 +00:00
class html_list_progress_trace extends moodle_progress_trace {
2009-05-22 03:26:07 +00:00
/** @var int */
2009-02-12 08:33:42 +00:00
protected $currentdepth = - 1 ;
2009-05-22 03:26:07 +00:00
/**
* Echo out the list
*
* @ param string $message The message to display
* @ param int $depth
* @ return void Output is echoed
*/
2009-02-12 08:33:42 +00:00
public function output ( $message , $depth = 0 ) {
$samedepth = true ;
while ( $this -> currentdepth > $depth ) {
echo " </li> \n </ul> \n " ;
$this -> currentdepth -= 1 ;
if ( $this -> currentdepth == $depth ) {
echo '<li>' ;
}
$samedepth = false ;
}
while ( $this -> currentdepth < $depth ) {
echo " <ul> \n <li> " ;
$this -> currentdepth += 1 ;
$samedepth = false ;
}
if ( $samedepth ) {
echo " </li> \n <li> " ;
}
echo htmlspecialchars ( $message );
flush ();
}
2009-05-22 03:26:07 +00:00
/**
* Called when the processing is finished .
*/
2009-02-12 08:33:42 +00:00
public function finished () {
while ( $this -> currentdepth >= 0 ) {
echo " </li> \n </ul> \n " ;
$this -> currentdepth -= 1 ;
}
}
}
2009-05-14 07:03:27 +00:00
/**
* Return the authentication plugin title
2009-05-22 03:26:07 +00:00
*
2009-05-14 07:03:27 +00:00
* @ param string $authtype plugin type
* @ return string
*/
2009-06-17 08:50:16 +00:00
function auth_get_plugin_title ( $authtype ) {
2009-05-14 07:03:27 +00:00
$authtitle = get_string ( " auth_ { $authtype } title " , " auth " );
if ( $authtitle == " [[auth_ { $authtype } title]] " ) {
$authtitle = get_string ( " auth_ { $authtype } title " , " auth_ { $authtype } " );
}
return $authtitle ;
}