ocPortal Developer's Guide: Tempcode
» Return to Contents
Tempcode objects are attached together as a tree structure as ocPortal progresses through generating a page, and are eventually evaluated to a string. The advantage of our tree structure approach over linear succession approaches are very significant, and allow us to have much cleaner and more intuitive code and templates that 'embed' each other: you can consider a form element in it's own right, for example, without having to consider the context of a form elements input row, or a form input rows input form, or a input rows input page; HTML tags start and close in the same template file, making it a lot more readable and easy to write.
sources/tempcode.php
Global_functions_tempcode.php
Function summary
|
void
|
init__tempcode ()
|
|
string
|
static_evaluate_tempcode (tempcode ob)
|
|
string
|
php_addslashes_twice (string in)
|
|
string
|
fast_uniqid ()
|
|
string
|
output_tempcode_parameter (mixed var, ID_TEXT parameter, ID_TEXT template_name)
|
|
tempcode
|
build_closure_tempcode (integer type, ID_TEXT name, ?array parameters, ?array escaping)
|
|
tempcode
|
symbol_tempcode (ID_TEXT symbol, ?array parameters, ?array escape)
|
|
tempcode
|
directive_tempcode (ID_TEXT directive, tempcode content, ?array parameters)
|
|
string
|
closure_while_loop (array args, array control_function, array main_function)
|
|
string
|
closure_eval (string code, array parameters)
|
|
string
|
closure_loop (array param, array args, array main_function)
|
|
tempcode
|
make_string_tempcode (string string)
|
|
string
|
apply_tempcode_escaping (array escaped, string value)
|
|
string
|
apply_tempcode_escaping_inline (array escaped, string value)
|
|
tempcode
|
do_lang_tempcode (ID_TEXT lang_string, ?mixed token1, ?mixed token2, ?mixed token3)
|
|
tempcode
|
do_template (ID_TEXT codename, ?array parameters, ?LANGUAGE_NAME lang, boolean light_error, ?ID_TEXT fallback, string suffix, string type, ?ID_TEXT theme)
|
|
void
|
handle_symbol_preprocessing (array bit, array children)
|
void init__tempcode()
Standard code module initialisation function.
Parameters…
(No return value)
function init__tempcode()
{
if (defined('ENTITY_ESCAPED')) return;
define('ENTITY_ESCAPED',1); // HTML entities
define('SQ_ESCAPED',2); // Single quotes
define('DQ_ESCAPED',3); // Double quotes
define('NL_ESCAPED',4); // New lines disappear
define('CC_ESCAPED',5); // Comcode
define('UL_ESCAPED',6); // URL
define('JSHTML_ESCAPED',7); // Javascript </ -> <\/
define('NL2_ESCAPED',8); // New lines go to \n
define('ID_ESCAPED',9); // Strings to to usable IDs
define('NAUGHTY_ESCAPED',10); // Used as a Javascript variable name, for example... to prevent code injection
define('NULL_ESCAPED',11); // This is useful to mark something that takes strings but does not need escaping (usually because it is escaped further down the line)
define('FORCIBLY_ENTITY_ESCAPED',12); // To force a language string to be escaped
define('CSS_ESCAPED',13); // To stop CSS injection
define('UL2_ESCAPED',14); // rawurlencode
define('TC_SYMBOL',0);
define('TC_KNOWN',1); // Either tempcode or string
define('TC_LANGUAGE_REFERENCE',2);
define('TC_PARAMETER',3); // A late parameter for a compiled template
define('TC_DIRECTIVE',4);
global $XHTML_SPIT_OUT,$NO_EVAL_CACHE,$MEMORY_OVER_SPEED,$CACHED_FOUND,$REQUEST_BLOCK_NEST_LEVEL,$LOADED_TPL_CACHE;
$XHTML_SPIT_OUT=NULL;
$NO_EVAL_CACHE=false;
$MEMORY_OVER_SPEED=false;
$CACHED_FOUND=array();
$REQUEST_BLOCK_NEST_LEVEL=0;
$LOADED_TPL_CACHE=array();
global $RECORD_TEMPLATES_USED,$RECORDED_TEMPLATES_USED,$RECORD_TEMPLATES_TREE,$POSSIBLY_IN_SAFE_MODE,$SCREEN_TEMPLATE_CALLED,$TITLE_CALLED;
$SCREEN_TEMPLATE_CALLED=false;
$RECORD_TEMPLATES_USED=false;
$RECORDED_TEMPLATES_USED=array();
$RECORD_TEMPLATES_TREE=false;
$SCREEN_TEMPLATE_CALLED=NULL;
$TITLE_CALLED=false;
$POSSIBLY_IN_SAFE_MODE=(get_param_integer('keep_safe_mode',0)==1);
global $SIMPLE_ESCAPED,$XSS_DETECT;
$SIMPLE_ESCAPED=array(ENTITY_ESCAPED);
if ($XSS_DETECT) $SIMPLE_ESCAPED=array(12345); // Don't allow $SIMPLE_ESCAPED to work, as we need to work through full manual escaping
require_code('symbols');
global $FULL_RESET_VAR_CODE,$RESET_VAR_CODE;
$FULL_RESET_VAR_CODE='foreach(array_keys(get_defined_vars()) as $x) { if ($x[0]==\'b\' && substr($x,0,6)==\'bound_\') unset($$x); } extract($parameters,EXTR_PREFIX_ALL,\'bound\');';
$RESET_VAR_CODE='extract($parameters,EXTR_PREFIX_ALL,\'bound\');';
global $TEMPLATE_PREVIEW_OP;
$TEMPLATE_PREVIEW_OP=array_key_exists('template_preview_op',$_POST) && ($_POST['template_preview_op']=='1') && ((get_page_name()!='admin_themes') || (get_param('type','')=='view'));
global $OB_GET_CLEAN;
$OB_GET_CLEAN=function_exists('ob_get_clean');
}
string static_evaluate_tempcode(tempcode ob)
Simple function to evaluate some Tempcode. Very rarely to be used, only if you can't call a method (e.g. you are copying direct into an array, such as in block cacheing).
Parameters…
| Name |
ob |
| Description |
Tempcode object |
| Type |
tempcode |
Returns…
| Description |
Evaluated string |
| Type |
string |
function static_evaluate_tempcode($ob)
{
return $ob->evaluate();
}
string php_addslashes_twice(string in)
Escape a string to fit within PHP double quotes TWICE. Needed sometimes when generating code. This function exists for performance reasons.
Parameters…
| Name |
in |
| Description |
String in |
| Type |
string |
Returns…
| Description |
Resultant string |
| Type |
string |
function php_addslashes_twice($in)
{
return php_addslashes(php_addslashes($in));
// This code does not work, provides awfully confusing Tempcode errors...
/*global $PHP_REP_FROM,$PHP_REP_TO_TWICE;
return str_replace($PHP_REP_FROM,$PHP_REP_TO_TWICE,$in);
//return str_replace("\n",'\n',str_replace('$','\$',str_replace('\\\'','\'',addslashes($in))));*/
}
string fast_uniqid()
The PHP uniqid function is slow on some PHP versions. This version is much faster.
Parameters…
Returns…
| Description |
Unique Identifier |
| Type |
string |
function fast_uniqid()
{
return uniqid('',true);
}
string output_tempcode_parameter(mixed var, ID_TEXT parameter, ID_TEXT template_name)
Get a string (natural for Tempcode's stream-based processing-model) representation of a bound Tempcode variable
Parameters…
| Name |
var |
| Description |
Variable (or NULL if not set) |
| Type |
mixed |
| Name |
parameter |
| Description |
The name of the parameter |
| Type |
ID_TEXT |
| Name |
template_name |
| Description |
The name of the template |
| Type |
ID_TEXT |
Returns…
| Description |
Value |
| Type |
string |
function output_tempcode_parameter($var,$parameter,$template_name)
{
switch (gettype($var))
{
case 'NULL':
return attach_message(do_lang_tempcode('MISSING_TEMPLATE_PARAMETER',$parameter,$template_name),'warn');
case 'string':
return $var;
case 'object':
return $var->evaluate();
case 'boolean':
return $var?'1':'0';
}
// Assuming array
$cnt=count($var);
return ($cnt==0)?'':strval($cnt);
}
tempcode build_closure_tempcode(integer type, ID_TEXT name, ?array parameters, ?array escaping)
Build a conventional tempcode object
Parameters…
| Name |
type |
| Description |
The type of symbol this is (TC_SYMBOL, TC_LANGUAGE_REFERENCE) |
| Type |
integer |
| Values restricted to |
0 2 |
| Name |
name |
| Description |
The name of the symbol |
| Type |
ID_TEXT |
| Name |
parameters |
| Description |
Parameters to the symbol (NULL: none). In same format as expected by ecv. |
| Type |
?array |
| Name |
escaping |
| Description |
Escaping for the symbol (NULL: none) |
| Default value |
|
| Type |
?array |
Returns…
| Description |
Tempcode object. |
| Type |
tempcode |
function build_closure_tempcode($type,$name,$parameters,$escaping=NULL)
{
if ($escaping===NULL)
{
$_escaping='array()';
} else
{
$_escaping='array('.@implode(',',$escaping).')';
}
$_type=strval($type);
if (preg_match('#^[\w\-]*$#',$name)==0)
$_name=php_addslashes_twice($name);
else $_name=$name;
$myfunc='do_runtime_'.uniqid('',true)/*fast_uniqid()*/;
$funcdef=/*if (!isset(\$TPL_FUNCS['$myfunc']))\n\t*/"\$TPL_FUNCS['$myfunc']=\"echo ecv(\\\$cl,".($_escaping).",".($_type).",\\\"".($_name)."\\\",\\\$parameters);\";\n";
$ret=new ocp_tempcode(array($funcdef,array(array($myfunc,($parameters===NULL)?array():$parameters,$type,$name,''))));
if ($type==TC_LANGUAGE_REFERENCE) $ret->pure_lang=true;
return $ret;
}
tempcode symbol_tempcode(ID_TEXT symbol, ?array parameters, ?array escape)
This will create a new tempcode object that is containing a single specifed symbol
Parameters…
| Name |
symbol |
| Description |
The ID of the symbol to use |
| Type |
ID_TEXT |
| Name |
parameters |
| Description |
Symbol parameters (NULL: none) |
| Default value |
|
| Type |
?array |
| Name |
escape |
| Description |
Escaping (NULL: none) |
| Default value |
|
| Type |
?array |
Returns…
| Description |
A symbol tempcode object |
| Type |
tempcode |
function symbol_tempcode($symbol,$parameters=NULL,$escape=NULL)
{
if ($parameters===NULL) $parameters=array();
return build_closure_tempcode(TC_SYMBOL,$symbol,$parameters,$escape);
}
tempcode directive_tempcode(ID_TEXT directive, tempcode content, ?array parameters)
This will create a new tempcode object that is containing a single specifed directive
Parameters…
| Name |
directive |
| Description |
The ID of the directive to use |
| Type |
ID_TEXT |
| Name |
content |
| Description |
The contents |
| Type |
tempcode |
| Name |
parameters |
| Description |
Directive parameters (NULL: none) |
| Default value |
|
| Type |
?array |
Returns…
| Description |
A directive tempcode object |
| Type |
tempcode |
function directive_tempcode($directive,$content,$parameters=NULL)
{
if ($parameters===NULL) $parameters=array();
$parameters[]=$content;
return build_closure_tempcode(TC_DIRECTIVE,$directive,$parameters);
}
string closure_while_loop(array args, array control_function, array main_function)
Perform a simple loop, that can be inlined in an expression.
Parameters…
| Name |
args |
| Description |
The template bound parameters |
| Type |
array |
| Name |
control_function |
| Description |
The loop control function |
| Type |
array |
| Name |
main_function |
| Description |
The loop execution function |
| Type |
array |
Returns…
| Description |
Result |
| Type |
string |
function closure_while_loop($args,$control_function,$main_function)
{
$out='';
while (call_user_func_array($control_function,$args)) $out.=call_user_func_array($main_function,$args);
return $out;
}
string closure_eval(string code, array parameters)
Evaluate some PHP code to put the result into an expression (code is allowed to have side effects).
Parameters…
| Name |
code |
| Description |
The code |
| Type |
string |
| Name |
parameters |
| Description |
Template parameters |
| Type |
array |
Returns…
| Description |
Result |
| Type |
string |
function closure_eval($code,$parameters)
{
if (get_value('allow_php_in_templates')!=='1')
{
return do_lang('NO_PHP_IN_TEMPLATES');
}
$ret=eval($code);
if (!is_string($ret)) $ret=@strval($ret);
return $ret;
}
string closure_loop(array param, array args, array main_function)
Perform a simple loop, that can be inlined in an expression.
Parameters…
| Name |
param |
| Description |
The template bound parameters |
| Type |
array |
| Name |
args |
| Description |
The loop directive parameters |
| Type |
array |
| Name |
main_function |
| Description |
The loop execution function |
| Type |
array |
Returns…
| Description |
Result |
| Type |
string |
function closure_loop($param,$args,$main_function)
{
$value='';
if (isset($param[0]))
{
$key=$param[0];
if ((is_numeric($key)) || (strpos($key,',')!==false))
{
$array=explode(',',$key);
} else
{
$array=isset($param['vars'][$key])?$param['vars'][$key]:array();
}
if (isset($param[1+1])) /* NB: +1 is due to there being a non-numeric index here too */
{
$columns=intval($param[1]);
$row_starter=isset($param[2+1])?$param[2]:'<tr>';
$row_terminator=isset($param[3+1])?$param[3]:'</tr>';
if ($array!=array()) $value.=$row_starter;
// Sorting
if (isset($param[4+1]))
{
$sort_key=$param[4];
$rev=((isset($param[5+1])) && ($param[5]=='DESC'));
if ($sort_key!='')
{
global $M_SORT_KEY;
$M_SORT_KEY=$sort_key;
uasort($array,'multi_sort');
}
if ($rev) $array=array_reverse($array);
}
}
$col=0;
$first=true;
$max_index=count($array)-1;
foreach ($array as $go_key=>$go)
{
if (!is_array($go)) $go=array('_loop_var'=>$go); else $go['_loop_var']='(array)'; // In case it's not a list of maps, but just a list
if ((isset($param[2])) && ($col%$columns==0) && ($col!=0))
{
$value.=$row_starter;
}
$ps=$go+array('_loop_key'=>is_integer($go_key)?strval($go_key):$go_key,'_i'=>strval($col),'_first'=>$first,'_last'=>$col==$max_index);
$args[0]=$ps+$args[0];
$args[0]['vars']=$args[0];
$value.=call_user_func_array($main_function,$args);
++$col;
if ((isset($param[3])) && ($col%$columns==0))
{
$value.=$row_terminator;
}
$first=false;
}
if ((isset($param[2])) && ($col%$columns!=0))
{
$value.=$row_terminator;
}
}
return $value;
}
tempcode make_string_tempcode(string string)
Convert a string to tempcode.
Parameters…
| Name |
string |
| Description |
String |
| Type |
string |
Returns…
| Description |
Tempcode |
| Type |
tempcode |
function make_string_tempcode($string)
{
$myfunc='string_attach_'.uniqid('',true)/*fast_uniqid()*/;
$code_to_preexecute="\$TPL_FUNCS['$myfunc']=\"echo \\\"".php_addslashes_twice($string)."\\\";\";\n";
$seq_parts=array(array($myfunc,array(),TC_KNOWN,'',''));
return new ocp_tempcode(array($code_to_preexecute,$seq_parts));
}
string apply_tempcode_escaping(array escaped, string value)
Apply whatever escaping is requested to the given value.
Parameters…
| Name |
escaped |
| Description |
A list of escaping to do |
| Type |
array |
| Name |
value |
| Description |
The string to apply the escapings to |
| Type |
string |
Returns…
| Description |
Output string (you do not need to collect this, as $value is pass-by-reference – but this is useful for chaining) |
| Type |
string |
function apply_tempcode_escaping($escaped,&$value)
{
global $HTML_ESCAPE_1_STRREP,$HTML_ESCAPE_2;
foreach ((isset($escaped[1])?array_reverse($escaped):$escaped) as $escape)
{
//if ($escape==NL_ESCAPED) echo str_replace(chr(10),'',$value)."\n\n\n\n\n";
if ($escape==ENTITY_ESCAPED) $value=str_replace($HTML_ESCAPE_1_STRREP,$HTML_ESCAPE_2,$value);
elseif ($escape==FORCIBLY_ENTITY_ESCAPED) $value=str_replace($HTML_ESCAPE_1_STRREP,$HTML_ESCAPE_2,$value);
elseif ($escape==SQ_ESCAPED) $value=str_replace(''','\'',str_replace('\'','\\\'',str_replace('\\','\\\\',$value)));
elseif ($escape==DQ_ESCAPED) $value=str_replace('"','\"',str_replace('"','\\"',str_replace('\\','\\\\',$value)));
elseif ($escape==NL_ESCAPED) $value=str_replace(chr(13),'',str_replace(chr(10),'',$value));
elseif ($escape==NL2_ESCAPED) $value=str_replace(chr(13),'',str_replace(chr(10),'\n',$value));
elseif ($escape==CC_ESCAPED) $value=str_replace('[','\\[',str_replace('\\','\\\\',$value));
elseif ($escape==UL_ESCAPED) $value=ocp_url_encode($value);
elseif ($escape==UL2_ESCAPED) $value=rawurlencode($value);
elseif ($escape==JSHTML_ESCAPED) $value=str_replace(']]>',']]\'+\'>',str_replace('</','<\/',$value));
elseif ($escape==ID_ESCAPED) $value=preg_replace('#^[\_\.\-]#','x',preg_replace('#[^A-Za-z\_\d\.\-]#','_',$value));
elseif ($escape==CSS_ESCAPED) $value=preg_replace('#[^\w\#\.\-\%]#','_',$value);
elseif ($escape==NAUGHTY_ESCAPED) $value=filter_naughty_harsh($value,true);
}
if (($GLOBALS['XSS_DETECT']) && ($escaped!=array())) ocp_mark_as_escaped($value);
return $value;
}
string apply_tempcode_escaping_inline(array escaped, string value)
Apply whatever escaping is requested to the given value.
Parameters…
| Name |
escaped |
| Description |
A list of escaping to do |
| Type |
array |
| Name |
value |
| Description |
The string to apply the escapings to |
| Type |
string |
Returns…
| Description |
Output string |
| Type |
string |
function apply_tempcode_escaping_inline($escaped,$value)
{
global $HTML_ESCAPE_1_STRREP,$HTML_ESCAPE_2;
foreach ((isset($escaped[1])?array_reverse($escaped):$escaped) as $escape)
{
//if ($escape==NL_ESCAPED) echo str_replace(chr(10),'',$value)."\n\n\n\n\n";
if ($escape==ENTITY_ESCAPED) $value=str_replace($HTML_ESCAPE_1_STRREP,$HTML_ESCAPE_2,$value);
elseif ($escape==FORCIBLY_ENTITY_ESCAPED) $value=str_replace($HTML_ESCAPE_1_STRREP,$HTML_ESCAPE_2,$value);
elseif ($escape==SQ_ESCAPED) $value=str_replace(''','\'',str_replace('\'','\\\'',str_replace('\\','\\\\',$value)));
elseif ($escape==DQ_ESCAPED) $value=str_replace('"','\"',str_replace('"','\\"',str_replace('\\','\\\\',$value)));
elseif ($escape==NL_ESCAPED) $value=str_replace(chr(13),'',str_replace(chr(10),'',$value));
elseif ($escape==NL2_ESCAPED) $value=str_replace(chr(13),'',str_replace(chr(10),'\n',$value));
elseif ($escape==CC_ESCAPED) $value=str_replace('[','\\[',str_replace('\\','\\\\',$value));
elseif ($escape==UL_ESCAPED) $value=ocp_url_encode($value);
elseif ($escape==UL2_ESCAPED) $value=rawurlencode($value);
elseif ($escape==JSHTML_ESCAPED) $value=str_replace(']]>',']]\'+\'>',str_replace('</','<\/',$value));
elseif ($escape==ID_ESCAPED) $value=preg_replace('#^[\_\.\-]#','x',preg_replace('#[^A-Za-z\_\d\.\-]#','_',$value));
elseif ($escape==CSS_ESCAPED) $value=preg_replace('#[^\w\#\.\-\%]#','_',$value);
elseif ($escape==NAUGHTY_ESCAPED) $value=filter_naughty_harsh($value,true);
}
if (($GLOBALS['XSS_DETECT']) && ($escaped!=array())) ocp_mark_as_escaped($value);
return $value;
}
tempcode do_lang_tempcode(ID_TEXT lang_string, ?mixed token1, ?mixed token2, ?mixed token3)
This will create a new tempcode object that is containing a single specifed language code
Parameters…
| Name |
lang_string |
| Description |
The ID of the language string to use |
| Type |
ID_TEXT |
| Name |
token1 |
| Description |
The first token [string or tempcode] (replaces {1}) (NULL: none) |
| Default value |
|
| Type |
?mixed |
| Name |
token2 |
| Description |
The second token [string or tempcode] (replaces {2}) (NULL: none) |
| Default value |
|
| Type |
?mixed |
| Name |
token3 |
| Description |
The third token (replaces {3}). May be an array of [of string], to allow any number of additional args (NULL: none) |
| Default value |
|
| Type |
?mixed |
Returns…
| Description |
A language tempcode object |
| Type |
tempcode |
function do_lang_tempcode($lang_string,$token1=NULL,$token2=NULL,$token3=NULL)
{
$parameters=array();
if (isset($token1)) $parameters[]=$token1;
if (isset($token2)) $parameters[]=$token2;
if (isset($token3))
{
if (!is_array($token3))
{
$parameters[]=$token3;
} else
{
$parameters=array_merge($parameters,$token3);
}
}
return build_closure_tempcode(TC_LANGUAGE_REFERENCE,$lang_string,$parameters);
}
tempcode do_template(ID_TEXT codename, ?array parameters, ?LANGUAGE_NAME lang, boolean light_error, ?ID_TEXT fallback, string suffix, string type, ?ID_TEXT theme)
Get a tempcoded version of a normal XHTML template. It is perhaps the most common ocPortal function to load up templates using do_template, and then attach them together either as parameters to each other, or via the tempcode attach method.
Parameters…
| Name |
codename |
| Description |
The codename of the template being loaded |
| Type |
ID_TEXT |
| Name |
parameters |
| Description |
A map of parameters for the template (key to value) (NULL: no parameters) |
| Default value |
|
| Type |
?array |
| Name |
lang |
| Description |
The language to load the template in (templates can embed language references) (NULL: users own language) |
| Default value |
|
| Type |
?LANGUAGE_NAME |
| Name |
light_error |
| Description |
Whether to not produce a stack dump if the template is missing |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
fallback |
| Description |
Alternate template to use if the primary one does not exist (NULL: none) |
| Default value |
|
| Type |
?ID_TEXT |
| Name |
suffix |
| Description |
File type suffix of template file (e.g. .tpl) |
| Default value |
.tpl |
| Type |
string |
| Name |
type |
| Description |
Subdirectory type to look in |
| Default value |
templates |
| Type |
string |
| Values restricted to |
templates css |
| Name |
theme |
| Description |
Theme to use (NULL: current theme) |
| Default value |
|
| Type |
?ID_TEXT |
Returns…
| Description |
The tempcode for this template |
| Type |
tempcode |
function do_template($codename,$parameters=NULL,$lang=NULL,$light_error=false,$fallback=NULL,$suffix='.tpl',$type='templates',$theme=NULL)
{
if ((!isset($lang)) || ($lang==''))
{
global $USER_LANG_CACHED;
$lang=isset($USER_LANG_CACHED)?$USER_LANG_CACHED:(function_exists('user_lang')?user_lang():'EN');
}
if ($GLOBALS['SEMI_DEBUG_MODE'])
{
if (($codename==strtolower($codename)) && ($type!='css') && ($codename!='tempcode_test') && ($codename!='handle_conflict_resolution'))
{
fatal_exit('Template names should be in upper case, and the files should be stored in upper case.');
}
if ((substr($codename,-7)=='_SCREEN') || (substr($codename,-8)=='_OVERLAY') || ($codename=='POOR_XHTML_WRAPPER') || ($codename=='OCF_WRAPPER'))
{
$GLOBALS['SCREEN_TEMPLATE_CALLED']=$codename;
}
}
global $TEMPLATE_PREVIEW_OP,$RECORD_TEMPLATES_USED,$RECORDED_TEMPLATES_USED,$FILE_ARRAY,$MEM_CACHE,$KEEP_MARKERS,$SHOW_EDIT_LINKS,$XHTML_SPIT_OUT,$CACHE_TEMPLATES,$FORUM_DRIVER,$POSSIBLY_IN_SAFE_MODE,$CACHED_THEME,$CACHED_FOUND,$LOADED_TPL_CACHE;
$special_treatment=((($KEEP_MARKERS) || ($SHOW_EDIT_LINKS)) && (is_null($XHTML_SPIT_OUT)));
if ($RECORD_TEMPLATES_USED)
{
$RECORDED_TEMPLATES_USED[]=$codename;
}
// Variables we'll need
if (!isset($theme))
$theme=isset($CACHED_THEME)?$CACHED_THEME:(((isset($FORUM_DRIVER)) && (is_object($FORUM_DRIVER)) && (method_exists($FORUM_DRIVER,'get_theme')))?filter_naughty($FORUM_DRIVER->get_theme()):'default');
$prefix_default=get_file_base().'/themes/';
$prefix=($theme=='default')?$prefix_default:(get_custom_file_base().'/themes/');
// Is it structurally cached on disk yet?
if (!isset($CACHED_FOUND[$codename][$lang][$theme][$suffix][$type]))
{
$loaded_this_once=false;
} else
{
$loaded_this_once=true;
}
$_data=false;
if (($CACHE_TEMPLATES) && (!$TEMPLATE_PREVIEW_OP) && ((!$POSSIBLY_IN_SAFE_MODE)/* || ($GLOBALS['SEMI_DEBUG_MODE'])*/ || (!in_safe_mode())))
{
$tcp_path=$prefix.$theme.'/templates_cached/'.$lang.'/'.$codename.$suffix.'.tcp';
if ($loaded_this_once)
{
if (isset($LOADED_TPL_CACHE[$codename][$theme]))
{
$_data=$LOADED_TPL_CACHE[$codename][$theme];
} else
{
$_data=new ocp_tempcode();
$test=$_data->from_assembly_executed($tcp_path,array($codename,$codename,$lang,$theme,$suffix,$type,$fallback));
if (!$test) $_data=false; // failed
}
} else
{
global $SITE_INFO;
$support_smart_decaching=(!isset($SITE_INFO['disable_smart_decaching'])) || ($SITE_INFO['disable_smart_decaching']=='0');
if ($support_smart_decaching)
{
if (!isset($CACHED_FOUND[$codename][$lang][$theme][$suffix][$type]))
{
$found=find_template_place($codename,$lang,$theme,$suffix,$type);
$CACHED_FOUND[$codename][$lang][$theme][$suffix][$type]=$found;
} else
{
$found=$CACHED_FOUND[$codename][$lang][$theme][$suffix][$type];
}
if (isset($GLOBALS['CURRENT_SHARE_USER']))
{
$file_path=get_custom_file_base().'/themes/'.$found[0].$found[1].$codename.$suffix;
if (!is_file($file_path))
$file_path=get_file_base().'/themes/'.$found[0].$found[1].$codename.$suffix;
} else
{
$file_path=((($theme=='default') && ($suffix!='.css'))?get_file_base():get_custom_file_base()).'/themes/'.$found[0].$found[1].$codename.$suffix;
}
$tcp_time=@filemtime($tcp_path);
}
if ((!$support_smart_decaching) || (($tcp_time!==false) && (is_file($file_path)))/*if in install can be found yet no file at path due to running from data.ocp*/ && ($found!==NULL))
{
if ((!$support_smart_decaching) || (filemtime($file_path)<$tcp_time))
{
$_data=new ocp_tempcode();
$test=$_data->from_assembly_executed($tcp_path,array($codename,$codename,$lang,$theme,$suffix,$type,$fallback));
if (!$test) $_data=false; // failed
}
}
}
}
if ($_data===false) // No, it's not
{
if (!isset($CACHED_FOUND[$codename][$lang][$theme][$suffix][$type]))
{
$found=find_template_place($codename,$lang,$theme,$suffix,$type);
$CACHED_FOUND[$codename][$lang][$theme][$suffix][$type]=$found;
} else
{
$found=$CACHED_FOUND[$codename][$lang][$theme][$suffix][$type];
}
unset($CACHED_FOUND[$codename][$lang][$theme][$suffix][$type]);
if (is_null($found))
{
if (is_null($fallback))
{
if ($light_error) return paragraph(do_lang_tempcode('MISSING_TEMPLATE_FILE',escape_html($codename)),'34rwefwfdee');
fatal_exit(do_lang_tempcode('MISSING_TEMPLATE_FILE',escape_html($codename)));
} else
{
$result=do_template($fallback,$parameters,$lang);
return $result;
}
} else
{
require_code('tempcode_compiler');
$_data=_do_template($found[0],$found[1],$codename,$codename,$lang,$suffix,$theme);
}
}
if ($loaded_this_once) // On 3rd load (and onwards) it will be fully cached
$LOADED_TPL_CACHE[$codename][$theme]=$_data;
if (!isset($parameters)) // Streamlined if no parameters involved
{
$out=new ocp_tempcode();
$out->codename=$codename;
$out->code_to_preexecute=$_data->code_to_preexecute;
$out->preprocessable_bits=$_data->preprocessable_bits;
$out->seq_parts=$_data->seq_parts;
foreach ($out->seq_parts as $i=>$bit)
{
if ($bit[1]!=array())
$out->seq_parts[$i][1]=array();
}
return $out;
}
$ret=$_data->bind($parameters,$codename);
if ($special_treatment)
{
$ret->codename='(mixed)'; // Stop optimisation that assumes the codename represents the sole content of it
}
if ($special_treatment)
{
if ($KEEP_MARKERS)
{
$__data=new ocp_tempcode();
$__data->attach('<!-- START-TEMPLATE='.$codename.' -->');
$__data->attach($ret);
$__data->attach('<!-- END-TEMPLATE='.$codename.' -->');
$ret=$__data;
}
if (($SHOW_EDIT_LINKS) && ($codename!='PARAM_INFO'))
{
$edit_url=build_url(array('page'=>'admin_themes','type'=>'_edit_templates','theme'=>$theme,'f0file'=>$codename),'adminzone');
$parameters2=array();
foreach ($parameters as $k=>$v)
{
if (is_array($v))
{
$parameters2[$k]='(array)';
} elseif (!is_object($v))
{
$parameters2[$k]=$v;
} else
{
$parameters2[$k]=$v->evaluate();
if (strlen($parameters2[$k])>100) $parameters2[$k]=substr($parameters2[$k],0,100).'...';
}
}
$param_info=do_template('PARAM_INFO',array('MAP'=>$parameters2));
$SHOW_EDIT_LINKS=false;
$ret=do_template('TEMPLATE_EDIT_LINK',array('_GUID'=>'511ae911d31a5b237a4371ff22fc78fd','PARAM_INFO'=>$param_info,'CONTENTS'=>$ret,'CODENAME'=>$codename,'EDIT_URL'=>$edit_url));
$SHOW_EDIT_LINKS=true;
}
}
return $ret;
}
void handle_symbol_preprocessing(array bit, array children)
Certain symbols need preprocessing, before the output stream is made.
Parameters…
| Name |
bit |
| Description |
Symbol details |
| Type |
array |
| Name |
children |
| Description |
Where we store children stuff |
| Type |
array |
(No return value)
function handle_symbol_preprocessing($bit,&$children)
{
switch ($bit[2])
{
case 'PAGE_LINK':
$param=$bit[3];
if (isset($param[0]))
{
if (is_object($param[0])) $param[0]=$param[0]->evaluate();
list(,$url_parts,)=page_link_decode($param[0]);
if ((!isset($url_parts['id'])) && (!array_key_exists('id',$url_parts))) return;
if ((!isset($url_parts['type'])) && (!array_key_exists('type',$url_parts))) $url_parts['type']='misc';
if ($url_parts['type']===NULL) $url_parts['type']='misc'; // NULL means "do not take from environment"; so we default it to 'misc' (even though it might actually be left out when SEO URLs are off, we know it cannot be for SEO URLs)
if (!array_key_exists('page',$url_parts)) return;
if ($url_parts['id']===NULL) $url_parts['id']=/*get_param('id',*/strval(db_get_first_id())/*)*/;
// Does this URL arrangement support monikers?
global $LOADED_MONIKERS;
if (!isset($LOADED_MONIKERS[$url_parts['page']][$url_parts['type']][$url_parts['id']]))
{
global $CONTENT_OBS,$LOADED_MONIKERS;
load_moniker_hooks();
$found=false;
$looking_for='_SEARCH:'.$url_parts['page'].':'.$url_parts['type'].':_WILD';
$ob_info=isset($CONTENT_OBS[$looking_for])?$CONTENT_OBS[$looking_for]:NULL;
if ($ob_info!==NULL)
$LOADED_MONIKERS[$url_parts['page']][$url_parts['type']][$url_parts['id']]=true; // Indicator to preload this
}
}
return;
case 'SET':
$param=$bit[3];
if (isset($param[1]))
{
global $TEMPCODE_SETGET;
$param_copy=array();
foreach ($param as $i=>$x)
{
if ($i!=0) $param_copy[]=is_object($x)?$x->evaluate():$x;
}
$TEMPCODE_SETGET[is_object($param[0])?$param[0]->evaluate():$param[0]]=implode(',',$param_copy);
if (($GLOBALS['RECORD_TEMPLATES_TREE']) && (is_object($param[1])))
{
$children[]=array(':set: '.(is_object($param[0])?$param[0]->evaluate():$param[0]),isset($param[1]->children)?$param[1]->children:array(),isset($param[1]->fresh)?$param[1]->fresh:false);
}
}
return;
case 'BLOCK':
$param=$bit[3];
global $REQUEST_BLOCK_NEST_LEVEL;
$REQUEST_BLOCK_NEST_LEVEL++;
if ($REQUEST_BLOCK_NEST_LEVEL>40) // 100 caused xdebug error, but ocPortal will have some overhead in both error handler and other code to get to here. We want xdebug error to not show, but of course to provide the same benefits as that error.
{
$REQUEST_BLOCK_NEST_LEVEL=0;
warn_exit(do_lang_tempcode('STOPPED_RECURSIVE_RESOURCE_INCLUDE'));
}
foreach ($param as $i=>$p)
if (is_object($p)) $param[$i]=$p->evaluate();
if ((count($param)==1) && (strpos($param[0],',')!==false))
{
$param=preg_split('#((?<![^\\\\])|(?<!\\\\\\\\)|(?<!^)),#',$param[0]);
}
//if (strpos(serialize($param),'side_stored_menu')!==false) { @debug_print_backtrace();exit(); } // Useful for debugging
global $LOADED_BLOCKS;
if (isset($LOADED_BLOCKS[serialize($param)]))
{
$REQUEST_BLOCK_NEST_LEVEL--;
return;
}
$block_parms=array();
foreach ($param as $_param)
{
$block_parts=explode('=',$_param,2);
if (!isset($block_parts[1]))
{
$LOADED_BLOCKS[serialize($param)]=do_lang_tempcode('INTERNAL_ERROR');
return;
}
list($key,$val)=$block_parts;
$block_parms[$key]=$val;
}
if ((isset($_GET['keep_show_loading'])) && (function_exists('memory_get_usage')) && ($_GET['keep_show_loading']=='1'))
{
$before=memory_get_usage();
}
$b_value=do_block($block_parms['block'],$block_parms);
if ((isset($_GET['keep_show_loading'])) && (function_exists('memory_get_usage')) && ($_GET['keep_show_loading']=='1'))
{
@ob_end_flush();
@ob_end_flush();
@ob_end_flush();
print('<!-- block: '.htmlentities($block_parms['block']).' ('.clean_file_size(memory_get_usage()-$before).' bytes used, now at '.integer_format(memory_get_usage()).') -->'."\n");
flush();
}
if ($GLOBALS['RECORD_TEMPLATES_TREE'])
{
$children[]=array(':block: '.$block_parms['block'],array(array($b_value->codename,isset($b_value->children)?$b_value->children:array(),isset($b_value->fresh)?$b_value->fresh:false)),true);
}
$b_value->handle_symbol_preprocessing();
$LOADED_BLOCKS[serialize($param)]=$b_value;
$REQUEST_BLOCK_NEST_LEVEL--;
return;
case 'JAVASCRIPT_INCLUDE':
$param=$bit[3];
foreach ($param as $i=>$p)
if (is_object($p)) $param[$i]=$p->evaluate();
require_javascript($param[0]);
return;
case 'FACILITATE_AJAX_BLOCK_CALL':
require_javascript('javascript_ajax');
return;
case 'CSS_INHERIT':
case 'CSS_INCLUDE':
$param=$bit[3];
foreach ($param as $i=>$p)
if (is_object($p)) $param[$i]=$p->evaluate();
require_css($param[0]);
return;
case 'TRIM':
$param=$bit[3];
if ((isset($param[0])) && (is_object($param[0])))
{
if ($GLOBALS['RECORD_TEMPLATES_TREE'])
{
$param[0]->handle_symbol_preprocessing();
$children[]=array(':trim',isset($param[0]->children)?$param[0]->children:array(),isset($param[0]->fresh)?$param[0]->fresh:false,true);
}
}
break;
case 'LOAD_PANEL':
$param=$bit[3];
foreach ($param as $i=>$p)
if (is_object($p)) $param[$i]=$p->evaluate();
global $LOADED_PANELS;
if (isset($LOADED_PANELS[serialize($param)])) return;
if (array_key_exists(0,$param))
{
if (substr(get_page_name(),0,6)!='panel_')
{
if (strpos($param[0],':')!==false)
$param=array_reverse(explode(':',$param[0],2));
if (substr($param[0],0,6)=='panel_') $param[0]=substr($param[0],6);
global $ZONE;
$wide_high=is_wide_high();
$wide=is_wide();
if ((($wide==0) || (($wide_high==0) && (($param[0]=='bottom') || ($param[0]=='top')))) && ((get_option('site_closed')=='0') || ($GLOBALS['IS_ACTUALLY_ADMIN']) || (has_specific_permission(get_member(),'access_closed_site'))))
{
if ((function_exists('memory_get_usage')) && (isset($_GET['keep_show_loading'])) && ($_GET['keep_show_loading']=='1'))
{
$before=memory_get_usage();
}
$tp_value=request_page('panel_'.$param[0],false,array_key_exists(1,$param)?$param[1]:NULL,NULL);
if ((function_exists('memory_get_usage')) && (isset($_GET['keep_show_loading'])) && ($_GET['keep_show_loading']=='1'))
{
@ob_end_flush();
@ob_end_flush();
@ob_end_flush();
print('<!-- panel: '.htmlentities('panel_'.$param[0]).' ('.clean_file_size(memory_get_usage()-$before).' bytes used, now at '.number_format(memory_get_usage()).') -->'."\n");
flush();
}
$tp_value->handle_symbol_preprocessing();
if ($GLOBALS['RECORD_TEMPLATES_TREE'])
{
$children[]=array(':panel: '.$param[0],array(array($tp_value->codename,isset($tp_value->children)?$tp_value->children:array(),isset($tp_value->fresh)?$tp_value->fresh:false)),true);
}
$value=$tp_value->evaluate();
} else $value='';
} else $value='';
} else $value='';
$LOADED_PANELS[serialize($param)]=$value;
return;
case 'JS_TEMPCODE':
if ($GLOBALS['RECORD_TEMPLATES_TREE'])
{
$param=$bit[3];
foreach ($param as $i=>$p)
if (is_object($p)) $param[$i]=$p->evaluate();
$temp=javascript_tempcode(array_key_exists(0,$param)?$param[0]:NULL);
$children[]=array(':container',isset($temp->children)?$temp->children:array(),isset($temp->fresh)?$temp->fresh:false);
}
return;
case 'CSS_TEMPCODE':
if ($GLOBALS['RECORD_TEMPLATES_TREE'])
{
$param=$bit[3];
$temp=css_tempcode();
$children[]=array(':container',isset($temp->children)?$temp->children:array(),isset($temp->fresh)?$temp->fresh:false);
}
return;
case 'LOAD_PAGE':
$param=$bit[3];
foreach ($param as $i=>$p)
if (is_object($p)) $param[$i]=$p->evaluate();
global $LOADED_PAGES;
if (array_key_exists(serialize($param),$LOADED_PAGES)) return;
if (array_key_exists(0,$param))
{
if (strpos($param[0],':')!==false)
$param=array_reverse(explode(':',$param[0],2));
$being_included=(!array_key_exists(2,$param)) || ($param[2]=='1');
if ((function_exists('memory_get_usage')) && (isset($_GET['keep_show_loading'])) && ($_GET['keep_show_loading']=='1'))
{
$before=memory_get_usage();
}
$tp_value=request_page($param[0],false,array_key_exists(1,$param)?$param[1]:NULL,NULL,$being_included);
if ((function_exists('memory_get_usage')) && (isset($_GET['keep_show_loading'])) && ($_GET['keep_show_loading']=='1'))
{
@ob_end_flush();
@ob_end_flush();
@ob_end_flush();
print('<!-- page: '.htmlentities($param[0]).' ('.clean_file_size(memory_get_usage()-$before).' bytes used, now at '.number_format(memory_get_usage()).') -->'."\n");
flush();
}
if ($GLOBALS['RECORD_TEMPLATES_TREE'])
{
$children[]=array(':page: '.$param[0],isset($tp_value->children)?$tp_value->children:array(),isset($tp_value->fresh)?$tp_value->fresh:false);
}
} else $tp_value=new ocp_tempcode();
$LOADED_PAGES[serialize($param)]=$tp_value;
return;
case 'FRACTIONAL_EDITABLE':
require_javascript('javascript_fractional_edit');
return;
}
}
ocp_tempcode
Function summary
|
void
|
ocp_tempcode (?array details)
|
|
array
|
__sleep ()
|
|
void
|
decache ()
|
|
void
|
handle_symbol_preprocessing ()
|
|
boolean
|
parameterless (integer at)
|
|
void
|
parse_from (string code, integer pos, integer len)
|
|
void
|
attach (mixed attach, boolean avoid_child_merge)
|
|
boolean
|
is_definitely_empty ()
|
|
boolean
|
is_empty ()
|
|
boolean
|
is_really_empty ()
|
|
string
|
to_assembly ()
|
|
boolean
|
from_assembly_executed (PATH file, array forced_reload_details)
|
|
void
|
_mark_all_as_escaped ()
|
|
boolean
|
from_assembly (string raw_data, boolean allow_failure)
|
|
void
|
singular_bind (string parameter, tempcode value)
|
|
tempcode
|
bind (array parameters, ID_TEXT codename)
|
|
string
|
evaluate_echo (?LANGUAGE_NAME current_lang, mixed _escape)
|
|
string
|
evaluate (?LANGUAGE_NAME current_lang, mixed _escape, ?integer up_to)
|
void ocp_tempcode(?array details)
Constructor of tempcode
Parameters…
| Name |
details |
| Description |
Pair: Code to preexecute, Initialisation seq-parts (NULL: start as empty) |
| Default value |
|
| Type |
?array |
(No return value)
function ocp_tempcode($details=NULL)
{
$this->preprocessable_bits=array();
$this->cached_output=NULL;
if (!isset($details))
{
$this->seq_parts=array();
$this->code_to_preexecute='';
} else
{
$this->code_to_preexecute=$details[0];
$this->seq_parts=$details[1];
foreach ($this->seq_parts as $seq_part)
{
if ($seq_part[2]==TC_SYMBOL)
{
switch ($seq_part[3])
{
case 'CSS_INCLUDE':
case 'JAVASCRIPT_INCLUDE':
case 'FACILITATE_AJAX_BLOCK_CALL':
case 'JS_TEMPCODE':
case 'CSS_TEMPCODE':
case 'SET':
case 'BLOCK':
case 'PAGE_LINK':
case 'LOAD_PAGE':
case 'LOAD_PANEL':
case 'TRIM':
$this->preprocessable_bits[]=array(array(),TC_SYMBOL,$seq_part[3],$seq_part[1]);
break;
}
}
elseif ($seq_part[2]==TC_DIRECTIVE)
{
switch ($seq_part[3])
{
case 'FRACTIONAL_EDITABLE':
$this->preprocessable_bits[]=array(array(),TC_DIRECTIVE,$seq_part[3],$seq_part[1]);
break;
}
}
}
}
if ($GLOBALS['RECORD_TEMPLATES_TREE'])
{
$this->fresh=true;
$this->children=array();
}
}
array __sleep()
PHP magic function to handle serialisation.
Parameters…
Returns…
| Description |
What is to be serialised |
| Type |
array |
function __sleep()
{
return array('code_to_preexecute','seq_parts','preprocessable_bits','last_attach','pure_lang','codename');
}
void decache()
Decache the object.
Parameters…
(No return value)
function decache()
{
foreach ($this->seq_parts as $seq_part)
{
foreach ($seq_part[1] as $val)
{
if (is_object($val)) $val->decache();
}
}
$this->cached_output=NULL;
}
void handle_symbol_preprocessing()
Scan this Tempcode for anything that needs to be symbol-preprocessed
Parameters…
(No return value)
function handle_symbol_preprocessing()
{
if (isset($this->preprocessed)) return;
foreach ($this->preprocessable_bits as $bit)
{
handle_symbol_preprocessing($bit,$this->children);
}
$this->preprocessed=true;
}
boolean parameterless(integer at)
Find whether a variable within this Tempcode is parameterless.
Parameters…
| Name |
at |
| Description |
Offset to the variable |
| Type |
integer |
Returns…
| Description |
Whether it is parameterless |
| Type |
boolean |
function parameterless($at)
{
return ((!array_key_exists($at,$this->seq_parts)) || ($this->seq_parts[$at][1]==array()));
}
void parse_from(string code, integer pos, integer len)
Parse a single symbol from an input stream and append it.
Parameters…
| Name |
code |
| Description |
Code string (input stream) |
| Type |
string |
| Name |
pos |
| Description |
Start position of input string |
| Type |
integer |
| Name |
len |
| Description |
End position of input string |
| Type |
integer |
(No return value)
function parse_from(&$code,&$pos,&$len)
{
$this->cached_output=NULL;
require_code('tempcode_compiler');
$temp=template_to_tempcode(substr($code,$pos,$len-$pos),0,false,'');
$this->code_to_preexecute=$temp->code_to_preexecute;
$this->seq_parts=$temp->seq_parts;
$this->preprocessable_bits=$temp->preprocessable_bits;
}
void attach(mixed attach, boolean avoid_child_merge)
Attach the specified tempcode to the right of the current tempcode object.
Parameters…
| Name |
attach |
| Description |
The tempcode/string to attach |
| Type |
mixed |
| Name |
avoid_child_merge |
| Description |
If we've already merged the children from what we're attaching into the child tree (at bind stage) |
| Default value |
boolean-false |
| Type |
boolean |
(No return value)
function attach($attach,$avoid_child_merge=false)
{
if ($attach==='') return;
unset($this->is_really_empty);
$this->cached_output=NULL;
if (is_object($attach)) // Consider it another piece of tempcode
{
foreach ($attach->seq_parts as $seq)
{
$seq[4]=$this->last_attach;
$this->seq_parts[]=$seq;
}
if (((strpos($this->code_to_preexecute,'/'.$attach->codename.'.')===false) && (strpos($this->code_to_preexecute,'$TPL_FUNCS[\'tcpfunc_'.$attach->codename.'\']')===false)) || ($GLOBALS['KEEP_MARKERS'])) // Optimisation for memory.
{
$this->code_to_preexecute.=$attach->code_to_preexecute;
}
$this->preprocessable_bits=array_merge($this->preprocessable_bits,$attach->preprocessable_bits);
if ((!$avoid_child_merge) && ($GLOBALS['RECORD_TEMPLATES_TREE']))
{
$this->children[]=array($attach->codename,isset($attach->children)?$attach->children:array(),isset($attach->fresh)?$attach->fresh:false);
}
$this->last_attach=$attach->codename;
} else // Consider it a string
{
$myfunc='string_attach_'.uniqid('',true)/*fast_uniqid()*/;
$funcdef=/*if (!isset(\$TPL_FUNCS['$myfunc']))\n\t*/"\$TPL_FUNCS['$myfunc']=\"echo \\\"".php_addslashes_twice($attach)."\\\";\";\n";
$this->code_to_preexecute.=$funcdef;
$this->seq_parts[]=array($myfunc,array(),TC_KNOWN,'','');
$this->last_attach='';
}
$this->codename='(mixed)';
}
boolean is_definitely_empty()
Find whether the current tempcode object is definitely blank, by doing a very quick check.
Parameters…
Returns…
| Description |
Whether the tempcode object is empty |
| Type |
boolean |
function is_definitely_empty()
{
return !isset($this->seq_parts[0]);
}
boolean is_empty()
Find whether the current tempcode object is blank or not.
Parameters…
Returns…
| Description |
Whether the tempcode object is empty |
| Type |
boolean |
function is_empty()
{
//return $this->code_to_preexecute=='';
return $this->is_really_empty();
}
boolean is_really_empty()
Tests to see if something would evaluate to blank or not
Parameters…
Returns…
| Description |
Whether it is really empty |
| Type |
boolean |
function is_really_empty()
{
if ($this->cached_output!==NULL) return strlen($this->cached_output)==0;
if (isset($this->is_really_empty)) return $this->is_really_empty;
if (!isset($this->seq_parts[0]))
{
$this->is_really_empty=true;
return true;
}
//$tempcode_profile_log_start=microtime();
//tempcode_profile_log($this->seq_parts);
ob_start();
global $NO_EVAL_CACHE,$XSS_DETECT,$USER_LANG_CACHED,$OB_GET_CLEAN;
if ($XSS_DETECT)
{
$before=@ini_get('ocproducts.xss_detect');
@ini_set('ocproducts.xss_detect','0');
}
$no_eval_cache_before=$NO_EVAL_CACHE;
if (isset($USER_LANG_CACHED))
{
$current_lang=$USER_LANG_CACHED;
} else
{
if (!function_exists('user_lang')) require_code('lang');
$current_lang=user_lang();
}
$cl=$current_lang;
$first_of_long=isset($this->seq_parts[3]);
global $KEEP_TPL_FUNCS,$MEMORY_OVER_SPEED,$FULL_RESET_VAR_CODE,$RESET_VAR_CODE;
$TPL_FUNCS=$KEEP_TPL_FUNCS;
foreach ($this->seq_parts as $bit)
{
//$before=memory_get_usage();
$bit_0=$bit[0];
if (!isset($TPL_FUNCS[$bit_0]))
{
//$MY_LOG_FILE=fopen(get_custom_file_base().'/../test.log','wt'); fwrite($MY_LOG_FILE,$this->code_to_preexecute); fclose($MY_LOG_FILE);
if (eval($this->code_to_preexecute)===false) fatal_exit(@strval($php_errormsg));
if (!isset($TPL_FUNCS[$bit_0])) $TPL_FUNCS[$bit_0]=' '; // Fudge to stop error. Actually caused by a race condition and output will be incomplete
}
if (($TPL_FUNCS[$bit_0][0]!='e'/*for echo*/) && (function_exists($TPL_FUNCS[$bit_0])))
{
call_user_func($TPL_FUNCS[$bit_0],$bit[1],$current_lang,$bit[4]);
} else
{
$parameters=$bit[1];
$last_attach=$bit[4];
if (eval($TPL_FUNCS[$bit_0])===false) fatal_exit(@strval($php_errormsg));
}
//@ob_end_flush();@ob_end_flush();@ob_end_flush();print('<!-- tempcode-eval-is_really_empty: '.htmlentities($this->codename).' ('.clean_file_size(memory_get_usage()-$before).' used, now at '.number_format(memory_get_usage()).') -->'."\n");flush();
if ((($first_of_long) || ($MEMORY_OVER_SPEED)) && (ob_get_length()>0)) // We only quick exit on the first iteration, as we know we likely didn't spend much time getting to it- anything more and we finish so that we can cache for later use by evaluate/evaluate_echo
{
//$tempcode_profile_log_end=microtime();
//tempcode_profile_log_diff($tempcode_profile_log_start,$tempcode_profile_log_end,$this->seq_parts);
@ob_end_clean();
if (!$no_eval_cache_before)
$NO_EVAL_CACHE=$no_eval_cache_before;
if ($XSS_DETECT)
@ini_set('ocproducts.xss_detect',$before);
$this->is_really_empty=false;
return false;
}
$first_of_long=false;
}
//$tempcode_profile_log_end=microtime();
//tempcode_profile_log_diff($tempcode_profile_log_start,$tempcode_profile_log_end,$this->seq_parts);
if (($MEMORY_OVER_SPEED) || ($NO_EVAL_CACHE))
{
if ($OB_GET_CLEAN)
{
$tmp=ob_get_clean();
} else
{
$tmp=ob_get_contents();
@ob_end_clean();
}
if ($XSS_DETECT)
@ini_set('ocproducts.xss_detect',$before);
if (!$no_eval_cache_before)
$NO_EVAL_CACHE=$no_eval_cache_before;
$ret=($tmp=='');
$this->is_really_empty=$ret;
return $ret;
}
if ($OB_GET_CLEAN)
{
$this->cached_output=ob_get_clean(); // Optimisation to store it in here. We don't do the same for evaluate_echo as that's a final use case and hence it would be unnecessarily inefficient to store the result
} else
{
$this->cached_output=ob_get_contents(); // Optimisation to store it in here. We don't do the same for evaluate_echo as that's a final use case and hence it would be unnecessarily inefficient to store the result
@ob_end_clean();
}
if (!$no_eval_cache_before)
$NO_EVAL_CACHE=$no_eval_cache_before;
if ($XSS_DETECT)
@ini_set('ocproducts.xss_detect',$before);
$ret=($this->cached_output=='');
$this->is_really_empty=$ret;
return $ret;
}
string to_assembly()
Assemble the current tempcode object into a single serialised (compiled) tempcode storage representation (parameters and certain symbols and not evaluated). The output of the function is language-tied.
Parameters…
Returns…
| Description |
The assembly result |
| Type |
string |
function to_assembly()
{
return 'return unserialize("'.php_addslashes(serialize(array($this->seq_parts,$this->preprocessable_bits,$this->codename,$this->last_attach,$this->pure_lang,$this->code_to_preexecute))).'");'.chr(10);
}
boolean from_assembly_executed(PATH file, array forced_reload_details)
The opposite of to_assembly - it decodes a tempcode storage representation and turns it into a proper tempcode object. This version handles the result of evaled code.
Parameters…
| Name |
file |
| Description |
The file to load |
| Type |
PATH |
| Name |
forced_reload_details |
| Description |
List of parameters for a forced reload if required |
| Type |
array |
Returns…
| Description |
Success status (it can fail, if the compiled cache file is corrupt) |
| Type |
boolean |
function from_assembly_executed($file,$forced_reload_details)
{
if ($GLOBALS['RECORD_TEMPLATES_TREE'])
{
$this->fresh=false;
$this->children=array();
}
$result=@include($file); // We don't eval on this because we want it to potentially be op-code cached by e.g. Zend Accelerator
if (!is_array($result)) return false; // May never get here, as PHP fatal errors can't be supressed or skipped over
$this->cached_output=NULL;
list($this->seq_parts,$this->preprocessable_bits,$this->codename,$this->last_attach,$this->pure_lang,$this->code_to_preexecute)=$result;
if ($forced_reload_details[6]===NULL) $forced_reload_details[6]='';
if ((isset($this->code_to_preexecute[800])) && ($GLOBALS['CACHE_TEMPLATES']))
{
// We don't actually use $code_to_preexecute, because it uses too much RAM and DB space throwing full templates into the cacheing. Instead we rewrite to custom load it whenever it's needed. This isn't inefficient due to normal opcode cacheing and optimizer opcode cacheing, and because we cache Tempcode object's evaluations at runtime so it can only happen once per screen view.
$this->code_to_preexecute='if (($result=@include(\''.php_addslashes($file).'\'))===false) { $tmp=do_template(\''.php_addslashes($forced_reload_details[0]).'\',NULL,\''.php_addslashes($forced_reload_details[2]).'\',false,\''.(($forced_reload_details[6]=='')?'':php_addslashes($forced_reload_details[6])).'\',\''.($forced_reload_details[4]).'\',\''.($forced_reload_details[5]).'\'); clearstatcache(); if (mt_rand(0,100)==1 || !is_file(\''.php_addslashes($file).'\')) { $GLOBALS[\'CACHE_TEMPLATES\']=false; } eval($tmp->code_to_preexecute); unset($tmp); }
else { eval($result[5]); unset($result); }';
}
global $SITE_INFO;
if (((!isset($SITE_INFO['disable_decaching_shift_encode'])) || ($SITE_INFO['disable_decaching_shift_encode']!='1')) && (@strpos(file_get_contents($file),'SHIFT_ENCODE')!==false))
{
$this->code_to_preexecute.='/*SHIFT_ENCODE*/';
}
if ($GLOBALS['XSS_DETECT'])
{
$this->_mark_all_as_escaped();
}
return true;
}
void _mark_all_as_escaped()
Recursively mark all parameters in this Tempcode as escaped. This is needed when loading from cache, as escape tainting data would have been lost.
Parameters…
(No return value)
function _mark_all_as_escaped()
{
foreach ($this->seq_parts as $seq_part)
{
foreach ($seq_part[1] as $key=>$val)
{
if (is_string($val))
{
ocp_mark_as_escaped($val);
} elseif (is_object($val))
{
$val->_mark_all_as_escaped();
}
$seq_part[1][$key]=$val;
}
}
}
boolean from_assembly(string raw_data, boolean allow_failure)
The opposite of to_assembly - it decodes a tempcode storage representation and turns it into a proper tempcode object.
Parameters…
| Name |
raw_data |
| Description |
The assembled tempcode |
| Type |
string |
| Name |
allow_failure |
| Description |
Return error code on failure, rather than exiting |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
Success status (it can fail, if the compiled cache file is corrupt) |
| Type |
boolean |
function from_assembly(&$raw_data,$allow_failure=false)
{
if ($GLOBALS['RECORD_TEMPLATES_TREE'])
{
$this->fresh=false;
$this->children=array();
}
$result=eval($raw_data);
if ($result===false)
{
if ($allow_failure) return false;
//inspect_plain($raw_data);
fatal_exit(@strval($php_errormsg));
}
$this->cached_output=NULL;
list($this->seq_parts,$this->preprocessable_bits,$this->codename,$this->last_attach,$this->pure_lang,$this->code_to_preexecute)=$result;
if ($GLOBALS['XSS_DETECT'])
{
$this->_mark_all_as_escaped();
}
if (strpos($raw_data,'SHIFT_ENCODE')!==false)
{
$this->code_to_preexecute.='/*SHIFT_ENCODE*/';
$this->evaluate();
}
return true;
}
void singular_bind(string parameter, tempcode value)
Replace the named parameter with a specific value. Hardly used, but still important. Note that this will bind to all kinds of things that might not normally take named parameters, like symbols; this should not cause problems though.
Parameters…
| Name |
parameter |
| Description |
Named parameter |
| Type |
string |
| Name |
value |
| Description |
Specific value |
| Type |
tempcode |
(No return value)
function singular_bind($parameter,$value)
{
$this->cached_output=NULL;
if ($this->seq_parts==array()) return;
foreach ($this->seq_parts as $i=>$bit)
{
if ((($bit[0][0]!='s') || (substr($bit[0],0,14)!='string_attach_')) && ($bit[2]!=TC_LANGUAGE_REFERENCE))
$bit[1][$parameter]=$value;
$this->seq_parts[$i]=$bit;
}
$this->preprocessable_bits=array_merge($value->preprocessable_bits,$value->preprocessable_bits);
}
tempcode bind(array parameters, ID_TEXT codename)
Bind the parameter bits, or recursively bind children (doesn't change self, returns a bound tempcode object)
Parameters…
| Name |
parameters |
| Description |
Map of parameters to bind parameter bits to |
| Type |
array |
| Name |
codename |
| Description |
The codename of the template this tempcode is from |
| Type |
ID_TEXT |
Returns…
| Description |
The new bound tempcode object |
| Type |
tempcode |
function bind(&$parameters,$codename)
{
if (!isset($parameters['_GUID']))
{
$parameters['_GUID']='';
static $dbt=NULL;
if ($dbt===NULL)
$dbt=function_exists('debug_backtrace');
if ($dbt)
{
$trace=debug_backtrace();
$parameters['_GUID']=isset($trace[3])?($trace[3]['function'].'/'.$trace[2]['function']):(isset($trace[2])?$trace[2]['function']:$trace[1]['function']);
}
}
$out=new ocp_tempcode();
$out->codename=$codename;
$out->code_to_preexecute=$this->code_to_preexecute;
$out->preprocessable_bits=array();
foreach ($this->preprocessable_bits as $preprocessable_bit)
{
foreach ($preprocessable_bit[3] as $i=>$param)
{
if ((($preprocessable_bit[2]!='SET') || (($i==1))) && (is_object($param)))
$preprocessable_bit[3][$i]=$param->bind($parameters,'');
}
$out->preprocessable_bits[]=$preprocessable_bit;
}
if ($GLOBALS['RECORD_TEMPLATES_TREE'])
{
$out->children=isset($this->children)?$this->children:array();
foreach ($parameters as $key=>$parameter)
{
if (is_object($parameter))
{
if (count($parameter->preprocessable_bits)!=0)
$parameter->handle_symbol_preprocessing(); // Needed to force children to be populated. Otherwise it is possible but not definite that evaluation will result in children being pushed down (SHIFT_ENCODING in a template can cause them to be misappropriated, as it causes a runtime cache string in the Tempcode tree).
$out->children[]=array($parameter->codename,isset($parameter->children)?$parameter->children:array(),isset($parameter->fresh)?$parameter->fresh:false);
}
elseif ((is_string($parameter)) && ($key=='_GUID'))
{
$out->children[]=array(':guid',array(array(':'.$parameter,array(),true)),true);
}
}
}
foreach ($parameters as $key=>$parameter)
{
$p_type=gettype($parameter);
if ($p_type=='string')
{
// Performance, this is most likely
}
elseif ($p_type=='object')
{
if (isset($parameter->preprocessable_bits[0]))
{
$out->preprocessable_bits=array_merge($out->preprocessable_bits,$parameter->preprocessable_bits);
} elseif (!isset($parameter->seq_parts[0])) $parameters[$key]=''; // Little optimisation to save memory
}
elseif ($p_type=='boolean')
{
$parameters[$key]=$parameter?'1':'0';
}
elseif (($p_type!='array') && ($p_type!='NULL'))
{
warn_exit(do_lang_tempcode('NO_INTEGERS_TEMPLATE',escape_html($key)));
}
}
foreach ($this->seq_parts as $bit)
{
if ((($bit[0][0]!='s') || (substr($bit[0],0,14)!='string_attach_')) && ($bit[2]!=TC_LANGUAGE_REFERENCE))
$bit[1]=&$parameters; // & is to preserve memory
$out->seq_parts[]=$bit;
}
// Force pre-execution, so shift encoding handled. This is prior to pre-processing (it needs to be for validity in interaction with what is in itself preprocessed), so you could consider it pre-pre-processing
if (strpos($out->code_to_preexecute,'SHIFT_ENCODE')!==false) $out->evaluate();
return $out;
}
string evaluate_echo(?LANGUAGE_NAME current_lang, mixed _escape)
Parse the current tempcode object, then echo it to the browser.
Parameters…
| Name |
current_lang |
| Description |
The language to evaluate with (NULL: current users language) |
| Default value |
|
| Type |
?LANGUAGE_NAME |
| Name |
_escape |
| Description |
Whether to escape the tempcode object (children may be recursively escaped regardless if those children/parents are marked to be) |
| Default value |
boolean-false |
| Type |
mixed |
Returns…
| Description |
Blank string. Allows chaining within echo statements |
| Type |
string |
function evaluate_echo($current_lang=NULL,$_escape=false)
{
if (ocp_srv('REQUEST_METHOD')=='HEAD') return '';
if ($this->cached_output!==NULL)
{
echo $this->cached_output;
$this->cached_output=NULL; // Won't be needed again
return '';
}
if (!isset($this->seq_parts[0]))
{
$this->cached_output='';
return '';
}
$cl=$current_lang;
//ob_start();
//$tempcode_profile_log_start=microtime();
//tempcode_profile_log($this->seq_parts);
global $KEEP_TPL_FUNCS,$FULL_RESET_VAR_CODE,$RESET_VAR_CODE;
$TPL_FUNCS=$KEEP_TPL_FUNCS;
$seq_parts=&$this->seq_parts;
foreach ($seq_parts as $i=>$bit)
{
//$before=memory_get_usage();
$bit_0=$bit[0];
if (!isset($TPL_FUNCS[$bit_0]))
{
//eval_log($this->code_to_preexecute);
if (eval($this->code_to_preexecute)===false) fatal_exit(@strval($php_errormsg));
if (!isset($TPL_FUNCS[$bit_0])) $TPL_FUNCS[$bit_0]=' '; // Fudge to stop error. Actually caused by a race condition and output will be incomplete
}
if (($TPL_FUNCS[$bit_0][0]!='e'/*for echo*/) && (function_exists($TPL_FUNCS[$bit_0])))
{
call_user_func($TPL_FUNCS[$bit_0],$bit[1],$current_lang,$bit[4]);
} else
{
$parameters=$bit[1];
$last_attach=$bit[4];
//eval_log($TPL_FUNCS[$bit_0]);
if (eval($TPL_FUNCS[$bit_0])===false) fatal_exit(@strval($php_errormsg));
}
//@ob_end_flush();@ob_end_flush();@ob_end_flush();print('<!-- tempcode-eval-evaluate_echo: '.htmlentities($this->codename).' ('.clean_file_size(memory_get_usage()-$before).' used, now at '.number_format(memory_get_usage()).') -->'."\n");flush();
// if (isset($GLOBALS['FINISHING_OUTPUT'])) $seq_parts[$i]=NULL;
}
/* if (isset($GLOBALS['FINISHING_OUTPUT'])) Optimisation to free memory up during wind down. Does not work well enough to risk the possible bugs doing this
{
$this->preprocessable_bits=NULL;
$this->seq_parts=NULL;
$this->code_to_preexecute=NULL;
}*/
//ob_end_flush();
//$tempcode_profile_log_end=microtime();
//tempcode_profile_log_diff($tempcode_profile_log_start,$tempcode_profile_log_end,$this->seq_parts);
return '';
}
string evaluate(?LANGUAGE_NAME current_lang, mixed _escape, ?integer up_to)
Parses the current tempcode object, then return the parsed string
Parameters…
| Name |
current_lang |
| Description |
The language to evaluate with (NULL: current user's language) |
| Default value |
|
| Type |
?LANGUAGE_NAME |
| Name |
_escape |
| Description |
Whether to escape the tempcode object (children may be recursively escaped regardless if those children/parents are marked to be) |
| Default value |
boolean-false |
| Type |
mixed |
| Name |
up_to |
| Description |
Evaluate at least this much (NULL: evaluate all) |
| Default value |
|
| Type |
?integer |
Returns…
| Description |
The evaluated thing. Voila, it's all over! |
| Type |
string |
function evaluate($current_lang=NULL,$_escape=false,$up_to=NULL)
{
static $do_memory_tracking=NULL;
if ($do_memory_tracking===NULL) $do_memory_tracking=(get_value('memory_tracking')==='1');
if ($do_memory_tracking)
{
if ((memory_get_usage()>50*1024*1024) && ((!isset($GLOBALS['FORUM_DRIVER'])) || (!$GLOBALS['FORUM_DRIVER']->is_super_admin(get_member()))))
{
fatal_exit('Memory problem - over 50MB used');
}
}
if (isset($this->cached_output)) return $this->cached_output;
if (!isset($this->seq_parts[0]))
{
$this->cached_output='';
return '';
}
global $NO_EVAL_CACHE,$MEMORY_OVER_SPEED,$USER_LANG_CACHED,$XSS_DETECT,$OB_GET_CLEAN;
ob_start();
if ($XSS_DETECT)
{
$before=@ini_get('ocproducts.xss_detect');
@ini_set('ocproducts.xss_detect','0');
}
if ($current_lang===NULL)
{
if (isset($USER_LANG_CACHED))
{
$current_lang=$USER_LANG_CACHED;
} else
{
if (!function_exists('user_lang')) require_code('lang');
$current_lang=user_lang();
}
}
$cl=$current_lang;
//$tempcode_profile_log_start=microtime();
//tempcode_profile_log($this->seq_parts);
global $KEEP_TPL_FUNCS,$FULL_RESET_VAR_CODE,$RESET_VAR_CODE;
$TPL_FUNCS=$KEEP_TPL_FUNCS; // NB: $TPL_FUNCS isn't really global, done like this for legacy reasons so our cache doesn't break. Eval'd code is in same variable scope
$doing_up_to=isset($up_to);
$seq_parts=&$this->seq_parts;
$no_eval_cache_before=$NO_EVAL_CACHE;
foreach ($seq_parts as $i=>$bit)
{
if (($doing_up_to) && (ob_get_length()>$up_to))
{
if ($OB_GET_CLEAN)
{
$ret=ob_get_clean();
} else
{
$ret=ob_get_contents();
@ob_end_clean();
}
if ($XSS_DETECT)
@ini_set('ocproducts.xss_detect',$before);
return $ret;
}
//$before=memory_get_usage();
$bit_0=$bit[0];
if (!isset($TPL_FUNCS[$bit_0]))
{
//eval_log($this->code_to_preexecute);
if (eval($this->code_to_preexecute)===false) fatal_exit(@strval($php_errormsg));
if (!isset($TPL_FUNCS[$bit_0])) $TPL_FUNCS[$bit_0]=' '; // Fudge to stop error. Actually caused by a race condition and output will be incomplete
}
if (($TPL_FUNCS[$bit_0][0]!='e'/*for echo*/) && (function_exists($TPL_FUNCS[$bit_0])))
{
call_user_func($TPL_FUNCS[$bit_0],$bit[1],$current_lang,$bit[4]);
} else
{
$parameters=$bit[1];
$last_attach=$bit[4];
/*$code=$TPL_FUNCS[$bit_0]; Debug code to find good stack traces but unfortunately it never worked
$file=get_custom_file_base().'/uploads/website_specific/'.substr(md5($code),0,10).'.php';
$myfile=fopen($file,'wb');
fwrite($myfile,'<?php'.chr(10));
fwrite($myfile,$code);
fclose($myfile);
fix_permissions($file);
sync_file($file);
if (@include($file)===false)*/
//eval_log($TPL_FUNCS[$bit_0]);
if (eval($TPL_FUNCS[$bit_0])===false)
{
//@ob_end_clean();@var_dump($this);@exit($php_errormsg);
fatal_exit(@strval($php_errormsg));
}
}
//@ob_end_flush();@ob_end_flush();@ob_end_flush();print('<!-- tempcode-eval-evaluate: '.htmlentities($this->codename).' ('.clean_file_size(memory_get_usage()-$before).' used, now at '.number_format(memory_get_usage()).') -->'."\n");flush();
}
if ($XSS_DETECT)
@ini_set('ocproducts.xss_detect',$before);
//$tempcode_profile_log_end=microtime();
//tempcode_profile_log_diff($tempcode_profile_log_start,$tempcode_profile_log_end,$this->seq_parts);
if ($NO_EVAL_CACHE || $MEMORY_OVER_SPEED)
{
if (!$no_eval_cache_before)
$NO_EVAL_CACHE=$no_eval_cache_before;
if ($OB_GET_CLEAN)
{
$ret=ob_get_clean();
} else
{
$ret=ob_get_contents();
@ob_end_clean();
}
return $ret;
}
if ($OB_GET_CLEAN)
{
$this->cached_output=ob_get_clean(); // Optimisation to store it in here. We don't do the same for evaluate_echo as that's a final use case and hence it would be unnecessarily inefficient to store the result
} else
{
$this->cached_output=ob_get_contents(); // Optimisation to store it in here. We don't do the same for evaluate_echo as that's a final use case and hence it would be unnecessarily inefficient to store the result
@ob_end_clean();
}
return $this->cached_output;
}
sources/symbols.php
Global_functions_symbols.php
Function summary
|
void
|
init__symbols ()
|
|
mixed
|
evaluate_conventional_variable (LANGUAGE_NAME lang, array escaped, integer type, ID_TEXT name, array param)
|
|
mixed
|
ecv (LANGUAGE_NAME lang, array escaped, integer type, ID_TEXT name, array param)
|
|
string
|
symbol_truncator (array param, string type, ?mixed tooltip_if_truncated)
|
|
string
|
keep_symbol (array param)
|
void init__symbols()
Standard code module initialisation function.
Parameters…
(No return value)
function init__symbols()
{
global $LOADED_NONREG_LOGO,$LOADED_BLOCKS,$LOADED_PAGES,$LOADED_PANELS,$NON_CACHEABLE_SYMBOLS,$EXTRA_SYMBOLS,$DOCUMENT_HELP,$HTTP_STATUS_CODE,$PREPROCESSABLE_SYMBOLS;
$LOADED_NONREG_LOGO=false;
$LOADED_BLOCKS=array();
$LOADED_PAGES=array();
$LOADED_PANELS=array();
$NON_CACHEABLE_SYMBOLS=array('SET_RAND'=>1,'RAND'=>1,'CSS_TEMPCODE'=>1,'JS_TEMPCODE'=>1); // these symbols can't be cached regardless of if they have params or not; other symbols can only be cached if they have no params or escaping
$PREPROCESSABLE_SYMBOLS=array('PAGE_LINK'=>1,'SET'=>1,'BLOCK'=>1,'FACILITATE_AJAX_BLOCK_CALL'=>1,'JAVASCRIPT_INCLUDE'=>1,'CSS_INCLUDE'=>1,'LOAD_PANEL'=>1,'JS_TEMPCODE'=>1,'CSS_TEMPCODE'=>1,'LOAD_PAGE'=>1,'FRACTIONAL_EDITABLE'=>1,);
$EXTRA_SYMBOLS=NULL;
$DOCUMENT_HELP='';
$HTTP_STATUS_CODE='200';
global $META_DATA;
$META_DATA=array();
global $SHIFT_VARIABLES,$SYMBOL_CACHE,$CYCLES,$TEMPCODE_SETGET;
$SHIFT_VARIABLES=array();
$SYMBOL_CACHE=array();
$CYCLES=array();
$TEMPCODE_SETGET=array();
}
mixed evaluate_conventional_variable(LANGUAGE_NAME lang, array escaped, integer type, ID_TEXT name, array param)
Evaluate a conventional tempcode variable, handling escaping. Long named one, for compatibility (we've moved to short one for shorter compiled Tempcode). DEPRECATED.
Parameters…
| Name |
lang |
| Description |
The language to evaluate this symbol in (some symbols refer to language elements) |
| Type |
LANGUAGE_NAME |
| Name |
escaped |
| Description |
Array of escaping operations |
| Type |
array |
| Name |
type |
| Description |
The type of symbol this is (TC_SYMBOL, TC_LANGUAGE_REFERENCE) |
| Type |
integer |
| Values restricted to |
0 2 |
| Name |
name |
| Description |
The name of the symbol |
| Type |
ID_TEXT |
| Name |
param |
| Description |
Parameters to the symbol. For all but directive it is an array of strings. For directives it is an array of Tempcode objects. Actually there may be template-style parameters in here, as an influence of singular_bind and these may be Tempcode, but we ignore them. |
| Type |
array |
Returns…
| Description |
The result. Either tempcode, or a string. |
| Type |
mixed |
function evaluate_conventional_variable($lang,$escaped,$type,$name,$param)
{
return ecv($lang,$escaped,$type,$name,$param);
}
mixed ecv(LANGUAGE_NAME lang, array escaped, integer type, ID_TEXT name, array param)
Evaluate a conventional tempcode variable, handling escaping
Parameters…
| Name |
lang |
| Description |
The language to evaluate this symbol in (some symbols refer to language elements) |
| Type |
LANGUAGE_NAME |
| Name |
escaped |
| Description |
Array of escaping operations |
| Type |
array |
| Name |
type |
| Description |
The type of symbol this is (TC_SYMBOL, TC_LANGUAGE_REFERENCE) |
| Type |
integer |
| Values restricted to |
0 2 |
| Name |
name |
| Description |
The name of the symbol |
| Type |
ID_TEXT |
| Name |
param |
| Description |
Parameters to the symbol. For all but directive it is an array of strings. For directives it is an array of Tempcode objects. Actually there may be template-style parameters in here, as an influence of singular_bind and these may be Tempcode, but we ignore them. |
| Type |
array |
Returns…
| Description |
The result. Either tempcode, or a string. |
| Type |
mixed |
function ecv($lang,$escaped,$type,$name,$param)
{
global $TEMPCODE_SETGET,$CYCLES,$PREPROCESSABLE_SYMBOLS,$DISPLAYED_TITLE;
//echo '<!--'.$name.'-->'."\n";
if ($type==TC_SYMBOL)
{
$escaped_codes=$name.(($escaped==array())?'':serialize($escaped));
$cacheable=(($param==array()) && (!isset($GLOBALS['NON_CACHEABLE_SYMBOLS'][$name])));
if ($cacheable)
{
global $SYMBOL_CACHE;
if (isset($SYMBOL_CACHE[$escaped_codes])) return $SYMBOL_CACHE[$escaped_codes];
}
$value='';
if ($GLOBALS['XSS_DETECT']) ocp_mark_as_escaped($value);
$temp_array=array();
if ((isset($PREPROCESSABLE_SYMBOLS[$name])) && ($name!='PAGE_LINK'))
handle_symbol_preprocessing(array($escaped,$type,$name,$param),$temp_array); // Late preprocessing. Should not be needed in case of full screen output (as this was properly preprocessed), but is in other cases
switch ($name) // Order by how common (performance)
{
case 'PAGE_LINK':
if (isset($param[0]))
{
list($zone,$map,$hash)=page_link_decode(is_object($param[0])?$param[0]->evaluate():$param[0]);
$skip=NULL;
if (isset($param[4]))
{
$skip=array_flip(explode('|',$param[4]));
}
$avoid_remap=isset($param[1]) && ($param[1]=='1');
$skip_keep=isset($param[2]) && ($param[2]=='1');
$keep_all=isset($param[3]) && ($param[3]=='1');
foreach ($map as $key=>$val)
{
if (is_object($val)) $map[$key]=$val->evaluate();
}
$value=_build_url($map,$zone,$skip,$keep_all,$avoid_remap,$skip_keep,$hash);
} else
{
$value=get_zone_name().':'.get_page_name();
foreach ($_GET as $key=>$val)
{
if ($key=='page') continue;
if (is_array($val)) continue;
if ((substr($key,0,5)=='keep_') && (!skippable_keep($key,$val))) continue;
$value.=':'.$key.'='.$val;
}
}
break;
case 'SET':
if (isset($param[1]))
{
if (isset($param[1]) && is_object($param[1]))
{
$TEMPCODE_SETGET[$param[0]]=$param[1];
} else
{
$param_copy=$param;
unset($param_copy[0]);
$TEMPCODE_SETGET[$param[0]]=implode(',',$param_copy);
}
}
break;
case 'GET':
if (isset($param[0]))
{
if (isset($TEMPCODE_SETGET[$param[0]]))
{
if (is_object($TEMPCODE_SETGET[$param[0]])) $TEMPCODE_SETGET[$param[0]]=$TEMPCODE_SETGET[$param[0]]->evaluate();
$value=$TEMPCODE_SETGET[$param[0]];
}
}
break;
case 'EQ':
if (isset($param[1]))
{
$first=array_shift($param);
$count=0;
foreach ($param as $test)
{
if ($first==$test)
{
$count++;
break;
}
}
$value=($count!=0)?'1':'0';
}
break;
case 'NEQ':
if (isset($param[1]))
{
$first=array_shift($param);
$count=0;
foreach ($param as $test)
{
if ($first==$test) $count++;
}
$value=($count==0)?'1':'0';
}
break;
case 'NOT':
if (isset($param[0]))
{
$value=(($param[0]=='1') || ($param[0]=='1'))?'0':'1';
}
break;
case 'OR':
$count=0;
foreach ($param as $test)
{
if (($test=='1') || ($test=='1')) $count++;
}
$value=($count>0)?'1':'0';
break;
case 'AND':
$count=0;
foreach ($param as $test)
{
if (($test=='1') || ($test=='1')) $count++;
}
$value=($count==count($param))?'1':'0';
break;
case 'HAS_ACTUAL_PAGE_ACCESS':
if (isset($param[0]))
{
$value=has_actual_page_access(((($param!==NULL)) && (isset($param[2])))?intval($param[2]):get_member(),$param[0],isset($param[1])?$param[1]:NULL)?'1':'0';
}
break;
case '?':
if (isset($param[1]))
{
$value=(($param[0]=='1') || ($param[0]=='1'))?$param[1]:(isset($param[2])?$param[2]:$value);
}
break;
case 'IMG':
if ((isset($param[0])) && (isset($GLOBALS['SITE_DB'])) && (function_exists('find_theme_image')) && ($GLOBALS['IN_MINIKERNEL_VERSION']==0))
{
$value=find_theme_image($param[0],((isset($param[3])) && ($param[3]=='1')),false,(array_key_exists(2,$param) && $param[2]!='')?$param[2]:NULL,NULL,((isset($param[1])) && ($param[1]=='1'))?$GLOBALS['FORUM_DB']:$GLOBALS['SITE_DB']);
}
break;
case '':
break;
case 'META_DATA':
if (isset($param[0]))
{
global $META_DATA;
if (isset($param[1]))
{
$META_DATA[$param[0]]=$param[1];
} else
{
$value=isset($META_DATA[$param[0]])?$META_DATA[$param[0]]:'';
if ($value===NULL) $value='';
}
}
break;
case 'SPECIAL_CLICK_TO_EDIT':
$_value=do_lang_tempcode('SPECIAL_CLICK_TO_EDIT');
$value=$_value->evaluate();
break;
case 'KEEP':
// What needs preserving in the URL
$value=keep_symbol($param);
break;
case 'BROWSER':
if (isset($param[1]))
{
$q=false;
foreach (explode('|',$param[0]) as $browser)
{
$q=browser_matches($browser);
if ($q) break;
}
$value=$q?$param[1]:(isset($param[2])?$param[2]:'');
if ($GLOBALS['XSS_DETECT']) ocp_mark_as_escaped($value);
}
break;
case 'JAVASCRIPT_INCLUDE':
if (isset($param[0]))
{
require_javascript($param[0]);
/*// Has to do this inline, as you're not allowed to reference scripts outside head
if (!array_key_exists($param[0],$GLOBALS['JAVASCRIPTS']))
{
$GLOBALS['JAVASCRIPTS'][$param[0]]=1;
$file=javascript_enforce($param[0]);
$_value=do_template('JAVASCRIPT_NEED_INLINE',array('_GUID'=>'d6c907e26c5a8dd8c65f1d36a1a674a9','CODE'=>file_get_contents($file,FILE_TEXT)));
$value=$_value->evaluate();
}*/
}
break;
case 'FACILITATE_AJAX_BLOCK_CALL':
if (isset($param[0]))
{
require_javascript('javascript_ajax');
require_code('blocks');
$_block_constraints=block_params_to_block_signature(block_params_str_to_arr($param[0]));
if (array_key_exists(1,$param))
{
$_block_constraints=array_merge($_block_constraints,block_params_str_to_arr($param[1]));
ksort($_block_constraints);
}
$block_constraints=block_params_arr_to_str($_block_constraints);
// Store permissions
$_auth_key=$GLOBALS['SITE_DB']->query_select('temp_block_permissions',array('id','p_time'),array(
'p_session_id'=>get_session_id(),
'p_block_constraints'=>$block_constraints,
),'',1);
if (!array_key_exists(0,$_auth_key))
{
$auth_key=$GLOBALS['SITE_DB']->query_insert('temp_block_permissions',array(
'p_session_id'=>get_session_id(),
'p_block_constraints'=>$block_constraints,
'p_time'=>time(),
),true);
} else
{
$auth_key=$_auth_key[0]['id'];
if (time()-$_auth_key[0]['p_time']>100)
{
$GLOBALS['SITE_DB']->query_update('temp_block_permissions',array('p_time'=>time()),array(
'p_session_id'=>get_session_id(),
'p_block_constraints'=>$block_constraints,
),'',1);
}
}
$keep=symbol_tempcode('KEEP');
$value=find_script('snippet').'?snippet=block&auth_key='.urlencode(strval($auth_key)).'&block_map='.urlencode($param[0]).$keep->evaluate();
}
break;
case 'LANG':
$value=user_lang();
break;
case '_GET':
if (isset($param[0]))
{
$value=get_param($param[0],isset($param[1])?$param[1]:'',true);
}
break;
case 'QUERY_STRING':
$value=ocp_srv('QUERY_STRING');
break;
case 'USER_AGENT':
$value=ocp_srv('HTTP_USER_AGENT');
break;
case 'STRIP_TAGS':
if (isset($param[0]))
{
if ((isset($param[1])) && ($param[1]=='1'))
{
$value=strip_tags(str_replace('))',')',str_replace('((','(',str_replace('<em>','(',str_replace('</em>',')',$param[0])))));
} else
{
$value=strip_tags($param[0],array_key_exists(2,$param)?$param[2]:'');
}
if ((isset($param[1])) && ($param[1]=='1')) $value=@html_entity_decode($value,ENT_QUOTES,get_charset());
}
break;
case 'CONFIG_OPTION':
if (isset($param[0]))
{
if (!isset($GLOBALS['OPTIONS'])) // Installer, likely executing JAVASCRIPT.tpl
{
$value='0';
} else
{
$value=get_option($param[0],true);
if ($value===NULL) $value='';
}
}
break;
case 'TRUNCATE_LEFT': // Truncate the left length of a string. 0: text to truncate, 1: the truncate length, 2: whether to use a tooltip mouse-over if it is truncated, 3: whether it is encoded as HTML (0=no [default, plain-text], 1=yes)
$value=symbol_truncator($param,'left');
break;
case 'TRUNCATE_RIGHT':
$value=symbol_truncator($param,'right');
break;
case 'TRUNCATE_SPREAD':
$value=symbol_truncator($param,'spread');
break;
case 'TRUNCATE_EXPAND':
$value=symbol_truncator($param,'expand');
break;
case 'THEME':
if (isset($GLOBALS['FORUM_DRIVER']))
{
$value=$GLOBALS['FORUM_DRIVER']->get_theme();
} else
{
$value='default';
}
break;
case 'REVERSE':
if (isset($param[0]))
{
$value=implode(',',array_reverse(explode(',',$param[0])));
}
break;
case 'COMMA_LIST_GET':
if (isset($param[1]))
{
require_code('blocks');
$values=block_params_str_to_arr($param[0]);
$value=isset($values[$param[1]])?$values[$param[1]]:'';
}
break;
case 'COMMA_LIST_SET':
if (isset($param[2]))
{
require_code('blocks');
$values=block_params_str_to_arr($param[0]);
$values[$param[1]]=$param[2];
$value=block_params_arr_to_str($values);
}
break;
case 'IS_EMPTY':
if (isset($param[0]))
{
$value=($param[0]=='')?'1':'0';
}
break;
case 'IS_NON_EMPTY':
if (isset($param[0]))
{
$value=($param[0]!='')?'1':'0';
}
break;
case 'CUSTOM_BASE_URL':
$value=get_custom_base_url((isset($param[0]) && ($param[0]!=''))?($param[0]=='1'):NULL);
if ((isset($param[1])) && ($param[1]=='1'))
{
$value=cdn_filter($value);
}
break;
case 'LOAD_PANEL':
foreach ($param as $i=>$p)
if (is_object($p)) $param[$i]=$p->evaluate();
global $LOADED_PANELS;
if (strpos($param[0],':')!==false)
$param=array_reverse(explode(':',$param[0],2));
if (substr($param[0],0,6)=='panel_') $param[0]=substr($param[0],6);
$sr=serialize($param);
$value=array_key_exists($sr,$LOADED_PANELS)?$LOADED_PANELS[$sr]:'';
break;
case 'HAS_JS':
case 'JS_ON':
if (isset($param[1]))
{
$value=has_js()?$param[0]:$param[1];
} else $value=has_js()?'1':'0';
break;
case 'BASE_URL_NOHTTP':
$value=preg_replace('#^https?://[^/]+#','',get_base_url());
if (substr($value,0,2)=='//') $value=substr($value,1);
if (!$GLOBALS['DEBUG_MODE']) break; // Debug mode changes base domain so we need to actually use it in full (fine, we don't have HTTPS in debug mode). Bubble on...
case 'CUSTOM_BASE_URL_NOHTTP':
$value=preg_replace('#^https?://[^/]+/#','/',get_custom_base_url());
if (substr($value,0,2)=='//') $value=substr($value,1);
if (!$GLOBALS['DEBUG_MODE']) break; // Debug mode changes base domain so we need to actually use it in full (fine, we don't have HTTPS in debug mode). Bubble on...
case 'BASE_URL':
$value=get_base_url(isset($param[0])?($param[0]=='1'):NULL);
break;
case 'ZONE':
$value=get_zone_name();
break;
case 'PAGE':
$value=get_page_name();
break;
case 'SITE_NAME':
$value=get_site_name();
break;
case 'HEADER_TEXT':
global $ZONE;
$value=$ZONE['zone_header_text_trans'];
break;
case 'PANEL_WIDTH':
if ((isset($TEMPCODE_SETGET['PANEL_WIDTH'])) && ($TEMPCODE_SETGET['PANEL_WIDTH']!=''))
{
$value=$TEMPCODE_SETGET['PANEL_WIDTH'];
} else
{
$value=get_option('panel_width',true);
if ($value===NULL) $value='13.3em';
}
break;
case 'PANEL_WIDTH_SPACED':
if ((isset($TEMPCODE_SETGET['PANEL_WIDTH_SPACED'])) && ($TEMPCODE_SETGET['PANEL_WIDTH_SPACED']!=''))
{
$value=$TEMPCODE_SETGET['PANEL_WIDTH_SPACED'];
} else
{
$value=get_option('panel_width_spaced',true);
if (is_null($value)) $value='14.3em';
}
break;
case 'TRIM':
if (isset($param[0]))
{
$value=preg_replace(array('#^\s+#','#^(<br\s*/?'.'>\s*)+#','#^( )+#','#\s+$#','#(<br\s*/?'.'>\s*)+$#','#( )+$#'),array('','','','','',''),$param[0]);
}
break;
case 'CPF_VALUE':
if (isset($param[0]))
{
if (is_numeric($param[0]))
{
require_code('ocf_members');
$fields=ocf_get_custom_fields_member(isset($param[1])?intval($param[1]):get_member());
if (array_key_exists(intval($param[0]),$fields)) $_value=$fields[intval($param[0])];
} elseif ((substr($param[0],0,2)=='m_') && (strpos(strtolower($param[0]),'hash')===false) && (strpos(strtolower($param[0]),'salt')===false))
{
$_value=$GLOBALS['FORUM_DRIVER']->get_member_row_field(isset($param[1])?intval($param[1]):get_member(),$param[0]);
} else
{
$_value=get_ocp_cpf($param[0],isset($param[1])?intval($param[1]):NULL);
}
if (!is_string($_value))
{
$value=is_null($_value)?'':strval($_value);
} else
{
$value=$_value;
}
}
break;
case 'BANNER':
if (addon_installed('banners'))
{
global $SITE_INFO;
$is_on_banners=((get_option('is_on_banners')=='1') && ((!has_specific_permission(get_member(),'banner_free')) || (($GLOBALS['FORUM_DRIVER']->is_super_admin(get_member())) && (get_option('admin_banners')=='1')) || (!is_null($GLOBALS['CURRENT_SHARE_USER']))));
if (array_key_exists('throttle_bandwidth_registered',$SITE_INFO))
{
$views_till_now=intval(get_value('page_views'));
$bandwidth_allowed=$SITE_INFO['throttle_bandwidth_registered'];
$total_bandwidth=intval(get_value('download_bandwidth'));
if ($bandwidth_allowed*1024*1024>=$total_bandwidth) $is_on_banners=false;
}
if (($is_on_banners) && (!is_page_https(get_zone_name(),get_page_name()))) // We can't show when HTTPS, due to HTTPS security warnings (can't show HTTP requests on HTTPS page, and banner has them by nature).
{
require_code('banners');
$b_type=isset($param[0])?$param[0]:'';
$internal_only=isset($param[1])?intval($param[1]):(($b_type=='')?0:1);
if (isset($GLOBALS['NON_CACHEABLE_SYMBOLS']['SET_RAND'])) // Normal operation
{
$_value=banners_script(true,'','',$b_type,$internal_only,'');
$value=$_value->evaluate();
} else // Been told to behave statically
{
$value='Banner goes here';
}
}
}
break;
case 'AVATAR':
$value=$GLOBALS['FORUM_DRIVER']->get_member_avatar_url(isset($param[0])?intval($param[0]):get_member());
if ((url_is_local($value)) && ($value!='')) $value=get_base_url().'/'.$value;
break;
case 'IS_GUEST':
if (isset($param[0]))
{
$value=(is_guest(intval($param[0])))?'1':'0';
} else
{
$value=is_guest()?'1':'0';
}
break;
case 'MEMBER':
$value=strval(get_member());
break;
case 'USER':
if (!isset($param[0]))
{
$value=strval(get_member());
} else
{
$member_id=$GLOBALS['FORUM_DRIVER']->get_member_from_username($param[0]);
$value=is_null($member_id)?'':strval($member_id);
}
break;
case 'CSS_INCLUDE':
if (isset($param[0]))
{
require_css($param[0]);
/*// Has to do this inline, as you're not allowed to reference sheets outside head
if (!array_key_exists($param[0],$GLOBALS['CSSS']))
{
$GLOBALS['CSSS'][$param[0]]=1;
$file=css_enforce($param[0]);
$_value=do_template('CSS_NEED_INLINE',array('_GUID'=>'9de994d2f6d47a622d49347feb7ebe96','CSS'=>str_replace('../../../../',get_base_url().'/',file_get_contents($file,FILE_TEXT))));
$value=$_value->evaluate();
}*/
}
break;
case 'USER_OVERIDE':
$value=get_param('id','');
if ((!is_numeric($value)) || ($value=='')) $value=strval(get_member());
break;
case 'IS_HTTPAUTH_LOGIN':
$value=is_httpauth_login()?'1':'0';
break;
case 'MEMBER_PROFILE_LINK':
$value=$GLOBALS['FORUM_DRIVER']->member_profile_url(((!is_null($param)) && (isset($param[0])))?intval($param[0]):get_member(),false,true);
if (is_null($value)) $value='';
break;
case 'USERNAME':
$value=$GLOBALS['FORUM_DRIVER']->get_username(((!is_null($param)) && (isset($param[0])))?intval($param[0]):get_member());
if (is_null($value)) $value=do_lang('UNKNOWN');
break;
case 'CYCLE':
if (isset($param[0]))
{
if (!isset($CYCLES[$param[0]])) $CYCLES[$param[0]]=0;
if (!isset($param[1])) // If we can't find a param simply return the index. Poor-mans cycle reader.
{
$value=strval($CYCLES[$param[0]]);
} else // Cycle
{
if (count($param)==2)
{
$param=array_merge(array($param[0]),explode(',',$param[1]));
}
++$CYCLES[$param[0]];
if (!array_key_exists($CYCLES[$param[0]],$param)) $CYCLES[$param[0]]=1;
$value=$param[$CYCLES[$param[0]]];
}
}
break;
case 'THUMBNAIL':
require_code('images');
$value=_symbol_thumbnail($param);
break;
case 'IMAGE_WIDTH':
require_code('images');
list($value,)=_symbol_image_dims($param);
break;
case 'IMAGE_HEIGHT':
require_code('images');
list(,$value)=_symbol_image_dims($param);
break;
case 'IS_IN_GROUP':
if (isset($param[0]))
{
if (in_array($param[count($param)-1],array('','primary','secondary')))
{
$last_param=$param[count($param)-1];
unset($param[count($param)-1]);
} else $last_param='';
$member_id=get_member();
$new_param='';
$param_2=array();
foreach ($param as $group)
{
if ((substr($group,0,1)=='!') && (is_numeric(substr($group,1))))
{
$member_id=intval(substr($group,1));
} else
{
$param_2=array_merge($param_2,explode(',',$group));
}
}
foreach ($param_2 as $group)
{
if ($new_param!='') $new_param.=',';
$new_param.=$group;
}
if ($last_param=='primary')
{
$member_row=$GLOBALS['FORUM_DRIVER']->get_member_row($member_id);
$real_group_list=array($GLOBALS['FORUM_DRIVER']->pname_group($member_row));
}
elseif ($last_param=='secondary')
{
$real_group_list=$GLOBALS['FORUM_DRIVER']->get_members_groups($member_id);
$member_row=$GLOBALS['FORUM_DRIVER']->get_member_row($member_id);
$real_group_list=array_diff($real_group_list,array($GLOBALS['FORUM_DRIVER']->pname_group($member_row)));
} else
{
$real_group_list=$GLOBALS['FORUM_DRIVER']->get_members_groups($member_id);
}
require_code('ocfiltering');
$value=(count(array_intersect(ocfilter_to_idlist_using_memory($new_param,$GLOBALS['FORUM_DRIVER']->get_usergroup_list()),$real_group_list))!=0)?'1':'0';
}
break;
case 'IS_STAFF':
if (isset($GLOBALS['FORUM_DRIVER']))
$value=$GLOBALS['FORUM_DRIVER']->is_staff(((!is_null($param)) && (isset($param[0])))?intval($param[0]):get_member())?'1':'0';
else $value='0';
break;
case 'IS_SUPER_ADMIN':
if (isset($GLOBALS['FORUM_DRIVER']))
$value=$GLOBALS['FORUM_DRIVER']->is_super_admin(((!is_null($param)) && (isset($param[0])))?intval($param[0]):get_member())?'1':'0';
else $value='0';
break;
case 'PHOTO':
if (isset($param[0]))
{
$value=$GLOBALS['FORUM_DRIVER']->get_member_photo_url(intval($param[0]));
if ((url_is_local($value)) && ($value!='')) $value=get_base_url().'/'.$value;
}
break;
case 'OCF_RANK_IMAGE':
if (addon_installed('ocf_forum'))
{
require_code('ocf_groups');
$rank_images=new ocp_tempcode();
$member_id=isset($param[0])?intval($param[0]):get_member();
$posters_groups=$GLOBALS['FORUM_DRIVER']->get_members_groups($member_id,true);
foreach ($posters_groups as $group)
{
$rank_image=ocf_get_group_property($group,'rank_image');
$group_leader=ocf_get_group_property($group,'group_leader');
$group_name=ocf_get_group_name($group);
$rank_image_pri_only=ocf_get_group_property($group,'rank_image_pri_only');
if (($rank_image!='') && (($rank_image_pri_only==0) || ($group==$GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id,'m_primary_group'))))
{
$rank_images->attach(do_template('OCF_RANK_IMAGE',array('USERNAME'=>$GLOBALS['FORUM_DRIVER']->get_username($member_id),'GROUP_NAME'=>$group_name,'IMG'=>$rank_image,'IS_LEADER'=>$group_leader==$member_id)));
}
}
$value=$rank_images->evaluate();
}
break;
case 'TOTAL_POINTS':
if (addon_installed('points'))
{
require_code('points');
$value=strval(total_points(isset($param[0])?intval($param[0]):get_member()));
}
break;
case 'POINTS_USED':
if (addon_installed('points'))
{
require_code('points');
$value=strval(points_used(isset($param[0])?intval($param[0]):get_member()));
}
break;
case 'AVAILABLE_POINTS':
if (addon_installed('points'))
{
require_code('points');
$value=strval(available_points(isset($param[0])?intval($param[0]):get_member()));
}
break;
case 'URL_FOR_GET_FORM':
if (isset($param[0]))
{
$url_bits=parse_url($param[0]);
if (array_key_exists('scheme',$url_bits))
{
$value=$url_bits['scheme'].'://'.(array_key_exists('host',$url_bits)?$url_bits['host']:'localhost');
if ((array_key_exists('port',$url_bits)) && ($url_bits['port']!=80)) $value.=':'.$url_bits['port'];
}
if (array_key_exists('path',$url_bits)) $value.=$url_bits['path'];
}
break;
case 'HIDDENS_FOR_GET_FORM':
$_value=new ocp_tempcode();
$url_bits=parse_url($param[0]);
if ((array_key_exists('query',$url_bits)) && ($url_bits['query']!=''))
{
foreach (explode('&',$url_bits['query']) as $exp)
{
$parts=explode('=',$exp,2);
if (count($parts)==2)
{
if (!in_array($parts[0],$param))
{
$_value->attach(form_input_hidden($parts[0],urldecode($parts[1])));
}
}
}
}
$value=$_value->evaluate();
break;
case 'NOTIFICATIONS_ENABLED':
$value='';
if (array_key_exists(0,$param))
{
require_code('notifications');
$value=notifications_enabled(array_key_exists(1,$param)?$param[1]:get_page_name(),$param[0])?'1':'0';
}
break;
case 'DOCUMENT_HELP':
global $DOCUMENT_HELP,$HELPER_PANEL_TUTORIAL;
$value=$DOCUMENT_HELP;
if (($value=='') && ($HELPER_PANEL_TUTORIAL!=''))
{
$value=brand_base_url().'/docs'.strval(ocp_version()).'/pg/'.$HELPER_PANEL_TUTORIAL;
}
break;
case 'HTTP_STATUS_CODE':
global $HTTP_STATUS_CODE;
$value=$HTTP_STATUS_CODE;
break;
case 'TEMPCODE':
if (isset($param[0]))
{
require_code('tempcode_compiler');
$_value=template_to_tempcode($param[0]);
$value=$_value->evaluate();
}
break;
case 'COMCODE':
if (isset($param[0]))
{
$_value=comcode_to_tempcode($param[0],NULL,true);
$value=$_value->evaluate();
}
break;
case 'FLAGRANT':
$_value=get_flagrant();
$value=$_value->evaluate();
break;
case 'IMG_WIDTH':
case 'IMG_HEIGHT':
if ((isset($param[0])) && (isset($GLOBALS['SITE_DB'])) && (function_exists('find_theme_image')) && ($GLOBALS['IN_MINIKERNEL_VERSION']==0))
{
global $THEME_IMG_DIMS_CACHE;
if (!isset($THEME_IMG_DIMS_CACHE))
{
$THEME_IMG_DIMS_CACHE=function_exists('persistant_cache_get')?persistant_cache_get('THEME_IMG_DIMS'):array();
}
if (isset($THEME_IMG_DIMS_CACHE[$param[0]]))
{
list($width,$height)=$THEME_IMG_DIMS_CACHE[$param[0]];
$value=($name=='IMG_WIDTH')?$width:$height;
} else
{
if (strpos($param[0],'://')===false)
{
$img_url=find_theme_image($param[0],false,false,array_key_exists(2,$param)?$param[2]:NULL,NULL,((isset($param[1])) && ($param[1]=='1'))?$GLOBALS['FORUM_DB']:$GLOBALS['SITE_DB']);
} else $img_url=$param[0];
require_code('images');
list($width,$height)=_symbol_image_dims(array($img_url));
$value=($name=='IMG_WIDTH')?$width:$height;
$THEME_IMG_DIMS_CACHE[$param[0]]=array($width,$height);
if (function_exists('persistant_cache_set')) persistant_cache_set('THEME_IMG_DIMS',$THEME_IMG_DIMS_CACHE);
}
}
break;
case 'CLEAN_FILE_SIZE':
if (isset($param[0]))
{
$bytes=is_numeric($param[0])?intval($param[0]):NULL;
require_code('files');
$value=clean_file_size($bytes);
}
break;
case 'TIME_PERIOD':
if (isset($param[0]))
{
$value=display_time_period(intval($param[0]));
}
break;
case 'MAKE_RELATIVE_DATE':
if (isset($param[0]))
{
if (get_option('use_contextual_dates')=='0')
{
$value=get_timezoned_date(intval($param[0]));
} else
{
$value=display_time_period(time()-intval($param[0]));
}
}
break;
case 'TIMEZONE':
$value=make_nice_timezone_name(get_site_timezone());
break;
case 'LOAD_PAGE':
foreach ($param as $i=>$p)
if (is_object($p)) $param[$i]=$p->evaluate();
global $LOADED_PAGES;
if (strpos($param[0],':')!==false)
$param=array_reverse(explode(':',$param[0],2));
$_value=$LOADED_PAGES[serialize($param)];
$value=$_value->evaluate();
break;
case 'RUNNING_SCRIPT':
if (isset($param[0]))
{
$value=running_script($param[0])?'1':'0';
}
break;
case 'MATCH_KEY_MATCH':
$value='0';
foreach ($param as $match_key)
{
if (($match_key=='1') || ($match_key=='0') || ($match_key=='')) continue;
if (match_key_match($match_key,((isset($param[1])) && ($match_key=='1')))) $value='1';
}
break;
case 'VERSION':
$value=strval(ocp_version());
break;
case 'PREVIEW_VALIDATION':
$value=(get_option('is_on_preview_validation')=='1')?'1':'0';
break;
case 'BLOCK':
if (isset($GLOBALS['NON_CACHEABLE_SYMBOLS']['SET_RAND'])) // Normal operation
{
foreach ($param as $i=>$p)
if (is_object($p)) $param[$i]=$p->evaluate();
if ((count($param)==1) && (strpos($param[0],',')!==false))
{
$param=preg_split('#((?<![^\\\\])|(?<!\\\\\\\\)|(?<!^)),#',$param[0]);
}
global $LOADED_BLOCKS;
if (isset($LOADED_BLOCKS[serialize($param)])) // Will always be set
$value=$LOADED_BLOCKS[serialize($param)]->evaluate();
}
break;
case 'CURRENCY':
if (addon_installed('ecommerce'))
{
if (isset($param[0]))
{
require_code('currency');
$value=currency_convert(floatval(str_replace(',','',$param[0])),((isset($param[1])) && ($param[1]!=''))?$param[1]:get_option('currency'),((isset($param[2])) && ($param[2]!=''))?$param[2]:NULL,((isset($param[3])) && ($param[3]=='1')));
if (is_null($value)) $value=do_lang('INTERNAL_ERROR');
} else $value=get_option('currency');
}
break;
case 'CURRENCY_SYMBOL':
if (addon_installed('ecommerce'))
{
require_code('ecommerce');
$value=ecommerce_get_currency_symbol();
}
break;
case 'GEOLOCATE':
$value=geolocate_ip(isset($param[0])?$param[0]:NULL);
break;
case 'NO_SAFE_MODE':
$value=(ini_get('safe_mode')=='1')?'0':'1';
break;
case 'FORCE_PREVIEWS':
if (get_option('forced_preview_option')=='1')
{
if (get_forum_type()=='ocf')
{
if ((is_guest()) && (get_option('default_preview_guests')=='0'))
{
$value='0';
} else
{
$value=($GLOBALS['FORUM_DRIVER']->get_member_row_field(get_member(),'m_preview_posts')==1)?'1':'0';
}
} else
{
$value=(get_option('default_preview_guests')=='0')?'0':'1';
}
} else
{
$value='0';
}
break;
case 'PREVIEW_URL':
$value=find_script('preview');
$value.='?page='.get_page_name();
$value.='&type='.get_param('type','',true);
break;
case 'ADDON_INSTALLED':
if (isset($param[0]))
{
$value=(addon_installed($param[0]))?'1':'0';
}
break;
case 'VALUE_OPTION':
if (isset($param[0]))
{
$value=function_exists('get_value')?get_value($param[0]):'';
if (is_null($value))
{
$value=function_exists('get_long_value')?get_long_value($param[0]):'';
if (is_null($value))
{
$value=isset($param[1])?$param[1]:'';
if (($param[0]=='textmate') && ((ocp_srv('HTTP_HOST')=='localhost') && (strpos(ocp_srv('HTTP_USER_AGENT'),'Macintosh')!==false))) $value='1';
}
}
}
break;
case 'KEEP_INDEX':
// What needs preserving in the URL
$value='index.php';
if (count($_GET)>0)
{
foreach ($_GET as $key=>$val)
{
if (is_array($val)) continue;
if (get_magic_quotes_gpc()) $val=stripslashes($val);
if ((substr($key,0,5)=='keep_') && (!skippable_keep($key,$val)) && (strpos($key,'_expand_')===false))
{
$value.=(($value=='index.php')?'?':'&').urlencode($key).'='.ocp_url_encode($val);
}
}
}
break;
case 'HIDE_HELP_PANEL':
$value=((array_key_exists('hide_help_panel',$_COOKIE)) && ($_COOKIE['hide_help_panel']=='1'))?'1':'0';
break;
case 'URLISE_LANG':
if (isset($param[1]))
{
$_value=urlise_lang($param[0],$param[1],isset($param[2])?$param[2]:'',isset($param[3])?($param[3]=='1'):false);
$value=$_value->evaluate();
}
break;
case 'FIND_SCRIPT_NOHTTP':
if ((isset($param[0])) && (function_exists('find_script')))
{
$value=preg_replace('#^https?://[^/]+#','',find_script($param[0],false,isset($param[1])?intval($param[1]):0));
}
if (!$GLOBALS['DEBUG_MODE']) break; // Debug mode changes base domain so we need to actually use it in full (fine, we don't have HTTPS in debug mode). Bubble on...
case 'FIND_SCRIPT':
if ((isset($param[0])) && (function_exists('find_script')))
{
$value=find_script($param[0],false,isset($param[1])?intval($param[1]):0);
}
break;
case 'MOBILE':
$value=is_mobile(NULL,array_key_exists(0,$param)?($param[0]=='1'):false)?'1':'0';
break;
case 'VALID_FILE_TYPES':
$value=get_option('valid_types');
$types=array_flip(explode(',',$value));
$value='';
ksort($types);
foreach (array_flip($types) as $val)
$value.=$val.',';
$value=substr($value,0,strlen($value)-1);
break;
case 'BROWSER_UA':
$browser=get_browser_string();
$value=$browser;
break;
case 'OS':
$os=get_os_string();
if (is_null($os)) $os='';
$value=$os;
break;
case 'ANCHOR':
if (isset($param[0]))
{
$_value=do_template('ANCHOR',array('_GUID'=>'8795c70c9dd7c6217bb765264ac24092','NAME'=>$param[0]));
$value=$_value->evaluate();
}
break;
case 'CSS_TEMPCODE':
$_value=css_tempcode();
$value=$_value->evaluate();
break;
case 'JS_TEMPCODE':
$_value=javascript_tempcode(isset($param[0])?$param[0]:NULL);
$value=$_value->evaluate();
break;
case 'PAD_LEFT':
if (array_key_exists(1,$param))
{
$value=str_pad($param[0],intval($param[1]),array_key_exists(2,$param)?$param[2]:'',STR_PAD_LEFT);
}
break;
case 'PAD_RIGHT':
if (array_key_exists(1,$param))
{
$value=str_pad($param[0],intval($param[1]),array_key_exists(2,$param)?$param[2]:'',STR_PAD_RIGHT);
}
break;
case 'PAGE_TITLE':
$value=is_null($DISPLAYED_TITLE)?'':$DISPLAYED_TITLE->evaluate();
break;
case 'SET_TITLE':
if (array_key_exists(0,$param))
{
get_page_title($param[0],false);
}
break;
case 'EXTRA_HEAD':
$_value=$GLOBALS['EXTRA_HEAD'];
if ($_value===NULL) $_value=new ocp_tempcode();
$value=$_value->evaluate();
break;
case 'EXTRA_FOOT':
if ($GLOBALS['EXTRA_FOOT']===NULL) $GLOBALS['EXTRA_FOOT']=new ocp_tempcode();
$_value=$GLOBALS['EXTRA_FOOT'];
if (array_key_exists(0,$param)) // Set
{
$GLOBALS['EXTRA_FOOT']->attach($param[0]);
} else // Get
{
$value=$_value->evaluate();
}
break;
case 'RAND':
if (isset($GLOBALS['NON_CACHEABLE_SYMBOLS']['RAND'])) // Normal operation
{
$GLOBALS['NO_EVAL_CACHE']=true;
$value=strval(mt_rand(0,32000));
} else // Been told to behave statically
{
$value='4';
}
break;
case 'SET_RAND':
if (isset($param[0]))
{
if (isset($GLOBALS['NON_CACHEABLE_SYMBOLS']['SET_RAND'])) // Normal operation
{
$GLOBALS['NO_EVAL_CACHE']=true;
$value=$param[mt_rand(0,count($param)-1)];
} else // Been told to behave statically
{
$value=$param[0];
}
}
break;
case 'COPYRIGHT':
$value=str_replace('$CURRENT_YEAR',date('Y'),get_option('copyright'));
break;
case 'KEYWORDS_SPACED':
$value=str_replace(',',' ',get_option('keywords'));
break;
case 'STAFF_ADDRESS_PURE':
$value=get_option('staff_address');
break;
case 'STAFF_ADDRESS':
require_code('obfuscate');
$value=obfuscate_email_address(get_option('staff_address'));
break;
case 'DOMAIN':
$value=get_domain();
break;
case 'BRAND_NAME':
$value=function_exists('get_value')?get_value('rebrand_name'):NULL;
if (is_null($value)) $value='ocPortal';
break;
case 'BRAND_BASE_URL':
$value=brand_base_url();
break;
case 'SHOW_DOCS':
$value=(get_option('show_docs')==='0')?'0':'1';
break;
case 'MEMBER_EMAIL':
$value=$GLOBALS['FORUM_DRIVER']->get_member_email_address(isset($param[0])?intval($param[0]):get_member());
break;
case 'OCF_MEMBER_HTML':
if (get_forum_type()=='ocf')
{
require_code('ocf_members');
require_code('ocf_members2');
$_value=ocf_show_member_box(isset($param[0])?intval($param[0]):get_member());
$value=$_value->evaluate();
}
break;
case 'HAS_SPECIFIC_PERMISSION':
if (isset($param[0]))
{
$value=has_specific_permission(((!is_null($param)) && (isset($param[1])))?intval($param[1]):get_member(),$param[0])?'1':'0';
}
break;
case 'HAS_ZONE_ACCESS':
if (isset($param[0]))
{
$value=has_zone_access(((!is_null($param)) && (isset($param[1])))?intval($param[1]):get_member(),$param[0])?'1':'0';
}
break;
case 'HAS_PAGE_ACCESS':
if ((isset($param[0])) && (isset($param[1])))
{
$value=has_page_access(((!is_null($param)) && (isset($param[2])))?intval($param[2]):get_member(),$param[0],$param[1],((!is_null($param)) && (isset($param[3])))?($param[3]=='1'):false)?'1':'0';
}
break;
case 'HAS_CATEGORY_ACCESS':
if (isset($param[0]))
{
$value=has_category_access(((!is_null($param)) && (isset($param[2])))?intval($param[2]):get_member(),$param[0],$param[1])?'1':'0';
}
break;
case 'HAS_ATTACHMENT_ACCESS':
if (isset($param[0]))
{
require_code('attachments');
$value=has_attachment_access(((!is_null($param)) && (isset($param[1])))?intval($param[1]):get_member(),$param[0])?'1':'0';
}
break;
case 'HAS_SUBMIT_PERMISSION':
if ((isset($param[0])) && ((strtolower($param[0])=='low') || (strtolower($param[0])=='mid') || (strtolower($param[0])=='high')))
{
$value=has_submit_permission(strtolower($param[0]),((!is_null($param)) && (isset($param[1])))?intval($param[1]):get_member(),((!is_null($param)) && (isset($param[2])))?$param[2]:get_ip_address(),((!is_null($param)) && (isset($param[3])))?$param[3]:get_page_name())?'1':'0';
}
break;
case 'HAS_DELETE_PERMISSION':
if ((isset($param[0])) && ((strtolower($param[0])=='low') || (strtolower($param[0])=='mid') || (strtolower($param[0])=='high')) && (isset($param[1])))
{
$value=has_delete_permission(strtolower($param[0]),((!is_null($param)) && (isset($param[2])))?intval($param[2]):get_member(),intval($param[1]),((!is_null($param)) && (isset($param[3])))?$param[3]:get_page_name())?'1':'0';
}
break;
case 'HAS_EDIT_PERMISSION':
if ((isset($param[0])) && ((strtolower($param[0])=='low') || (strtolower($param[0])=='mid') || (strtolower($param[0])=='high')) && (isset($param[1])))
{
$value=has_edit_permission(strtolower($param[0]),((!is_null($param)) && (isset($param[2])))?intval($param[2]):get_member(),intval($param[1]),((!is_null($param)) && (isset($param[3])))?$param[3]:get_page_name())?'1':'0';
}
break;
case 'ENTITY_DECODE':
if (isset($param[0]))
{
$value=@html_entity_decode($param[0],ENT_QUOTES,get_charset());
}
break;
case 'RESET_CYCLE':
if (isset($param[0]))
{
$CYCLES[$param[0]]=0;
}
break;
case 'SITE_SCOPE':
$value=get_option('site_scope');
break;
case 'LAST_VISIT_TIME':
if (get_forum_type()=='ocf')
{
$member_info=ocf_read_in_member_profile(get_member(),true);
$value=strval($member_info['last_visit_time']);
}
break;
case 'NUM_NEW_TOPICS':
if (get_forum_type()=='ocf')
{
$member_info=ocf_read_in_member_profile(get_member(),true);
$_new_topics=$GLOBALS['FORUM_DB']->query('SELECT COUNT(*) AS mycnt FROM '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_topics WHERE NOT t_forum_id IS NULL AND t_cache_first_time>'.strval((integer)$member_info['last_visit_time']));
$new_topics=$_new_topics[0]['mycnt'];
$value=strval($new_topics);
}
break;
case 'NUM_NEW_POSTS':
if (get_forum_type()=='ocf')
{
$member_info=ocf_read_in_member_profile(get_member(),true);
$_new_posts=$GLOBALS['FORUM_DB']->query('SELECT COUNT(*) AS mycnt FROM '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_posts WHERE NOT p_cache_forum_id IS NULL AND p_time>'.strval((integer)$member_info['last_visit_time']));
$new_posts=$_new_posts[0]['mycnt'];
$value=strval($new_posts);
}
break;
case 'HAS_FORUM':
$value=has_no_forum()?'0':'1';
break;
case 'OCF':
$value=(get_forum_type()=='ocf')?'1':'0';
break;
case 'BOARD_PREFIX':
$value=get_forum_base_url();
break;
case 'DATE_AND_TIME':
$use_contextual_dates=(isset($param[0]) && ($param[0]=='1'));
$verbose=(isset($param[1]) && ($param[1]=='1'));
$server_time=(isset($param[2]) && ($param[2]=='1'));
$time=isset($param[3])?intval($param[3]):time();
$value=get_timezoned_date($time,true,$verbose,$server_time,!$use_contextual_dates);
break;
case 'DATE':
$use_contextual_dates=(isset($param[0]) && ($param[0]=='1'));
$verbose=(isset($param[1]) && ($param[1]=='1'));
$server_time=(isset($param[2]) && ($param[2]=='1'));
$time=isset($param[3])?intval($param[3]):time();
$value=get_timezoned_date($time,false,$verbose,$server_time,!$use_contextual_dates);
break;
case 'TIME':
$time=isset($param[0])?intval($param[0]):time();
$value=get_timezoned_time($time);
break;
case 'SECONDS_PERIOD':
if (array_key_exists(0,$param))
{
$value=display_seconds_period(intval($param[0]));
}
break;
case 'FROM_TIMESTAMP':
if (isset($param[0]))
{
$timestamp=isset($param[1])?intval($param[1]):time();
$value=locale_filter(my_strftime($param[0],$timestamp));
if ($value==$param[0]) $value=date($param[0],utctime_to_usertime($timestamp));
} else $value=strval(time());
break;
case 'TO_TIMESTAMP':
if (isset($param[0]))
{
$value=strval(strtotime($param[0]));
} else $value=strval(time());
break;
case 'SESSION_HASHED':
$value=md5(strval(get_session_id()));
break;
case 'SESSION':
$value=strval(get_session_id());
break;
case 'IN_ARRAY':
if (isset($param[1])) // Hard coding array
{
$array=array_slice($param,1);
$value=in_array($param[0],$array)?'1':'0';
}
break;
case 'MULT':
if (isset($param[1]))
{
$value=float_to_raw_string(floatval($param[0])*floatval($param[1]));
}
break;
case 'ROUND':
if (isset($param[0]))
{
$amount=isset($param[1])?intval($param[1]):0;
if ($amount>0)
{
$value=float_format(floatval($param[0]),$amount);
} else
{
$value=strval(intval(round(floatval($param[0]),$amount)));
}
}
break;
case 'DEV_MODE':
$value=$GLOBALS['DEBUG_MODE']?'1':'0';
break;
case 'BROWSER_MATCHES':
if (isset($param[0]))
{
$q=false;
foreach (explode('|',$param[0]) as $browser)
{
$q=browser_matches($browser);
if ($q) break;
}
$value=$q?'1':'0';
}
break;
case 'ISSET':
if (isset($param[0]))
{
$value=(isset($TEMPCODE_SETGET[$param[0]]))?'1':'0';
}
break;
case 'INIT':
if (isset($param[1]))
{
if (!isset($TEMPCODE_SETGET[$param[0]])) $TEMPCODE_SETGET[$param[0]]=$param[1];
}
break;
case 'INC':
if (isset($param[0]))
{
if (!isset($TEMPCODE_SETGET[$param[0]])) $TEMPCODE_SETGET[$param[0]]='0';
$TEMPCODE_SETGET[$param[0]]=strval(intval($TEMPCODE_SETGET[$param[0]])+1);
}
break;
case 'DEC':
if (isset($param[0]))
{
if (!isset($TEMPCODE_SETGET[$param[0]])) $TEMPCODE_SETGET[$param[0]]='0';
$TEMPCODE_SETGET[$param[0]]=strval(intval($TEMPCODE_SETGET[$param[0]])-1);
}
break;
case 'PREG_MATCH':
if (isset($param[1]))
{
$value=(preg_match('#'.str_replace('#','\#',$param[0]).'#'.(isset($param[2])?str_replace('e','',$param[2]):''),$param[1])!=0)?'1':'0';
}
break;
case 'PREG_REPLACE':
if (isset($param[2]))
{
$value=preg_replace('#'.str_replace('#','\#',$param[0]).'#'.(isset($param[3])?str_replace('e','',$param[3]):''),$param[1],$param[2]);
}
break;
case 'MAX':
if (isset($param[0]))
{
$value=strval(max(intval($param[0]),intval($param[1])));
}
break;
case 'MIN':
if (isset($param[0]))
{
$value=strval(min(intval($param[0]),intval($param[1])));
}
break;
case 'MOD':
if (isset($param[0]))
{
$value=strval(max(intval($param[0]),-intval($param[0])));
}
break;
case 'REM':
if (isset($param[1]))
{
$value=strval(intval($param[0])%intval($param[1]));
}
break;
case 'DIV_FLOAT':
if (isset($param[1]))
{
$value=float_to_raw_string(floatval($param[0])/floatval($param[1]));
}
break;
case 'DIV':
if (isset($param[1]))
{
$value=strval(intval(floor(floatval($param[0])/floatval($param[1]))));
}
break;
case 'SUBTRACT':
if (isset($param[1]))
{
$value=float_to_raw_string(floatval(str_replace(',','',$param[0]))-floatval(str_replace(',','',$param[1])));
}
break;
case 'ADD':
if (isset($param[1]))
{
$value=float_to_raw_string(floatval(str_replace(',','',$param[0]))+floatval(str_replace(',','',$param[1])));
}
break;
case 'WCASE':
if (isset($param[0]))
{
$value=ucwords($param[0]);
}
break;
case 'LCASE':
if (isset($param[0]))
{
$value=ocp_mb_strtolower($param[0]);
}
break;
case 'UCASE':
if (isset($param[0]))
{
$value=ocp_mb_strtoupper($param[0]);
}
break;
case '_POST':
if (isset($param[0]))
{
$value=post_param($param[0],isset($param[1])?$param[1]:'');
}
break;
case 'REPLACE':
if (isset($param[2]))
{
$value=str_replace($param[0],$param[1],$param[2]);
}
break;
case 'AT':
if (isset($param[1]))
{
$value=ocp_mb_substr($param[0],intval($param[1]),1);
}
break;
case 'STRPOS':
if (isset($param[1]))
{
$t_value=strpos($param[0],$param[1]);
$value=($t_value===false)?'0':strval($t_value);
}
break;
case 'IN_STR':
if (isset($param[1]))
{
if ($param[1]=='') // Would generate a PHP notice
{
$value='0';
} else
{
$value='0';
foreach ($param as $i=>$check)
{
if ((is_integer($i)) && ($i!=0) && ($check!=''))
{
if (strpos($param[0],$check)!==false)
{
$value='1';
break;
}
}
}
}
}
break;
case 'SUBSTR_COUNT':
if (isset($param[1]))
{
$value=strval(substr_count($param[0],$param[1]));
}
break;
case 'SUBSTR':
if (isset($param[1]))
{
$value=ocp_mb_substr($param[0],intval($param[1]),isset($param[2])?intval($param[2]):strlen($param[0]));
}
break;
case 'LENGTH':
if (isset($param[0]))
{
$value=strval(ocp_mb_strlen($param[0]));
}
break;
case 'WORDWRAP':
if (isset($param[1]))
{
$cut=isset($param[3]) && ($param[3]=='1');
$value=wordwrap($param[0],intval($param[1]),isset($param[2])?$param[2]:'<br />',$cut);
}
break;
case 'ALTERNATOR_TRUNCATED': // Alternate values according to whether some given text WOULD have been truncated. 0: text to check against, 1: the truncate length, 2:IF would not be do this, 3: if it would be do this, 4: whether given text is encoded as HTML (0=no [default, plain-text], 1=yes)
if (isset($param[3]))
{
$amount=intval($param[1]);
$is_html=((isset($param[4])) && ($param[4]=='1'));
if (strlen($is_html?strip_tags($param[0]):$param[0])>$amount)
{
$value=$param[3];
} else $value=$param[2];
}
break;
case 'ESCAPE':
if (isset($param[0]))
{
$d_escaping=array(isset($param[1])?constant($param[1]):ENTITY_ESCAPED);
if (is_string($param[0])) apply_tempcode_escaping($d_escaping,$param[0]);
$value=$param[0];
}
break;
case 'COOKIE_PATH':
$value=function_exists('get_cookie_path')?get_cookie_path():'/';
break;
case 'COOKIE_DOMAIN':
$s_value=function_exists('get_cookie_domain')?get_cookie_domain():'';
$value=is_null($s_value)?'':$s_value;
break;
case 'IS_A_COOKIE_LOGIN':
global $IS_A_COOKIE_LOGIN;
$value=($IS_A_COOKIE_LOGIN && (ini_get('suhosin.cookie.max_name_length')!=='64'))?'1':'0';
break;
case 'GROUP_ID':
if (isset($param[0]))
{
$groups=$GLOBALS['FORUM_DRIVER']->get_members_groups(isset($param[1])?intval($param[1]):get_member());
$value=array_key_exists(intval($param[0]),$groups)?strval($groups[intval($param[0])]):'';
}
break;
case 'GROUP_NAME':
if (isset($param[0]))
{
$groups=$GLOBALS['FORUM_DRIVER']->get_members_groups(isset($param[1])?intval($param[1]):get_member());
if (array_key_exists(intval($param[0]),$groups))
{
$all_usergroups=$GLOBALS['FORUM_DRIVER']->get_usergroup_list();
$value=$all_usergroups[$groups[intval($param[0])]];
}
}
break;
case 'NEGATE':
if (isset($param[0]))
{
$value=strval(-intval($param[0]));
}
break;
case 'XOR':
$count=0;
foreach ($param as $test)
{
if (($test=='1') || ($test=='1')) $count++;
}
$value=($count==1)?'1':'0';
break;
case 'NOR':
$count=0;
foreach ($param as $test)
{
if (($test=='1') || ($test=='1')) $count++;
}
$value=($count>0)?'0':'1';
break;
case 'NAND':
$count=0;
foreach ($param as $test)
{
if (($test=='1') || ($test=='1')) $count++;
}
$value=($count==count($param))?'0':'1';
break;
case 'LT':
if (isset($param[1]))
{
$value=(intval($param[0])<intval($param[1]))?'1':'0';
}
break;
case 'GT':
if (isset($param[1]))
{
$value=(intval($param[0])>intval($param[1]))?'1':'0';
}
break;
case 'COPPA_ON':
$value=(get_option('is_on_coppa')=='1')?'1':'0';
break;
case 'OBFUSCATE':
if (isset($param[0]))
{
require_code('obfuscate');
$value=obfuscate_entities($param[0]);
}
break;
case 'FIX_ID':
if (isset($param[0]))
{
$value=fix_id($param[0]);
if (($GLOBALS['XSS_DETECT']) && (ocp_is_escaped($param[0]))) ocp_mark_as_escaped($value);
}
break;
case 'MAILTO':
require_code('obfuscate');
$value=mailto_obfuscated();
break;
case 'INLINE_STATS':
$value=(get_option('show_inline_stats')=='1')?'1':'0';
break;
case 'ATTACHMENT_DOWNLOADS':
if (isset($param[0]))
{
$db=$GLOBALS['SITE_DB'];
if ((isset($param[1])) && ($param[1]=='1')) $db=$GLOBALS['FORUM_DB'];
$_value=$db->query_value_null_ok('attachments','a_num_downloads',array('id'=>intval($param[0])));
$value=is_null($_value)?'?':strval($_value);
}
break;
case 'CSS_DIMENSION_REDUCE':
if (isset($param[1]))
{
$value=$param[0];
if (substr($value,-2)=='px')
{
$b=$param[1];
$value=strval(intval(substr($value,0,-2))-intval($b)).'px';
}
if ($value=='') $value='0px';
}
break;
case 'COMMENT_COUNT':
if (isset($param[1]))
{
if (get_option('is_on_comments')=='1')
{
$count=0;
$_comments=$GLOBALS['FORUM_DRIVER']->get_forum_topic_posts($GLOBALS['FORUM_DRIVER']->find_topic_id_for_topic_identifier(get_option('comments_forum_name'),$param[0].'_'.$param[1]),$count,0,0,false);
$_value=do_lang_tempcode('_COMMENTS',integer_format(0));
if (is_array($_comments)) $_value=do_lang_tempcode('_COMMENTS',escape_html(integer_format($count)));
$value=$_value->evaluate();
} else
{
$value=do_lang('VIEW');
}
}
break;
case 'CAN_SPELLCHECK':
$value=(function_exists('pspell_check'))?'1':'0';
break;
case 'AWARD_ID':
if (array_key_exists(0,$param))
{
$value=$GLOBALS['SITE_DB']->query_value_null_ok('award_archive','content_id',array('a_type_id'=>intval($param[0])),'ORDER BY date_and_time DESC');
if (is_null($value)) $value='';
}
break;
case 'SELF_URL':
$extra_params=NULL;
if (isset($param[3]))
{
$extra_params=array();
$i=3;
while (isset($param[$i]))
{
$bits=explode('=',$param[$i],2);
if ($bits[1]=='<null>') $bits[1]=NULL;
$extra_params[$bits[0]]=$bits[1];
$i++;
}
}
$value=get_self_url(true,(isset($param[0])) && ($param[0]=='1'),$extra_params,(isset($param[1])) && ($param[1]=='1'),(isset($param[2])) && ($param[2]=='1'));
break;
case 'SHIFT_DECODE':
if (isset($param[0]))
{
global $SHIFT_VARIABLES;
$key=$param[0];
$value=isset($SHIFT_VARIABLES[$key])?$SHIFT_VARIABLES[$key]->evaluate():'';
}
break;
case 'NUMBER_FORMAT':
if (isset($param[0]))
{
$value=integer_format(intval($param[0]));
}
break;
case 'FLOAT_FORMAT':
if (isset($param[0]))
{
$value=float_format(floatval($param[0]));
}
break;
case 'CURRENTLY_INVISIBLE':
$value=is_invisible()?'1':'0';
break;
case 'IS_FRIEND':
if (isset($param[0]))
{
$test=$GLOBALS['SITE_DB']->query_value_null_ok('chat_buddies','member_likes',array('member_likes'=>isset($param[1])?intval($param[1]):get_member(),'member_liked'=>intval($param[0])));
$value=is_null($test)?'0':'1';
}
break;
case 'SSW':
$value=(get_option('ssw')=='1')?'1':'0';
break;
case 'RATING':
if (isset($param[1]))
{
require_code('feedback');
$rating=get_rating_simple_array(array_key_exists(2,$param)?$param[2]:get_self_url(true),array_key_exists(3,$param)?$param[3]:(is_null($DISPLAYED_TITLE)?'':$DISPLAYED_TITLE->evaluate()),$param[0],$param[1],array_key_exists(2,$param)?$param[2]:NULL);
if ((!array_key_exists(2,$param)) || ($param[2]=='0'))
{
$value=isset($rating['ALL_RATING_CRITERIA'][0]['RATING'])?$rating['ALL_RATING_CRITERIA'][0]['RATING']:'';
} else
{
$value=do_template('RATING_INLINE_STATIC',$rating);
}
if (is_object($value)) $value=$value->evaluate();
}
break;
case 'VIEWS':
if (isset($param[2]))
{
$id_field=/*isset($param[4])?$param[4]:*/'id'; // Not allowed for security reasons
if (preg_match('#^\w*views\w*$#',$param[1])!=0)
{
$test=$GLOBALS['SITE_DB']->query_value_null_ok($param[0],$param[1],array($id_field=>$param[2]));
if (!is_null($test)) $value=integer_format($test);
}
}
break;
default:
global $EXTRA_SYMBOLS;
if (is_null($EXTRA_SYMBOLS))
{
$EXTRA_SYMBOLS=array();
$hooks=find_all_hooks('systems','symbols');
foreach (array_keys($hooks) as $hook)
{
$EXTRA_SYMBOLS[$hook]=array();
}
}
if (array_key_exists($name,$EXTRA_SYMBOLS))
{
if (!array_key_exists('ob',$EXTRA_SYMBOLS[$name]))
{
require_code('hooks/systems/symbols/'.filter_naughty_harsh($name));
$EXTRA_SYMBOLS[$name]['ob']=object_factory('Hook_symbol_'.filter_naughty_harsh($name));
}
$value=$EXTRA_SYMBOLS[$name]['ob']->run($param);
break;
}
if (defined($name))
{
$value=constant($name);
break;
}
$value='';
require_code('site');
attach_message(do_lang_tempcode('MISSING_SYMBOL',escape_html($name)),'warn');
}
if ($escaped!=array())
{
if (is_object($value)) $value=$value->evaluate();
apply_tempcode_escaping($escaped,$value);
}
if ($cacheable) $SYMBOL_CACHE[$escaped_codes]=$value;
return $value;
}
// Is it a directive?
if ($type==TC_DIRECTIVE)
{
$value='';
if ($GLOBALS['XSS_DETECT']) ocp_mark_as_escaped($value);
// In our param we should have a map of bubbled template parameters (under 'vars') and our numbered directive parameters
if ($param===NULL) $param=array();
// Closure-based Tempcode parser may send in strings, so we need to adapt...
foreach ($param as $key=>$val)
{
if (is_string($val)) $param[$key]=make_string_tempcode($val);
}
if (!isset($param['vars'])) $param['vars']=array();
switch ($name)
{
case 'SHIFT_ENCODE':
break;
case 'PARAM_INFO':
$_value=do_template('PARAM_INFO',array('MAP'=>$param['vars']));
$value=$_value->evaluate();
break;
case 'CSS_INHERIT': // e.g. {+START,CSS_INHERIT,global,default,#886aa9}{+END}
if (isset($param[0]))
{
require_code('css_and_js');
$css_file=$param[0]->evaluate();
$theme=isset($param[1])?$param[1]->evaluate():'default';
$seed=isset($param[2])?$param[2]->evaluate():NULL;
if ($seed=='') $seed=NULL;
$dark=isset($param[3])?($param[3]->evaluate()=='1'):false;
$algorithm=isset($param[4])?($param[4]->evaluate()):'equations';
$value=css_inherit($css_file,$theme,$GLOBALS['FORUM_DRIVER']->get_theme(),$seed,$dark,$algorithm);
}
break;
case 'FRACTIONAL_EDITABLE':
foreach (array_keys($param) as $key)
{
if (!is_numeric($key)) unset($param[$key]);
}
if (isset($param[3]))
{
$edit_text=$param[0]->evaluate();
$edit_param_name=$param[1]->evaluate();
$edit_pagelink=$param[2]->evaluate();
$supports_comcode=(isset($param[4])?$param[3]->evaluate():'0')=='1';
list($zone,$attributes,)=page_link_decode($edit_pagelink);
if ($zone=='_SEARCH') $zone=get_module_zone($attributes['page']);
if (has_actual_page_access(get_member(),$attributes['page'],$zone))
{
$keep=symbol_tempcode('KEEP');
$url=find_script('fractional_edit').'?edit_param_name='.urlencode($edit_param_name).'&supports_comcode='.($supports_comcode?'1':'0').'&zone='.urlencode($zone).$keep->evaluate();
foreach ($attributes as $key=>$val)
{
$url.='&'.$key.'='.urlencode($val);
}
$_value=$param[count($param)-1];
$_value=do_template('FRACTIONAL_EDIT',array('_GUID'=>'075ac126c427d28b309004bc67b32b08','VALUE'=>$_value,'URL'=>$url,'EDIT_TEXT'=>$edit_text,'EDIT_PARAM_NAME'=>$edit_param_name));
$value=$_value->evaluate();
} else
{
$value=$param[count($param)-1]->evaluate();
}
}
break;
case 'SET':
if (isset($param[1]))
{
$var=$param[0]->evaluate();
$set_val='';
$i=1;
while (isset($param[$i]))
{
if ($i!=1) $set_val.=',';
$set_val.=$param[1]->evaluate();
$i++;
}
$TEMPCODE_SETGET[$var]=$set_val;
}
break;
case 'IN_ARRAY':
if (isset($param[1]))
{
$key=$param[1]->evaluate();
$array=array_key_exists($key,$param['vars'])?$param['vars'][$key]:array();
$value=in_array($param[0]->evaluate(),$array)?'1':'0';
}
break;
case 'NOT_IN_ARRAY':
if (isset($param[1]))
{
$key=$param[1]->evaluate();
$array=array_key_exists($key,$param['vars'])?$param['vars'][$key]:array();
$value=in_array($param[0]->evaluate(),$array)?'0':'1';
}
break;
case 'IF_IN_ARRAY':
if (isset($param[2]))
{
$key=$param[1]->evaluate();
$array=array_key_exists($key,$param['vars'])?$param['vars'][$key]:array();
$value=in_array($param[0]->evaluate(),$array)?$param[2]->evaluate():'';
}
break;
case 'IF_NOT_IN_ARRAY':
if (isset($param[2]))
{
$key=$param[1]->evaluate();
$array=array_key_exists($key,$param['vars'])?$param['vars'][$key]:array();
$value=in_array($param[0]->evaluate(),$array)?'':$param[2]->evaluate();
}
break;
case 'IMPLODE':
if (isset($param[1]))
{
$key=$param[1]->evaluate();
$array=array_key_exists($key,$param['vars'])?$param['vars'][$key]:array();
if ((isset($param[2])) && ($param[2]->evaluate()=='1'))
{
$delim=$param[0]->evaluate();
foreach ($array as $key=>$val)
{
if ($value!='') $value.=$delim;
$value.=(is_integer($key)?integer_format($key):$key).' = '.$val;
}
} else
{
$value=implode($param[0]->evaluate(),$array);
}
}
break;
case 'COUNT':
if (isset($param[0]))
{
$key=$param[0]->evaluate();
$array=array_key_exists($key,$param['vars'])?$param['vars'][$key]:array();
$value=strval(count($array));
}
break;
case 'BOX':
unset($param['vars']);
$title=isset($param[1])?$param[0]->evaluate():'';
$dimensions=isset($param[2])?$param[1]->evaluate():'100%';
if ($dimensions=='') $dimensions='100%';
$box_type=isset($param[3])?$param[2]->evaluate():'classic';
$options=isset($param[4])?$param[3]->evaluate():'';
$meta=isset($param[5])?$param[4]->evaluate():'';
$links=isset($param[6])?$param[5]->evaluate():'';
$expand=isset($param[7])?($param[6]->evaluate()=='1'):false;
$toplink=isset($param[8])?$param[7]->evaluate():'';
$tmp=put_in_standard_box(array_pop($param),$title,$dimensions,$box_type,$options,$meta,$links,$expand,$toplink);
$value=$tmp->evaluate();
break;
case 'IF_NON_EMPTY':
if (isset($param[1]))
{
if (!$param[0]->is_really_empty())
{
$value=$param[1]->evaluate();
}
}
break;
case 'IF_PASSED':
if (isset($param[1]))
{
$t=$param[0]->evaluate();
if (isset($param['vars'][$t]))
{
$value=$param[1]->evaluate();
}
}
break;
case 'IF_NON_PASSED':
if (isset($param[1]))
{
$t=$param[0]->evaluate();
if (!isset($param['vars'][$t]))
{
$value=$param[1]->evaluate();
}
}
break;
case 'IF_EMPTY':
if (isset($param[1]))
{
if ($param[0]->is_really_empty())
{
$value=$param[1]->evaluate();
}
}
break;
case 'IF_ARRAY_EMPTY':
if (isset($param[0]))
{
$looking_at=$param[0]->evaluate();
if (array_key_exists($looking_at,$param['vars']))
if (count($param['vars'][$looking_at])==0) $value=$param[1]->evaluate();
}
break;
case 'IF_ARRAY_NON_EMPTY':
if (isset($param[0]))
{
$looking_at=$param[0]->evaluate();
if (array_key_exists($looking_at,$param['vars']))
if (count($param['vars'][$looking_at])!=0) $value=$param[1]->evaluate();
}
break;
case 'OF':
if (isset($param[1]))
{
$key=$param[0]->evaluate();
$x=$param[1]->evaluate();
$array=array_key_exists($key,$param['vars'])?$param['vars'][$key]:array();
$x2=is_numeric($x)?intval($x):$x;
if (is_integer($x2))
{
if ($x2<0) $x2=count($array)-1;
elseif ($x2>=count($array)) $x2-=count($array);
}
$value=array_key_exists($x2,$array)?$array[$x2]:'';
}
break;
case 'INCLUDE':
if (isset($param[1]))
{
$tpl_params=$param['vars'];
$explode=explode(chr(10),$param[1]->evaluate());
foreach ($explode as $val)
{
$bits=explode('=',$val,2);
if (count($bits)==2) $tpl_params[ltrim($bits[0])]=$bits[1];
}
$td=isset($param[3])?$param[2]->evaluate():'';
if ($td=='') $td='templates';
$ex=isset($param[2])?$param[1]->evaluate():'';
if ($ex=='') $ex='.tpl';
$_value=do_template($param[0]->evaluate(),$tpl_params,NULL,false,NULL,$ex,$td);
$value=$_value->evaluate();
}
break;
case 'WHILE':
if (isset($param[1]))
{
$_p=$param[0]->evaluate();
if (($_p=='1') || ($_p=='1'))
{
$value='';
$value.=$param[1]->evaluate();
$value.=ecv($lang,$escaped,$type,$name,$param);
}
}
break;
case 'IF':
if (isset($param[1]))
{
$_p=$param[0]->evaluate();
if (($_p=='1') || ($_p=='1'))
{
$value=$param[1]->evaluate();
}
}
break;
case 'LOOP':
if (isset($param[0]))
{
if (!array_key_exists($param[0]->evaluate(),$param['vars']))
{
require_code('site');
attach_message(do_lang_tempcode('MISSING_TEMPLATE_PARAMETER',$param[0]->evaluate(),'???'),'warn');
return '';
}
$array_key=$param[0]->evaluate();
if ((is_numeric($array_key)) || (strpos($array_key,',')!==false))
{
$array=explode(',',$array_key);
} else
{
$array=array_key_exists($array_key,$param['vars'])?$param['vars'][$array_key]:array();
if (!is_array($array)) $array=array();
}
$value='';
if (array_key_exists(1+1,$param))
{
$columns=$param[1]->evaluate();
$row_starter=array_key_exists(2+1,$param)?$param[2]->evaluate():'<tr>';
$row_terminator=array_key_exists(3+1,$param)?$param[3]->evaluate():'</tr>';
$value.=$row_starter;
// Sorting
if (array_key_exists(4+1,$param))
{
$sort_key=$param[4]->evaluate();
$rev=((array_key_exists(5+1,$param)) && ($param[5]->evaluate()=='DESC'));
if ($sort_key!='')
{
global $M_SORT_KEY;
$M_SORT_KEY=$sort_key;
uasort($array,'multi_sort');
}
if ($rev) $array=array_reverse($array);
}
}
$last=count($param)-2;
$col=0;
$first=true;
foreach ($array as $go_key=>$go)
{
if (!is_array($go)) $go=array('_loop_key'=>make_string_tempcode(is_integer($go_key)?strval($go_key):$go_key),'_loop_var'=>make_string_tempcode($go)); // In case it's not a list of maps, but just a list
if ((isset($param[2])) && ($col%$columns==0) && ($col!=0))
{
$value.=$row_starter;
}
$ps=$go+$param['vars']+array('_loop_key'=>make_string_tempcode(is_integer($go_key)?strval($go_key):$go_key),'_i'=>strval($col),'_first'=>$first,'_last'=>$col==count($array)-1);
$bound=$param[$last]->bind($ps,'');
$value.=$bound->evaluate();
++$col;
if ((isset($param[3])) && ($col%$columns==0))
{
$value.=$row_terminator;
}
$first=false;
}
if ((isset($param[2])) && ($col%$columns!=0))
{
$value.=$row_terminator;
}
}
break;
default:
require_code('site');
attach_message(do_lang_tempcode('UNKNOWN_DIRECTIVE',escape_html($name)),'warn');
}
if ($escaped!=array())
{
apply_tempcode_escaping($escaped,$value);
}
return $value;
}
// By elimination, it's language
$a=isset($param[0])?(is_object($param[0])?$param[0]->evaluate():$param[0]):NULL;
$b=isset($param[1])?(is_object($param[1])?$param[1]->evaluate():$param[1]):NULL;
$c=isset($param[2])?array_splice($param,2):NULL;
if ($c!==NULL)
{
foreach ($c as $i=>$cc)
{
if (is_object($cc)) $c[$i]=$cc->evaluate();
}
}
static $dle=false;
if (!$dle) $dle=function_exists('do_lang');
$ret=$dle?do_lang($name,$a,$b,$c,$lang,false):escape_html($name.':'.(!is_null($a)?$a:'').','.(!is_null($b)?$b:''));
if ($ret===NULL)
{
if ($type!=TC_PARAMETER) // TC_PARAMETER would be due to preprocessing of something that is tied to a variable not bound yet due to a LOOP
{
require_code('site');
attach_message(do_lang_tempcode('MISSING_LANG_ENTRY',escape_html($name)),'warn');
}
$value='';
if ($GLOBALS['XSS_DETECT']) ocp_mark_as_escaped($value);
return $value;
}
if ($escaped!=array() && $escaped!=array(ENTITY_ESCAPED)) apply_tempcode_escaping(array_diff($escaped,array(ENTITY_ESCAPED)),$ret); // Escape but without ENTITY_ESCAPED because we don't do that on lang strings
return $ret;
}
string symbol_truncator(array param, string type, ?mixed tooltip_if_truncated)
Handle truncation symbols in all their complexity
Parameters…
| Name |
param |
| Description |
Parameters passed to the symbol (0=text, 1=amount, 2=tooltip?, 3=is_html?, 4=use as grammatical length rather than HTML byte length, 5=fractional-deviation-tolerance for grammar-preservation) |
| Type |
array |
| Name |
type |
| Description |
The type of truncation to do |
| Type |
string |
| Values restricted to |
left right spread |
| Name |
tooltip_if_truncated |
| Description |
Tooltip to add on, but only if we end up creating our own tooltip (NULL: none) |
| Default value |
|
| Type |
?mixed |
Returns…
| Description |
The result. |
| Type |
string |
function symbol_truncator($param,$type,$tooltip_if_truncated=NULL)
{
$value='';
if (is_object($param[0]))
{
$param[0]=$param[0]->evaluate();
if (!isset($param[2])) $param[2]='0';
$param[3]='1';
}
$amount=intval(isset($param[1])?$param[1]:'60');
$is_html=((isset($param[3])) && ($param[3]=='1'));
if ($is_html)
{
$not_html=@html_entity_decode(strip_tags($param[0]),ENT_QUOTES,get_charset()); // In case it contains HTML. This is imperfect, but having to cut something up is imperfect from the offset.
$html=$param[0];
if ($GLOBALS['XSS_DETECT']) ocp_mark_as_escaped($html);
if (($html==$not_html) && (strpos($html,'&')===false) && (strpos($html,'<')===false)) $is_html=false; // Conserve memory
} else
{
$not_html=$param[0];
$html=escape_html($param[0]);
}
if (ocp_mb_strlen($not_html)>$amount)
{
$tooltip=((isset($param[2])) && ($param[2]=='1'));
$literal_pos=isset($param[4])?($param[4]=='1'):false;
$grammar_completeness_tolerance=isset($param[5])?floatval($param[5]):0.0;
if ($is_html || $grammar_completeness_tolerance!=0.0)
{
require_code('xhtml');
}
$truncated=$not_html;
switch ($type)
{
case 'left':
$temp=(($is_html || $grammar_completeness_tolerance!=0.0)?xhtml_substr($html,0,$amount-3,$literal_pos,false,$grammar_completeness_tolerance):escape_html(ocp_mb_substr($not_html,0,$amount-3)));
if ($temp!=$html && in_array(substr($temp,-1),array('.','?','!'))) $temp.='<br />'; // so the "..." does not go right after the sentence terminator
$truncated=($temp==$html)?$temp:str_replace(array('</p>…','</div>…'),array('…</p>','…</div>'),(rtrim($temp).'…'));
break;
case 'expand':
$temp=(($is_html || $grammar_completeness_tolerance!=0.0)?xhtml_substr($html,0,$amount-3,$literal_pos,false,$grammar_completeness_tolerance):escape_html(ocp_mb_substr($not_html,0,$amount-3)));
if ($temp!=$html && in_array(substr($temp,-1),array('.','?','!'))) $temp.='<br />'; // so the "..." does not go right after the sentence terminator
$_truncated=do_template('COMCODE_HIDE',array('TEXT'=>protect_from_escaping($temp),'CONTENT'=>protect_from_escaping($html)));
$truncated=$_truncated->evaluate();
break;
case 'right':
$truncated=str_replace(array('</p>…','</div>…'),array('…</p>','…</div>'),('…'.ltrim(($is_html || $grammar_completeness_tolerance!=0.0)?xhtml_substr($html,-$amount-3,NULL,$literal_pos,false,$grammar_completeness_tolerance):escape_html(ocp_mb_substr($not_html,-$amount-3)))));
break;
case 'spread':
$pos=intval(floor(floatval($amount)/2.0))-1;
$truncated=str_replace(array('</p>…','</div>…'),array('…</p>','…</div>'),rtrim((($is_html || $grammar_completeness_tolerance!=0.0)?xhtml_substr($html,0,$pos,$literal_pos,false,$grammar_completeness_tolerance):escape_html(ocp_mb_substr($not_html,0,$pos))).'…'.ltrim(($is_html || $grammar_completeness_tolerance!=0.0)?xhtml_substr($html,-$pos-1):escape_html(ocp_mb_substr($not_html,-$pos-1)))));
break;
}
if ($tooltip)
{
if (!is_null($tooltip_if_truncated))
{
$tif=(is_object($tooltip_if_truncated)?$tooltip_if_truncated->evaluate():$tooltip_if_truncated);
if (strpos($tif,$html)!==false)
{
$html=$tif;
} else
{
$html.=' – '.$tif;
}
}
$tpl=((strpos($truncated,'<div')!==false || strpos($truncated,'<p')!==false || strpos($truncated,'<table')!==false)?'CROP_TEXT_MOUSE_OVER':'CROP_TEXT_MOUSE_OVER_INLINE');
$value_tempcode=do_template($tpl,array('_GUID'=>'36ae945ed864633cfa0d67e5c3f2d1c8','TEXT_SMALL'=>$truncated,'TEXT_LARGE'=>$html));
$value=$value_tempcode->evaluate();
if ($GLOBALS['XSS_DETECT']) ocp_mark_as_escaped($value);
} else $value=$truncated;
} else
{
$value=$html;
}
return $value;
}
string keep_symbol(array param)
String to tack onto URL to keep 'keep_' parameters
Parameters…
| Name |
param |
| Description |
Parameters passed to the symbol (0=whether this starts off the query string, 1=force session append even if it's also available a session cookie e.g. when put into download manager) |
| Type |
array |
Returns…
| Description |
The result. |
| Type |
string |
function keep_symbol($param)
{
$value='';
$get_vars=$_GET;
if ((isset($param[1])) && ($param[1]=='1') && (!array_key_exists('keep_session',$get_vars))) $get_vars['keep_session']=strval(get_session_id());
if (count($get_vars)>0)
{
$first=false;
if ((isset($param[0])) && ($param[0]=='1')) $first=true;
foreach ($get_vars as $key=>$val)
{
if ((get_magic_quotes_gpc()) && (is_string($val))) $val=stripslashes($val);
if ((substr($key,0,5)=='keep_') && (strpos($key,'_expand_')===false) && ((!skippable_keep($key,$val)) || (($key=='keep_session') && (is_null(get_bot_type())) && (isset($param[1])) && ($param[1]=='1'))) && (is_string($val)))
{
$value.=($first?'?':'&').urlencode($key).'='.ocp_url_encode($val);
$first=false;
}
}
}
return $value;
}
0 reviews: Unrated (average)
There have been no comments yet