ocPortal Developer's Guide: Core support functions
» Return to Contents
Sources/global.php file is the main file, the one that is included first, and the one that contains the functions required to start everything else off.
Please be careful when modifying this file, as it is very easy to make a mistake and ruin your installation of ocPortal.
global.php launches global2.php, which may, like any source file except minikernel.php and global.php, be overridden in sources_custom. This overriding system allows you to distinguish which files you have changed, to maintain the original copy of the file, and to not lose your changes on upgrade.
The downside to this is that upgrades may file if you have overrided source files that have had necessary changes to them.
The override system is rolled out across ocPortal, for everything from modules to templates. For files that may be edited inside ocPortal itself, the overriding system works as a great file-permission solution: you do not need to chmod all your templates, because the originals are never changed, only overridden.
sources/global.php
Global_functions_global.php
void require_code(string codename, boolean light_exit)
This function is a very important one when coding. It allows you to include a source code file (from root/sources/ or root/sources_custom/) through the proper channels.You should remember this function, and not substitute anything else for it, as that will likely make your code unstable.It is key to source code modularity in ocPortal.
Parameters…
| Name |
codename |
| Description |
The codename for the source module to load (or a full relative path, ending with .php; if custom checking is needed, this must be the custom version) |
| Type |
string |
| Name |
light_exit |
| Description |
Whether to cleanly fail when a source file is missing |
| Default value |
boolean-false |
| Type |
boolean |
(No return value)
function require_code($codename,$light_exit=false)
{
$hphp=defined('HIPHOP_PHP');
if (($hphp)/* || ((array_key_exists('keep_old_parser',$_GET)) && ($_GET['keep_old_parser']=='1'))*/)
{
if ($codename=='tempcode')
$codename='tempcode__runtime';
if ($codename=='tempcode_compiler')
$codename='tempcode_compiler__runtime';
}
global $_REQUIRED_CODE,$FILE_BASE;
if (isset($_REQUIRED_CODE[$codename])) return;
$_REQUIRED_CODE[$codename]=1;
$shorthand=(strpos($codename,'.php')===false);
if (!$shorthand)
{
$non_custom_codename=str_replace('_custom','',$codename);
$_REQUIRED_CODE[$non_custom_codename]=1;
}
$codename=filter_naughty($codename);
static $mue=NULL;
if ($mue===NULL) $mue=function_exists('memory_get_usage');
if (($mue) && (isset($_GET['keep_show_loading'])) && ($_GET['keep_show_loading']=='1'))
{
if (function_exists('memory_get_usage')) // Repeated, for code quality checker; done previously, for optimisation
{
$before=memory_get_usage();
}
}
$worked=false;
$path_a=$FILE_BASE.'/'.($shorthand?('sources_custom/'.$codename.'.php'):$codename);
$path_b=$FILE_BASE.'/'.($shorthand?('sources/'.$codename.'.php'):$non_custom_codename);
$has_original=NULL;
if (isset($GLOBALS['MEM_CACHE']))
{
global $CODE_OVERRIDES;
if (!isset($CODE_OVERRIDES))
{
$CODE_OVERRIDES=persistant_cache_get('CODE_OVERRIDES');
if ($CODE_OVERRIDES===NULL) $CODE_OVERRIDES=array();
}
if (isset($CODE_OVERRIDES[$codename]))
{
$has_override=$CODE_OVERRIDES[$codename];
$has_original=$CODE_OVERRIDES['!'.$codename];
} else
{
$has_override=is_file($path_a);
$has_original=is_file($path_b);
$CODE_OVERRIDES[$codename]=$has_override;
$CODE_OVERRIDES['!'.$codename]=$has_original;
persistant_cache_set('CODE_OVERRIDES',$CODE_OVERRIDES,true);
}
} else
{
$has_override=is_file($path_a);
}
if (($has_override) && ((!function_exists('in_safe_mode')) || (!in_safe_mode()) || (!is_file($path_b))))
{
$done_init=false;
$init_func='init__'.str_replace('/','__',str_replace('.php','',$codename));
if (!isset($has_original)) $has_original=is_file($path_b);
if (($path_a!=$path_b) && ($has_original))
{
$orig=str_replace(array('?'.'>','<?php'),array('',''),file_get_contents($path_b));
$a=file_get_contents($path_a);
if (((strpos($codename,'.php')===false) || (strpos($a,'class Mx_')===false)) && ((function_exists('quercus_version')) || (!$hphp)))
{
$functions_before=get_defined_functions();
$classes_before=get_declared_classes();
include($path_a); // Include our overrride
$functions_after=get_defined_functions();
$classes_after=get_declared_classes();
$functions_diff=array_diff($functions_after['user'],$functions_before['user']); // Our override defined these functions
$classes_diff=array_diff($classes_after,$classes_before);
$pure=true; // We will set this to false if it does not have all functions the main one has. If it does have all functions we know we should not run the original init, as it will almost certainly just have been the same code copy&pasted through.
$overlaps=false;
foreach ($functions_diff as $function) // Go through override's functions and make sure original doesn't have them: rename original's to non_overrided__ equivs.
{
if (strpos($orig,'function '.$function.'(')!==false)
{
$orig=str_replace('function '.$function.'(','function non_overrided__'.$function.'(',$orig);
$overlaps=true;
} else
{
$pure=false;
}
}
foreach ($classes_diff as $class)
{
if (substr(strtolower($class),0,6)=='module') $class=ucfirst($class);
if (substr(strtolower($class),0,4)=='hook') $class=ucfirst($class);
if (strpos($orig,'class '.$class)!==false)
{
$orig=str_replace('class '.$class,'class non_overrided__'.$class,$orig);
$overlaps=true;
} else
{
$pure=false;
}
}
// See if we can get away with loading init function early. If we can we do a special version of it that supports fancy code modification. Our override isn't allowed to call the non-overridden init function as it won't have been loaded up by PHP in time. Instead though we will call it ourselves if it still exists (hasn't been removed by our own init function) because it likely serves a different purpose to our code-modification init function and copy&paste coding is bad.
$doing_code_modifier_init=function_exists($init_func);
if ($doing_code_modifier_init)
{
$test=call_user_func_array($init_func,array($orig));
if (is_string($test)) $orig=$test;
$done_init=true;
}
if (!$doing_code_modifier_init && !$overlaps) // To make stack traces more helpful and help with opcode caching
{
include($path_b);
} else
{
eval($orig); // Load up modified original
}
if ((!$pure) && ($doing_code_modifier_init) && (function_exists('non_overrided__init__'.str_replace('/','__',str_replace('.php','',$codename)))))
{
call_user_func('non_overrided__init__'.str_replace('/','__',str_replace('.php','',$codename)));
}
} else
{
// Note we load the original and then the override. This is so function_exists can be used in the overrides (as we can't support the re-definition) OR in the case of Mx_ class derivation, so that the base class is loaded first.
if ((isset($_GET['keep_show_parse_errors'])) && ((function_exists('quercus_version')) || (!$hphp)))
{
@ini_set('display_errors','0');
$orig=str_replace('?'.'>','',str_replace('<?php','',file_get_contents($path_b)));
if (eval($orig)===false)
{
if ((!function_exists('fatal_exit')) || ($codename=='failure')) critical_error('PASSON',@strval($php_errormsg).' [sources/'.$codename.'.php]');
fatal_exit(@strval($php_errormsg).' [sources/'.$codename.'.php]');
}
} else
{
include($path_b);
}
if ((isset($_GET['keep_show_parse_errors'])) && ((function_exists('quercus_version')) || (!$hphp)))
{
@ini_set('display_errors','0');
$orig=str_replace('?'.'>','',str_replace('<?php','',file_get_contents($path_a)));
if (eval($orig)===false)
{
if ((!function_exists('fatal_exit')) || ($codename=='failure')) critical_error('PASSON',@strval($php_errormsg).' [sources_custom/'.$codename.'.php]');
fatal_exit(@strval($php_errormsg).' [sources_custom/'.$codename.'.php]');
}
} else
{
include($path_a);
}
}
} else
{
if ((isset($_GET['keep_show_parse_errors'])) && ((function_exists('quercus_version')) || (!$hphp)))
{
@ini_set('display_errors','0');
$orig=str_replace('?'.'>','',str_replace('<?php','',file_get_contents($path_a)));
if (eval($orig)===false)
{
if ((!function_exists('fatal_exit')) || ($codename=='failure')) critical_error('PASSON',@strval($php_errormsg).' [sources_custom/'.$codename.'.php]');
fatal_exit(@strval($php_errormsg).' [sources_custom/'.$codename.'.php]');
}
} else
{
include($path_a);
}
}
if (($mue) && (isset($_GET['keep_show_loading'])) && ($_GET['keep_show_loading']=='1'))
{
if (function_exists('memory_get_usage')) // Repeated, for code quality checker; done previously, for optimisation
{
print('<!-- require_code: '.htmlentities($codename).' ('.number_format(memory_get_usage()-$before).' bytes used, now at '.number_format(memory_get_usage()).') -->'."\n");
flush();
}
}
if (!$done_init)
if (function_exists($init_func)) call_user_func($init_func);
$worked=true;
} else
{
if ((isset($_GET['keep_show_parse_errors'])) && ((function_exists('quercus_version')) || (!$hphp)))
{
$contents=@file_get_contents($path_b);
if ($contents!==false)
{
@ini_set('display_errors','0');
$orig=str_replace(array('?'.'>','<'.'?php'),array('',''),$contents);
if (eval($orig)===false)
{
if ((!function_exists('fatal_exit')) || ($codename=='failure')) critical_error('PASSON',@strval($php_errormsg).' [sources/'.$codename.'.php]');
fatal_exit(@strval($php_errormsg).' [sources/'.$codename.'.php]');
}
$worked=true;
}
} else
{
$php_errormsg='';
@include($path_b);
if ($php_errormsg=='') $worked=true;
}
if ($worked)
{
if (($mue) && (isset($_GET['keep_show_loading'])) && ($_GET['keep_show_loading']=='1'))
{
if (function_exists('memory_get_usage')) // Repeated, for code quality checker; done previously, for optimisation
{
print('<!-- require_code: '.htmlentities($codename).' ('.number_format(memory_get_usage()-$before).' bytes used, now at '.number_format(memory_get_usage()).') -->'."\n");
flush();
}
}
$init_func='init__'.str_replace(array('/','.php'),array('__',''),$codename);
if (function_exists($init_func)) call_user_func($init_func);
}
}
if ($worked) return;
if ($light_exit)
{
warn_exit(do_lang_tempcode('MISSING_SOURCE_FILE',escape_html($codename),escape_html($path_b)));
}
if (!function_exists('do_lang'))
{
if ($codename=='critical_errors')
{
exit('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'.chr(10).'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="EN" lang="EN"><head><title>Critical startup error</title></head><body><h1>ocPortal startup error</h1><p>The ocPortal critical error message file, sources/critical_errors.php, could not be located. This is almost always due to an incomplete upload of the ocPortal system, so please check all files are uploaded correctly.</p><p>Once all ocPortal files are in place, ocPortal must actually be installed by running the installer. You must be seeing this message either because your system has become corrupt since installation, or because you have uploaded some but not all files from our manual installer package: the quick installer is easier, so you might consider using that instead.</p><p>ocProducts maintains full documentation for all procedures and tools, especially those for installation. These may be found on the <a href="http://ocportal.com">ocPortal website</a>. If you are unable to easily solve this problem, we may be contacted from our website and can help resolve it for you.</p><hr /><p style="font-size: 0.8em">ocPortal is a website engine created by ocProducts.</p></body></html>'); require($GLOBALS['FILE_BASE'].'/sources/global.php');
}
critical_error('MISSING_SOURCE',$codename);
}
fatal_exit(do_lang_tempcode('MISSING_SOURCE_FILE',escape_html($codename),escape_html($path_b)));
}
void require_code_no_override(string codename)
Require code, but without looking for sources_custom overrides
Parameters…
| Name |
codename |
| Description |
The codename for the source module to load |
| Type |
string |
(No return value)
function require_code_no_override($codename)
{
global $_REQUIRED_CODE;
if (array_key_exists($codename,$_REQUIRED_CODE)) return;
$_REQUIRED_CODE[$codename]=1;
require_once(get_file_base().'/sources/'.filter_naughty($codename).'.php');
if (function_exists('init__'.str_replace('/','__',$codename))) call_user_func('init__'.str_replace('/','__',$codename));
}
?object object_factory(string class, boolean null_ok)
Make an object of the given class
Parameters…
| Name |
class |
| Description |
The class name |
| Type |
string |
| Name |
null_ok |
| Description |
Whether to return NULL if there is no such class |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
The object (NULL: no such class) |
| Type |
?object |
function object_factory($class,$null_ok=false)
{
if (!class_exists($class))
{
if ($null_ok) return NULL;
fatal_exit(escape_html('Missing class: '.$class));
}
return new $class;
}
PATH get_file_base()
Get the file base for your installation of ocPortal
Parameters…
Returns…
| Description |
The file base, without a trailing slash |
| Type |
PATH |
function get_file_base()
{
global $FILE_BASE;
return $FILE_BASE;
}
PATH get_custom_file_base()
Get the file base for your installation of ocPortal. For a shared install only, this is different to the base-url.
Parameters…
Returns…
| Description |
The file base, without a trailing slash |
| Type |
PATH |
function get_custom_file_base()
{
global $FILE_BASE,$SITE_INFO;
if (isset($SITE_INFO['custom_file_base_stub']))
{
require_code('shared_installs');
$u=current_share_user();
if (!is_null($u))
return $SITE_INFO['custom_file_base_stub'].'/'.$u;
}
return $FILE_BASE;
}
string filter_naughty(string in, boolean preg)
Get the parameter put into it, with no changes. If it detects that the parameter is naughty (i.e malicious, and probably from a hacker), it will log the hack-attack and output an error message.This function is designed to be called on parameters that will be embedded in a path, and defines malicious as trying to reach a parent directory using '..'. All file paths in ocPortal should be absolute
Parameters…
| Name |
in |
| Description |
String to test |
| Type |
string |
| Name |
preg |
| Description |
Whether to just filter out the naughtyness |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
Same as input string |
| Type |
string |
function filter_naughty($in,$preg=false)
{
if (strpos($in,'..')!==false)
{
if ($preg) return str_replace('.','',$in);
$in=str_replace('...','',$in);
if (strpos($in,'..')!==false)
log_hack_attack_and_exit('PATH_HACK');
warn_exit(do_lang_tempcode('INVALID_URL'));
}
return $in;
}
string filter_naughty_harsh(string in, boolean preg)
This function is similar to filter_naughty, except it requires the parameter to be strictly alphanumeric. It is intended for use on text that will be put into an eval.
Parameters…
| Name |
in |
| Description |
String to test |
| Type |
string |
| Name |
preg |
| Description |
Whether to just filter out the naughtyness |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
Same as input string |
| Type |
string |
function filter_naughty_harsh($in,$preg=false)
{
if (preg_match('#^[\w\-]*$#',$in)!=0) return $in;
if (preg_match('#^[\w\-]*/#',$in)!=0) warn_exit(do_lang_tempcode('MISSING_RESOURCE')); // Probably a relative URL underneath an SEO URL, should not really happen
if ($preg)
{
return preg_replace('#[^\w\-]#','',$in);
}
log_hack_attack_and_exit('EVAL_HACK',$in);
return ''; // trick to make Zend happy
}
~LONG_TEXT file_get_contents(SHORT_TEXT filename, integer type)
Get the contents of a file.
Parameters…
| Name |
filename |
| Description |
The file name. |
| Type |
SHORT_TEXT |
| Name |
type |
| Description |
Either FILE_TEXT or FILE_BINARY. |
| Default value |
0 |
| Type |
integer |
Returns…
| Description |
The file contents (false: error). |
| Type |
~LONG_TEXT |
function file_get_contents($filename,$type=0)
{
$data='';
$file=@fopen($filename,($type==FILE_TEXT)?'rt':'rb');
if ($file)
{
while (!feof($file)) $data.=fread($file,1024);
fclose($file);
}
return $data;
}
sources/global2.php
Global_functions_global2.php
Function summary
|
void
|
init__global2 ()
|
|
mixed
|
str_word_count (string input, integer format)
|
|
string
|
html_entity_decode (string input, integer quote_style, ?string charset)
|
|
~string
|
unichrm_hex (array matches)
|
|
~string
|
unichrm (array matches)
|
|
~string
|
unichr (integer c)
|
|
void
|
debug_mode_aftertests ()
|
|
boolean
|
can_fast_spider_cache ()
|
|
void
|
fast_spider_cache (boolean bot)
|
|
void
|
disable_php_memory_limit ()
|
|
string
|
get_charset ()
|
|
void
|
load_user_stuff ()
|
|
void
|
catch_fatal_errors ()
|
|
boolean
|
ocportal_error_handler (integer errno, PATH errstr, string errfile, integer errline)
|
|
boolean
|
is_browser_decacheing ()
|
|
boolean
|
running_script (string is_this_running)
|
|
void
|
inform_exit (mixed text)
|
|
void
|
warn_exit (mixed text)
|
|
void
|
suggest_fatalistic ()
|
|
void
|
fatal_exit (mixed text)
|
|
void
|
log_hack_attack_and_exit (ID_TEXT reason, SHORT_TEXT reason_param_a, SHORT_TEXT reason_param_b, boolean silent)
|
|
boolean
|
handle_has_checked_recently (ID_TEXT id_code)
|
|
integer
|
make_seed ()
|
|
string
|
ocp_version_full ()
|
|
string
|
get_domain ()
|
|
string
|
get_forum_type ()
|
|
URLPATH
|
get_forum_base_url (boolean forum_base)
|
|
?string
|
get_cookie_path ()
|
|
?string
|
get_cookie_domain ()
|
|
integer
|
get_cookie_days ()
|
|
string
|
get_site_name ()
|
|
boolean
|
in_safe_mode ()
|
|
URLPATH
|
find_script (string name, boolean append_keep, integer base_url_code)
|
|
URLPATH
|
get_base_url (?boolean https, ?ID_TEXT zone_for)
|
|
URLPATH
|
get_custom_base_url (?boolean https)
|
|
URLPATH
|
get_complex_base_url (URLPATH at)
|
|
?string
|
either_param (ID_TEXT name, ?mixed default)
|
|
?string
|
post_param (ID_TEXT name, ?mixed default, boolean html, boolean conv_from_wysiwyg)
|
|
?string
|
get_param (ID_TEXT name, ?mixed default, boolean no_security)
|
|
string
|
__param (array array, string name, ?mixed default, boolean integer, ?boolean posted)
|
|
boolean
|
simulated_wildcard_match (string context, string word, boolean full_cover)
|
|
?integer
|
either_param_integer (ID_TEXT name, ?mixed default)
|
|
?integer
|
post_param_integer (ID_TEXT name, ?mixed default)
|
|
?integer
|
get_param_integer (ID_TEXT name, ?mixed default, boolean not_string_ok)
|
|
string
|
unixify_line_format (string in, ?ID_TEXT desired_charset, boolean html, boolean from_disk)
|
|
string
|
javascript_enforce (string j, ?ID_TEXT theme, ?boolean minify)
|
|
tempcode
|
javascript_tempcode (?string position)
|
|
void
|
require_javascript (ID_TEXT javascript)
|
|
string
|
css_enforce (string c, ?ID_TEXT theme, ?boolean minify)
|
|
tempcode
|
css_tempcode (boolean inline, boolean only_global, ?string context, ?ID_TEXT theme)
|
|
void
|
require_css (ID_TEXT css)
|
|
void
|
sync_file (PATH filename)
|
|
void
|
sync_file_move (PATH old, PATH new)
|
|
void
|
convert_data_encodings (boolean known_utf8)
|
|
boolean
|
will_be_unicode_neutered (string data)
|
void init__global2()
Standard code module initialisation function.
Parameters…
(No return value)
function init__global2()
{
global $BOOTSTRAPPING,$CHECKING_SAFEMODE,$BAD_WORD_CHARS,$FIXED_WORD_CHARS,$FIXED_WORD_CHARS_HTML,$BROWSER_DECACHEING,$CHARSET,$TEMP_CHARSET,$RELATIVE_PATH,$CURRENTLY_HTTPS,$RUNNING_SCRIPT_CACHE,$SERVER_TIMEZONE,$HAS_SET_ERROR_HANDLER,$DYING_BADLY,$XSS_DETECT,$SITE_INFO,$JAVASCRIPTS,$JAVASCRIPT,$CSSS,$IN_MINIKERNEL_VERSION,$EXITING,$FILE_BASE,$MOBILE,$CACHE_TEMPLATES,$BASE_URL_HTTP,$BASE_URL_HTTPS,$WORDS_TO_FILTER,$FIELD_RESTRICTIONS,$VALID_ENCODING,$CONVERTED_ENCODING,$MICRO_BOOTUP,$MICRO_AJAX_BOOTUP,$QUERY_LOG,$_CREATED_FILES,$CURRENT_SHARE_USER,$CACHE_FIND_SCRIPT;
if (ini_get('output_buffering')=='1') @ob_end_clean();
if (array_key_exists('HTTP_X_REWRITE_URL',$_SERVER))
{
foreach ($_GET as $key=>$val)
{
if ($key[0]=='?')
{
unset($_GET[$key]);
$_GET[substr($key,1)]=$val;
}
}
$_SERVER['REQUEST_URI']=$_SERVER['HTTP_X_REWRITE_URL'];
} elseif ((!array_key_exists('REQUEST_URI',$_SERVER)) && (!array_key_exists('REQUEST_URI',$_ENV)))
{
$_SERVER['REQUEST_URI']=$_SERVER['PHP_SELF'];
$first=true;
foreach ($_GET as $key=>$val)
{
$_SERVER['REQUEST_URI'].=$first?'?':'&';
$_SERVER['REQUEST_URI'].=urlencode($key).'='.urlencode($val);
$first=false;
}
}
if ((array_key_exists('SCRIPT_FILENAME',$_SERVER)) && (!array_key_exists('PHP_SELF',$_SERVER))) $_SERVER['PHP_SELF']=$_SERVER['SCRIPT_FILENAME'];
elseif ((array_key_exists('SCRIPT_NAME',$_SERVER)) && (defined('HIPHOP_PHP'))) $_SERVER['PHP_SELF']=$_SERVER['SCRIPT_NAME'];
@header('Expires: Mon, 20 Dec 1998 01:00:00 GMT');
@header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
//@header('Cache-Control: no-cache, must-revalidate'); // DISABLED AS MAKES IE RELOAD ON 'BACK' AND LOSE FORM CONTENTS
@header('Pragma: no-cache'); // for proxies, and also IE
if ((strpos($_SERVER['PHP_SELF'],'upgrader.php')===false) && ((!isset($SITE_INFO['no_extra_closed_file'])) || ($SITE_INFO['no_extra_closed_file']=='0')))
{
if (is_file('closed.html'))
{
if ((@strpos($_SERVER['SERVER_SOFTWARE'],'IIS')===false)) header('HTTP/1.0 503 Service Temporarily Unavailable');
header('Location: closed.html');
exit();
}
if (@is_file('../closed.html'))
{
if ((@strpos($_SERVER['SERVER_SOFTWARE'],'IIS')===false)) header('HTTP/1.0 503 Service Temporarily Unavailable');
header('Location: ../closed.html');
exit();
}
}
// Cover up holes in old PHP versions functionality
if (!function_exists('str_word_count'))
{
/**
* Isolate the words in the input string.
*
* @param string String to count words in
* @param integer The format
* @set 0 1 2
* @return mixed Typically a list - the words of the input string
*/
function str_word_count($input,$format=0)
{
//count words
$pattern="/[^(\w|\d|\'|\"|\.|\!|\?|;|,|\\|\/|\-\-|:|\&|@)]+/";
$all_words=trim(preg_replace($pattern,' ',$input));
$a=array();
$pos=0;
while (true)
{
$old_pos=$pos;
$pos=strpos($all_words,' ',$pos);
if ($pos===false)
{
$a[$old_pos]=substr($all_words,$old_pos);
break;
}
$a[$old_pos]=substr($all_words,$old_pos,$pos-$old_pos);
}
if ($format==0) return count($a);
return $a;
}
}
if (!function_exists('html_entity_decode'))
{
/**
* Decode the HTML entitity encoded input string.
*
* @param string The text to decode
* @param integer The quote style code
* @param ?string Character set to decode to (NULL: default)
* @return string The decoded text
*/
function html_entity_decode($input,$quote_style,$charset=NULL)
{
unset($quote_style);
unset($charset);
/* // NB:   does not go to <space>. It's not something you use with html escaping, it's for hard-space-formatting. URL's don't contain spaces, but that's due to URL escaping (%20)
$replace_array=array(
'&'=>'&',
'>'=>'>',
'<'=>'<',
'''=>'\'',
'"'=>'"',
);
foreach ($replace_array as $from=>$to)
{
$input=str_replace($from,$to,$input);
}
return $input;*/
$trans_tbl=get_html_translation_table(HTML_ENTITIES);
$trans_tbl=array_flip($trans_tbl);
return strtr($input,$trans_tbl);
}
}
if (version_compare(phpversion(),'4.3.0')>=0)
{
if (!function_exists('unichrm_hex'))
{
/**
* Convert a unicode character number to a unicode string. Callback for preg_replace.
*
* @param array Regular expression match array.
* @return ~string Converted data (false: could not convert).
*/
function unichrm_hex($matches)
{
return unichr(hexdec($matches[1]));
}
}
if (!function_exists('unichrm'))
{
/**
* Convert a unicode character number to a unicode string. Callback for preg_replace.
*
* @param array Regular expression match array.
* @return ~string Converted data (false: could not convert).
*/
function unichrm($matches)
{
return unichr(intval($matches[1]));
}
}
if (!function_exists('unichr'))
{
/**
* Convert a unicode character number to a HTML-entity enabled string, using lower ASCII characters where possible.
*
* @param integer Character number.
* @return ~string Converted data (false: could not convert).
*/
function unichr($c)
{
if ($c<=0x7F)
{
return chr($c);
} else
{
return '#&'.strval($c).';';
}
}
}
}
$BOOTSTRAPPING=1;
$CHECKING_SAFEMODE=false;
$BAD_WORD_CHARS=array(chr(128),chr(130),chr(131),chr(132),chr(133),chr(134),chr(135),chr(136),chr(137),chr(138),chr(139),chr(140),chr(142),chr(145),chr(146),chr(147),chr(148),chr(149),chr(150),chr(151),chr(152),chr(153),chr(154),chr(155),chr(156),chr(158),chr(159));
$FIXED_WORD_CHARS=array('(EUR-)',',','{f.}','"','...','-|-','=|=','^','{%o}','{~S}','<','CE','{~Z}',"'","'",'"','"','-','-','--','~','(TM)','{~s}','>','ce','{~z}','{.Y.}'); // some of these are Comcode shortcuts. We can't use entities as we can't assume we're converting into Comcode.
$FIXED_WORD_CHARS_HTML=array('€','‚','ƒ','„','…','†','‡','ˆ','‰','Š','‹','Œ','Ž',"‘","’",'“','”','•','–','—','˜','™','š','›','œ','ž','Ÿ');
$RUNNING_SCRIPT_CACHE=array();
$BROWSER_DECACHEING=NULL;
$CHARSET=NULL;
$TEMP_CHARSET=NULL;
$CURRENTLY_HTTPS=NULL;
$CACHE_FIND_SCRIPT=array();
error_reporting(E_ALL);
@ini_set('html_errors','1');
@ini_set('docref_root','http://www.php.net/manual/en/');
@ini_set('docref_ext','.php');
$SERVER_TIMEZONE=function_exists('date_default_timezone_get')?@date_default_timezone_get():ini_get('date.timezone');
@ini_set('date.timezone','UTC');
if (function_exists('date_default_timezone_set')) date_default_timezone_set('UTC'); // Needed for HPHP
$HAS_SET_ERROR_HANDLER=false;
$DYING_BADLY=false; // If ocPortal is bailing out uncontrollably, setting this will make sure the error hander does not try and suppress
$XSS_DETECT=function_exists('ocp_mark_as_escaped');
$GLOBALS['DEBUG_MODE']=(((!array_key_exists('debug_mode',$SITE_INFO) || ($SITE_INFO['debug_mode']=='1')) && ((is_dir(get_file_base().'/.svn')) || (is_dir(get_file_base().'/.git')) || (function_exists('ocp_mark_as_escaped')))) && ((!array_key_exists('keep_no_debug_mode',$_GET) || ($_GET['keep_no_debug_mode']=='0'))));
$GLOBALS['SEMI_DEBUG_MODE']=(((!array_key_exists('debug_mode',$SITE_INFO) || ($SITE_INFO['debug_mode']=='1')) && ((is_dir(get_file_base().'/.svn')) || (is_dir(get_file_base().'/.git')) || (function_exists('ocp_mark_as_escaped')))));
if (function_exists('set_time_limit')) @set_time_limit(60);
if ($GLOBALS['DEBUG_MODE'])
{
if (function_exists('set_time_limit')) @set_time_limit(10);
@ini_set('ocproducts.type_strictness','1');
@ini_set('ocproducts.xss_detect','1');
}
if ($GLOBALS['DEBUG_MODE'])
{
require_code('developer_tools');
}
$JAVASCRIPTS=array('javascript'=>1,'javascript_thumbnails'=>1);
if (($GLOBALS['CURRENT_SHARE_USER']!==NULL) || (get_domain()=='myocp.com')) $JAVASCRIPTS['javascript_ajax']=1;
$CSSS=array('no_cache'=>1,'global'=>1);
// Try and make the PHP environment as we need it
if (function_exists('set_magic_quotes_runtime')) @set_magic_quotes_runtime(0); // @'d because it's deprecated and PHP 5.3 may give an error
srand(make_seed());
mt_srand(make_seed());
@ini_set('auto_detect_line_endings','0');
@ini_set('include_path','');
@ini_set('default_socket_timeout','60');
@ini_set('allow_url_fopen','0');
@ini_set('suhosin.executor.disable_emodifier','1'); // Extra security if suhosin is available
@ini_set('suhosin.executor.multiheader','1'); // Extra security if suhosin is available
@ini_set('suhosin.executor.disable_eval','0');
@ini_set('suhosin.executor.eval.whitelist','');
@ini_set('suhosin.executor.func.whitelist','');
// Load most basic config
$IN_MINIKERNEL_VERSION=0;
$EXITING=0;
if ((array_key_exists('use_ocf',$_GET)) && (running_script('upgrader')))
{
$SITE_INFO['forum_type']='ocf';
$SITE_INFO['ocf_table_prefix']=$SITE_INFO['table_prefix'];
}
$CACHE_TEMPLATES=true;
// The URL to our install (no trailing /)
$BASE_URL_HTTP=NULL;
$BASE_URL_HTTPS=NULL;
$WORDS_TO_FILTER=NULL;
$FIELD_RESTRICTIONS=NULL;
$VALID_ENCODING=false;
$CONVERTED_ENCODING=false;
if (!isset($MICRO_BOOTUP)) $MICRO_BOOTUP=0;
if (!isset($MICRO_AJAX_BOOTUP)) $MICRO_AJAX_BOOTUP=0;
require_code_no_override('version');
if (($MICRO_BOOTUP==0) && ($MICRO_AJAX_BOOTUP==0))
{
@header('X-Powered-By: ocPortal '.ocp_version_full().' (PHP '.phpversion().')');
$QUERY_LOG=false;
if ((isset($_REQUEST['special_page_type'])) && ($_REQUEST['special_page_type']=='query'))
{
$QUERY_LOG=true;
}
}
// Most critical things
require_code('support'); // A lot of support code is present in this
if (($MICRO_BOOTUP==0) && ($MICRO_AJAX_BOOTUP==0)) // Fast cacheing for bots
{
if ((running_script('index')) && (count($_POST)==0))
{
$bot_type=get_bot_type();
if (($bot_type!==NULL) && (isset($SITE_INFO['fast_spider_cache'])) && ($SITE_INFO['fast_spider_cache']!='0'))
{
fast_spider_cache(true);
}
}
}
require_code('caches'); // Recently taken out of 'support' so makes sense to load it here
require_code('database'); // There's nothing without the database
if (((!isset($SITE_INFO['known_suexec'])) || ($SITE_INFO['known_suexec']=='0')) && (!is_writable_wrap(get_file_base().'/.htaccess'))) // If we have to run this in software
{
require_code('support2');
if (ip_banned(get_ip_address())) critical_error('BANNED');
}
if ((running_script('messages')) && (get_param('action','new')=='new') && (get_param_integer('routine_refresh',0)==0)) // Architecturally unsound chat message precheck (for extra efficiency)
{
require_code('chat_poller');
chat_poller();
}
if ($MICRO_BOOTUP==0)
{
load_user_stuff();
}
// For any kind of niceness we need these. The order is chosen for complex dependency reasons - don't mess with it
if ($MICRO_AJAX_BOOTUP==0)
{
require_code('themes'); // Output needs to know about themes
require_code('templates'); // So that we can do error templates
require_code('tempcode'); // Output is done with tempcode
if ($MICRO_BOOTUP==0)
{
require_code('comcode'); // Much output goes through comcode
}
}
require_code('zones'); // Zone is needed because zones are where all ocPortal pages reside
require_code('config'); // Config is needed for much active stuff
if ((get_option('collapse_user_zones',true)==='1') && ($RELATIVE_PATH=='site'))
{
get_base_url();/*force calculation first*/
$RELATIVE_PATH='';
}
require_code('users'); // Users are important due to permissions
if (($MICRO_BOOTUP==0) && ($MICRO_AJAX_BOOTUP==0)) // Fast cacheing for Guests
{
if ((running_script('index')) && (count($_POST)==0))
{
if ((isset($SITE_INFO['any_guest_cached_too'])) && ($SITE_INFO['any_guest_cached_too']=='1') && (is_guest(NULL,true)))
{
fast_spider_cache(false);
}
}
}
$CACHE_TEMPLATES=((get_option('is_on_template_cache')=='1') || (get_param_integer('keep_cache',0)==1) || (get_param_integer('cache',0)==1)) && (get_param_integer('keep_cache',NULL)!==0) && (get_param_integer('cache',NULL)!==0);
if ($MICRO_AJAX_BOOTUP==0)
{
require_code('temporal'); // Date/time functions
require_code('files'); // Contains fix_permissions, needed for 'lang'
require_code('lang'); // So that we can do language stuff (e.g. errors)
convert_data_encodings();
if ($MICRO_BOOTUP==0)
{
require_code('permissions'); // So we can check access
}
}
// At this point we can display errors nicely
$GLOBALS['SUPRESS_ERROR_DEATH']=false;
set_error_handler('ocportal_error_handler');
if (function_exists('error_get_last')) register_shutdown_function('catch_fatal_errors');
$HAS_SET_ERROR_HANDLER=true;
if ($MICRO_BOOTUP==0)
{
if (method_exists($GLOBALS['FORUM_DRIVER'],'forum_layer_initialise')) $GLOBALS['FORUM_DRIVER']->forum_layer_initialise();
}
if ($MICRO_AJAX_BOOTUP==0)
{
$JAVASCRIPT=new ocp_tempcode();
}
if ($MICRO_BOOTUP==0)
{
if (($IN_MINIKERNEL_VERSION!=1) && ($MICRO_AJAX_BOOTUP==0))
{
has_cookies(); // Will determine at early point whether we have cookie support
get_num_users_site(); // Will kill site if there are too many users
}
}
require_code('urls'); // URL building is crucial
@header('Content-type: text/html; charset='.get_charset());
if (($MICRO_AJAX_BOOTUP==0) && ($MICRO_BOOTUP==0))
{
// Before anything gets outputted
handle_logins();
require_code('site'); // This powers the site (top level page generation)
// Are we installed?
get_option('site_name');
}
// Our logging (change false to true for temporarily changing it so staff get logging)
if (get_option('log_php_errors')=='1')
{
@ini_set('log_errors','1');
if (addon_installed('errorlog'))
@ini_set('error_log',get_custom_file_base().'/data_custom/errorlog.php');
}
if (($MICRO_BOOTUP==0) && ($MICRO_AJAX_BOOTUP==0) && ((get_option('display_php_errors')=='1') || (running_script('upgrader')) || (has_specific_permission(get_member(),'see_php_errors'))))
{
@ini_set('display_errors','1');
} elseif (!$GLOBALS['DEBUG_MODE']) @ini_set('display_errors','0');
// G-zip?
@ini_set('zlib.output_compression',(get_option('gzip_output')=='1')?'On':'Off');
if ((function_exists('setlocale')) && ($MICRO_AJAX_BOOTUP==0))
{
$locales=explode(',',do_lang('locale'));
setlocale(LC_ALL,$locales[0]);
@setlocale(LC_ALL,$locales);
unset($locales);
}
if (($MICRO_AJAX_BOOTUP==0) && ($MICRO_BOOTUP==0) && ((!isset($SITE_INFO['no_installer_checks'])) || ($SITE_INFO['no_installer_checks']=='0')))
{
if ((is_file(get_file_base().'/install.php')) && (!is_file(get_file_base().'/install_ok')) && (running_script('index')))
warn_exit(do_lang_tempcode('MUST_DELETE_INSTALLER'));
}
if (($MICRO_AJAX_BOOTUP==0) && ($MICRO_BOOTUP==0))
{
$changed_base_url=!array_key_exists('base_url',$SITE_INFO) && get_long_value('last_base_url')!==get_base_url(false);
if ((running_script('index')) && ((is_browser_decacheing()) || ($changed_base_url)))
{
require_code('view_modes');
erase_tempcode_cache();
erase_cached_templates(!$changed_base_url);
erase_cached_language();
persistant_cache_empty();
if ($changed_base_url)
{
require_lang('zones');
require_code('zones3');
erase_comcode_page_cache();
set_long_value('last_base_url',get_base_url(false));
}
}
if (has_zone_access(get_member(),'adminzone'))
{
$JAVASCRIPTS['javascript_staff']=1;
$JAVASCRIPTS['javascript_ajax']=1;
if (addon_installed('occle')) $JAVASCRIPTS['javascript_button_occle']=1;
}
if ((addon_installed('realtime_rain')) && (get_option('bottom_show_realtime_rain_button',true)==='1')) $JAVASCRIPTS['javascript_button_realtime_rain']=1;
}
/*ocp_memory_profile('startup');
$func=get_defined_functions();
print_r($func['user']);*/
if (((ocp_srv('HTTPS')!='') && (ocp_srv('HTTPS')!='off')) && (((!defined('HIPHOP_PHP')) || (tacit_https()) || (is_page_https(get_zone_name(),get_page_name()))))) // Fix IE bug
{
@header('Cache-Control: private');
@header('Pragma: private');
}
$BOOTSTRAPPING=0;
if (($GLOBALS['SEMI_DEBUG_MODE']) && ($MICRO_AJAX_BOOTUP==0)) // Lots of code that only runs if you're a programmer. It tries to make sure coding standards are met.
{
if ($GLOBALS['SEMI_DEBUG_MODE'])
{
/*if ((mt_rand(0,2)==1) && ($GLOBALS['DEBUG_MODE']) && (running_script('index'))) We know this works now, so let's stop messing up our development speed
{
require_code('view_modes');
erase_cached_templates(true); // Stop anything trying to read a template cache item (E.g. CSS, JS) that might not exist!
}*/
if ((strpos(ocp_srv('HTTP_REFERER'),ocp_srv('HTTP_HOST'))!==false) && (strpos(ocp_srv('HTTP_REFERER'),'keep_devtest')!==false) && (!running_script('attachment')) && (!running_script('upgrader')) && (strpos(ocp_srv('HTTP_REFERER'),'login')===false) && (is_null(get_param('keep_devtest',NULL))))
{
$_GET['keep_devtest']='1';
fatal_exit('URL not constructed properly: development mode in use but keep_devtest was not specified. This indicates that links have been made without build_url (in PHP) or keep_stub (in Javascript). Whilst not fatal this time, failure to use these functions can cause problems when your site goes live. See the ocPortal codebook for more details.');
} else $_GET['keep_devtest']='1';
}
if ((browser_matches('true_xhtml')) && (get_value('html5')!=='1') && (get_value('html5')!=='_true'/*TODO: deprecate old _true check*/) && (get_param_integer('keep_no_xhtml',0)==0) && (!running_script('upgrader'))) // In theory this is supported (and mostly does work), but a lot of necessary Javascript is not standardised, and the browser's that support XHTML properly do not agree on how to implement this Javascript in a usable way when it is enabled. This leads to a lot of corner-cases. If you're seeing this code enabled, it was possible for us to resolve them, otherwise not yet.
{
@header('Content-type: application/xhtml+xml; charset='.get_charset());
}
if (isset($_CREATED_FILES)) // Comes from ocProducts custom PHP version
{
/**
* Run after-tests for debug mode, to make sure coding standards are met.
*/
function debug_mode_aftertests()
{
global $_CREATED_FILES,$_MODIFIED_FILES;
// Use the info from ocProduct's custom PHP version to make sure that all files that were created/modified got synched as they should have been.
foreach ($_CREATED_FILES as $file)
{
if ((substr($file,0,strlen(get_file_base()))==get_file_base()) && (substr($file,-4)!='.log') && (basename($file)!='permissioncheckslog.php'))
@exit(escape_html('File not permission-synched: '.$file));
}
foreach ($_MODIFIED_FILES as $file)
{
if ((strpos($file,'_cache')===false) && (substr($file,0,strlen(get_file_base()))==get_file_base()) && (substr($file,-4)!='.log') && (basename($file)!='permissioncheckslog.php'))
@exit(escape_html('File not change-synched: '.$file));
}
global $TITLE_CALLED,$SCREEN_TEMPLATE_CALLED,$EXITING;
if ((is_null($SCREEN_TEMPLATE_CALLED)) && ($EXITING==0) && (strpos(ocp_srv('PHP_SELF'),'index.php')!==false)) @exit(escape_html('No screen template called.'));
if ((!$TITLE_CALLED) && ((is_null($SCREEN_TEMPLATE_CALLED)) || ($SCREEN_TEMPLATE_CALLED!='')) && ($EXITING==0) && (strpos(ocp_srv('PHP_SELF'),'index.php')!==false)) @exit(escape_html('No title used on screen.'));
}
register_shutdown_function('debug_mode_aftertests');
}
if ((ocp_srv('SCRIPT_FILENAME')!='') && ($GLOBALS['DEBUG_MODE']) && (strpos(ocp_srv('SCRIPT_FILENAME'),'data_custom')===false))
{
if (@strlen(file_get_contents(ocp_srv('SCRIPT_FILENAME'),FILE_TEXT))>4500)
{
fatal_exit('Entry scripts (front controllers) should not be shoved full of code.');
}
}
}
// FirePHP console support, only for administrators
if (((get_param_integer('keep_firephp',0)==1) || (get_param_integer('keep_queries',0)==1)) && (($GLOBALS['FORUM_DRIVER']->is_super_admin(get_member())) || ($GLOBALS['IS_ACTUALLY_ADMIN'])))
{
require_code('firephp');
}
@ini_set('memory_limit','128M');
if ((isset($GLOBALS['FORUM_DRIVER'])) && ($GLOBALS['FORUM_DRIVER']->is_super_admin(get_member())))
{
if (get_param_integer('keep_avoid_memory_limit',0)==1)
{
disable_php_memory_limit();
}
$memory_test=get_param_integer('keep_memory_limit_test',0);
if (($memory_test!=0) && ($memory_test<=32))
{
@ini_set('memory_limit',strval($memory_test).'M');
}
}
if ((get_option('sitewide_im',true)==='1') && (running_script('index')) /* i.e. not running script */ && (get_param('type','misc',true)!='room'))
{
require_code('chat');
enter_chat_lobby();
}
// Startup hooks
if (!running_script('upgrader'))
{
$startup_hooks=find_all_hooks('systems','startup');
foreach (array_keys($startup_hooks) as $hook)
{
require_code('hooks/systems/startup/'.filter_naughty_harsh($hook));
$ob=object_factory('Hook_startup_'.filter_naughty_harsh($hook),true);
if ($ob===NULL) continue;
$ob->run($MICRO_BOOTUP,$MICRO_AJAX_BOOTUP,0);
}
if (($CURRENT_SHARE_USER!==NULL) && (float_to_raw_string(ocp_version_number())!=get_value('version')))
{
require_code('upgrade');
clear_caches_2();
version_specific();
upgrade_modules();
ocf_upgrade();
}
}
}
mixed str_word_count(string input, integer format)
Isolate the words in the input string.
Parameters…
| Name |
input |
| Description |
String to count words in |
| Type |
string |
| Name |
format |
| Description |
The format |
| Default value |
0 |
| Type |
integer |
| Values restricted to |
0 1 2 |
Returns…
| Description |
Typically a list - the words of the input string |
| Type |
mixed |
function str_word_count($input,$format=0)
{
//count words
$pattern="/[^(\w|\d|\'|\"|\.|\!|\?|;|,|\\|\/|\-\-|:|\&|@)]+/";
$all_words=trim(preg_replace($pattern,' ',$input));
$a=array();
$pos=0;
while (true)
{
$old_pos=$pos;
$pos=strpos($all_words,' ',$pos);
if ($pos===false)
{
$a[$old_pos]=substr($all_words,$old_pos);
break;
}
$a[$old_pos]=substr($all_words,$old_pos,$pos-$old_pos);
}
if ($format==0) return count($a);
return $a;
}
string html_entity_decode(string input, integer quote_style, ?string charset)
Decode the HTML entitity encoded input string.
Parameters…
| Name |
input |
| Description |
The text to decode |
| Type |
string |
| Name |
quote_style |
| Description |
The quote style code |
| Type |
integer |
| Name |
charset |
| Description |
Character set to decode to (NULL: default) |
| Default value |
|
| Type |
?string |
Returns…
| Description |
The decoded text |
| Type |
string |
function html_entity_decode($input,$quote_style,$charset=NULL)
{
unset($quote_style);
unset($charset);
/* // NB:   does not go to <space>. It's not something you use with html escaping, it's for hard-space-formatting. URL's don't contain spaces, but that's due to URL escaping (%20)
$replace_array=array(
'&'=>'&',
'>'=>'>',
'<'=>'<',
'''=>'\'',
'"'=>'"',
);
foreach ($replace_array as $from=>$to)
{
$input=str_replace($from,$to,$input);
}
return $input;*/
$trans_tbl=get_html_translation_table(HTML_ENTITIES);
$trans_tbl=array_flip($trans_tbl);
return strtr($input,$trans_tbl);
}
~string unichrm_hex(array matches)
Convert a unicode character number to a unicode string. Callback for preg_replace.
Parameters…
| Name |
matches |
| Description |
Regular expression match array. |
| Type |
array |
Returns…
| Description |
Converted data (false: could not convert). |
| Type |
~string |
function unichrm_hex($matches)
{
return unichr(hexdec($matches[1]));
}
~string unichrm(array matches)
Convert a unicode character number to a unicode string. Callback for preg_replace.
Parameters…
| Name |
matches |
| Description |
Regular expression match array. |
| Type |
array |
Returns…
| Description |
Converted data (false: could not convert). |
| Type |
~string |
function unichrm($matches)
{
return unichr(intval($matches[1]));
}
~string unichr(integer c)
Convert a unicode character number to a HTML-entity enabled string, using lower ASCII characters where possible.
Parameters…
| Name |
c |
| Description |
Character number. |
| Type |
integer |
Returns…
| Description |
Converted data (false: could not convert). |
| Type |
~string |
function unichr($c)
{
if ($c<=0x7F)
{
return chr($c);
} else
{
return '#&'.strval($c).';';
}
}
void debug_mode_aftertests()
Run after-tests for debug mode, to make sure coding standards are met.
Parameters…
(No return value)
function debug_mode_aftertests()
{
global $_CREATED_FILES,$_MODIFIED_FILES;
// Use the info from ocProduct's custom PHP version to make sure that all files that were created/modified got synched as they should have been.
foreach ($_CREATED_FILES as $file)
{
if ((substr($file,0,strlen(get_file_base()))==get_file_base()) && (substr($file,-4)!='.log') && (basename($file)!='permissioncheckslog.php'))
@exit(escape_html('File not permission-synched: '.$file));
}
foreach ($_MODIFIED_FILES as $file)
{
if ((strpos($file,'_cache')===false) && (substr($file,0,strlen(get_file_base()))==get_file_base()) && (substr($file,-4)!='.log') && (basename($file)!='permissioncheckslog.php'))
@exit(escape_html('File not change-synched: '.$file));
}
global $TITLE_CALLED,$SCREEN_TEMPLATE_CALLED,$EXITING;
if ((is_null($SCREEN_TEMPLATE_CALLED)) && ($EXITING==0) && (strpos(ocp_srv('PHP_SELF'),'index.php')!==false)) @exit(escape_html('No screen template called.'));
if ((!$TITLE_CALLED) && ((is_null($SCREEN_TEMPLATE_CALLED)) || ($SCREEN_TEMPLATE_CALLED!='')) && ($EXITING==0) && (strpos(ocp_srv('PHP_SELF'),'index.php')!==false)) @exit(escape_html('No title used on screen.'));
}
boolean can_fast_spider_cache()
Find if we can use the fast spider cache.
Parameters…
Returns…
| Description |
Whether we can |
| Type |
boolean |
function can_fast_spider_cache()
{
if (isset($_GET['keep_session'])) return false;
if (isset($_GET['redirect'])) return false;
if (isset($_GET['zone'])) return false;
if (isset($_GET['date'])) return false;
$url_easy=get_self_url_easy();
if (strpos($url_easy,'sort=')!==false) return false;
if (strpos($url_easy,'start=')!==false) return false;
if (strpos($url_easy,'max=')!==false) return false;
return true;
}
void fast_spider_cache(boolean bot)
If possible dump the user to 100% static caching.
Parameters…
| Name |
bot |
| Description |
Whether to cache as a bot |
| Default value |
boolean-true |
| Type |
boolean |
(No return value)
function fast_spider_cache($bot=true)
{
global $SITE_INFO;
require_code('urls');
if (!can_fast_spider_cache()) return;
$fast_cache_path=get_custom_file_base().'/persistant_cache/'.md5(serialize(get_self_url_easy()));
if (!$bot) $fast_cache_path.='__non-bot';
if (!array_key_exists('js_on',$_COOKIE)) $fast_cache_path.='__no-js';
$fast_cache_path.='.gcd';
if (is_file($fast_cache_path))
{
$expires=60*60*intval($SITE_INFO['fast_spider_cache']);
$mtime=filemtime($fast_cache_path);
if ($mtime>time()-$expires)
{
if ($bot) // Only bots can do this, as they won't try to login and end up reaching a previously cached page
{
header("Pragma: public");
header("Cache-Control: maxage=".strval($expires));
header('Expires: '.gmdate('D, d M Y H:i:s',time()+$expires).' GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s',$mtime).' GMT');
$since=ocp_srv('HTTP_IF_MODIFIED_SINCE');
if ($since!='')
{
if (strtotime($since)<$mtime)
{
header('HTTP/1.0 304 Not Modified');
exit();
}
}
}
if (function_exists('gzencode'))
{
ini_set('zlib.output_compression','Off');
header('Content-Encoding: gzip');
}
exit(file_get_contents($fast_cache_path));
} else
{
@unlink($fast_cache_path);
sync_file($fast_cache_path);
}
}
}
void disable_php_memory_limit()
Disable the PHP memory limit. Do not use this carelessly, use it if a screen is a bit fat or in an importer, don't use it assuming memory is infinite.
Parameters…
(No return value)
function disable_php_memory_limit()
{
$shl=@ini_get('suhosin.memory_limit');
if (($shl===false) || ($shl=='') || ($shl=='0'))
{
@ini_set('memory_limit','128M');
@ini_set('memory_limit','-1');
} else
{
@ini_set('memory_limit',$shl);
}
}
string get_charset()
Get the character set to use. We try and be clever to allow AJAX scripts to avoid loading up language
Parameters…
Returns…
| Description |
The character set |
| Type |
string |
function get_charset()
{
global $CHARSET;
if (isset($CHARSET)) return $CHARSET;
global $SITE_INFO;
if (isset($SITE_INFO['charset'])) // An optimisation, if you want to put it in here
{
$CHARSET=$SITE_INFO['charset'];
return $CHARSET;
}
if (function_exists('do_lang'))
{
$attempt=do_lang('charset',NULL,NULL,NULL,NULL,false);
if ($attempt!==NULL)
{
$CHARSET=$attempt;
return $attempt;
}
}
global $TEMP_CHARSET;
if (isset($TEMP_CHARSET)) return $TEMP_CHARSET;
global $SITE_INFO;
$lang=array_key_exists('default_lang',$SITE_INFO)?$SITE_INFO['default_lang']:'EN';
$path=get_file_base().'/lang_custom/'.$lang.'/global.ini';
if (!is_file($path)) $path=get_file_base().'/lang/'.$lang.'/global.ini';
if (!is_file($path))
{
$path=get_file_base().'/lang_custom/'.$lang.'/global.po';
if (is_file($path))
{
$TEMP_CHARSET='utf-8';
return $TEMP_CHARSET;
}
}
if (!is_file($path))
{
$path=get_file_base().'/lang_custom/'.$lang.'/global-'.strtolower($lang).'.po';
if (is_file($path))
{
$TEMP_CHARSET='utf-8';
return $TEMP_CHARSET;
}
}
if (!is_file($path)) $path=get_file_base().'/lang/EN/global.ini';
$file=fopen($path,'rt');
$contents=str_replace(chr(13),chr(10),fread($file,3000));
fclose($file);
$matches=array();
if (preg_match('#\[strings\].*charset=([\w\-]+)\n#s',$contents,$matches)!=0)
{
$TEMP_CHARSET=$matches[1];
return $TEMP_CHARSET;
}
$TEMP_CHARSET='iso-8859-1';
return $TEMP_CHARSET;
}
void load_user_stuff()
Load stuff that allows user code to work.
Parameters…
(No return value)
function load_user_stuff()
{
if ((!array_key_exists('FORUM_DRIVER',$GLOBALS)) || ($GLOBALS['FORUM_DRIVER']===NULL)) // Second clause is for Quercus, as it pre-NULLs referenced variables
{
global $SITE_INFO;
require_code('forum_stub');
if (!array_key_exists('forum_type',$SITE_INFO)) $SITE_INFO['forum_type']='ocf';
require_code('forum/'.$SITE_INFO['forum_type']); // So we can at least get user details
$GLOBALS['FORUM_DRIVER']=object_factory('forum_driver_'.filter_naughty_harsh($SITE_INFO['forum_type']));
if (($SITE_INFO['forum_type']=='ocf') && (get_db_forums()==get_db_site()) && ($GLOBALS['FORUM_DRIVER']->get_drivered_table_prefix()==get_table_prefix()) && (!$GLOBALS['DEBUG_MODE'])) // NB: In debug mode needs separating so we can properly test our boundaries
{
$GLOBALS['FORUM_DRIVER']->connection=$GLOBALS['SITE_DB'];
}
elseif ($SITE_INFO['forum_type']!='none')
{
$GLOBALS['FORUM_DRIVER']->connection=new database_driver(get_db_forums(),get_db_forums_host(),get_db_forums_user(),get_db_forums_password(),$GLOBALS['FORUM_DRIVER']->get_drivered_table_prefix());
}
$GLOBALS['FORUM_DRIVER']->MEMBER_ROWS_CACHED=array();
$GLOBALS['FORUM_DB']=&$GLOBALS['FORUM_DRIVER']->connection;
}
}
void catch_fatal_errors()
ocPortal error catcher for fatal versions. This is hooked in only on PHP5.2 as error_get_last() only works on these versions.
Parameters…
(No return value)
function catch_fatal_errors()
{
if (!function_exists('error_get_last')) return;
$error=error_get_last();
if (!is_null($error))
{
if (!array_key_exists('message',$error)) return; // Needed for HipHop PHP
if (substr($error['message'],0,26)=='Maximum execution time of ')
{
if (function_exists('i_force_refresh'))
{
i_force_refresh();
}
}
//$tmp=$GLOBALS;unset($tmp['GLOBALS']);@var_dump($tmp);@exit();
//@var_dump(get_defined_functions()); exit(); // Useful for debugging memory problems, finding unneeded stuff that is loaded
switch($error['type'])
{
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$GLOBALS['SUPRESS_ERROR_DEATH']=false; // We can't recover as we've lost our execution track. Force a nice death rather than trying to display a recoverable error.
$GLOBALS['DYING_BADLY']=true; // Does not actually work unfortunately. @'d calls never get here at all.
ocportal_error_handler($error['type'],$error['message'],$error['file'],$error['line']);
}
}
}
boolean ocportal_error_handler(integer errno, PATH errstr, string errfile, integer errline)
ocPortal error handler (hooked into PHP error system).
Parameters…
| Name |
errno |
| Description |
The error code-number |
| Type |
integer |
| Name |
errstr |
| Description |
The error message |
| Type |
PATH |
| Name |
errfile |
| Description |
The file the error occurred in |
| Type |
string |
| Name |
errline |
| Description |
The line the error occurred on |
| Type |
integer |
Returns…
| Description |
Always false |
| Type |
boolean |
function ocportal_error_handler($errno,$errstr,$errfile,$errline)
{
if ((error_reporting()==0) && (!$GLOBALS['DYING_BADLY'])) return false; // This actually tells if @ was used oddly enough. You wouldn't figure from the PHP docs.
if ((error_reporting() & $errno) || ($GLOBALS['DYING_BADLY']))
{
// Strip down path for security
if (substr(str_replace(DIRECTORY_SEPARATOR,'/',$errfile),0,strlen(get_file_base().'/'))==str_replace(DIRECTORY_SEPARATOR,'/',get_file_base().'/'))
$errfile=substr($errfile,strlen(get_file_base().'/'));
// Work out the error type
if (!defined('E_RECOVERABLE_ERROR')) define('E_RECOVERABLE_ERROR',4096);
switch ($errno)
{
case E_RECOVERABLE_ERROR: // constant not defined in all php versions but we defined it
case E_USER_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_ERROR:
$type='error';
break;
case -123: // Hacked in for the memtrack extension, which was buggy
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_USER_WARNING:
case E_WARNING:
$type='warning';
break;
//case E_STRICT: (constant not defined in all php versions)
//case E_DEPRECATED: (constant not defined in all php versions)
//case E_USER_DEPRECATED: (constant not defined in all php versions)
case E_USER_NOTICE:
case E_NOTICE:
$type='notice';
break;
default: // We don't know the error type so it's probably best to continue (could be a problem with something getting deprecated)
return false;
}
$GLOBALS['DYING_BADLY']=false; // So error suppress works again
if (strpos($errstr,'Allowed memory')!==false)
{
global $_REQUIRED_CODE;
if (!array_key_exists('failure',$_REQUIRED_CODE))
{
critical_error('EMERGENCY',$errstr.' ['.$errfile.' at '.strval($errline).']');
}
}
require_code('failure');
_ocportal_error_handler($type,$errno,$errstr,$errfile,$errline);
}
return false;
}
boolean is_browser_decacheing()
Find whether the browser session is set to be doing a hard cache-empty refresh.
Parameters…
Returns…
| Description |
Whether the browser session is set to be doing a hard cache-empty refresh |
| Type |
boolean |
function is_browser_decacheing()
{
global $BROWSER_DECACHEING;
if ($BROWSER_DECACHEING!==NULL) return $BROWSER_DECACHEING;
if (is_null(get_value('ran_once')))
{
set_value('ran_once','1');
return true;
}
$header_method=(array_key_exists('HTTP_CACHE_CONTROL',$_SERVER)) && ($_SERVER['HTTP_CACHE_CONTROL']=='no-cache') && (ocp_srv('REQUEST_METHOD')!='POST') && ((!function_exists('browser_matches')) || (!browser_matches('opera')));
$BROWSER_DECACHEING=(($header_method) && ((array_key_exists('FORUM_DRIVER',$GLOBALS)) && (has_actual_page_access(get_member(),'admin_cleanup')) || ($GLOBALS['IS_ACTUALLY_ADMIN'])));
return $BROWSER_DECACHEING;
}
boolean running_script(string is_this_running)
Find whether a certain script is being run to get here.
Parameters…
| Name |
is_this_running |
| Description |
Script filename (canonically we want NO .php file type suffix) |
| Type |
string |
Returns…
| Description |
Whether the script is running |
| Type |
boolean |
function running_script($is_this_running)
{
// First check cache
global $RUNNING_SCRIPT_CACHE;
if (isset($RUNNING_SCRIPT_CACHE[$is_this_running.'.php'])) return $RUNNING_SCRIPT_CACHE[$is_this_running.'.php'];
if (isset($RUNNING_SCRIPT_CACHE[$is_this_running])) return $RUNNING_SCRIPT_CACHE[$is_this_running];
// Make $is_this_running fully-qualified, to stop common filename prefixes matching with a stem compare
if (substr($is_this_running,-4)!='.php') $is_this_running.='.php';
// Strip down current URL so we can do a simple stem compare
$stripped_current_url=preg_replace('#^.*/#','',function_exists('ocp_srv')?ocp_srv('PHP_SELF'):$_SERVER['PHP_SELF']);
// Do the stem compare
$answer=(substr($stripped_current_url,0,strlen($is_this_running))==$is_this_running);
// Cache and return result
$RUNNING_SCRIPT_CACHE[$is_this_running]=$answer;
return $answer;
}
void inform_exit(mixed text)
This is a intended to output an informational exit at the same time as terminating execution
Parameters…
| Name |
text |
| Description |
The error message (string or tempcode) |
| Type |
mixed |
(No return value)
function inform_exit($text)
{
require_code('failure'); // It's in failure.php although this isn't REALLY failure. Still it's an exceptional event so we can't justify loading the code as global.
_generic_exit($text,'INFORM_SCREEN');
}
void warn_exit(mixed text)
This is a less-revealing alternative to fatal_exit, that is used for user-errors/common-corruption-scenarios
Parameters…
| Name |
text |
| Description |
The error message (string or tempcode) |
| Type |
mixed |
(No return value)
function warn_exit($text)
{
require_code('failure');
suggest_fatalistic();
_generic_exit($text,'WARN_SCREEN');
if (running_script('cron_bridge'))
relay_error_notification(is_object($text)?$text->evaluate():escape_html($text),false,'error_occurred_cron');
}
void suggest_fatalistic()
Give the user an option to see a stack trace by adding in a link, but only if they have permission
Parameters…
(No return value)
function suggest_fatalistic()
{
if ((may_see_stack_dumps()) && (get_param_integer('keep_fatalistic',0)==0) && (running_script('index')))
{
if (count($_POST)==0)
{
$stack_trace_url=build_url(array('page'=>'_SELF','keep_fatalistic'=>1),'_SELF',NULL,true);
$st=do_lang_tempcode('WARN_TO_STACK_TRACE',escape_html($stack_trace_url->evaluate()));
} elseif (count($_FILES)==0)
{
$stack_trace_url=build_url(array('page'=>'_SELF','keep_fatalistic'=>1),'_SELF',NULL,true);
$p=build_keep_post_fields();
$st=do_lang_tempcode('WARN_TO_STACK_TRACE_2',escape_html($stack_trace_url->evaluate()),$p->evaluate());
} else
{
$stack_trace_url=build_url(array('page'=>'','keep_fatalistic'=>1),'');
$st=do_lang_tempcode('WARN_TO_STACK_TRACE_3',escape_html($stack_trace_url->evaluate()));
}
require_code('site');
attach_message($st,'inform');
}
}
void fatal_exit(mixed text)
Do a fatal exit, echo the header (if possible) and an error message, followed by a debugging back-trace.It also adds an entry to the error log, for reference.
Parameters…
| Name |
text |
| Description |
The error message (string or tempcode) |
| Type |
mixed |
(No return value)
function fatal_exit($text)
{
require_code('failure');
_fatal_exit($text);
}
void log_hack_attack_and_exit(ID_TEXT reason, SHORT_TEXT reason_param_a, SHORT_TEXT reason_param_b, boolean silent)
Log a hackattack, then displays an error message. It also attempts to send an e-mail to the staff alerting them of the hackattack.
Parameters…
| Name |
reason |
| Description |
The reason for the hack attack. This has to be a language string codename |
| Type |
ID_TEXT |
| Name |
reason_param_a |
| Description |
A parameter for the hack attack language string (this should be based on a unique ID, preferably) |
| Default value |
|
| Type |
SHORT_TEXT |
| Name |
reason_param_b |
| Description |
A more illustrative parameter, which may be anything (e.g. a title) |
| Default value |
|
| Type |
SHORT_TEXT |
| Name |
silent |
| Description |
Whether to silently log the hack rather than also exiting |
| Default value |
boolean-false |
| Type |
boolean |
(No return value)
function log_hack_attack_and_exit($reason,$reason_param_a='',$reason_param_b='',$silent=false)
{
require_code('failure');
_log_hack_attack_and_exit($reason,$reason_param_a,$reason_param_b,$silent);
}
boolean handle_has_checked_recently(ID_TEXT id_code)
Use the url_title_cache table (a bit of a hack but saved changed the DB structure) to see if a check-op was performed has been performed within the last 30 days.
Parameters…
| Name |
id_code |
| Description |
Special check code (often a URL but does not need to be). |
| Type |
ID_TEXT |
Returns…
| Description |
Whether the check has happened recently. |
| Type |
boolean |
function handle_has_checked_recently($id_code)
{
$last_check_test=$GLOBALS['SITE_DB']->query_value_null_ok('url_title_cache','t_title',array('t_url'=>'!'.$id_code));
if ((is_null($last_check_test)) || (substr($last_check_test,0,1)!='!') || (intval(substr($last_check_test,1))+60*60*24*30<time())) // only re-checks every 30 days
{
// Show when it was last tested
$GLOBALS['SITE_DB']->query_delete('url_title_cache',array('t_url'=>'!'.$id_code),'',1); // To make sure it can insert below
$GLOBALS['SITE_DB']->query_insert('url_title_cache',array('t_title'=>'!'.strval(time()),'t_url'=>'!'.$id_code),false,true); // To stop weird race-like conditions
return false;
}
return true;
}
integer make_seed()
A custom random number seed generator. It returns a random number seed.
Parameters…
Returns…
| Description |
A random seed |
| Type |
integer |
function make_seed()
{
list($usec,$sec)=explode(' ', microtime(false));
$u=uniqid('');
return intval(floatval($sec)*floatval($usec))+ord(substr($u,0,1))+(ord(substr($u,1,2))<<8);
}
string ocp_version_full()
Get the full string version of ocPortal that you are running.
Parameters…
Returns…
| Description |
The string saying the full ocPortal version number |
| Type |
string |
function ocp_version_full()
{
$minor=ocp_version_minor();
return strval(ocp_version()).(($minor=='')?'':(is_numeric($minor[0])?'.':'-').$minor);
}
string get_domain()
Get the domain the website is installed on (preferably, without any www). The domain is used for e-mail defaults amongst other things.
Parameters…
Returns…
| Description |
The domain of the website |
| Type |
string |
function get_domain()
{
global $SITE_INFO;
$ret=array_key_exists('domain',$SITE_INFO)?$SITE_INFO['domain']:'';
if ($ret=='')
{
if ((!array_key_exists('base_url',$SITE_INFO)) || ($SITE_INFO['base_url']=='')) return array_key_exists('HTTP_HOST',$_SERVER)?preg_replace('#^www\.#','',$_SERVER['HTTP_HOST']):'localhost'; // Can't be ocp_srv due to bootstrap order
$matches=array();
preg_match('#://([^/\#]+)#',$SITE_INFO['base_url'],$matches);
$ret=preg_replace('#^www\.#','',$matches[1]);
}
return $ret;
}
string get_forum_type()
Get the type of forums installed.
Parameters…
Returns…
| Description |
The type of forum installed |
| Type |
string |
function get_forum_type()
{
global $SITE_INFO;
if (!isset($SITE_INFO['forum_type'])) $SITE_INFO['forum_type']='ocf';
return $SITE_INFO['forum_type'];
}
URLPATH get_forum_base_url(boolean forum_base)
Get the installed forum base URL.
Parameters…
| Name |
forum_base |
| Description |
Whether to get the base directory of the forum. Unless running OCF, this makes no difference - if possibly running OCF, you need to think about this parameter: are you trying to reach the MSN-central-site or just a link to the forums? |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
The installed forum base URL |
| Type |
URLPATH |
function get_forum_base_url($forum_base=false)
{
global $SITE_INFO;
if (!array_key_exists('board_prefix',$SITE_INFO)) $SITE_INFO['board_prefix']=get_base_url();
$forum_type=get_forum_type();
if ($forum_type=='none') return '';
$needs_forum_strip=(substr($SITE_INFO['board_prefix'],-6)=='/forum') && (substr(get_base_url(),-6)!='/forum');
if (($forum_type=='ocf') && (!$forum_base) && ($needs_forum_strip)) return substr($SITE_INFO['board_prefix'],0,strlen($SITE_INFO['board_prefix'])-6);
if (($forum_type=='ocf') && ($forum_base) && ($needs_forum_strip)) return $SITE_INFO['board_prefix'].'/forum';
return $SITE_INFO['board_prefix'];
}
?string get_cookie_path()
Get the ocPortal cookie path.
Parameters…
Returns…
| Description |
The ocPortal cookie path (NULL: no special path, global) |
| Type |
?string |
function get_cookie_path()
{
global $SITE_INFO;
$ret=array_key_exists('cookie_path',$SITE_INFO)?$SITE_INFO['cookie_path']:'/';
return ($ret=='')?NULL:$ret;
}
?string get_cookie_domain()
Get the ocPortal cookie domain.
Parameters…
Returns…
| Description |
The ocPortal cookie domain (NULL: current domain) |
| Type |
?string |
function get_cookie_domain()
{
global $SITE_INFO;
$ret=array_key_exists('cookie_domain',$SITE_INFO)?$SITE_INFO['cookie_domain']:NULL;
return ($ret=='')?NULL:$ret;
}
integer get_cookie_days()
Get the number of days to store our cookies.
Parameters…
Returns…
| Description |
The number of days to store our cookies |
| Type |
integer |
function get_cookie_days()
{
global $SITE_INFO;
return array_key_exists('cookie_domain',$SITE_INFO)?intval($SITE_INFO['cookie_days']):120;
}
string get_site_name()
Get the site name.
Parameters…
Returns…
| Description |
The name of the site |
| Type |
string |
function get_site_name()
{
return get_option('site_name');
}
boolean in_safe_mode()
Find whether we are running in safe mode.
Parameters…
Returns…
| Description |
Whether we are in safe mode |
| Type |
boolean |
function in_safe_mode()
{
global $CHECKING_SAFEMODE;
if ($CHECKING_SAFEMODE) return false; // Stops infinite loops (e.g. Check safe mode > Check access > Check usergroups > Check implicit usergroup hooks > Check whether to look at custom implicit usergroup hooks [i.e. if not in safe mode])
$CHECKING_SAFEMODE=true;
$ret=((get_param_integer('keep_safe_mode',0)==1) && ((isset($GLOBALS['IS_ACTUALLY_ADMIN']) && ($GLOBALS['IS_ACTUALLY_ADMIN'])) || (!array_key_exists('FORUM_DRIVER',$GLOBALS)) || ($GLOBALS['FORUM_DRIVER']===NULL) || (!function_exists('get_member')) || ($GLOBALS['FORUM_DRIVER']->is_super_admin(get_member()))));
$CHECKING_SAFEMODE=false;
return $ret;
}
URLPATH find_script(string name, boolean append_keep, integer base_url_code)
Find the URL to a certain external handler script (ocPortal allows these to be moved around between zones, to suit site .htaccess requirements).
Parameters…
| Name |
name |
| Description |
The codename of the needed script |
| Type |
string |
| Name |
append_keep |
| Description |
Whether to append keep variables |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
base_url_code |
| Description |
Code representing what base URL type to use (0=guess, 1=http, 2=https) |
| Default value |
0 |
| Type |
integer |
| Values restricted to |
0 1 2 |
Returns…
| Description |
The URL to the script |
| Type |
URLPATH |
function find_script($name,$append_keep=false,$base_url_code=0)
{
$append='';
if ($append_keep)
{
$keep=symbol_tempcode('KEEP',array('1'));
$append.=$keep->evaluate();
}
global $CACHE_FIND_SCRIPT;
if ($CACHE_FIND_SCRIPT===array())
{
if (function_exists('persistant_cache_get')) $CACHE_FIND_SCRIPT=persistant_cache_get('SCRIPT_PLACES');
if ($CACHE_FIND_SCRIPT===NULL) $CACHE_FIND_SCRIPT=array();
}
if (isset($CACHE_FIND_SCRIPT[$name][$append_keep][$base_url_code])) return $CACHE_FIND_SCRIPT[$name][$append_keep][$base_url_code].$append;
$zones=array(get_zone_name());
if (!in_safe_mode())
{
$zones[]='data_custom';
}
$zones[]='data';
$zones=array_merge($zones,find_all_zones());
foreach ($zones as $zone)
{
if ($zone!='site') // If not found, we assume in here
{
if (is_file(get_file_base().'/'.$zone.'/'.$name.'.php'))
{
$ret=get_base_url().'/'.$zone.(($zone!='')?'/':'').$name.'.php';
$CACHE_FIND_SCRIPT[$name][$append_keep][$base_url_code]=$ret;
if (function_exists('persistant_cache_set')) persistant_cache_set('SCRIPT_PLACES',$CACHE_FIND_SCRIPT,true);
return $ret.$append;
}
}
}
$ret=get_base_url(($base_url_code==0)?NULL:($base_url_code==2)).'/site/'.$name.'.php';
$CACHE_FIND_SCRIPT[$name][$append_keep][$base_url_code]=$ret;
if (function_exists('persistant_cache_set')) persistant_cache_set('SCRIPT_PLACES',$CACHE_FIND_SCRIPT,true);
return $ret.$append;
}
URLPATH get_base_url(?boolean https, ?ID_TEXT zone_for)
Get the base url (the minimum fully qualified URL to our installation).
Parameters…
| Name |
https |
| Description |
Whether to get the HTTPS base URL (NULL: do so only if the current page uses the HTTPS base URL) |
| Default value |
|
| Type |
?boolean |
| Name |
zone_for |
| Description |
The zone the link is for (NULL: root zone) |
| Default value |
|
| Type |
?ID_TEXT |
Returns…
| Description |
The base-url |
| Type |
URLPATH |
function get_base_url($https=NULL,$zone_for=NULL)
{
if ($https===NULL) // If we don't know, we go by what the current page is
{
global $CURRENTLY_HTTPS;
$https=$CURRENTLY_HTTPS;
if ($https===NULL)
{
if ((get_option('enable_https',true)=='0') || (!running_script('index')))
{
$https=false;
} else
{
$https=function_exists('is_page_https') && function_exists('get_zone_name') && ((tacit_https()) || is_page_https(get_zone_name(),get_page_name()));
}
$CURRENTLY_HTTPS=$https;
}
}
global $BASE_URL_HTTP,$BASE_URL_HTTPS,$VIRTUALISED_ZONES;
if ($VIRTUALISED_ZONES===NULL)
{
require_code('zones');
get_zone_name();
}
if (($BASE_URL_HTTP!==NULL) && (!$https) && ((!$VIRTUALISED_ZONES) || ($zone_for===NULL))) return $BASE_URL_HTTP.(($zone_for=='')?'':('/'.$zone_for));
if (($BASE_URL_HTTPS!==NULL) && ($https) && ((!$VIRTUALISED_ZONES) || ($zone_for===NULL))) return $BASE_URL_HTTPS.(($zone_for=='')?'':('/'.$zone_for));
global $SITE_INFO;
if ((!isset($SITE_INFO)) || (!array_key_exists('base_url',$SITE_INFO)) || ($SITE_INFO['base_url']=='')) // Try and autodetect the base URL if it's not configured
{
$domain=ocp_srv('HTTP_HOST');
$colon_pos=strpos($domain,':');
if ($colon_pos!==false) $domain=substr($domain,0,$colon_pos);
$port=ocp_srv('SERVER_PORT');
if (($port=='') || ($port=='80') || ($port=='443')) $port=''; else $port=':'.$port;
$SITE_INFO['base_url']='http://'.$domain.$port.str_replace('%2F','/',rawurlencode(preg_replace('#/'.str_replace('#','\#',preg_quote($GLOBALS['RELATIVE_PATH'])).'$#','',str_replace('\\','/',dirname(ocp_srv('PHP_SELF'))))));
}
$base_url=$SITE_INFO['base_url'];
global $CURRENT_SHARE_USER;
if ($CURRENT_SHARE_USER!==NULL)
{
$base_url=preg_replace('#^http://([\w]+\.)?'.str_replace('#','\#',preg_quote($SITE_INFO['custom_share_domain'])).'#','http://'.ocp_srv('HTTP_HOST'),$base_url);
}
$found_mapping=false;
if ($VIRTUALISED_ZONES)
{
$zone_doing=($zone_for===NULL)?'':str_replace('/','',$zone_for);
if (array_key_exists('ZONE_MAPPING_'.$zone_doing,$SITE_INFO))
{
$domain=$SITE_INFO['ZONE_MAPPING_'.$zone_doing][0];
$path=$SITE_INFO['ZONE_MAPPING_'.$zone_doing][1];
$base_url='http://'.$domain;
if ($path!='') $base_url.='/'.$path;
$found_mapping=true;
}
}
if ($https)
{
$base_url='https://'.preg_replace('#^\w*://#','',$base_url);
if ((!$VIRTUALISED_ZONES) || ($zone_for===NULL)) $BASE_URL_HTTPS=$base_url;
} elseif ((!$VIRTUALISED_ZONES) || ($zone_for===NULL)) $BASE_URL_HTTP=$base_url;
if (!$found_mapping)
{
$base_url.=(($zone_for=='')?'':('/'.$zone_for));
}
return $base_url;
}
URLPATH get_custom_base_url(?boolean https)
Get the base url (the minimum fully qualified URL to our personal data installation). For a shared install only, this is different to the base-url.
Parameters…
| Name |
https |
| Description |
Whether to get the HTTPS base URL (NULL: do so only if the current page uses the HTTPS base URL) |
| Default value |
|
| Type |
?boolean |
Returns…
| Description |
The base-url |
| Type |
URLPATH |
function get_custom_base_url($https=NULL)
{
global $SITE_INFO;
if (!isset($SITE_INFO['custom_base_url_stub'])) return get_base_url($https);
// Note that HTTPS is not supported for shared installs
$u=current_share_user();
if ($u===NULL) return get_base_url($https);
return $SITE_INFO['custom_base_url_stub'].'/'.$u;
}
URLPATH get_complex_base_url(URLPATH at)
Function to get a base URL for an OCF relative-URL. The situation is complex as it needs to take into account OCF multi-site-network's, locally defined theme images, and shared-installs (myocp style).
Parameters…
| Name |
at |
| Description |
Short base URL we need to probe |
| Type |
URLPATH |
Returns…
| Description |
The appropriate base-url |
| Type |
URLPATH |
function get_complex_base_url($at)
{
return ((get_forum_base_url()!=get_base_url())?get_forum_base_url():((substr($at,0,22)=='themes/default/images/')?get_base_url():get_custom_base_url()));
}
?string either_param(ID_TEXT name, ?mixed default)
Get a value (either POST or GET), or the default if neither can be found.
Parameters…
| Name |
name |
| Description |
The name of the parameter to get |
| Type |
ID_TEXT |
| Name |
default |
| Description |
The default value to give the parameter if the parameter value is not defined (NULL: allow missing parameter) (false: give error on missing parameter) |
| Default value |
boolean-false |
| Type |
?mixed |
Returns…
| Description |
The parameter value (NULL: missing) |
| Type |
?string |
function either_param($name,$default=false)
{
$a=__param(array_merge($_POST,$_GET),$name,$default,false,NULL);
if ($a===NULL) return NULL;
if ($a!==$default) // Check input field security
{
require_code('input_filter');
check_input_field($name,$a);
}
return function_exists('ocp_url_decode_post_process')?ocp_url_decode_post_process($a):$a;
}
?string post_param(ID_TEXT name, ?mixed default, boolean html, boolean conv_from_wysiwyg)
Get the value of the specified POST key, if it is found, or the default otherwise.
Parameters…
| Name |
name |
| Description |
The name of the parameter to get |
| Type |
ID_TEXT |
| Name |
default |
| Description |
The default value to give the parameter if the parameter value is not defined (NULL: allow missing parameter) (false: give error on missing parameter) |
| Default value |
boolean-false |
| Type |
?mixed |
| Name |
html |
| Description |
Whether we are cleaning for HTML rather than Comcode/plain-text |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
conv_from_wysiwyg |
| Description |
Whether to convert WYSIWYG contents to Comcode automatically |
| Default value |
boolean-true |
| Type |
boolean |
Returns…
| Description |
The parameter value (NULL: missing) |
| Type |
?string |
function post_param($name,$default=false,$html=false,$conv_from_wysiwyg=true)
{
$a=__param($_POST,$name,$default,false,true);
if ($a===NULL) return NULL;
if ((trim($a)=='') && ($default!='') && (array_key_exists('require__'.$name,$_POST)) && ($_POST['require__'.$name]!='0'))
{
require_code('failure');
improperly_filled_in_post($name);
}
if (($a!='') && (addon_installed('wordfilter')))
{
if ($name!='password')
{
require_code('word_filter');
$a=check_word_filter($a,$name);
}
}
if ($a!==NULL) $a=unixify_line_format($a,NULL,$html);
if ((isset($_POST[$name.'__is_wysiwyg'])) && ($_POST[$name.'__is_wysiwyg']=='1') && ($conv_from_wysiwyg))
{
if (trim($a)=='')
{
$a='';
} else
{
require_code('comcode_from_html');
$a=trim(semihtml_to_comcode($a));
}
} else
{
if ((substr($a,0,10)=='[semihtml]') && (substr(trim($a),-11)=='[/semihtml]'))
{
$_a=trim($a);
$_a=substr($_a,10,strlen($_a)-11-10);
if (strpos($_a,'[semihtml')===false)
{
require_code('comcode_from_html');
$a=trim(semihtml_to_comcode($_a));
}
}
}
return function_exists('ocp_url_decode_post_process')?ocp_url_decode_post_process($a):$a;
}
?string get_param(ID_TEXT name, ?mixed default, boolean no_security)
Get the value of the specified GET key, if it is found, or the default otherwise.
Parameters…
| Name |
name |
| Description |
The name of the parameter to get |
| Type |
ID_TEXT |
| Name |
default |
| Description |
The default value to give the parameter if the parameter value is not defined (NULL: allow missing parameter) (false: give error on missing parameter) |
| Default value |
boolean-false |
| Type |
?mixed |
| Name |
no_security |
| Description |
Whether to skip the security check |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
The parameter value (NULL: missing) |
| Type |
?string |
function get_param($name,$default=false,$no_security=false)
{
$a=__param($_GET,$name,$default);
if (($a=='') && (isset($_GET['require__'.$name])) && ($default!==$a) && ($_GET['require__'.$name]!='0'))
{
// We didn't give some required input
$GLOBALS['HTTP_STATUS_CODE']='400';
if (!headers_sent())
{
if ((!browser_matches('ie')) && (strpos(ocp_srv('SERVER_SOFTWARE'),'IIS')===false)) header('HTTP/1.0 400 Bad Request');
}
warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN'));
}
if ($a===$default) return $a;
if (strpos($a,':')!==false)
$a=function_exists('ocp_url_decode_post_process')?ocp_url_decode_post_process($a):$a;
// Security check
$is_url=($name=='from') || ($name=='preview_url') || ($name=='redirect') || ($name=='redirect_passon') || ($name=='url');
if (($name!='s_message') && (!$is_url) && (!$no_security))
{
if (((isset($a[100])) && (strpos(substr($a,10),'::slash::slash:')===false) && (strpos(substr($a,10),'://')===false) && (strpos(substr($a,10),'::slash::slash:')===false)) || (preg_match('#\n|\000|<|(".*[=<>])|\.\./|^\s*((((j\s*a\s*v\s*a\s*)|(v\s*b\s*))?s\s*c\s*r\s*i\s*p\s*t)|(d\s*a\s*t\s*a\s*))\s*:#mi',$a)!=0))
{
log_hack_attack_and_exit('DODGY_GET_HACK',$name,$a);
}
} else
{
if ($is_url)
{
if (preg_match('#\n|\000|<|(".*[=<>])|^\s*((((j\s*a\s*v\s*a\s*)|(v\s*b\s*))?s\s*c\s*r\s*i\s*p\s*t)|(d\s*a\s*t\s*a\s*))\s*:#mi',$a)!=0)
{
log_hack_attack_and_exit('DODGY_GET_HACK',$name,$a);
}
$bu=get_base_url();
if ((looks_like_url($a)) && (substr($a,0,strlen($bu))!=$bu)) // Don't allow external redirections
{
$a=get_base_url();
}
}
}
if ($a===NULL) return NULL;
return $a;
}
string __param(array array, string name, ?mixed default, boolean integer, ?boolean posted)
Helper function to load up a GET/POST parameter.
Parameters…
| Name |
array |
| Description |
The array we're extracting parameters from |
| Type |
array |
| Name |
name |
| Description |
The name of the parameter |
| Type |
string |
| Name |
default |
| Description |
The default value to give the parameter if the parameter value is not defined (NULL: allow missing parameter) (false: give error on missing parameter) |
| Type |
?mixed |
| Name |
integer |
| Description |
Whether the parameter has to be an integer |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
posted |
| Description |
Whether the parameter is a POST parameter (NULL: undetermined) |
| Default value |
boolean-false |
| Type |
?boolean |
Returns…
| Description |
The value of the parameter |
| Type |
string |
function __param($array,$name,$default,$integer=false,$posted=false)
{
if ((!isset($array[$name])) || (($integer) && ($array[$name]=='')))
{
if ($default!==false) return $default;
require_code('failure');
improperly_filled_in($name,$posted,$array);
}
$val=$array[$name];
if (is_array($val)) $val=implode(',',$val);
if (get_magic_quotes_gpc()) $val=stripslashes($val);
if (($posted) && ($GLOBALS['BOOTSTRAPPING']==0) && ($GLOBALS['MICRO_AJAX_BOOTUP']==0)) // Check against fields.xml
{
require_code('input_filter');
return check_posted_field($name,$val);
}
return $val;
}
boolean simulated_wildcard_match(string context, string word, boolean full_cover)
Do a wildcard match by converting to a regular expression.
Parameters…
| Name |
context |
| Description |
The haystack |
| Type |
string |
| Name |
word |
| Description |
The needle (a wildcard expression) |
| Type |
string |
| Name |
full_cover |
| Description |
Whether full-coverance is required |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
Whether we have a match |
| Type |
boolean |
function simulated_wildcard_match($context,$word,$full_cover=false)
{
$rexp=str_replace('%','.*',str_replace('_','.',str_replace('\\?','.',str_replace('\\*','.*',preg_quote($word)))));
if ($full_cover) $rexp='^'.$rexp.'$';
return preg_match('#'.str_replace('#','\#',$rexp).'#i',$context)!=0;
}
?integer either_param_integer(ID_TEXT name, ?mixed default)
This function is the integeric partner of either_param, as it returns the value as an integer.You should always use integer specified versions when inputting integers, for the added security that type validation allows. If the value is of the wrong type, it indicates a hack attempt and will be logged.
Parameters…
| Name |
name |
| Description |
The name of the parameter to get |
| Type |
ID_TEXT |
| Name |
default |
| Description |
The default value to give the parameter if the parameter value is not defined or the empty string (NULL: allow missing parameter) (false: give error on missing parameter) |
| Default value |
boolean-false |
| Type |
?mixed |
Returns…
| Description |
The parameter value (NULL: not set, and NULL given as default) |
| Type |
?integer |
function either_param_integer($name,$default=false)
{
$ret=__param(array_merge($_POST,$_GET),$name,($default===false)?$default:(($default===NULL)?'':strval($default)),true,NULL); // $_REQUEST contains cookies too, so can't use
if (($default===NULL) && ($ret==='')) return NULL;
$ret=trim($ret);
if (!is_numeric($ret))
{
require_code('failure');
$ret=_param_invalid($name,$ret,true);
}
$reti=intval($ret);
if (($reti>2147483647) || ($reti<-2147483648))
{
require_code('failure');
_param_invalid($name,NULL,true);
}
return $reti;
}
?integer post_param_integer(ID_TEXT name, ?mixed default)
This function is the integeric partner of post_param, as it returns the value as an integer.
Parameters…
| Name |
name |
| Description |
The name of the parameter to get |
| Type |
ID_TEXT |
| Name |
default |
| Description |
The default value to give the parameter if the parameter value is not defined or the empty string (NULL: allow missing parameter) (false: give error on missing parameter) |
| Default value |
boolean-false |
| Type |
?mixed |
Returns…
| Description |
The parameter value (NULL: not set, and NULL given as default) |
| Type |
?integer |
function post_param_integer($name,$default=false)
{
$ret=__param($_POST,$name,($default===false)?$default:(($default===NULL)?'':strval($default)),true,true);
if (($default===NULL) && ($ret==='')) return NULL;
$ret=trim($ret);
if (!is_numeric($ret))
{
require_code('failure');
$ret=_param_invalid($name,$ret,true);
}
if ($ret=='0') return 0;
if ($ret=='1') return 1;
$reti=intval($ret);
$retf=floatval($reti);
if (($retf>2147483647.0) || ($retf<-2147483648.0))
{
if ($name!='security_image')
{
require_code('failure');
_param_invalid($name,NULL,true);
}
}
return $reti;
}
?integer get_param_integer(ID_TEXT name, ?mixed default, boolean not_string_ok)
This function is the integeric partner of get_param, as it returns the value as an integer.
Parameters…
| Name |
name |
| Description |
The name of the parameter to get |
| Type |
ID_TEXT |
| Name |
default |
| Description |
The default value to give the parameter if the parameter value is not defined or the empty string (NULL: allow missing parameter) (false: give error on missing parameter) |
| Default value |
boolean-false |
| Type |
?mixed |
| Name |
not_string_ok |
| Description |
If a string is given, use the default parameter rather than giving an error (only use this if you are suffering from a parameter conflict situation between different parts of ocPortal) |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
The parameter value (NULL: not set, and NULL given as default) |
| Type |
?integer |
function get_param_integer($name,$default=false,$not_string_ok=false)
{
$m_default=($default===false)?false:(isset($default)?(($default==0)?'0':strval($default)):'');
$ret=__param($_GET,$name,$m_default,true); // do not set $ret to mixed(), breaks bootstrapping
if ((!isset($default)) && ($ret==='')) return NULL;
$ret=trim($ret);
if (!is_numeric($ret))
{
if (substr($ret,-1)=='/') $ret=substr($ret,0,strlen($ret)-1);
if (!is_numeric($ret)) // Bizarre situation (bug in IIS?)
{
$matches=array();
if (preg_match('#^(\d+)\#[\w]*$#',$ret,$matches)!=0)
{
$ret=$matches[1];
} else
{
if ($not_string_ok) return $default;
require_code('failure');
$ret=_param_invalid($name,$ret,false);
}
}
}
if ($ret=='0') return 0;
if ($ret=='1') return 1;
$reti=intval($ret);
$retf=floatval($reti);
if (($retf>2147483647.0) || ($retf<-2147483648.0))
{
require_code('failure');
_param_invalid($name,NULL,false);
}
return $reti;
}
string unixify_line_format(string in, ?ID_TEXT desired_charset, boolean html, boolean from_disk)
Make sure that lines are seperated by chr(10), with no chr(13)'s there at all. For Mac data, this will be a flip scenario. For Linux data this will be a null operation. For windows data this will be change from chr(13).chr(10) to just chr(10). For a realistic scenario, data could have originated on all kinds of platforms, with some editors converting, some situations being inter-platform, and general confusion. Don't make blind assumptions - use this function to clean data, then write clean code that only considers chr(10)'s.
Parameters…
| Name |
in |
| Description |
The data to clean |
| Type |
string |
| Name |
desired_charset |
| Description |
The character set it should be in. We don't do any real conversions using this, only make sure that common problems with fed ISO-8859-1 data are resolved (NULL: output character set) |
| Default value |
|
| Type |
?ID_TEXT |
| Name |
html |
| Description |
Whether we are cleaning for HTML rather than Comcode/plain-text |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
from_disk |
| Description |
Whether the file is loaded from disk (less conversion needed) |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
The cleaned data |
| Type |
string |
function unixify_line_format($in,$desired_charset=NULL,$html=false,$from_disk=false)
{
if ($in=='') return $in;
if ($desired_charset===NULL) $desired_charset=get_charset();
$in=str_replace(array(chr(13).chr(10),'',chr(13)),array(chr(10),'',chr(10)),$in); //  is very odd- seems to come from open office copy & paste
if (!$from_disk)
{
if ($desired_charset=='ISO-8859-1') // Fix up Windows ANSI characters
{
$in=str_replace($GLOBALS['BAD_WORD_CHARS'],$html?$GLOBALS['FIXED_WORD_CHARS_HTML']:$GLOBALS['FIXED_WORD_CHARS'],$in);
}
}
return $in;
}
string javascript_enforce(string j, ?ID_TEXT theme, ?boolean minify)
Force a Javascript file to be cached (ordinarily we can rely on this to be automated by require_javascript/javascript_tempcode).
Parameters…
| Name |
j |
| Description |
The javascript file required |
| Type |
string |
| Name |
theme |
| Description |
The name of the theme (NULL: current theme) |
| Default value |
|
| Type |
?ID_TEXT |
| Name |
minify |
| Description |
Whether to minify (NULL: read from environment) |
| Default value |
|
| Type |
?boolean |
Returns…
| Description |
The path to the javascript file in the cache (blank: no file) |
| Type |
string |
function javascript_enforce($j,$theme=NULL,$minify=NULL)
{
if (get_param_integer('keep_textonly',0)==1) return '';
if ($minify===NULL)
$minify=(get_param_integer('keep_no_minify',0)==0);
global $SITE_INFO;
// Make sure the Javascript exists
if ($theme===NULL)
$theme=filter_naughty($GLOBALS['FORUM_DRIVER']->get_theme());
$dir=get_custom_file_base().'/themes/'.$theme.'/templates_cached/'.filter_naughty(user_lang());
if ((!isset($SITE_INFO['no_disk_sanity_checks'])) || ($SITE_INFO['no_disk_sanity_checks']=='0'))
{
if (!is_dir($dir))
{
if (@mkdir($dir,0777)===false)
{
warn_exit(do_lang_tempcode('WRITE_ERROR_DIRECTORY_REPAIR',escape_html($dir)));
}
fix_permissions($dir,0777);
sync_file($dir);
}
}
$js_cache_path=$dir.'/'.filter_naughty_harsh($j);
if (!$minify) $js_cache_path.='_non_minified';
if ((get_option('enable_https',true)=='1') && function_exists('is_page_https') && function_exists('get_zone_name') && ((tacit_https()) || is_page_https(get_zone_name(),get_page_name())))
$js_cache_path.='_ssl';
if (is_mobile()) $js_cache_path.='_mobile';
$js_cache_path.='.js';
global $CACHE_TEMPLATES;
$support_smart_decaching=(!isset($SITE_INFO['disable_smart_decaching'])) || ($SITE_INFO['disable_smart_decaching']=='0');
$is_cached=($CACHE_TEMPLATES || !running_script('index')/*must cache for non-index to stop getting blanked out in depended sub-script output generation and hence causing concurrency issues*/) && (@filesize($js_cache_path)!=0) && (!is_browser_decacheing()) && (!in_safe_mode());
if (($support_smart_decaching) || (!$is_cached))
{
$found=find_template_place(strtoupper($j),'',$theme,'.tpl','templates');
if ($found===NULL) return '';
$theme=$found[0];
$fullpath=get_custom_file_base().'/themes/'.$theme.$found[1].strtoupper($j).'.tpl';
if (!is_file($fullpath))
$fullpath=get_file_base().'/themes/'.$theme.$found[1].strtoupper($j).'.tpl';
$globals_custom=str_replace('default/templates/JAVASCRIPT.tpl',filter_naughty($GLOBALS['FORUM_DRIVER']->get_theme()).'/templates_custom/JAVASCRIPT_CUSTOM_GLOBALS.tpl',$fullpath);
}
if ((($support_smart_decaching) && ((@(filemtime($js_cache_path)<filemtime($fullpath)) && (@filemtime($fullpath)<time())) || (@filemtime(get_file_base().'/info.php')>@filemtime($js_cache_path)) || ((is_file($globals_custom)) && (@filemtime($globals_custom)>@filemtime($js_cache_path))))) || (!$is_cached))
{
require_code('css_and_js');
js_compile($j,$js_cache_path,$minify);
}
if (filesize($js_cache_path)==0) return '';
return $js_cache_path;
}
tempcode javascript_tempcode(?string position)
Get tempcode to tie in (to the HTML, in <head>) all the Javascript files that have been required.
Parameters…
| Name |
position |
| Description |
Position to get Javascript for (NULL: all positions) |
| Default value |
|
| Type |
?string |
| Values restricted to |
NULL header footer |
Returns…
| Description |
The tempcode to tie in the Javascript files |
| Type |
tempcode |
function javascript_tempcode($position=NULL)
{
global $JAVASCRIPTS,$JAVASCRIPT;
$js=new ocp_tempcode();
$minify=(get_param_integer('keep_no_minify',0)==0);
$https=((get_option('enable_https',true)=='1') && function_exists('is_page_https') && function_exists('get_zone_name') && ((tacit_https()) || is_page_https(get_zone_name(),get_page_name())));
$mobile=is_mobile();
// Special merge operation for staff. In truth it's to get a better score on Google Page Speed ;)
$to_merge=array('javascript_staff','javascript_button_occle','javascript_fractional_edit');
$good_to_merge=true;
foreach ($to_merge as $j)
if (!array_key_exists($j,$JAVASCRIPTS)) $good_to_merge=false;
if ($good_to_merge)
{
$j='javascript_staff___merged';
if (!$minify) $j.='_non_minified';
if ($https) $j.='_ssl';
if ($mobile) $j.='_mobile';
$theme=filter_naughty($GLOBALS['FORUM_DRIVER']->get_theme());
$dir=get_custom_file_base().'/themes/'.$theme.'/templates_cached/'.filter_naughty(user_lang());
$write_path=$dir.'/'.filter_naughty_harsh($j);
$write_path.='.js';
/*$rebuild=false; Performance hit
foreach ($to_merge as $j2)
{
$merge_from=javascript_enforce($j2);
if (filemtime($merge_from)==time()) $rebuild=true; // Hmm, just recalculated
}*/
if (!is_file($write_path)/* || $rebuild*/) // Merging algorithm
{
$data='';
foreach ($to_merge as $j2)
{
$merge_from=javascript_enforce($j2);
if (is_file($merge_from))
{
$data.=unixify_line_format(file_get_contents($merge_from,FILE_TEXT));
} else // race condition
{
$good_to_merge=false;
break;
}
}
if ($good_to_merge)
{
$myfile=@fopen($write_path,'wb') OR intelligent_write_error($write_path); // Intentionally wb to stop line ending conversions on Windows
fwrite($myfile,$data);
fclose($myfile);
fix_permissions($write_path,0777);
sync_file($write_path);
}
}
if ($good_to_merge)
{
if ($position!='header')
$js->attach(do_template('JAVASCRIPT_NEED',array('CODE'=>$j)));
}
}
// Our main loop
$bottom_ones=array('javascript_staff'=>1,'javascript_button_occle'=>1,'javascript_fractional_edit'=>1,'javascript_thumbnails'=>1,'javascript_button_realtime_rain'=>1);
foreach (array_keys($JAVASCRIPTS) as $j)
{
if (($good_to_merge) && (in_array($j,$to_merge))) continue;
if ($position!==NULL)
{
$bottom=(isset($bottom_ones[$j])); // TODO: progmattic way of saying this at point of calls
if (($position=='header') && ($bottom)) continue;
if (($position=='footer') && (!$bottom)) continue;
}
$temp=javascript_enforce($j);
if ($temp!='')
{
if (!$minify) $j.='_non_minified';
if ($https) $j.='_ssl';
if ($mobile) $j.='_mobile';
$js->attach(do_template('JAVASCRIPT_NEED',array('_GUID'=>'b5886d9dfc4d528b7e1b0cd6f0eb1670','CODE'=>$j)));
}
}
$js->attach($JAVASCRIPT);
return $js;
}
void require_javascript(ID_TEXT javascript)
Make sure that the given javascript file is loaded up.
Parameters…
| Name |
javascript |
| Description |
The javascript file required |
| Type |
ID_TEXT |
(No return value)
function require_javascript($javascript)
{
//if ((!array_key_exists('DONE_HEADER',$GLOBALS)) || (!$GLOBALS['DONE_HEADER']))
//{
if ($javascript=='javascript_forums_embed') // Has to be first
{
$GLOBALS['JAVASCRIPTS']=array_merge(array('javascript_forums_embed'=>1),$GLOBALS['JAVASCRIPTS']);
} else
{
$GLOBALS['JAVASCRIPTS'][$javascript]=1;
}
/*} else -- Won't work, as we can't sync with the output properly
{
$GLOBALS['JAVASCRIPTS'][$javascript]=1;
$file=javascript_enforce($javascript);
$temp=do_template('JAVASCRIPT_NEED_INLINE',array('_GUID'=>'a6c907e26c5a8dd8c65f1d36a1a674a9','CODE'=>file_get_contents($file,FILE_TEXT)));
$temp->evaluate_echo();
}*/
}
string css_enforce(string c, ?ID_TEXT theme, ?boolean minify)
Force a CSS file to be cached.
Parameters…
| Name |
c |
| Description |
The CSS file required |
| Type |
string |
| Name |
theme |
| Description |
The name of the theme (NULL: current theme) |
| Default value |
|
| Type |
?ID_TEXT |
| Name |
minify |
| Description |
Whether to minify (NULL: read from environment) |
| Default value |
|
| Type |
?boolean |
Returns…
| Description |
The path to the CSS file in the cache (blank: no file) |
| Type |
string |
function css_enforce($c,$theme=NULL,$minify=NULL)
{
$text_only=(get_param_integer('keep_textonly',0)==1);
if ($text_only) $c.='_textonly';
if ($minify===NULL)
$minify=(get_param_integer('keep_no_minify',0)==0);
global $SITE_INFO;
// Make sure the CSS file exists
if ($theme===NULL)
$theme=@method_exists($GLOBALS['FORUM_DRIVER'],'get_theme')?$GLOBALS['FORUM_DRIVER']->get_theme():'default';
$dir=get_custom_file_base().'/themes/'.$theme.'/templates_cached/'.filter_naughty(user_lang());
if ((!isset($SITE_INFO['no_disk_sanity_checks'])) || ($SITE_INFO['no_disk_sanity_checks']=='0'))
{
if (!is_dir($dir))
{
if (@mkdir($dir,0777)===false)
{
warn_exit(do_lang_tempcode('WRITE_ERROR_DIRECTORY_REPAIR',escape_html($dir)));
}
fix_permissions($dir,0777);
sync_file($dir);
}
}
$css_cache_path=$dir.'/'.filter_naughty_harsh($c);
if (!$minify) $css_cache_path.='_non_minified';
if ((get_option('enable_https',true)=='1') && function_exists('is_page_https') && function_exists('get_zone_name') && ((tacit_https()) || is_page_https(get_zone_name(),get_page_name())))
$css_cache_path.='_ssl';
if (is_mobile()) $css_cache_path.='_mobile';
$css_cache_path.='.css';
global $CACHE_TEMPLATES;
$support_smart_decaching=(!isset($SITE_INFO['disable_smart_decaching'])) || ($SITE_INFO['disable_smart_decaching']=='0');
$is_cached=($CACHE_TEMPLATES || !running_script('index')/*must cache for non-index to stop getting blanked out in depended sub-script output generation and hence causing concurrency issues*/) && (@filesize($css_cache_path)!=0) && (!is_browser_decacheing()) && (!in_safe_mode());
if (($support_smart_decaching) || (!$is_cached) || ($text_only))
{
$found=find_template_place($c,'',$theme,'.css','css');
if ($found===NULL) return '';
$theme=$found[0];
$fullpath=get_custom_file_base().'/themes/'.$theme.$found[1].$c.'.css';
if (!is_file($fullpath))
$fullpath=get_file_base().'/themes/'.$theme.$found[1].$c.'.css';
if (($text_only) && (!is_file($fullpath))) return '';
}
if (((!$is_cached) || (($support_smart_decaching) && (@(filemtime($css_cache_path)<filemtime($fullpath)) && (@filemtime($fullpath)<time())))))
{
require_code('css_and_js');
css_compile($theme,$c,$fullpath,$css_cache_path,$minify);
}
if (filesize($css_cache_path)==0) return '';
return $css_cache_path;
}
tempcode css_tempcode(boolean inline, boolean only_global, ?string context, ?ID_TEXT theme)
Get tempcode to tie in (to the HTML, in <head>) all the CSS files that have been required.
Parameters…
| Name |
inline |
| Description |
Force inline CSS |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
only_global |
| Description |
Only do global CSS |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
context |
| Description |
HTML context for which we filter (minimise) any CSS we spit out as inline (NULL: none) |
| Default value |
|
| Type |
?string |
| Name |
theme |
| Description |
The name of the theme (NULL: current theme) |
| Default value |
|
| Type |
?ID_TEXT |
Returns…
| Description |
The tempcode to tie in the CSS files |
| Type |
tempcode |
function css_tempcode($inline=false,$only_global=false,$context=NULL,$theme=NULL)
{
global $CSSS;
$seed='';
if (has_specific_permission(get_member(),'view_profiling_modes'))
{
$seed=get_param('keep_theme_seed','');
}
$text_only=(get_param_integer('keep_textonly',0)==1);
$minify=(get_param_integer('keep_no_minify',0)==0);
$https=((get_option('enable_https',true)=='1') && function_exists('is_page_https') && function_exists('get_zone_name') && ((tacit_https()) || is_page_https(get_zone_name(),get_page_name())));
$mobile=is_mobile();
$css=new ocp_tempcode();
$css_need_inline=new ocp_tempcode();
$css_to_do=$only_global?array('global','no_cache'):array_keys($CSSS);
foreach ($css_to_do as $c)
{
if ($seed!='')
{
$keep=symbol_tempcode('KEEP');
$css->attach(do_template('CSS_NEED_FULL',array('URL'=>find_script('themewizard').'?type=css&show='.$c.'.css'.$keep->evaluate()),user_lang(),false,NULL,'.tpl','templates',$theme));
}
elseif (($c=='no_cache') || ($inline))
{
if (!$text_only)
{
$_css=do_template($c,NULL,user_lang(),false,NULL,'.css','css',$theme);
$__css=$_css->evaluate();
if ($context!==NULL)
{
$__css=filter_css($__css,$context);
} else
{
$__css=str_replace('} ','}'.chr(10),preg_replace('#\s+#',' ',$__css));
}
if (trim($__css)!='')
$css_need_inline->attach(do_template('CSS_NEED_INLINE',array('_GUID'=>'f5b225e080c633ffa033ec5af5aec866','CSS'=>$__css),user_lang(),false,NULL,'.tpl','templates',$theme));
}
} else
{
$temp=css_enforce($c,$theme);
if (!$minify) $c.='_non_minified';
if ($https) $c.='_ssl';
if ($mobile) $c.='_mobile';
if ($temp!='')
$css->attach(do_template('CSS_NEED',array('_GUID'=>'ed35fac857214000f69a1551cd483096','CODE'=>$c),user_lang(),false,NULL,'.tpl','templates',$theme));
}
}
$css_need_inline->attach($css);
return $css_need_inline;
}
void require_css(ID_TEXT css)
Make sure that the given CSS file is loaded up.
Parameters…
| Name |
css |
| Description |
The CSS file required |
| Type |
ID_TEXT |
(No return value)
function require_css($css)
{
// if ((!array_key_exists('DONE_HEADER',$GLOBALS)) || (!$GLOBALS['DONE_HEADER']))
{
$GLOBALS['CSSS'][$css]=1;
}/* else -- Won't work, as we can't sync with the output properly
{
$GLOBALS['CSSS'][$css]=1;
$file=css_enforce($css);
$temp=do_template('CSS_NEED_INLINE',array('_GUID'=>'b6c907e26c5a8dd8c65f1d36a1a674a9','CSS'=>file_get_contents($file,FILE_TEXT)));
$temp->evaluate_echo();
}*/
}
void sync_file(PATH filename)
Provides a hook for file synchronisation between mirrored servers. Called after any file creation, deletion or edit.
Parameters…
| Name |
filename |
| Description |
File/directory name to sync on (full path) |
| Type |
PATH |
(No return value)
function sync_file($filename)
{
global $FILE_BASE,$_MODIFIED_FILES,$_CREATED_FILES;
static $has_sync_script=NULL;
if (is_null($has_sync_script)) $has_sync_script=is_file($FILE_BASE.'/data_custom/sync_script.php');
if ((!$has_sync_script) && (!isset($_MODIFIED_FILES))) return;
if (substr($filename,0,strlen($FILE_BASE)+1)==$FILE_BASE.'/')
{
$filename=substr($filename,strlen($FILE_BASE)+1);
}
if ($has_sync_script)
{
require_once($FILE_BASE.'/data_custom/sync_script.php');
if (function_exists('master__sync_file')) master__sync_file($filename);
}
if (isset($_MODIFIED_FILES))
foreach ($_MODIFIED_FILES as $i=>$x)
if (($x==$FILE_BASE.'/'.$filename) || ($x==$filename)) unset($_MODIFIED_FILES[$i]);
if (isset($_CREATED_FILES))
foreach ($_CREATED_FILES as $i=>$x)
if (($x==$FILE_BASE.'/'.$filename) || ($x==$filename)) unset($_CREATED_FILES[$i]);
}
void sync_file_move(PATH old, PATH new)
Provides a hook for file-move synchronisation between mirrored servers. Called after any rename or move action.
Parameters…
| Name |
old |
| Description |
File/directory name to move from (may be full or relative path) |
| Type |
PATH |
| Name |
new |
| Description |
File/directory name to move to (may be full or relative path) |
| Type |
PATH |
(No return value)
function sync_file_move($old,$new)
{
require_code('files2');
_sync_file_move($old,$new);
}
void convert_data_encodings(boolean known_utf8)
Performs lots of magic to make sure data encodings are converted correctly. Input, and output too (as often stores internally in UTF or performs automatic dynamic conversions from internal to external charsets).Roll on PHP6 that has a true internal UTF string model. For now, anyone who uses UTF will get some (albeit minor) imperfections from PHP's manipulations of the strings.
Parameters…
| Name |
known_utf8 |
| Description |
Whether we know we are working in UTF-8. This is the case for AJAX calls. |
| Default value |
boolean-false |
| Type |
boolean |
(No return value)
function convert_data_encodings($known_utf8=false)
{
global $VALID_ENCODING,$CONVERTED_ENCODING;
$VALID_ENCODING=true;
if ($CONVERTED_ENCODING) return; // Already done it
if ((array_key_exists('KNOWN_UTF8',$GLOBALS)) && ($GLOBALS['KNOWN_UTF8'])) $known_utf8=true;
$charset=get_charset();
$done_something=false;
// Conversion of parameters that might be in the wrong character encoding (e.g. Javascript uses UTF to make requests regardless of document encoding, so the stuff needs converting)
// If we don't have any PHP extensions (mbstring etc) that can perform the detection/conversion, our code will take this into account and use utf8_decode at points where it knows that it's being communicated with by Javascript.
if (@strlen(ini_get('unicode.runtime_encoding'))>0)
{
@ini_set('default_charset',$charset);
@ini_set('unicode.runtime_encoding',$charset);
@ini_set('unicode.output_encoding',$charset);
@ini_set('unicode.semantics','1');
$done_something=true;
}
elseif (($known_utf8) && ((version_compare(phpversion(),'4.3.0')>=0) || (strtolower($charset)=='iso-8859-1')) && /*test method works...*/(will_be_unicode_neutered(serialize($_GET).serialize($_POST))) && (in_array(strtolower($charset),array('iso-8859-1','iso-8859-15','koi8-r','big5','gb2312','big5-hkscs','shift_jis','euc-jp')))) // Preferred as it will sub entities where there's no equivalent character
{
require_code('character_sets');
do_environment_utf8_conversion($charset);
$done_something=true;
}
elseif ((function_exists('iconv_set_encoding')) && (get_value('disable_iconv')!=='1'))
{
$encoding=$known_utf8?'UTF-8':$charset;
if (@iconv_set_encoding('input_encoding',$encoding))
{
iconv_set_encoding('output_encoding',$charset);
iconv_set_encoding('internal_encoding',$charset);
} else
{
$VALID_ENCODING=false;
}
$done_something=true;
}
elseif ((function_exists('mb_convert_encoding')) && (get_value('disable_mbstring')!=='1'))
{
if (function_exists('mb_list_encodings'))
{
$VALID_ENCODING=in_array(strtolower($charset),array_map('strtolower',mb_list_encodings()));
} else $VALID_ENCODING=true;
if ($VALID_ENCODING)
{
$encoding=$known_utf8?'UTF-8':'';
if ((function_exists('mb_http_input')) && ($encoding==''))
{
if (count($_POST)!=0)
{
$encoding=mb_http_input('P');
if ((!is_string($encoding)) || ($encoding=='pass')) $encoding='';
}
}
if ((function_exists('mb_http_input')) && ($encoding==''))
{
$encoding=mb_http_input('G');
if ((!is_string($encoding)) || ($encoding=='pass')) $encoding='';
if ((function_exists('mb_detect_encoding')) && ($encoding=='') && (ocp_srv('REQUEST_URI')!=''))
{
$encoding=mb_detect_encoding(urldecode(ocp_srv('REQUEST_URI')),$charset.',UTF-8,ISO-8859-1');
if ((!is_string($encoding)) || ($encoding=='pass')) $encoding='';
}
}
if ($encoding!='')
{
foreach ($_GET as $key=>$val)
{
if (is_string($val))
{
$_GET[$key]=mb_convert_encoding($val,$charset,$encoding);
} elseif (is_array($val))
{
foreach ($val as $i=>$v)
{
$_GET[$key][$i]=mb_convert_encoding($v,$charset,$encoding);
}
}
}
foreach ($_POST as $key=>$val)
{
if (is_string($val))
{
$_POST[$key]=mb_convert_encoding($val,$charset,$encoding);
} elseif (is_array($val))
{
foreach ($val as $i=>$v)
{
$_POST[$key][$i]=mb_convert_encoding($v,$charset,$encoding);
}
}
}
}
if (function_exists('mb_http_output')) mb_http_output($charset);
}
$done_something=true;
}
elseif (($known_utf8) && (strtolower($charset)!='utf-8') && (strtolower($charset)!='utf8')) // This is super-easy, but it's imperfect as it assumes ISO-8859-1 -- hence our worst option
{
require_code('character_sets');
do_simple_environment_utf8_conversion();
$done_something=true;
}
if ($done_something) $CONVERTED_ENCODING=true;
}
boolean will_be_unicode_neutered(string data)
Guard for entity_utf8_decode. Checks that the data can be stripped so there is no unicode left. Either the htmlentities function must convert mechanically to entity-characters or all higher ascii character codes (which are actually unicode control codes in a unicode interpretation) that are used happen to be linked to named entities.
Parameters…
| Name |
data |
| Description |
Data to check. |
| Type |
string |
Returns…
| Description |
Whether we are good to execute entity_utf8_decode. |
| Type |
boolean |
function will_be_unicode_neutered($data)
{
$data=@htmlentities($data,ENT_COMPAT,'UTF-8');
if ($data=='') return false; // Some servers fail at the first step
for ($i=0;$i<strlen($data);$i++)
{
if (ord($data[$i])>0x7F) return false;
}
return true;
}
0 reviews: Unrated (average)
There have been no comments yet