Code :
// Add a next page link
if ($num_pages > 1 && !$link_to_all && $cur_page < $num_pages)
$pages[] = '<a'.(empty($pages) ? ' class="item1"' : '').' href="'.$link.'&p='.($cur_page +1).'">'.$lang_common['Next'].'</a>';
}
return implode(' ', $pages);
}
//
// Display a message
//
function message($message, $no_back_link = false)
{
global $db, $lang_common, $pun_config, $pun_start, $tpl_main, $pun_user;
if (!defined('PUN_HEADER'))
{
$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Info']);
define('PUN_ACTIVE_PAGE', 'index');
require PUN_ROOT.'header.php';
}
?>
<div id="msg" class="block">
<h2><span><?php echo $lang_common['Info'] ?></span></h2>
<div class="box">
<div class="inbox">
<p><?php echo $message ?></p>
<?php if (!$no_back_link): ?> <p><a href="javascript: history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
<?php endif; ?> </div>
</div>
</div>
<?php
require PUN_ROOT.'footer.php';
}
//
// Format a time string according to $time_format and time zones
//
function format_time($timestamp, $date_only = false, $date_format = null, $time_format = null, $time_only = false, $no_text = false)
{
global $pun_config, $lang_common, $pun_user, $forum_date_formats, $forum_time_formats;
if ($timestamp == '')
return $lang_common['Never'];
$diff = ($pun_user['timezone'] + $pun_user['dst']) * 3600;
$timestamp += $diff;
$now = time();
if($date_format == null)
$date_format = $forum_date_formats[$pun_user['date_format']];
if($time_format == null)
$time_format = $forum_time_formats[$pun_user['time_format']];
$date = gmdate($date_format, $timestamp);
$today = gmdate($date_format, $now+$diff);
$yesterday = gmdate($date_format, $now+$diff-86400);
if(!$no_text)
{
if ($date == $today)
$date = $lang_common['Today'];
else if ($date == $yesterday)
$date = $lang_common['Yesterday'];
}
if ($date_only)
return $date;
else if ($time_only)
return gmdate($time_format, $timestamp);
else
return $date.' '.gmdate($time_format, $timestamp);
}
//
// A wrapper for PHP's number_format function
//
function forum_number_format($number, $decimals = 0)
{
global $lang_common;
return is_numeric($number) ? number_format($number, $decimals, $lang_common['lang_decimal_point'], $lang_common['lang_thousands_sep']) : $number;
}
//
// Generate a random key of length $len
//
function random_key($len, $readable = false, $hash = false)
{
$key = '';
if ($hash)
$key = substr(pun_hash(uniqid(rand(), true)), 0, $len);
else if ($readable)
{
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for ($i = 0; $i < $len; ++$i)
$key .= substr($chars, (mt_rand() % strlen($chars)), 1);
}
else
{
for ($i = 0; $i < $len; ++$i)
$key .= chr(mt_rand(33, 126));
}
return $key;
}
//
// Make sure that HTTP_REFERER matches base_url/script
//
function confirm_referrer($script, $error_msg = false)
{
global $pun_config, $lang_common;
// There is no referrer
if (empty($_SERVER['HTTP_REFERER']))
message($error_msg ? $error_msg : $lang_common['Bad referrer']);
$referrer = parse_url(strtolower($_SERVER['HTTP_REFERER']));
// Remove www subdomain if it exists
if (strpos($referrer['host'], 'www.') === 0)
$referrer['host'] = substr($referrer['host'], 4);
$valid = parse_url(strtolower(get_base_url().'/'.$script));
// Remove www subdomain if it exists
if (strpos($valid['host'], 'www.') === 0)
$valid['host'] = substr($valid['host'], 4);
// Check the host and path match. Ignore the scheme, port, etc.
if ($referrer['host'] != $valid['host'] || $referrer['path'] != $valid['path'])
message($error_msg ? $error_msg : $lang_common['Bad referrer']);
}
//
// Generate a random password of length $len
// Compatibility wrapper for random_key
//
function random_pass($len)
{
return random_key($len, true);
}
//
// Compute a hash of $str
//
function pun_hash($str)
{
return sha1($str);
}
//
// Try to determine the correct remote IP-address
//
function get_remote_address()
{
$remote_addr = $_SERVER['REMOTE_ADDR'];
// If we are behind a reverse proxy try to find the real users IP
if (defined('FORUM_BEHIND_REVERSE_PROXY'))
{
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
// The general format of the field is:
// X-Forwarded-For: client1, proxy1, proxy2
// where the value is a comma+space separated list of IP addresses, the left-most being the farthest downstream client,
// and each successive proxy that passed the request adding the IP address where it received the request from.
$remote_addr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$remote_addr = trim($remote_addr[0]);
}
}
return $remote_addr;
}
//
// Calls htmlspecialchars with a few options already set
//
function pun_htmlspecialchars($str)
{
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
//
// Calls htmlspecialchars_decode with a few options already set
//
function pun_htmlspecialchars_decode($str)
{
if (function_exists('htmlspecialchars_decode'))
return htmlspecialchars_decode($str, ENT_QUOTES);
static $translations;
if (!isset($translations))
{
$translations = get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES);
$translations['''] = '\''; // get_html_translation_table doesn't include ' which is what htmlspecialchars translates ' to, but apparently that is okay?! http://bugs.php.net/bug.php?id=25927
$translations = array_flip($translations);
}
return strtr($str, $translations);
}
//
// A wrapper for utf8_strlen for compatibility
//
function pun_strlen($str)
{
return utf8_strlen($str);
}
//
// Convert \r\n and \r to \n
//
function pun_linebreaks($str)
{
return str_replace("\r", "\n", str_replace("\r\n", "\n", $str));
}
//
// A wrapper for utf8_trim for compatibility
//
function pun_trim($str, $charlist = false)
{
return utf8_trim($str, $charlist);
}
//
// Checks if a string is in all uppercase
//
function is_all_uppercase($string)
{
return utf8_strtoupper($string) == $string && utf8_strtolower($string) != $string;
}
//
// Inserts $element into $input at $offset
// $offset can be either a numerical offset to insert at (eg: 0 inserts at the beginning of the array)
// or a string, which is the key that the new element should be inserted before
// $key is optional: it's used when inserting a new key/value pair into an associative array
//
function array_insert(&$input, $offset, $element, $key = null)
{
if ($key == null)
$key = $offset;
// Determine the proper offset if we're using a string
if (!is_int($offset))
$offset = array_search($offset, array_keys($input), true);
// Out of bounds checks
if ($offset > count($input))
$offset = count($input);
else if ($offset < 0)
$offset = 0;
$input = array_merge(array_slice($input, 0, $offset), array($key => $element), array_slice($input, $offset));
}
//
// Display a message when board is in maintenance mode
//
function maintenance_message()
{
global $db, $pun_config, $lang_common, $pun_user;
// Send no-cache headers
header('Expires: Thu, 21 Jul 1977 07:30:00 GMT'); // When yours truly first set eyes on this world! :)
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache'); // For HTTP/1.0 compatibility
// Send the Content-type header in case the web server is setup to send something else
header('Content-type: text/html; charset=utf-8');
// Deal with newlines, tabs and multiple spaces
$pattern = array("\t", ' ', ' ');
$replace = array(' ', ' ', ' ');
$message = str_replace($pattern, $replace, $pun_config['o_maintenance_message']);
if (file_exists(PUN_ROOT.'style/'.$pun_user['style'].'/maintenance.tpl'))
{
$tpl_file = PUN_ROOT.'style/'.$pun_user['style'].'/maintenance.tpl';
$tpl_inc_dir = PUN_ROOT.'style/'.$pun_user['style'].'/';
}
else
{
$tpl_file = PUN_ROOT.'include/template/maintenance.tpl';
$tpl_inc_dir = PUN_ROOT.'include/user/';
}
$tpl_maint = file_get_contents($tpl_file);
// START SUBST - <pun_include "*">
preg_match_all('#<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">#', $tpl_maint, $pun_includes, PREG_SET_ORDER);
foreach ($pun_includes as $cur_include)
{
ob_start();
// Allow for overriding user includes, too.
if (file_exists($tpl_inc_dir.$cur_include[1].'.'.$cur_include[2]))
require $tpl_inc_dir.$cur_include[1].'.'.$cur_include[2];
else if (file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]))
require PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2];
else
error(sprintf($lang_common['Pun include error'], htmlspecialchars($cur_include[0]), basename($tpl_file)));
$tpl_temp = ob_get_contents();
$tpl_maint = str_replace($cur_include[0], $tpl_temp, $tpl_maint);
ob_end_clean();
}
// END SUBST - <pun_include "*">
// START SUBST - <pun_language>
$tpl_maint = str_replace('<pun_language>', $lang_common['lang_identifier'], $tpl_maint);
// END SUBST - <pun_language>
// START SUBST - <pun_content_direction>
$tpl_maint = str_replace('<pun_content_direction>', $lang_common['lang_direction'], $tpl_maint);
// END SUBST - <pun_content_direction>
// START SUBST - <pun_head>
ob_start();
$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Maintenance']);
?>
<title><?php echo generate_page_title($page_title) ?></title>
<link rel="stylesheet" type="text/css" href="style/<?php echo $pun_user['style'].'.css' ?>" />
<?php
$tpl_temp = trim(ob_get_contents());
$tpl_maint = str_replace('<pun_head>', $tpl_temp, $tpl_maint);
ob_end_clean();
// END SUBST - <pun_head>
// START SUBST - <pun_maint_main>
ob_start();
?>
<div class="block">
<h2><?php echo $lang_common['Maintenance'] ?></h2>
<div class="box">
<div class="inbox">
<p><?php echo $message ?></p>
</div>
</div>
</div>
<?php
$tpl_temp = trim(ob_get_contents());
$tpl_maint = str_replace('<pun_maint_main>', $tpl_temp, $tpl_maint);
ob_end_clean();
// END SUBST - <pun_maint_main>
// End the transaction
$db->end_transaction();
// Close the db connexion (and free up any result data)
$db->close();
exit($tpl_maint);
}
//
// Display $message and redirect user to $destination_url
//
function redirect($destination_url, $message)
{
global $db, $pun_config, $lang_common, $pun_user;
// Prefix with base_url (unless there's already a valid URI)
if (strpos($destination_url, 'http://') !== 0 && strpos($destination_url, 'https://') !== 0 && strpos($destination_url, '/') !== 0)
$destination_url = get_base_url(true).'/'.$destination_url;
// Do a little spring cleaning
$destination_url = preg_replace('/([\r\n])|(%0[ad])|(;\s*data\s*:)/i', '', $destination_url);
// If the delay is 0 seconds, we might as well skip the redirect all together
if ($pun_config['o_redirect_delay'] == '0')
header('Location: '.str_replace('&', '&', $destination_url));
// Send no-cache headers
header('Expires: Thu, 21 Jul 1977 07:30:00 GMT'); // When yours truly first set eyes on this world! :)
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache'); // For HTTP/1.0 compatibility
// Send the Content-type header in case the web server is setup to send something else
header('Content-type: text/html; charset=utf-8');
if (file_exists(PUN_ROOT.'style/'.$pun_user['style'].'/redirect.tpl'))
{
$tpl_file = PUN_ROOT.'style/'.$pun_user['style'].'/redirect.tpl';
$tpl_inc_dir = PUN_ROOT.'style/'.$pun_user['style'].'/';
}
else
{
$tpl_file = PUN_ROOT.'include/template/redirect.tpl';
$tpl_inc_dir = PUN_ROOT.'include/user/';
}
$tpl_redir = file_get_contents($tpl_file);
// START SUBST - <pun_include "*">
preg_match_all('#<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">#', $tpl_redir, $pun_includes, PREG_SET_ORDER);
foreach ($pun_includes as $cur_include)
{
ob_start();
// Allow for overriding user includes, too.
if (file_exists($tpl_inc_dir.$cur_include[1].'.'.$cur_include[2]))
require $tpl_inc_dir.$cur_include[1].'.'.$cur_include[2];
else if (file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]))
require PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2];
else
error(sprintf($lang_common['Pun include error'], htmlspecialchars($cur_include[0]), basename($tpl_file)));
$tpl_temp = ob_get_contents();
$tpl_redir = str_replace($cur_include[0], $tpl_temp, $tpl_redir);
ob_end_clean();
}
// END SUBST - <pun_include "*">
// START SUBST - <pun_language>
$tpl_redir = str_replace('<pun_language>', $lang_common['lang_identifier'], $tpl_redir);
// END SUBST - <pun_language>
// START SUBST - <pun_content_direction>
$tpl_redir = str_replace('<pun_content_direction>', $lang_common['lang_direction'], $tpl_redir);
// END SUBST - <pun_content_direction>
// START SUBST - <pun_head>
ob_start();
$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Redirecting']);
?>
<meta http-equiv="refresh" content="<?php echo $pun_config['o_redirect_delay'] ?>;URL=<?php echo str_replace(array('<', '>', '"'), array('<', '>', '"'), $destination_url) ?>" />
<title><?php echo generate_page_title($page_title) ?></title>
<link rel="stylesheet" type="text/css" href="style/<?php echo $pun_user['style'].'.css' ?>" />
<?php
$tpl_temp = trim(ob_get_contents());
$tpl_redir = str_replace('<pun_head>', $tpl_temp, $tpl_redir);
ob_end_clean();
// END SUBST - <pun_head>
// START SUBST - <pun_redir_main>
ob_start();
?>
<div class="block">
<h2><?php echo $lang_common['Redirecting'] ?></h2>
<div class="box">
<div class="inbox">
<p><?php echo $message.'<br /><br /><a href="'.$destination_url.'">'.$lang_common['Click redirect'].'</a>' ?></p>
</div>
</div>
</div>
<?php
$tpl_temp = trim(ob_get_contents());
$tpl_redir = str_replace('<pun_redir_main>', $tpl_temp, $tpl_redir);
ob_end_clean();
// END SUBST - <pun_redir_main>
// START SUBST - <pun_footer>
ob_start();
// End the transaction
$db->end_transaction();
// Display executed queries (if enabled)
if (defined('PUN_SHOW_QUERIES'))
display_saved_queries();
$tpl_temp = trim(ob_get_contents());
$tpl_redir = str_replace('<pun_footer>', $tpl_temp, $tpl_redir);
ob_end_clean();
// END SUBST - <pun_footer>
// Close the db connexion (and free up any result data)
$db->close();
exit($tpl_redir);
}
//
// Display a simple error message
//
function error($message, $file = null, $line = null, $db_error = false)
{
global $pun_config, $lang_common;
// Set some default settings if the script failed before $pun_config could be populated
if (empty($pun_config))
{
$pun_config = array(
'o_board_title' => 'FluxBB',
'o_gzip' => '0'
);
}
// Set some default translations if the script failed before $lang_common could be populated
if (empty($lang_common))
{
$lang_common = array(
'Title separator' => ' / ',
'Page' => 'Page %s'
);
}
// Empty all output buffers and stop buffering
while (@ob_end_clean());
// "Restart" output buffering if we are using ob_gzhandler (since the gzip header is already sent)
if ($pun_config['o_gzip'] && extension_loaded('zlib'))
ob_start('ob_gzhandler');
// Send no-cache headers
header('Expires: Thu, 21 Jul 1977 07:30:00 GMT'); // When yours truly first set eyes on this world! :)
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache'); // For HTTP/1.0 compatibility
// Send the Content-type header in case the web server is setup to send something else
header('Content-type: text/html; charset=utf-8');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), 'Error') ?>
<title><?php echo generate_page_title($page_title) ?></title>
<style type="text/css">
<!--
BODY {MARGIN: 10% 20% auto 20%; font: 10px Verdana, Arial, Helvetica, sans-serif}
#errorbox {BORDER: 1px solid #B84623}
H2 {MARGIN: 0; COLOR: #FFFFFF; BACKGROUND-COLOR: #B84623; FONT-SIZE: 1.1em; PADDING: 5px 4px}
#errorbox DIV {PADDING: 6px 5px; BACKGROUND-COLOR: #F1F1F1}
-->
</style>
</head>
<body>
<div id="errorbox">
<h2>An error was encountered</h2>
<div>
<?php
if (defined('PUN_DEBUG') && $file !== null && $line !== null)
{
echo "\t\t".'<strong>File:</strong> '.$file.'<br />'."\n\t\t".'<strong>Line:</strong> '.$line.'<br /><br />'."\n\t\t".'<strong>FluxBB reported</strong>: '.$message."\n";
if ($db_error)
{
echo "\t\t".'<br /><br /><strong>Database reported:</strong> '.pun_htmlspecialchars($db_error['error_msg']).(($db_error['error_no']) ? ' (Errno: '.$db_error['error_no'].')' : '')."\n";
if ($db_error['error_sql'] != '')
echo "\t\t".'<br /><br /><strong>Failed query:</strong> '.pun_htmlspecialchars($db_error['error_sql'])."\n";
}
}
else
echo "\t\t".'Error: <strong>'.$message.'.</strong>'."\n";
?>
</div>
</div>
</body>
</html>
<?php
// If a database connexion was established (before this error) we close it
if ($db_error)
$GLOBALS['db']->close();
exit;
}
//
// Unset any variables instantiated as a result of register_globals being enabled
//
function forum_unregister_globals()
{
$register_globals = ini_get('register_globals');
if ($register_globals === '' || $register_globals === '0' || strtolower($register_globals) === 'off')
return;
// Prevent script.php?GLOBALS[foo]=bar
if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS']))
exit('I\'ll have a steak sandwich and... a steak sandwich.');
// Variables that shouldn't be unset
$no_unset = array('GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES');
// Remove elements in $GLOBALS that are present in any of the superglobals
$input = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES, isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array());
foreach ($input as $k => $v)
{
if (!in_array($k, $no_unset) && isset($GLOBALS[$k]))
{
unset($GLOBALS[$k]);
unset($GLOBALS[$k]); // Double unset to circumvent the zend_hash_del_key_or_index hole in PHP <4.4.3 and <5.1.4
}
}
}
//
// Removes any "bad" characters (characters which mess with the display of a page, are invisible, etc) from user input
//
function forum_remove_bad_characters()
{
$_GET = remove_bad_characters($_GET);
$_POST = remove_bad_characters($_POST);
$_COOKIE = remove_bad_characters($_COOKIE);
$_REQUEST = remove_bad_characters($_REQUEST);
}
//
// Removes any "bad" characters (characters which mess with the display of a page, are invisible, etc) from the given string
// See: http://kb.mozillazine.org/Network.IDN.blacklist_chars
//
function remove_bad_characters($array)
{
static $bad_utf8_chars;
if (!isset($bad_utf8_chars))
{
$bad_utf8_chars = array(
"\xcc\xb7" => '', // COMBINING SHORT SOLIDUS OVERLAY 0337 *
"\xcc\xb8" => '', // COMBINING LONG SOLIDUS OVERLAY 0338 *
"\xe1\x85\x9F" => '', // HANGUL CHOSEONG FILLER 115F *
"\xe1\x85\xA0" => '', // HANGUL JUNGSEONG FILLER 1160 *
"\xe2\x80\x8b" => '', // ZERO WIDTH SPACE 200B *
"\xe2\x80\x8c" => '', // ZERO WIDTH NON-JOINER 200C
"\xe2\x80\x8d" => '', // ZERO WIDTH JOINER 200D
"\xe2\x80\x8e" => '', // LEFT-TO-RIGHT MARK 200E
"\xe2\x80\x8f" => '', // RIGHT-TO-LEFT MARK 200F
"\xe2\x80\xaa" => '', // LEFT-TO-RIGHT EMBEDDING 202A
"\xe2\x80\xab" => '', // RIGHT-TO-LEFT EMBEDDING 202B
"\xe2\x80\xac" => '', // POP DIRECTIONAL FORMATTING 202C
"\xe2\x80\xad" => '', // LEFT-TO-RIGHT OVERRIDE 202D
"\xe2\x80\xae" => '', // RIGHT-TO-LEFT OVERRIDE 202E
"\xe2\x80\xaf" => '', // NARROW NO-BREAK SPACE 202F *
"\xe2\x81\x9f" => '', // MEDIUM MATHEMATICAL SPACE 205F *
"\xe2\x81\xa0" => '', // WORD JOINER 2060
"\xe3\x85\xa4" => '', // HANGUL FILLER 3164 *
"\xef\xbb\xbf" => '', // ZERO WIDTH NO-BREAK SPACE FEFF
"\xef\xbe\xa0" => '', // HALFWIDTH HANGUL FILLER FFA0 *
"\xef\xbf\xb9" => '', // INTERLINEAR ANNOTATION ANCHOR FFF9 *
"\xef\xbf\xba" => '', // INTERLINEAR ANNOTATION SEPARATOR FFFA *
"\xef\xbf\xbb" => '', // INTERLINEAR ANNOTATION TERMINATOR FFFB *
"\xef\xbf\xbc" => '', // OBJECT REPLACEMENT CHARACTER FFFC *
"\xef\xbf\xbd" => '', // REPLACEMENT CHARACTER FFFD *
"\xe2\x80\x80" => ' ', // EN QUAD 2000 *
"\xe2\x80\x81" => ' ', // EM QUAD 2001 *
"\xe2\x80\x82" => ' ', // EN SPACE 2002 *
"\xe2\x80\x83" => ' ', // EM SPACE 2003 *
"\xe2\x80\x84" => ' ', // THREE-PER-EM SPACE 2004 *
"\xe2\x80\x85" => ' ', // FOUR-PER-EM SPACE 2005 *
"\xe2\x80\x86" => ' ', // SIX-PER-EM SPACE 2006 *
"\xe2\x80\x87" => ' ', // FIGURE SPACE 2007 *
"\xe2\x80\x88" => ' ', // PUNCTUATION SPACE 2008 *
"\xe2\x80\x89" => ' ', // THIN SPACE 2009 *
"\xe2\x80\x8a" => ' ', // HAIR SPACE 200A *
"\xE3\x80\x80" => ' ', // IDEOGRAPHIC SPACE 3000 *
);
}
if (is_array($array))
return array_map('remove_bad_characters', $array);
// Strip out any invalid characters
$array = utf8_bad_strip($array);
// Remove control characters
$array = preg_replace('/[\x{00}-\x{08}\x{0b}-\x{0c}\x{0e}-\x{1f}]/', '', $array);
// Replace some "bad" characters
$array = str_replace(array_keys($bad_utf8_chars), array_values($bad_utf8_chars), $array);
return $array;
}
//
// Converts the file size in bytes to a human readable file size
//
function file_size($size)
{
$units = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB');
for ($i = 0; $size > 1024; $i++)
$size /= 1024;
return round($size, 2).' '.$units[$i];
}
//
// Fetch a list of available styles
//
function forum_list_styles()
{
$styles = array();
$d = dir(PUN_ROOT.'style');
while (($entry = $d->read()) !== false)
{
if ($entry{0} == '.')
continue;
if (substr($entry, -4) == '.css')
$styles[] = substr($entry, 0, -4);
}
$d->close();
natcasesort($styles);
return $styles;
}
//
// Fetch a list of available language packs
//
function forum_list_langs()
{
$languages = array();
$d = dir(PUN_ROOT.'lang');
while (($entry = $d->read()) !== false)
{
if ($entry{0} == '.')
continue;
if (is_dir(PUN_ROOT.'lang/'.$entry) && file_exists(PUN_ROOT.'lang/'.$entry.'/common.php'))
$languages[] = $entry;
}
$d->close();
natcasesort($languages);
return $languages;
}
//
// Generate a cache ID based on the last modification time for all stopwords files
//
function generate_stopwords_cache_id()
{
$files = glob(PUN_ROOT.'lang/*/stopwords.txt');
if ($files === false)
return 'cache_id_error';
$hash = array();
foreach ($files as $file)
{
$hash[] = $file;
$hash[] = filemtime($file);
}
return sha1(implode('|', $hash));
}
//
// Fetch a list of available admin plugins
//
function forum_list_plugins($is_admin)
{
$plugins = array();
$d = dir(PUN_ROOT.'plugins');
while (($entry = $d->read()) !== false)
{
if ($entry{0} == '.')
continue;
$prefix = substr($entry, 0, strpos($entry, '_'));
$suffix = substr($entry, strlen($entry) - 4);
if ($suffix == '.php' && ((!$is_admin && $prefix == 'AMP') || ($is_admin && ($prefix == 'AP' || $prefix == 'AMP'))))
$plugins[] = array(substr($entry, strpos($entry, '_') + 1, -4), $entry);
}
$d->close();
return $plugins;
}
//
// Split text into chunks ($inside contains all text inside $start and $end, and $outside contains all text outside)
//
function split_text($text, $start, $end, &$errors, $retab = true)
{
global $pun_config, $lang_common;
$tokens = explode($start, $text);
$outside[] = $tokens[0];
$num_tokens = count($tokens);
for ($i = 1; $i < $num_tokens; ++$i)
{
$temp = explode($end, $tokens[$i]);
if (count($temp) != 2)
{
$errors[] = $lang_common['BBCode code problem'];
return array(null, array($text));
}
$inside[] = $temp[0];
$outside[] = $temp[1];
}
if ($pun_config['o_indent_num_spaces'] != 8 && $retab)
{
$spaces = str_repeat(' ', $pun_config['o_indent_num_spaces']);
$inside = str_replace("\t", $spaces, $inside);
}
return array($inside, $outside);
}
//
// function url_valid($url) {
//
// Return associative array of valid URI components, or FALSE if $url is not
// RFC-3986 compliant. If the passed URL begins with: "www." or "ftp.", then
// "http://" or "ftp://" is prepended and the corrected full-url is stored in
// the return array with a key name "url". This value should be used by the caller.
//
// Return value: FALSE if $url is not valid, otherwise array of URI components:
// e.g.
// Given: "http://www.jmrware.com:80/articles?height=10&width=75#fragone"
// Array(
// [scheme] => http
// [authority] => www.jmrware.com:80
// [userinfo] =>
// [host] => www.jmrware.com
// [IP_literal] =>
// [IPV6address] =>
// [ls32] =>
// [IPvFuture] =>
// [IPv4address] =>
// [regname] => www.jmrware.com
// [port] => 80
// [path_abempty] => /articles
// [query] => height=10&width=75
// [fragment] => fragone
// [url]=> http://www.jmrware.com:80/articles?height=10&width=75#fragone
// )
function url_valid($url)
{
if (strpos($url, 'www.') === 0) $url = 'http://'. $url;
if (strpos($url, 'ftp.') === 0) $url = 'ftp://'. $url;
if (!preg_match('/# Valid absolute URI having a non-empty, valid DNS host.
^
(?P<scheme>[A-Za-z][A-Za-z0-9+\-.]*):\/\/
(?P<authority>
(?:(?P<userinfo>(?:[A-Za-z0-9\-._~!$&\'()*+,;=:]|%[0-9A-Fa-f]{2})*)@)?
(?P<host>
(?P<IP_literal>
\[
(?:
(?P<IPV6address>
(?: (?:[0-9A-Fa-f]{1,4}:){6}
| ::(?:[0-9A-Fa-f]{1,4}:){5}
| (?: [0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}
| (?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}
| (?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}
| (?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?:: [0-9A-Fa-f]{1,4}:
| (?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::
)
(?P<ls32>[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}
| (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
)
| (?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?:: [0-9A-Fa-f]{1,4}
| (?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::
)
| (?P<IPvFuture>[Vv][0-9A-Fa-f]+\.[A-Za-z0-9\-._~!$&\'()*+,;=:]+)
)
\]
)
| (?P<IPv4address>(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
| (?P<regname>(?:[A-Za-z0-9\-._~!$&\'()*+,;=]|%[0-9A-Fa-f]{2})+)
)
(?::(?P<port>[0-9]*))?
)
(?P<path_abempty>(?:\/(?:[A-Za-z0-9\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)
(?:\?(?P<query> (?:[A-Za-z0-9\-._~!$&\'()*+,;=:@\\/?]|%[0-9A-Fa-f]{2})*))?
(?:\#(?P<fragment> (?:[A-Za-z0-9\-._~!$&\'()*+,;=:@\\/?]|%[0-9A-Fa-f]{2})*))?
$
/mx', $url, $m)) return FALSE;
switch ($m['scheme'])
{
case 'https':
case 'http':
if ($m['userinfo']) return FALSE; // HTTP scheme does not allow userinfo.
break;
case 'ftps':
case 'ftp':
break;
default:
return FALSE; // Unrecognised URI scheme. Default to FALSE.
}
// Validate host name conforms to DNS "dot-separated-parts".
if ($m{'regname'}) // If host regname specified, check for DNS conformance.
{
if (!preg_match('/# HTTP DNS host name.
^ # Anchor to beginning of string.
(?!.{256}) # Overall host length is less than 256 chars.
(?: # Group dot separated host part alternatives.
[0-9A-Za-z]\. # Either a single alphanum followed by dot
| # or... part has more than one char (63 chars max).
[0-9A-Za-z] # Part first char is alphanum (no dash).
[\-0-9A-Za-z]{0,61} # Internal chars are alphanum plus dash.
[0-9A-Za-z] # Part last char is alphanum (no dash).
\. # Each part followed by literal dot.
)* # One or more parts before top level domain.
(?: # Explicitly specify top level domains.
com|edu|gov|int|mil|net|org|biz|
info|name|pro|aero|coop|museum|
asia|cat|jobs|mobi|tel|travel|
[A-Za-z]{2}) # Country codes are exqactly two alpha chars.
$ # Anchor to end of string.
/ix', $m['host'])) return FALSE;
}
$m['url'] = $url;
for ($i = 0; isset($m[$i]); ++$i) unset($m[$i]);
return $m; // return TRUE == array of useful named $matches plus the valid $url.
}
//
// Replace string matching regular expression
//
// This function takes care of possibly disabled unicode properties in PCRE builds
//
function ucp_preg_replace($pattern, $replace, $subject)
{
$replaced = preg_replace($pattern, $replace, $subject);
// If preg_replace() returns false, this probably means unicode support is not built-in, so we need to modify the pattern a little
if ($replaced === false)
{
if (is_array($pattern))
{
foreach ($pattern as $cur_key => $cur_pattern)
$pattern[$cur_key] = str_replace('\p{L}\p{N}', '\w', $cur_pattern);
$replaced = preg_replace($pattern, $replace, $subject);
}
else
$replaced = preg_replace(str_replace('\p{L}\p{N}', '\w', $pattern), $replace, $subject);
}
return $replaced;
}
// DEBUG FUNCTIONS BELOW
//
// Display executed queries (if enabled)
//
function display_saved_queries()
{
global $db, $lang_common;
// Get the queries so that we can print them out
$saved_queries = $db->get_saved_queries();
?>
<div id="debug" class="blocktable">
<h2><span><?php echo $lang_common['Debug table'] ?></span></h2>
<div class="box">
<div class="inbox">
<table cellspacing="0">
<thead>
<tr>
<th class="tcl" scope="col"><?php echo $lang_common['Query times'] ?></th>
<th class="tcr" scope="col"><?php echo $lang_common['Query'] ?></th>
</tr>
</thead>
<tbody>
<?php
$query_time_total = 0.0;
foreach ($saved_queries as $cur_query)
{
$query_time_total += $cur_query[1];
?>
<tr>
<td class="tcl"><?php echo ($cur_query[1] != 0) ? $cur_query[1] : ' ' ?></td>
<td class="tcr"><?php echo pun_htmlspecialchars($cur_query[0]) ?></td>
</tr>
<?php
}
?>
<tr>
<td class="tcl" colspan="2"><?php printf($lang_common['Total query time'], $query_time_total.' s') ?></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<?php
}
//
// Dump contents of variable(s)
//
function dump()
{
echo '<pre>';
$num_args = func_num_args();
for ($i = 0; $i < $num_args; ++$i)
{
print_r(func_get_arg($i));
echo "\n\n";
}
echo '</pre>';
exit;
}