* @version $Revision: 2911 $
*/
$global_thumb_count =0;
/**
* Logs execution time of script
* if $CONF['log_script_timing'] isn't set, nothing happens
* if $CONF['log_script_timing'] == 'file' timings are logged in the logs folder
* if $CONF['log_script_timing'] == 'apache' timings are logged via apache
*/
function log_script_timing()
{
global $STARTTIME,$USER,$CONF;
list($usec, $sec) = explode(' ',microtime());
$endtime = ((float)$usec + (float)$sec);
$timetaken = sprintf('%0.4f', $endtime - $STARTTIME);
if ($CONF['log_script_timing']=='file')
{
//%03.4f doesn't seem to work so we must add our own padding
//this makes the output file easily sortable
if ($timetaken<100)
$timetaken='0'.$timetaken;
if ($timetaken<10)
$timetaken='0'.$timetaken;
$logfile=$CONF['log_script_folder'].'/'.date('Ymd-H').'.log';
$h = @fopen($logfile,'a');
if ($h)
{
$time = date("i:s");
$logline = "$timetaken,$time,{$_SERVER['SCRIPT_URL']},{$_SERVER['REQUEST_METHOD']},\"{$_SERVER['QUERY_STRING']}\",{$_SERVER['REMOTE_ADDR']},{$USER->user_id},\"{$_SERVER['HTTP_REFERER']}\"\n";
fwrite($h,$logline);
fclose($h);
}
}
elseif($CONF['log_script_timing']=='apache')
{
@apache_note('php_timing', $timetaken);
}
}
/**
* Smarty block handler
* Although it doesn't appear to do much, this is registered as a
* non-caching block handler - anything between {dynamic}{/dynamic} will
* not be cached
*/
function smarty_block_dynamic($param, $content, &$smarty)
{
if (!empty($param) && !empty($param['cached_user_id'])) {
$smarty->assign('cached_user_id',$param['cached_user_id']);
}
return $content;
}
/**
* Smarty Getamap linker
*
* Makes linking to OS maps easy {getamap gridref='TL0000' text='get a map'}
*/
function smarty_function_getamap($params)
{
global $CONF;
$icon=empty($params['icon'])?"
":'';
//get params
$matches=array();
$gridref4=preg_replace('/^([A-Z]{1,3})\s*(\d{2,5})\s*(\d{2,5})$/i','$1$2$3',$params['gridref']);
if (preg_match('/^document\./i', $gridref4))
{
if (!empty($params['gridref2']))
$gridref4 .= ",'{$params['gridref2']}'";
return "{$params['text']}$icon";
}
else if (preg_match('/^([A-Z]{1,3})(\d{4,10})$/i', $gridref4, $matches))
{
if (!empty($params['text']))
$text=$params['text'];
else
$text=$params['gridref'];
$gridref6="";
$coords=$matches[2];
$l=strlen($coords);
switch ($l)
{
case 4: $gridref6=$matches[1].substr($coords,0,2)."5".substr($coords,2,2)."5"; break;
default: $gridref6=$gridref4;
}
if (isset($params['title']))
$title=$params['title'];
else
$title="Ordnance Survey Get-a-Map for $gridref4";
return "$text$icon";
}
else if (empty($gridref4))
{
if (!empty($params['text']))
$text=$params['text'];
else
$text='OS Get-a-Map';
return "$text$icon";
}
else
{
//error
return $gridref4;
}
}
/**
* Smarty new window linker
*
* Provides centralised formatting of external links
* href, title and text are the params here...
*/
function smarty_function_newwin($params)
{
global $CONF;
//get params and use intelligent defaults...
$href=str_replace(' ','+',trim($params['href']));
if (isset($params['text']))
$text=$params['text'];
else
$text=$href;
if (isset($params['title']))
$title=$params['title'];
else
$title=$text;
if (isset($params['nofollow']))
$title .= "\" rel=\"nofollow";
if (isset($params['onclick']))
$title .= "\" onclick=\"".$params['onclick'];
return "$text".
"
";
}
/**
* Smarty new window linker
*
* Provides centralised formatting of external links
* href, title and text are the params here...
*/
function smarty_function_external($params)
{
global $CONF;
//get params and use intelligent defaults...
$href=str_replace(' ','+',$params['href']);
if (strpos($href,'http://') !== 0)
$href ="http://$href";
if (isset($params['text']))
$text=$params['text'];
else
$text=$href;
if (isset($params['title']))
$title=$params['title'];
else
$title=$text;
if (isset($params['nofollow']))
$title .= "\" rel=\"nofollow";
if ($params['target'] == '_blank') {
return "$text".
"
";
} else {
return "$text".
"
";
}
}
/**
* Smarty gridimage thumbnail link
*
* given image id makes a nice thumbnail link
*/
function smarty_function_gridimage($params)
{
global $imageCredits;
$image=new GridImage;
$image->loadFromId($params['id']);
if (isset($imageCredits[$image->realname])) {
$imageCredits[$image->realname]++;
} else {
$imageCredits[$image->realname]=1;
}
$html='
',$posterText);
} elseif ($ok) {
$g_title=$g_image->grid_reference.' : '.htmlentities2($g_image->title);
if ($g_matches[1][$g_i]) {
if ($thumbs) {
$g_title.=' by '.htmlentities($g_image->realname);
$g_img = $g_image->getThumbnail(120,120,false,true);
$posterText = str_replace("[[[$prefix$g_id]]]","$g_img",$posterText);
if (isset($imageCredits[$g_image->realname])) {
$imageCredits[$g_image->realname]++;
} else {
$imageCredits[$g_image->realname]=1;
}
} else {
//we don't place thumbnails in non forum links
$posterText = str_replace("[[[$prefix$g_id]]]","$g_title",$posterText);
}
} else {
$posterText = preg_replace("/(?$g_title",$posterText);
}
}
$global_thumb_count++;
}
$thumb_count++;
} else {
//link to grid ref
$posterText = str_replace("[[$prefix$g_id]]","$g_id",$posterText);
}
}
}
if ($CONF['CONTENT_HOST'] != $_SERVER['HTTP_HOST']) {
$posterText = str_replace($CONF['CONTENT_HOST'],$_SERVER['HTTP_HOST'],$posterText);
}
$posterText = preg_replace('/(?F=])(https?:\/\/[\w\.-]+\.\w{2,}\/?[\w\~\-\.\?\,=\'\/\\\+&%\$#\(\)\;\:]*)(?\"\$1\",'text'=>'Link','nofollow'=>1,'title'=>\"\$1\"))",$posterText);
$posterText = preg_replace('/(?\"http://\$1\",'text'=>'Link','nofollow'=>1,'title'=>\"\$1\"))",$posterText);
return $posterText;
}
//available as a function, as doesn't come into effect if just re-using a smarty cache
function dieUnderHighLoad($threshold = 2,$template = 'function_unavailable.tpl') {
global $smarty,$USER,$CONF;
if ($threshold == 0) {
if ($CONF['template']=='archive') {
//heritrix doesn't understand 503 errors - so lets cause it to timeout.... (uses a socket timeout of 20000ms)
sleep(30);
}
header("HTTP/1.1 503 Service Unavailable");
$smarty->assign('searchq',stripslashes($_GET['q']));
$smarty->display($template);
exit;
} elseif (!isset($_ENV["OS"]) || strpos($_ENV["OS"],'Windows') === FALSE) {
$threshold *= 1.5;
//lets give registered users a bit more leaway!
if ($USER->registered) {
$threshold *= 2;
}
//check load average, abort if too high
$buffer = "0 0 0";
if (is_readable("/proc/loadavg")) {
$f = fopen("/proc/loadavg","r");
if ($f)
{
if (!feof($f)) {
$buffer = fgets($f, 1024);
}
fclose($f);
}
}
$loads = explode(" ",$buffer);
$load=(float)$loads[0];
if ($load>$threshold)
{
if ($CONF['template']=='archive') {
//heritrix doesn't understand 503 errors - so lets cause it to timeout.... (uses a socket timeout of 20000ms)
sleep(30);
}
header("HTTP/1.1 503 Service Unavailable");
$smarty->assign('searchq',stripslashes($_GET['q']));
$smarty->display($template);
exit;
}
}
}
function datetimeToTimestamp($datetime) {
$p = explode('-',$datetime);
return mktime(0, 0, 0, intval($p[1]), intval($p[2]), intval($p[0]));
}
function getFormattedDate($input) {
list($y,$m,$d)=explode('-', $input);
$date="";
if ($d>0) {
if ($y>1970) {
//we can use strftime
$t=strtotime($input." 0:0:0");//stop a warning
$date=strftime("%A, %e %B, %Y", $t); //%e doesnt work on WINDOWS! (could use %d)
} else {
//oh my!
$t=strtotime("2000-$m-$d");
$date=strftime("%e %B", $t)." $y";
}
} elseif ($m>0) {
//well, it saves having an array of months...
$t=strtotime("2000-$m-01");
if ($y > 0) {
$date=strftime("%B", $t)." $y";
} else {
$date=strftime("%B", $t);
}
} elseif ($y>0) {
$date=$y;
}
return $date;
}
//credit: http://www.php.net/fsockopen
function connectToURL($addr, $port, $path, $userpass="", $timeout="30") {
$urlHandle = @fsockopen($addr, $port, $errno, $errstr, $timeout);
if ($urlHandle) {
socket_set_timeout($urlHandle, $timeout);
if ($path) {
$urlString = "GET $path HTTP/1.0\r\nHost: $addr\r\nUser-Agent: {$_SERVER['HTTP_HOST']}\r\n";
if ($userpass)
$urlString .= "Authorization: Basic ".base64_encode("$userpass")."\r\n";
$urlString .= "\r\n";
fputs($urlHandle, $urlString);
$response = fgets($urlHandle);
if (substr_count($response, "200 OK") > 0) { // Check the status of the link
$endHeader = false; // Strip initial header information
while ($urlHandle && !$endHeader && !feof($urlHandle)) {
if (fgets($urlHandle) == "\r\n")
$endHeader = true;
}
return $urlHandle; // All OK, return the file handle
} else if (strlen($response) < 15) { // Cope with wierd non standard responses
fclose($urlHandle);
return -1;
} else { // Cope with a standard error response
fclose($urlHandle);
return substr($response,9,3);
}
}
return $urlHandle;
} else
return 0;
}
function customCacheControl($mtime,$uniqstr,$useifmod = true,$gmdate_mod = 0) {
global $encoding;
if (isset($encoding) && $encoding != 'none' && $encoding != '') {
$uniqstr .= $encoding;
}
$hash = "\"".md5($mtime.'-'.$uniqstr)."\"";
if(isset($_SERVER['HTTP_IF_NONE_MATCH'])) { // check ETag
if($_SERVER['HTTP_IF_NONE_MATCH'] == $hash ) {
header("HTTP/1.0 304 Not Modified");
header ("Etag: $hash");
header('Content-Length: 0');
exit;
}
//also check legacy Etag
$hash2 = "\"".$mtime.'-'.md5($uniqstr)."\"";
if($_SERVER['HTTP_IF_NONE_MATCH'] == $hash2 ) {
header("HTTP/1.0 304 Not Modified");
header ("Etag: $hash2");
header('Content-Length: 0');
exit;
}
}
header ("Etag: $hash");
if (!$gmdate_mod)
$gmdate_mod = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
if ($useifmod && !empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$if_modified_since = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']);
if ($if_modified_since == $gmdate_mod) {
header("HTTP/1.0 304 Not Modified");
header('Content-Length: 0');
exit;
}
}
header("Last-Modified: $gmdate_mod");
}
function customNoCacheHeader($type = 'nocache',$disable_auto = false) {
//none/nocache/private/private_no_expire/public
if ($type == 'nocache') {
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
customExpiresHeader(-1);
}
if ($disable_auto) {
//call to disable the auto session one, could then call another here if needbe
session_cache_limiter('none');
}
}
function customExpiresHeader($diff,$public = false,$overwrite = false) {
$private = ($public)?'':', private';
if ($diff > 0) {
$expires=gmstrftime("%a, %d %b %Y %H:%M:%S GMT", time()+$diff);
header("Expires: $expires");
header("Cache-Control: max-age=$diff$private",$overwrite);
if ($overwrite) {
header("Pragma:"); //sessions by default set this
}
} else {
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Cache-Control: max-age=0$private",$overwrite);
}
if ($public)
header("Cache-Control: Public",false);
}
function getEncoding() {
global $encoding;
if (!empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
$gzip = strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
$deflate = strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate');
$encoding = $gzip ? 'gzip' : ($deflate ? 'deflate' : '');
if (!strstr($_SERVER['HTTP_USER_AGENT'], 'Opera') &&
preg_match('/^Mozilla\/4\.0 \(compatible; MSIE ([0-9]\.[0-9])/i', $_SERVER['HTTP_USER_AGENT'], $matches)) {
$version = floatval($matches[1]);
if ($version < 6)
$encoding = '';
if ($version == 6 && !strstr($_SERVER['HTTP_USER_AGENT'], 'EV1'))
$encoding = '';
}
} else {
$encoding = '';
}
return $encoding;
}
function customGZipHandlerStart() {
global $encoding;
if ($encoding = getEncoding()) {
ob_start();
register_shutdown_function('customGZipHandlerEnd');
}
}
function customGZipHandlerEnd() {
global $encoding;
$contents =& ob_get_clean();
if (isset($encoding) && $encoding) {
// Send compressed contents
$contents = gzencode($contents, 9, ($encoding == 'gzip') ? FORCE_GZIP : FORCE_DEFLATE);
header ('Content-Encoding: '.$encoding);
header ('Vary: Accept-Encoding');
}
//else ... we could still send Vary: but because a browser that doesnt will accept non gzip in all cases, doesnt matter if the cache caches the non compressed version (the otherway doesnt hold true, hence the Vary: above)
header('Content-Length: '.strlen($contents));
echo $contents;
}
function htmlspecialchars2( $myHTML,$quotes = ENT_COMPAT,$char_set = 'ISO-8859-1')
{
return preg_replace( "/&([A-Za-z]{0,4}\w{2,3};|#[0-9]{2,4};|#x[0-9a-fA-F]{2,4};)/", '&$1' ,htmlspecialchars($myHTML,$quotes,$char_set));
}
function htmlentities2( $myHTML,$quotes = ENT_COMPAT,$char_set = 'ISO-8859-1')
{
return preg_replace( "/&([A-Za-z]{0,4}\w{2,3};|#[0-9]{2,4};|#x[0-9a-fA-F]{2,4};)/", '&$1' ,htmlentities($myHTML,$quotes,$char_set));
}
function htmlnumericentities($myXML){
return str_replace('&','&',preg_replace('/[^!-%\x27-;=?-~ ]/e', '"".ord("$0").chr(59)', htmlspecialchars($myXML)));
}
function pagesString($currentPage,$numberOfPages,$prefix,$postfix = '',$extrahtml = '',$showLastPage = false) {
static $r;
if (!empty($r))
return($r);
if ($currentPage > 1)
$r .= "< < prev ";
$start = max(1,$currentPage-5);
$endr = min($numberOfPages+1,$currentPage+8);
if ($start > 1)
$r .= "1 ... ";
for($index = $start;$index<$endr;$index++) {
if ($index == $currentPage)
$r .= "$index ";
else
$r .= "$index ";
}
if ($endr < $numberOfPages+1)
$r .= "... ";
if ($numberOfPages > $currentPage)
$r .= "next >> ";
if ($showLastPage)
$r .= "last ";
return $r;
}
/**
* returns a standard textual representation of a number
*/
function heading_string($deg) {
$dirs = array('north','east','south','west');
$rounded = round($deg / 22.5) % 16;
if ($rounded < 0)
$rounded += 16;
if (($rounded % 4) == 0) {
$s = $dirs[$rounded/4];
} else {
$s = $dirs[2 * intval(((intval($rounded / 4) + 1) % 4) / 2)];
$s .= $dirs[1 + 2 * intval($rounded / 8)];
if ($rounded % 2 == 1) {
$s = $dirs[round($rounded/4) % 4] . '-' . $s;
}
}
return $s;
}
?>