libdir/filterlib.php");
require_once("$CFG->libdir/ajax/ajaxlib.php");
/// Constants
/// Define text formatting types ... eventually we can add Wiki, BBcode etc
/**
* Does all sorts of transformations and filtering
*/
define('FORMAT_MOODLE', '0'); // Does all sorts of transformations and filtering
/**
* Plain HTML (with some tags stripped)
*/
define('FORMAT_HTML', '1'); // Plain HTML (with some tags stripped)
/**
* Plain text (even tags are printed in full)
*/
define('FORMAT_PLAIN', '2'); // Plain text (even tags are printed in full)
/**
* Wiki-formatted text
* 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)
*/
define('FORMAT_WIKI', '3'); // Wiki-formatted text
/**
* Markdown-formatted text http://daringfireball.net/projects/markdown/
*/
define('FORMAT_MARKDOWN', '4'); // Markdown-formatted text http://daringfireball.net/projects/markdown/
/**
* TRUSTTEXT marker - if present in text, text cleaning should be bypassed
*/
define('TRUSTTEXT', '#####TRUSTTEXT#####');
/**
* Javascript related defines
*/
define('REQUIREJS_BEFOREHEADER', 0);
define('REQUIREJS_INHEADER', 1);
define('REQUIREJS_AFTERHEADER', 2);
/**
* Allowed tags - string of html tags that can be tested against for safe html tags
* @global string $ALLOWED_TAGS
*/
global $ALLOWED_TAGS;
$ALLOWED_TAGS =
'
';
return implode("\n", $menu);
}
/**
* Prints form items with the names $day, $month and $year
*
* @param string $day fieldname
* @param string $month fieldname
* @param string $year fieldname
* @param int $currenttime A default timestamp in GMT
* @param boolean $return
*/
function print_date_selector($day, $month, $year, $currenttime=0, $return=false) {
if (!$currenttime) {
$currenttime = time();
}
$currentdate = usergetdate($currenttime);
for ($i=1; $i<=31; $i++) {
$days[$i] = $i;
}
for ($i=1; $i<=12; $i++) {
$months[$i] = userdate(gmmktime(12,0,0,$i,15,2000), "%B");
}
for ($i=1970; $i<=2020; $i++) {
$years[$i] = $i;
}
// Build or print result
$result='';
// Note: There should probably be a fieldset around these fields as they are
// clearly grouped. However this causes problems with display. See Mozilla
// bug 474415
$result.='';
$result.=choose_from_menu($days, $day, $currentdate['mday'], '', '', '0', true);
$result.='';
$result.=choose_from_menu($months, $month, $currentdate['mon'], '', '', '0', true);
$result.='';
$result.=choose_from_menu($years, $year, $currentdate['year'], '', '', '0', true);
if ($return) {
return $result;
} else {
echo $result;
}
}
/**
*Prints form items with the names $hour and $minute
*
* @param string $hour fieldname
* @param string ? $minute fieldname
* @param $currenttime A default timestamp in GMT
* @param int $step minute spacing
* @param boolean $return
*/
function print_time_selector($hour, $minute, $currenttime=0, $step=5, $return=false) {
if (!$currenttime) {
$currenttime = time();
}
$currentdate = usergetdate($currenttime);
if ($step != 1) {
$currentdate['minutes'] = ceil($currentdate['minutes']/$step)*$step;
}
for ($i=0; $i<=23; $i++) {
$hours[$i] = sprintf("%02d",$i);
}
for ($i=0; $i<=59; $i+=$step) {
$minutes[$i] = sprintf("%02d",$i);
}
// Build or print result
$result='';
// Note: There should probably be a fieldset around these fields as they are
// clearly grouped. However this causes problems with display. See Mozilla
// bug 474415
$result.='';
$result.=choose_from_menu($hours, $hour, $currentdate['hours'], '','','0',true);
$result.='';
$result.=choose_from_menu($minutes, $minute, $currentdate['minutes'], '','','0',true);
if ($return) {
return $result;
} else {
echo $result;
}
}
/**
* Prints time limit value selector
*
* @uses $CFG
* @param int $timelimit default
* @param string $unit
* @param string $name
* @param boolean $return
*/
function print_timer_selector($timelimit = 0, $unit = '', $name = 'timelimit', $return=false) {
global $CFG;
if ($unit) {
$unit = ' '.$unit;
}
// Max timelimit is sessiontimeout - 10 minutes.
$maxvalue = ($CFG->sessiontimeout / 60) - 10;
for ($i=1; $i<=$maxvalue; $i++) {
$minutes[$i] = $i.$unit;
}
return choose_from_menu($minutes, $name, $timelimit, get_string('none'), '','','0',$return);
}
/**
* Prints a grade menu (as part of an existing form) with help
* Showing all possible numerical grades and scales
*
* @uses $CFG
* @param int $courseid ?
* @param string $name ?
* @param string $current ?
* @param boolean $includenograde ?
* @todo Finish documenting this function
*/
function print_grade_menu($courseid, $name, $current, $includenograde=true, $return=false) {
global $CFG;
$output = '';
$strscale = get_string('scale');
$strscales = get_string('scales');
$scales = get_scales_menu($courseid);
foreach ($scales as $i => $scalename) {
$grades[-$i] = $strscale .': '. $scalename;
}
if ($includenograde) {
$grades[0] = get_string('nograde');
}
for ($i=100; $i>=1; $i--) {
$grades[$i] = $i;
}
$output .= choose_from_menu($grades, $name, $current, '', '', 0, true);
$linkobject = '';
$output .= link_to_popup_window ('/course/scales.php?id='. $courseid .'&list=true', 'ratingscales',
$linkobject, 400, 500, $strscales, 'none', true);
if ($return) {
return $output;
} else {
echo $output;
}
}
/**
* Prints a scale menu (as part of an existing form) including help button
* Just like {@link print_grade_menu()} but without the numeric grades
*
* @param int $courseid ?
* @param string $name ?
* @param string $current ?
* @todo Finish documenting this function
*/
function print_scale_menu($courseid, $name, $current, $return=false) {
global $CFG;
$output = '';
$strscales = get_string('scales');
$output .= choose_from_menu(get_scales_menu($courseid), $name, $current, '', '', 0, true);
$linkobject = '';
$output .= link_to_popup_window ('/course/scales.php?id='. $courseid .'&list=true', 'ratingscales',
$linkobject, 400, 500, $strscales, 'none', true);
if ($return) {
return $output;
} else {
echo $output;
}
}
/**
* Prints a help button about a scale
*
* @uses $CFG
* @param id $courseid ?
* @param object $scale ?
* @todo Finish documenting this function
*/
function print_scale_menu_helpbutton($courseid, $scale, $return=false) {
global $CFG;
$output = '';
$strscales = get_string('scales');
$linkobject = '';
$output .= link_to_popup_window ('/course/scales.php?id='. $courseid .'&list=true&scaleid='. $scale->id, 'ratingscale',
$linkobject, 400, 500, $scale->name, 'none', true);
if ($return) {
return $output;
} else {
echo $output;
}
}
/**
* Print an error page displaying an error message. New method - use this for new code.
*
* @param string $errorcode The name of the string from error.php to print
* @param string $module name of module
* @param string $link The url where the user will be prompted to continue. If no url is provided the user will be directed to the site index page.
* @param object $a Extra words and phrases that might be required in the error string
* @return terminates script, does not return!
*/
function print_error($errorcode, $module='error', $link='', $a=NULL) {
global $CFG, $UNITTEST;
// If unittest running, throw exception instead
if (!empty($UNITTEST->running)) {
// Errors in unit test become exceptions, so you can unit test
// code that might call error().
throw new moodle_exception($errorcode, $module, $link, $a);
}
if (empty($module) || $module == 'moodle' || $module == 'core') {
$module = 'error';
}
if (!isset($CFG->theme) or !isset($CFG->stylesheets)) {
// error found before setup.php finished
_print_early_error($errorcode, $module, $a);
} else {
_print_normal_error($errorcode, $module, $a, $link, debug_backtrace());
}
}
/**
* Internal function - do not use directly!!
*/
function _print_normal_error($errorcode, $module, $a, $link, $backtrace, $debuginfo=null, $showerrordebugwarning=false) {
global $CFG, $SESSION, $THEME, $DB, $PAGE;
if ($DB) {
//if you enable db debugging and exception is thrown, the print footer prints a lot of rubbish
$DB->set_debug(0);
}
if ($module === 'error') {
$modulelink = 'moodle';
} else {
$modulelink = $module;
}
$message = get_string($errorcode, $module, $a);
if ($module === 'error' and strpos($message, '[[') === 0) {
//search in moodle file if error specified - needed for backwards compatibility
$message = get_string($errorcode, 'moodle', $a);
}
if (CLI_SCRIPT) {
// Errors in cron should be mtrace'd.
mtrace($message);
die;
}
if (empty($link) and !defined('ADMIN_EXT_HEADER_PRINTED')) {
if ( !empty($SESSION->fromurl) ) {
$link = $SESSION->fromurl;
unset($SESSION->fromurl);
} else {
$link = $CFG->wwwroot .'/';
}
}
if (!empty($CFG->errordocroot)) {
$errordocroot = $CFG->errordocroot;
} else if (!empty($CFG->docroot)) {
$errordocroot = $CFG->docroot;
} else {
$errordocroot = 'http://docs.moodle.org';
}
if (!$PAGE->headerprinted) {
//header not yet printed
@header('HTTP/1.0 404 Not Found');
print_header(get_string('error'));
} else {
print_container_end_all(false, $THEME->open_header_containers);
}
echo ' ';
$message = clean_text('
');
print_simple_box($message, '', '', '', '', 'errorbox');
if ($showerrordebugwarning) {
debugging('error() is a deprecated function, please call print_error() instead of error()', DEBUG_DEVELOPER);
} else {
if (debugging('', DEBUG_DEVELOPER)) {
if ($debuginfo) {
debugging($debuginfo, DEBUG_DEVELOPER, $backtrace);
} else {
notify('Stack trace:'.print_backtrace($backtrace, true), 'notifytiny');
}
}
}
if (!empty($link)) {
print_continue($link);
}
print_footer();
for ($i=0;$i<512;$i++) { // Padding to help IE work with 404
echo ' ';
}
die;
}
/**
* Internal function - do not use directly!!
* This function is used if fatal error occures before the themes are fully initialised (eg. in lib/setup.php)
*/
function _print_early_error($errorcode, $module, $a, $backtrace=null, $debuginfo=null) {
$message = get_string($errorcode, $module, $a);
if ($module === 'error' and strpos($message, '[[') === 0) {
//search in moodle file if error specified - needed for backwards compatibility
$message = get_string($errorcode, 'moodle', $a);
}
$message = clean_text($message);
// In the name of protocol correctness, monitoring and performance
// profiling, set the appropriate error headers for machine comsumption
if (isset($_SERVER['SERVER_PROTOCOL'])) {
// Avoid it with cron.php. Note that we assume it's HTTP/1.x
@header($_SERVER['SERVER_PROTOCOL'] . ' 503 Service Unavailable');
}
// better disable any caching
@header('Content-Type: text/html; charset=utf-8');
@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');
echo '
'.get_string('error').'
'.$message.'
';
if (debugging('', DEBUG_DEVELOPER)) {
if ($debuginfo) {
debugging($debuginfo, DEBUG_DEVELOPER, $backtrace);
} else if ($backtrace) {
notify('Stack trace:'.print_backtrace($backtrace, true), 'notifytiny');
}
}
echo '';
die;
}
/**
* 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:
*
* do_somethting() or mdie("Something went wrong");
*
* @param string $msg Error message
* @param integer $errorcode Error code to emit
*/
function mdie($msg='', $errorcode=1) {
trigger_error($msg);
exit($errorcode);
}
/**
* 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.
* @param mixed $helptopics variable amount of params accepted. Each param may be a string or an array of arguments for
* helpbutton.
* @return string
*/
function editorhelpbutton(){
global $CFG, $SESSION;
$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");
} else if (is_string($item)) {
$urlparams[] = "button$i=".urlencode($item);
switch ($item) {
case 'reading' :
$titles[] = get_string("helpreading");
break;
case 'writing' :
$titles[] = get_string("helpwriting");
break;
case 'questions' :
$titles[] = get_string("helpquestions");
break;
case 'emoticons2' :
$titles[] = get_string("helpemoticons");
break;
case 'richtext2' :
$titles[] = get_string('helprichtext');
break;
case 'text2' :
$titles[] = get_string('helptext');
break;
default :
print_error('unknownhelp', '', '', $item);
}
}
$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);
$paramstring = join('&', $urlparams);
$linkobject = '';
return link_to_popup_window(s('/lib/form/editorhelp.php?'.$paramstring), 'popup', $linkobject, 400, 500, $alttag, 'none', true);
}
/**
* Print a help button.
*
* @uses $CFG
* @param string $page The keyword that defines a help page
* @param string $title The title of links, rollover tips, alt tags etc
* 'Help with' (or the language equivalent) will be prefixed and '...' will be stripped.
* @param string $module Which module is the page defined in
* @param mixed $image Use a help image for the link? (true/false/"both")
* @param boolean $linktext If true, display the title next to the help icon.
* @param string $text If defined then this text is used in the page, and
* the $page variable is ignored.
* @param boolean $return If true then the output is returned as a string, if false it is printed to the current page.
* @param string $imagetext The full text for the helpbutton icon. If empty use default help.gif
* @return string
* @todo Finish documenting this function
*/
function helpbutton($page, $title, $module='moodle', $image=true, $linktext=false, $text='', $return=false,
$imagetext='') {
global $CFG, $COURSE;
//warning if ever $text parameter is used
//$text option won't work properly because the text needs to be always cleaned and,
// when cleaned... html tags always break, so it's unusable.
if ( isset($text) && $text!='') {
debugging('Warning: it\'s not recommended to use $text parameter in helpbutton ($page=' . $page . ', $module=' . $module . ') function', DEBUG_DEVELOPER);
}
// Catch references to the old text.html and emoticons.html help files that
// were renamed in MDL-13233.
if (in_array($page, array('text', 'emoticons', 'richtext'))) {
$oldname = $page;
$page .= '2';
debugging("You are referring to the old help file '$oldname'. " .
"This was renamed to '$page' becuase of MDL-13233. " .
"Please update your code.", DEBUG_DEVELOPER);
}
if ($module == '') {
$module = 'moodle';
}
if ($title == '' && $linktext == '') {
debugging('Error in call to helpbutton function: at least one of $title and $linktext is required');
}
// Warn users about new window for Accessibility
$tooltip = get_string('helpprefix2', '', trim($title, ". \t")) .' ('.get_string('newwindow').')';
$linkobject = '';
if ($image) {
if ($linktext) {
// MDL-7469 If text link is displayed with help icon, change to alt to "help with this".
$linkobject .= $title.' ';
$tooltip = get_string('helpwiththis');
}
if ($imagetext) {
$linkobject .= $imagetext;
} else {
$linkobject .= '';
}
} else {
$linkobject .= $tooltip;
}
// fix for MDL-7734
if ($text) {
$url = '/help.php?text='. s(urlencode($text));
} else {
$url = '/help.php?module='. $module .'&file='. $page .'.html';
// fix for MDL-7734
if (!empty($COURSE->lang)) {
$url .= '&forcelang=' . $COURSE->lang;
}
}
$link = '' . link_to_popup_window($url, 'popup',
$linkobject, 400, 500, $tooltip, 'none', true) . '';
if ($return) {
return $link;
} else {
echo $link;
}
}
/**
* Print a help button.
*
* Prints a special help button that is a link to the "live" emoticon popup
* @uses $CFG
* @uses $SESSION
* @param string $form ?
* @param string $field ?
* @todo Finish documenting this function
*/
function emoticonhelpbutton($form, $field, $return = false) {
global $CFG, $SESSION;
$SESSION->inserttextform = $form;
$SESSION->inserttextfield = $field;
$imagetext = '';
$help = helpbutton('emoticons2', get_string('helpemoticons'), 'moodle', true, true, '', true, $imagetext);
if (!$return){
echo $help;
} else {
return $help;
}
}
/**
* Print a help button.
*
* Prints a special help button for html editors (htmlarea in this case)
* @uses $CFG
*/
function editorshortcutshelpbutton() {
global $CFG;
//TODO: detect current editor and print correct info
/* $imagetext = '';
return helpbutton('editorshortcuts', get_string('editorshortcutkeys'), 'moodle', true, false, '', true, $imagetext);*/
return '';
}
/**
* Print a message and exit.
*
* @uses $CFG
* @param string $message ?
* @param string $link ?
* @todo Finish documenting this function
*/
function notice ($message, $link='', $course=NULL) {
global $CFG, $SITE, $THEME, $COURSE, $PAGE;
$message = clean_text($message); // In case nasties are in here
if (CLI_SCRIPT) {
// notices in cron should be mtrace'd.
mtrace($message);
die;
}
if (!$PAGE->headerprinted) {
//header not yet printed
print_header(get_string('notice'));
} else {
print_container_end_all(false, $THEME->open_header_containers);
}
print_box($message, 'generalbox', 'notice');
print_continue($link);
if (empty($course)) {
print_footer($COURSE);
} else {
print_footer($course);
}
exit;
}
/**
* Print a message along with "Yes" and "No" links for the user to continue.
*
* @param string $message The text to display
* @param string $linkyes The link to take the user to if they choose "Yes"
* @param string $linkno The link to take the user to if they choose "No"
* TODO Document remaining arguments
*/
function notice_yesno ($message, $linkyes, $linkno, $optionsyes=NULL, $optionsno=NULL, $methodyes='post', $methodno='post') {
global $CFG;
$message = clean_text($message);
$linkyes = clean_text($linkyes);
$linkno = clean_text($linkno);
print_box_start('generalbox', 'notice');
echo '
';
print_box_end();
}
/**
* Redirects the user to another page, after printing a notice
*
* @param string $url The url to take the user to
* @param string $message The text message to display to the user about the redirect, if any
* @param string $delay How long before refreshing to the new page at $url?
* @todo '&' needs to be encoded into '&' for XHTML compliance,
* however, this is not true for javascript. Therefore we
* first decode all entities in $url (since we cannot rely on)
* the correct input) and then encode for where it's needed
* echo "";
*/
function redirect($url, $message='', $delay=-1) {
global $CFG, $THEME, $SESSION, $PAGE;
if (!empty($CFG->usesid) && !isset($_COOKIE[session_name()])) {
$url = $SESSION->sid_process_url($url);
}
$message = clean_text($message);
$encodedurl = preg_replace("/\&(?![a-zA-Z0-9#]{1,8};)/", "&", $url);
$encodedurl = preg_replace('/^.*href="([^"]*)".*$/', "\\1", clean_text(''));
$url = str_replace('&', '&', $encodedurl);
/// At developer debug level. Don't redirect if errors have been printed on screen.
/// Currenly only works in PHP 5.2+; we do not want strict PHP5 errors
$lasterror = error_get_last();
$error = defined('DEBUGGING_PRINTED') or (!empty($lasterror) && ($lasterror['type'] & DEBUG_DEVELOPER));
$errorprinted = debugging('', DEBUG_ALL) && $CFG->debugdisplay && $error;
if ($errorprinted) {
$message = "Error output, so disabling automatic redirect.
" . $message;
}
$performanceinfo = '';
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']);
}
}
/// when no message and header printed yet, try to redirect
if (empty($message) and !$PAGE->headerprinted) {
// Technically, HTTP/1.1 requires Location: header to contain
// the absolute path. (In practice browsers accept relative
// paths - but still, might as well do it properly.)
// This code turns relative into absolute.
if (!preg_match('|^[a-z]+:|', $url)) {
// Get host name http://www.wherever.com
$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;
} else {
// URLs not beginning with / are relative to path of current script, so add that on.
$url = $hostpart.preg_replace('|\?.*$|','',me()).'/../'.$url;
}
// Replace all ..s
while (true) {
$newurl = preg_replace('|/(?!\.\.)[^/]*/\.\./|', '/', $url);
if ($newurl == $url) {
break;
}
$url = $newurl;
}
}
$delay = 0;
//try header redirection first
@header($_SERVER['SERVER_PROTOCOL'] . ' 303 See Other'); //302 might not work for POST requests, 303 is ignored by obsolete clients
@header('Location: '.$url);
//another way for older browsers and already sent headers (eg trailing whitespace in config.php)
echo '';
print_js_call('document.location.replace', array($url));
die;
}
if ($delay == -1) {
$delay = 3; // if no delay specified wait 3 seconds
}
if (!$PAGE->headerprinted) {
// this type of redirect might not be working in some browsers - such as lynx :-(
print_header('', '', '', '', $errorprinted ? '' : (''));
$delay += 3; // double redirect prevention, it was sometimes breaking upgrades before 1.7
} else {
print_container_end_all(false, $THEME->open_header_containers);
}
echo '
';
if (!$errorprinted) {
print_delayed_js_call($delay, 'document.location.replace', array($url));
}
$CFG->docroot = false; // to prevent the link to moodle docs from being displayed on redirect page.
print_footer('none');
die;
}
/**
* Print a bold message in an optional color.
*
* @param string $message The message to print out
* @param string $style Optional style to display message text in
* @param string $align Alignment option
* @param bool $return whether to return an output string or echo now
*/
function notify($message, $style='notifyproblem', $align='center', $return=false) {
global $DB;
if ($style == 'green') {
$style = 'notifysuccess'; // backward compatible with old color system
}
$message = clean_text($message);
if (!CLI_SCRIPT) {
$output = '
'. $message .'
'."\n";
} else {
if ($style === 'notifysuccess') {
$output = '++'.$message.'++';
} else {
$output = '!!'.$message.'!!';
}
}
if ($return) {
return $output;
}
if (!CLI_SCRIPT) {
echo $output;
} else {
console_write($output."\n", '', false);
}
}
/**
* Given an email address, this function will return an obfuscated version of it
*
* @param string $email The email address to obfuscate
* @return string
*/
function obfuscate_email($email) {
$i = 0;
$length = strlen($email);
$obfuscated = '';
while ($i < $length) {
if (rand(0,2)) {
$obfuscated.='%'.dechex(ord($email{$i}));
} else {
$obfuscated.=$email{$i};
}
$i++;
}
return $obfuscated;
}
/**
* This function takes some text and replaces about half of the characters
* with HTML entity equivalents. Return string is obviously longer.
*
* @param string $plaintext The text to be obfuscated
* @return string
*/
function obfuscate_text($plaintext) {
$i=0;
$length = strlen($plaintext);
$obfuscated='';
$prev_obfuscated = false;
while ($i < $length) {
$c = ord($plaintext{$i});
$numerical = ($c >= ord('0')) && ($c <= ord('9'));
if ($prev_obfuscated and $numerical ) {
$obfuscated.=''.ord($plaintext{$i}).';';
} else if (rand(0,2)) {
$obfuscated.=''.ord($plaintext{$i}).';';
$prev_obfuscated = true;
} else {
$obfuscated.=$plaintext{$i};
$prev_obfuscated = false;
}
$i++;
}
return $obfuscated;
}
/**
* This function uses the {@link obfuscate_email()} and {@link obfuscate_text()}
* to generate a fully obfuscated email link, ready to use.
*
* @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
* @return string
*/
function obfuscate_mailto($email, $label='', $dimmed=false) {
if (empty($label)) {
$label = $email;
}
if ($dimmed) {
$title = get_string('emaildisable');
$dimmed = ' class="dimmed"';
} else {
$title = '';
$dimmed = '';
}
return sprintf("%s",
obfuscate_text('mailto'), obfuscate_email($email),
obfuscate_text($label));
}
/**
* Prints a single paging bar to provide access to other pages (usually in a search)
*
* @param int $totalcount Thetotal number of entries available to be paged through
* @param int $page The page you are currently viewing
* @param int $perpage The number of entries that should be shown per page
* @param mixed $baseurl If this is a string then it is the url which will be appended with $pagevar, an equals sign and the page number.
* If this is a moodle_url object then the pagevar param will be replaced by the page no, for each page.
* @param string $pagevar This is the variable name that you use for the page number in your code (ie. 'tablepage', 'blogpage', etc)
* @param bool $nocurr do not display the current page as a link
* @param bool $return whether to return an output string or echo now
* @return bool or string
*/
function print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar='page',$nocurr=false, $return=false) {
$maxdisplay = 18;
$output = '';
if ($totalcount > $perpage) {
$output .= '
';
}
if ($return) {
return $output;
}
echo $output;
return true;
}
/**
* This function is used to rebuild the tag because some formats (PLAIN and WIKI)
* will transform it to html entities
*
* @param string $text Text to search for nolink tag in
* @return string
*/
function rebuildnolinktag($text) {
$text = preg_replace('/<(\/*nolink)>/i','<$1>',$text);
return $text;
}
/**
* Prints a nice side block with an optional header. The content can either
* be a block of HTML or a list of text with optional icons.
*
* @param string $heading HTML for the heading. Can include full HTML or just
* plain text - plain text will automatically be enclosed in the appropriate
* heading tags.
* @param string $content HTML for the content
* @param array $list an alternative to $content, it you want a list of things with optional icons.
* @param array $icons optional icons for the things in $list.
* @param string $footer Extra HTML content that gets output at the end, inside a <div class="footer">
* @param array $attributes an array of attribute => value pairs that are put on the
* outer div of this block. If there is a class attribute ' sideblock' gets appended to it. If there isn't
* already a class, class='sideblock' is used.
* @param string $title Plain text title, as embedded in the $heading.
* @todo Finish documenting this function. Show example of various attributes, etc.
*/
function print_side_block($heading='', $content='', $list=NULL, $icons=NULL, $footer='', $attributes = array(), $title='') {
//Accessibility: skip block link, with title-text (or $block_id) to differentiate links.
static $block_id = 0;
$block_id++;
if (empty($heading)) {
$skip_text = get_string('skipblock', 'access').' '.$block_id;
}
else {
$skip_text = get_string('skipa', 'access', strip_tags($title));
}
$skip_link = ''.$skip_text.'';
$skip_dest = '';
if (! empty($heading)) {
echo $skip_link;
}
//ELSE: a single link on a page "Skip block 4" is too confusing - ignore.
print_side_block_start($heading, $attributes);
// The content.
if ($content) {
echo $content;
} else {
if ($list) {
$row = 0;
//Accessibility: replaced unnecessary table with list, see themes/standard/styles_layout.css
echo "\n
\n";
foreach ($list as $key => $string) {
echo '
';
if ($icons) {
echo '
'. $icons[$key] .'
';
}
echo '
'. $string .'
';
echo "
\n";
$row = $row ? 0:1;
}
echo "
\n";
}
}
// Footer, if any.
if ($footer) {
echo '';
}
print_side_block_end($attributes, $title);
echo $skip_dest;
}
/**
* Starts a nice side block with an optional header.
*
* @param string $heading HTML for the heading. Can include full HTML or just
* plain text - plain text will automatically be enclosed in the appropriate
* heading tags.
* @param array $attributes ?
* @todo Finish documenting this function
*/
function print_side_block_start($heading='', $attributes = array()) {
global $CFG, $THEME;
// If there are no special attributes, give a default CSS class
if (empty($attributes) || !is_array($attributes)) {
$attributes = array('class' => 'sideblock');
} else if(!isset($attributes['class'])) {
$attributes['class'] = 'sideblock';
} else if(!strpos($attributes['class'], 'sideblock')) {
$attributes['class'] .= ' sideblock';
}
// OK, the class is surely there and in addition to anything
// else, it's tagged as a sideblock
/*
// IE misery: if I do it this way, blocks which start hidden cannot be "unhidden"
// If there is a cookie to hide this thing, start it hidden
if (!empty($attributes['id']) && isset($_COOKIE['hide:'.$attributes['id']])) {
$attributes['class'] = 'hidden '.$attributes['class'];
}
*/
$attrtext = '';
foreach ($attributes as $attr => $val) {
$attrtext .= ' '.$attr.'="'.$val.'"';
}
echo '
';
if (!empty($THEME->customcorners)) {
echo '
'."\n";
}
if ($heading) {
// Some callers pass in complete html for the heading, which may include
// complicated things such as the 'hide block' button; some just pass in
// text. If they only pass in plain text i.e. it doesn't include a
//
, then we add in standard tags that make it look like a normal
// page block including the h2 for accessibility
if(strpos($heading,'
')===false) {
$heading='
'.$heading.'
';
}
echo '
';
if (!empty($THEME->customcorners)) {
echo '
';
echo '
';
echo '
';
}
echo $heading;
if (!empty($THEME->customcorners)) {
echo '
';
}
echo '
';
} else {
if (!empty($THEME->customcorners)) {
echo '
';
}
}
if (!empty($THEME->customcorners)) {
echo '
';
echo '
';
}
echo '
';
}
/**
* Print table ending tags for a side block box.
*/
function print_side_block_end($attributes = array(), $title='') {
global $CFG, $THEME;
echo '
';
if (!empty($THEME->customcorners)) {
echo '
';
}
echo '
';
$strshow = addslashes_js(get_string('showblocka', 'access', strip_tags($title)));
$strhide = addslashes_js(get_string('hideblocka', 'access', strip_tags($title)));
// IE workaround: if I do it THIS way, it works! WTF?
if (!empty($CFG->allowuserblockhiding) && isset($attributes['id'])) {
echo '';
}
}
/**
* @deprecated since Moodle 2.0 - use $PAGE->pagetype instead of the .
* @param string $getid used to return $PAGE->pagetype.
* @param string $getclass used to return $PAGE->legacyclass.
*/
function page_id_and_class(&$getid, &$getclass) {
global $PAGE;
debugging('Call to deprecated function page_id_and_class. Please use $PAGE->pagetype instead.', DEBUG_DEVELOPER);
$getid = $PAGE->pagetype;
$getclass = $PAGE->legacyclass;
}
/**
* Prints a maintenance message from /maintenance.html
*/
function print_maintenance_message () {
global $CFG, $SITE;
$PAGE->set_pagetype('maintenance-message');
print_header(strip_tags($SITE->fullname), $SITE->fullname, 'home');
print_box_start();
print_heading(get_string('sitemaintenance', 'admin'));
@include($CFG->dataroot.'/1/maintenance.html');
print_box_end();
print_footer();
}
/**
* Adjust the list of allowed tags based on $CFG->allowobjectembed and user roles (admin)
*/
function adjust_allowed_tags() {
global $CFG, $ALLOWED_TAGS;
if (!empty($CFG->allowobjectembed)) {
$ALLOWED_TAGS .= '