--- a/includes/template.php Mon Jun 30 17:22:29 2008 -0400
+++ b/includes/template.php Wed Jul 02 19:36:44 2008 -0400
@@ -86,23 +86,9 @@
// List out all CSS files for this theme
foreach ( $this->theme_list as $i => &$theme )
{
- $theme['css'] = array();
- $dir = ENANO_ROOT . "/themes/{$theme['theme_id']}/css";
- if ( $dh = @opendir($dir) )
- {
- while ( ( $file = @readdir($dh) ) !== false )
- {
- if ( preg_match('/\.css$/', $file) )
- $theme['css'][] = preg_replace('/\.css$/', '', $file);
- }
- closedir($dh);
- }
- // No CSS files? If so, nuke it.
- if ( count($theme['css']) < 1 )
- {
- unset($this->theme_list[$i]);
- }
+ $theme['css'] = $this->get_theme_css_files($theme['theme_id']);
}
+ unset($theme);
$this->theme_list = array_values($this->theme_list);
// Create associative array of themes
foreach ( $this->theme_list as $i => &$theme )
@@ -116,6 +102,33 @@
}
/**
+ * Gets the list of available CSS files (styles) for the specified theme.
+ * @param string Theme ID
+ * @return array
+ */
+
+ function get_theme_css_files($theme_id)
+ {
+ $css = array();
+ $dir = ENANO_ROOT . "/themes/{$theme_id}/css";
+ if ( $dh = @opendir($dir) )
+ {
+ while ( ( $file = @readdir($dh) ) !== false )
+ {
+ if ( preg_match('/\.css$/', $file) )
+ $css[] = preg_replace('/\.css$/', '', $file);
+ }
+ closedir($dh);
+ }
+ // No CSS files? If so, nuke it.
+ if ( count($css) < 1 )
+ {
+ unset($this->theme_list[$theme_id]);
+ }
+ return $css;
+ }
+
+ /**
* Failsafe constructor for upgrades.
*/
@@ -566,8 +579,6 @@
// PAGE TOOLBAR (on-page controls/actions)
//
- profiler_log('template: var init: finished initial setup, starting toolbar');
-
// Initialize the toolbar
$tb = '';
@@ -948,8 +959,6 @@
// OTHER SWITCHES
//
- profiler_log('template: var init: finshed toolbar, starting other switches');
-
$is_opera = (isset($_SERVER['HTTP_USER_AGENT']) && strstr($_SERVER['HTTP_USER_AGENT'], 'Opera')) ? true : false;
$this->tpl_bool = Array(
@@ -1043,8 +1052,6 @@
$admin_link = $parser->run();
- profiler_log('template: var init: finished sidebar/misc processing, starting dynamic vars and finalization');
-
$SID = ($session->sid_super) ? $session->sid_super : '';
$urlname_clean = str_replace('\'', '\\\'', str_replace('\\', '\\\\', dirtify_page_id($local_fullpage)));
@@ -1111,8 +1118,6 @@
}
$js_dynamic .= "\n //]]>\n </script>";
- profiler_log('template: var init: finished JS dynamic vars and assigning final var set');
-
$tpl_strings = Array(
'PAGE_NAME'=>htmlspecialchars($local_cdata['name']),
'PAGE_URLNAME'=> $urlname_clean,
@@ -1154,14 +1159,14 @@
$this->assign_vars($tpl_strings, true);
+ profiler_log('template: var init: finished toolbar building and initial assign()');
+
//
// COMPILE THE SIDEBAR
//
// This is done after the big assign_vars() so that sidebar code has access to the newly assigned variables
- profiler_log('template: var init: finished final var set, executing and applying sidebar templates');
-
list($this->tpl_strings['SIDEBAR_LEFT'], $this->tpl_strings['SIDEBAR_RIGHT'], $min) = $this->fetch_sidebar();
$this->tpl_bool['sidebar_left'] = ( $this->tpl_strings['SIDEBAR_LEFT'] != $min) ? true : false;
$this->tpl_bool['sidebar_right'] = ( $this->tpl_strings['SIDEBAR_RIGHT'] != $min) ? true : false;
@@ -1299,7 +1304,11 @@
$t = str_replace('[[EnanoPoweredLinkLong]]', $lang->get('page_enano_powered_long', array('about_uri' => $this->tpl_strings['URL_ABOUT_ENANO'])), $t);
if ( defined('ENANO_DEBUG') )
+ {
$t = str_replace('</body>', '<div id="profile" style="margin: 10px;">' . profiler_make_html() . '</div></body>', $t);
+ // ob_end_clean();
+ // return profiler_make_html();
+ }
return $t;
}
@@ -1381,8 +1390,28 @@
$this->init_vars();
}
+ $cache_file = ENANO_ROOT . '/cache/' . $this->theme . '-' . str_replace('/', '-', $file) . '.php';
+ if ( file_exists($cache_file) )
+ {
+ // this is about the time of the breaking change to cache file format
+ if ( filemtime($cache_file) > 1215038089 )
+ {
+ $result = @include($cache_file);
+ if ( isset($md5) )
+ {
+ if ( $md5 == md5_file(ENANO_ROOT . "/themes/{$this->theme}/$file") )
+ {
+ $result = $this->compile_template_text_post($result);
+ return $result;
+ }
+ }
+ }
+ }
+
$compiled = $this->compile_template($file);
- return eval($compiled);
+ $result = eval($compiled);
+
+ return $result;
}
/**
@@ -1475,30 +1504,7 @@
</p>');
}
- // Check for cached copy
- // This will make filenames in the pattern of theme-file.tpl.php
- $cache_file = ENANO_ROOT . '/cache/' . $this->theme . '-' . str_replace('/', '-', $filename) . '.php';
-
- // Only use cached copy if caching is enabled
- // (it is enabled by default I think)
- if ( file_exists($cache_file) && getConfig('cache_thumbs') == '1' )
- {
- // Cache files are auto-generated, but otherwise are normal PHP files
- include($cache_file);
-
- // Fetch content of the ORIGINAL
- $text = file_get_contents($tpl_file_fullpath);
-
- // $md5 will be set by the cached file
- // This makes sure that a cached copy of the template is used only if its MD5
- // matches the MD5 of the file that the compiled file was compiled from.
- if ( isset($md5) && $md5 == md5($text) )
- {
- return $this->compile_template_text_post(str_replace('\\"', '"', $tpl_text));
- }
- }
-
- // We won't use the cached copy here
+ // We won't use the cached copy here.
$text = file_get_contents($tpl_file_fullpath);
// This will be used later when writing the cached file
@@ -1507,6 +1513,9 @@
// Preprocessing and checks complete - compile the code
$text = $this->compile_tpl_code($text);
+ // Generate cache filename
+ $cache_file = ENANO_ROOT . '/cache/' . $this->theme . '-' . str_replace('/', '-', $filename) . '.php';
+
// Perhaps caching is enabled and the admin has changed the template?
if ( is_writable( ENANO_ROOT . '/cache/' ) && getConfig('cache_thumbs') == '1' )
{
@@ -1517,19 +1526,22 @@
return $text;
}
- // Escape the compiled code so it can be eval'ed
- $text_escaped = addslashes($text);
- $notice = <<<EOF
+ // Final contents of cache file
+ $file_contents = <<<EOF
+<?php
/*
* NOTE: This file was automatically generated by Enano and is based on compiled code. Do not edit this file.
* If you edit this file, any changes you make will be lost the next time the associated source template file is edited.
*/
+\$md5 = '$md5';
+
+$text
EOF;
// This is really just a normal PHP file that sets a variable or two and exits.
// $tpl_text actually will contain the compiled code
- fwrite($h, '<?php ' . $notice . ' $md5 = \'' . $md5 . '\'; $tpl_text = \'' . $text_escaped . '\'; ?>');
+ fwrite($h, $file_contents);
fclose($h);
}
@@ -1613,6 +1625,26 @@
global $db, $session, $paths, $template, $plugins; // Common objects
global $lang;
+ $START = microtime_float();
+
+ // localize the whole string first
+ preg_match_all('/\{lang:([a-z0-9]+_[a-z0-9_]+)\}/', $message, $matches);
+ foreach ( $matches[1] as $i => $string_id )
+ {
+ $string = $lang->get($string_id);
+ $string = str_replace('\\', '\\\\', $string);
+ $string = str_replace('\'', '\\\'', $string);
+ $message = str_replace_once($matches[0][$i], $string, $message);
+ }
+
+ // first: the hackish optimization -
+ // if it's only a bunch of letters, numbers and spaces, just skip this sh*t.
+
+ if ( preg_match('/^[\w\s\.]*$/i', $message) )
+ {
+ return $message;
+ }
+
$filter_links = false;
$tplvars = $this->extract_vars($filename);
if($session->sid_super) $as = htmlspecialchars(urlSeparator).'auth='.$session->sid_super;
@@ -1636,185 +1668,45 @@
// Conditionals
- preg_match_all('#\{if ([A-Za-z0-9_ \(\)&\|\!-]*)\}(.*?)\{\/if\}#is', $message, $links);
-
- // Temporary exception from coding standards - using tab length of 4 here for clarity
- for ( $i = 0; $i < sizeof($links[1]); $i++ )
- {
- $condition =& $links[1][$i];
- $message = str_replace('{if '.$condition.'}'.$links[2][$i].'{/if}', '{CONDITIONAL:'.$i.':'.$random_id.'}', $message);
-
- // Time for some manual parsing...
- $chk = false;
- $current_id = '';
- $prn_level = 0;
- // Used to keep track of where we are in the conditional
- // Object of the game: turn {if this && ( that OR !something_else )} ... {/if} into if( ( isset($this->tpl_bool['that']) && $this->tpl_bool['that'] ) && ...
- // Method of attack: escape all variables, ignore all else. Non-valid code is filtered out by a regex above.
- $in_var_now = true;
- $in_var_last = false;
- $current_var = '';
- $current_var_start_pos = 0;
- $current_var_end_pos = 0;
- $j = -1;
- $condition = $condition . ' ';
- $d = strlen($condition);
- while($j < $d)
- {
- $j++;
- $in_var_last = $in_var_now;
-
- $char = substr($condition, $j, 1);
- $in_var_now = ( preg_match('#^([A-z0-9_]*){1}$#', $char) ) ? true : false;
- if(!$in_var_last && $in_var_now)
- {
- $current_var_start_pos = $j;
- }
- if($in_var_last && !$in_var_now)
- {
- $current_var_end_pos = $j;
- }
- if($in_var_now)
- {
- $current_var .= $char;
- continue;
- }
- // OK we are not inside of a variable. That means that we JUST hit the end because the counter ($j) will be advanced to the beginning of the next variable once processing here is complete.
- if($char != ' ' && $char != '(' && $char != ')' && $char != 'A' && $char != 'N' && $char != 'D' && $char != 'O' && $char != 'R' && $char != '&' && $char != '|' && $char != '!' && $char != '<' && $char != '>' && $char != '0' && $char != '1' && $char != '2' && $char != '3' && $char != '4' && $char != '5' && $char != '6' && $char != '7' && $char != '8' && $char != '9')
- {
- // XSS attack! Bail out
- $errmsg = '<p><b>Error:</b> Syntax error (possibly XSS attack) caught in template code:</p>';
- $errmsg .= '<pre>';
- $errmsg .= '{if '.htmlspecialchars($condition).'}';
- $errmsg .= "\n ";
- for ( $k = 0; $k < $j; $k++ )
- {
- $errmsg .= " ";
- }
- // Show position of error
- $errmsg .= '<span style="color: red;">^</span>';
- $errmsg .= '</pre>';
- $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $errmsg, $message);
- continue 2;
- }
- if($current_var != '')
- {
- $cd = '( isset($this->tpl_bool[\''.$current_var.'\']) && $this->tpl_bool[\''.$current_var.'\'] )';
- $cvt = substr($condition, 0, $current_var_start_pos) . $cd . substr($condition, $current_var_end_pos, strlen($condition));
- $j = $j + strlen($cd) - strlen($current_var);
- $current_var = '';
- $condition = $cvt;
- $d = strlen($condition);
- }
- }
- $condition = substr($condition, 0, strlen($condition)-1);
- $condition = '$chk = ( '.$condition.' ) ? true : false;';
- eval($condition);
-
- if($chk)
- {
- if(strstr($links[2][$i], '{else}')) $c = substr($links[2][$i], 0, strpos($links[2][$i], '{else}'));
- else $c = $links[2][$i];
- $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $c, $message);
- }
- else
- {
- if(strstr($links[2][$i], '{else}')) $c = substr($links[2][$i], strpos($links[2][$i], '{else}')+6, strlen($links[2][$i]));
- else $c = '';
- $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $c, $message);
- }
- }
-
- preg_match_all('#\{!if ([A-Za-z_-]*)\}(.*?)\{\/if\}#is', $message, $links);
-
- for($i=0;$i<sizeof($links[1]);$i++)
- {
- $message = str_replace('{!if '.$links[1][$i].'}'.$links[2][$i].'{/if}', '{CONDITIONAL:'.$i.':'.$random_id.'}', $message);
- if(isset($this->tpl_bool[$links[1][$i]]) && $this->tpl_bool[$links[1][$i]]) {
- if(strstr($links[2][$i], '{else}')) $c = substr($links[2][$i], strpos($links[2][$i], '{else}')+6, strlen($links[2][$i]));
- else $c = '';
- $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $c, $message);
- } else {
- if(strstr($links[2][$i], '{else}')) $c = substr($links[2][$i], 0, strpos($links[2][$i], '{else}'));
- else $c = $links[2][$i];
- $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $c, $message);
- }
- }
-
- preg_match_all('/\{lang:([a-z0-9]+_[a-z0-9_]+)\}/', $message, $matches);
- foreach ( $matches[1] as $i => $string_id )
- {
- $string = $lang->get($string_id);
- $string = str_replace('\\', '\\\\', $string);
- $string = str_replace('\'', '\\\'', $string);
- $message = str_replace_once($matches[0][$i], $string, $message);
- }
+ $message = $this->twf_parse_conditionals($message);
/*
* HTML RENDERER
*/
// Images
- $j = preg_match_all('#\[\[:'.$paths->nslist['File'].'([\w\s0-9_\(\)!@%\^\+\|\.-]+?)\]\]#is', $message, $matchlist);
- $matches = Array();
- $matches['images'] = $matchlist[1];
- for($i=0;$i<sizeof($matchlist[1]);$i++)
- {
- if(isPage($paths->nslist['File'].$matches['images'][$i]))
- {
- $message = str_replace('[[:'.$paths->nslist['File'].$matches['images'][$i].']]',
- '<img alt="'.$matches['images'][$i].'" style="border: 0" src="'.makeUrlNS('Special', 'DownloadFile/'.$matches['images'][$i]).'" />',
- $message);
- }
- }
+ $message = RenderMan::process_image_tags($message, $taglist);
+ $message = RenderMan::process_imgtags_stage2($message, $taglist);
// Internal links
-
- $text_parser = $this->makeParserText($tplvars['sidebar_button']);
-
- preg_match_all("#\[\[([^\|\]\n\a\r\t]*?)\]\]#is", $message, $il);
- for($i=0;$i<sizeof($il[1]);$i++)
- {
- $href = makeUrl(str_replace(' ', '_', $il[1][$i]), null, true);
- $text_parser->assign_vars(Array(
- 'HREF' => $href,
- 'FLAGS' => '',
- 'TEXT' => $il[1][$i]
- ));
- $message = str_replace("[[{$il[1][$i]}]]", $text_parser->run(), $message);
- }
-
- preg_match_all('#\[\[([^\|\]\n\a\r\t]*?)\|([^\]\r\n\a\t]*?)\]\]#is', $message, $il);
- for($i=0;$i<sizeof($il[1]);$i++)
- {
- $href = makeUrl(str_replace(' ', '_', $il[1][$i]), null, true);
- $text_parser->assign_vars(Array(
- 'HREF' => $href,
- 'FLAGS' => '',
- 'TEXT' => $il[2][$i]
- ));
- $message = str_replace("[[{$il[1][$i]}|{$il[2][$i]}]]", $text_parser->run(), $message);
- }
+ $message = RenderMan::parse_internal_links($message, $tplvars['sidebar_button']);
// External links
- // $message = preg_replace('#\[(http|ftp|irc):\/\/([a-z0-9\/:_\.\?&%\#@_\\\\-]+?) ([^\]]+)\\]#', '<a href="\\1://\\2">\\3</a><br style="display: none;" />', $message);
- // $message = preg_replace('#\[(http|ftp|irc):\/\/([a-z0-9\/:_\.\?&%\#@_\\\\-]+?)\\]#', '<a href="\\1://\\2">\\1://\\2</a><br style="display: none;" />', $message);
- preg_match_all('/\[((https?|ftp|irc):\/\/([^@\s\]"\':]+)?((([a-z0-9-]+\.)*)[a-z0-9-]+)(\/[A-z0-9_%\|~`!\!@#\$\^&\*\(\):;\.,\/-]*(\?(([a-z0-9_-]+)(=[A-z0-9_%\|~`\!@#\$\^&\*\(\):;\.,\/-\[\]]+)?((&([a-z0-9_-]+)(=[A-z0-9_%\|~`!\!@#\$\^&\*\(\):;\.,\/-]+)?)*))?)?)?) ([^\]]+)\]/is', $message, $ext_link);
-
- // die('<pre>' . htmlspecialchars( print_r($ext_link, true) ) . '</pre>');
+ $url_regexp = <<<EOF
+(
+ (?:https?|ftp|irc):\/\/ # protocol
+ (?:[^@\s\]"\':]+@)? # username (FTP only but whatever)
+ (?:(?:(?:[a-z0-9-]+\.)*)[a-z0-9-]+) # hostname
+ (?:\/[A-z0-9_%\|~`!\!@#\$\^&?=\*\(\):;\.,\/-]*)? # path
+)
+EOF;
+
+ $text_parser = $this->makeParserText($tplvars['sidebar_button']);
+
+ preg_match_all('/\[' . $url_regexp . '[ ]([^\]]+)\]/isx', $message, $ext_link);
for ( $i = 0; $i < count($ext_link[0]); $i++ )
{
$text_parser->assign_vars(Array(
'HREF' => $ext_link[1][$i],
'FLAGS' => '',
- 'TEXT' => $ext_link[16][$i]
+ 'TEXT' => $ext_link[2][$i]
));
$message = str_replace($ext_link[0][$i], $text_parser->run(), $message);
}
- preg_match_all('/\[((https?|ftp|irc):\/\/([^@\s\]"\':]+)?((([a-z0-9-]+\.)*)[a-z0-9-]+)(\/[A-z0-9_%\|~`!\!@#\$\^&\*\(\):;\.,\/-]*(\?(([a-z0-9_-]+)(=[A-z0-9_%\|~`\!@#\$\^&\*\(\):;\.,\/-\[\]]+)?((&([a-z0-9_-]+)(=[A-z0-9_%\|~`!\!@#\$\^&\*\(\):;\.,\/-]+)?)*))?)?)?)\]/is', $message, $ext_link);
+ preg_match_all('/\[' . $url_regexp . '\]/is', $message, $ext_link);
for ( $i = 0; $i < count($ext_link[0]); $i++ )
{
@@ -1826,34 +1718,182 @@
$message = str_replace($ext_link[0][$i], $text_parser->run(), $message);
}
- $parser1 = $this->makeParserText($tplvars['sidebar_section']);
- $parser2 = $this->makeParserText($tplvars['sidebar_section_raw']);
-
- preg_match_all('#\{slider(2|)=([^\}]*?)\}(.*?)\{\/slider(2|)\}#is', $message, $sb);
-
- // Modified to support the sweet new template var system
- for($i=0;$i<sizeof($sb[1]);$i++)
- {
- $p = ($sb[1][$i] == '2') ? $parser2 : $parser1;
- $p->assign_vars(Array('TITLE'=>$sb[2][$i],'CONTENT'=>$sb[3][$i]));
- $message = str_replace("{slider{$sb[1][$i]}={$sb[2][$i]}}{$sb[3][$i]}{/slider{$sb[4][$i]}}", $p->run(), $message);
- }
+ $TIME = microtime_float() - $START;
/*
- Extras ;-)
- $message = preg_replace('##is', '', $message);
- $message = preg_replace('##is', '', $message);
- $message = preg_replace('##is', '', $message);
- $message = preg_replace('##is', '', $message);
- $message = preg_replace('##is', '', $message);
+ if ( $TIME > 0.02 )
+ {
+ echo 'template: tplWikiFormat took a while for this one. string dump:<pre>';
+ echo htmlspecialchars($message);
+ echo '</pre>';
+ }
*/
- //die('<pre>'.htmlspecialchars($message).'</pre>');
- //eval($message); exit;
+ return $message;
+ }
+
+ /**
+ * Parses conditional {if} blocks in sidebars and other tplWikiFormatted things
+ * @param string A string potentially containing conditional blocks
+ * @return string Processed string
+ */
+
+ function twf_parse_conditionals($message)
+ {
+ if ( !preg_match_all('/\{(!?)if ([a-z0-9_\(\)\|&! ]+)\}(.*?)(?:\{else\}(.*?))?\{\/if\}/is', $message, $matches) )
+ {
+ return $message;
+ }
+ foreach ( $matches[0] as $match_id => $full_block )
+ {
+ // 1 = "not" flag
+ // 2 = condition
+ // 3 = if true
+ // 4 = else
+ $condresult = $this->process_condition($matches[2][$match_id]);
+ if ( !empty($matches[1][$match_id]) )
+ {
+ if ( $condresult == 1 )
+ $condresult = 2;
+ else if ( $condresult == 2 )
+ $condresult = 1;
+ }
+ switch($condresult)
+ {
+ case 1:
+ // evaluated to false
+ $message = str_replace_once($full_block, $matches[4][$match_id], $message);
+ break;
+ case 2:
+ // evaluated to true
+ $message = str_replace_once($full_block, $matches[3][$match_id], $message);
+ break;
+ case 3:
+ $message = str_replace_once($full_block, "Syntax error: mismatched parentheses (" . htmlspecialchars($matches[2][$match_id]) . ")<br />\n", $message);
+ break;
+ case 4:
+ $message = str_replace_once($full_block, "Syntax error: illegal character (" . htmlspecialchars($matches[2][$match_id]) . ")<br />\n", $message);
+ break;
+ case 5:
+ $message = str_replace_once($full_block, "Syntax error: illegal sequence (" . htmlspecialchars($matches[2][$match_id]) . ")<br />\n", $message);
+ break;
+ }
+ }
return $message;
}
/**
+ * Inner-loop parser for a conditional block. Verifies a string condition to make sure it's syntactically correct, then returns what it evaluates to.
+ * Return values:
+ * 1 - string evaluates to true
+ * 2 - string evaluates to false
+ * 3 - Syntax error - mismatched parentheses
+ * 4 - Syntax error - unknown token
+ * 5 - Syntax error - invalid sequence
+ * @param string
+ * @return int
+ *
+ */
+
+ function process_condition($condition)
+ {
+ // make sure parentheses are matched
+ $parentheses = preg_replace('/[^\(\)]/', '', $condition);
+ if ( !empty($parentheses) )
+ {
+ $i = 0;
+ $parentheses = enano_str_split($parentheses);
+ foreach ( $parentheses as $chr )
+ {
+ $inc = ( $chr == '(' ) ? 1 : -1;
+ $i += $inc;
+ }
+ if ( $i != 0 )
+ {
+ // mismatched parentheses
+ return 3;
+ }
+ }
+ // sequencer check
+ // first, pad all sequences of characters with spaces
+ $seqcheck = preg_replace('/([a-z0-9_]+)/i', '\\1 ', $condition);
+ $seqcheck = preg_replace('/([&|()!])/i', '\\1 ', $seqcheck);
+ // now shrink all spaces to one space each
+ $seqcheck = preg_replace('/[ ]+/', ' ', $seqcheck);
+
+ // explode it. the allowed sequences are:
+ // - TOKEN_NOT + TOKEN_VARIABLE
+ // - TOKEN_NOT + TOKEN_PARENTHLEFT
+ // - TOKEN_BOOLOP + TOKEN_NOT
+ // - TOKEN_PARENTHRIGHT + TOKEN_NOT
+ // - TOKEN_VARIABLE + TOKEN_BOOLOP
+ // - TOKEN_BOOLOP + TOKEN_PARENTHLEFT
+ // - TOKEN_PARENTHLEFT + TOKEN_VARIABLE
+ // - TOKEN_BOOLOP + TOKEN_VARIABLE
+ // - TOKEN_VARIABLE + TOKEN_PARENTHRIGHT
+ // - TOKEN_PARENTHRIGHT + TOKEN_BOOLOP
+ $seqcheck = explode(' ', trim($seqcheck));
+ $last_item = TOKEN_BOOLOP;
+ foreach ( $seqcheck as $i => $token )
+ {
+ // determine type
+ if ( $token == '(' )
+ {
+ $type = TOKEN_PARENTHLEFT;
+ }
+ else if ( $token == ')' )
+ {
+ $type = TOKEN_PARENTHRIGHT;
+ }
+ else if ( $token == '!' )
+ {
+ $type = TOKEN_NOT;
+ }
+ else if ( strtolower($token) == 'and' || strtolower($token) == 'or' || $token == '&&' || $token == '||' )
+ {
+ $type = TOKEN_BOOLOP;
+ }
+ else if ( preg_match('/^[a-z0-9_]+$/i', $token) )
+ {
+ $type = TOKEN_VARIABLE;
+ // at this point it's considered safe to wrap it
+ $seqcheck[$i] = "( isset(\$this->tpl_bool['$token']) && \$this->tpl_bool['$token'] )";
+ }
+ else
+ {
+ // syntax error - doesn't match known token types
+ return 4;
+ }
+ // inner sequence check
+ if (
+ ( $last_item == TOKEN_BOOLOP && $type == TOKEN_NOT ) ||
+ ( $last_item == TOKEN_PARENTHRIGHT && $type == TOKEN_NOT ) ||
+ ( $last_item == TOKEN_NOT && $type == TOKEN_VARIABLE ) ||
+ ( $last_item == TOKEN_NOT && $type == TOKEN_PARENTHLEFT ) ||
+ ( $last_item == TOKEN_VARIABLE && $type == TOKEN_BOOLOP ) ||
+ ( $last_item == TOKEN_BOOLOP && $type == TOKEN_PARENTHLEFT ) ||
+ ( $last_item == TOKEN_PARENTHLEFT && $type == TOKEN_VARIABLE ) ||
+ ( $last_item == TOKEN_BOOLOP && $type == TOKEN_VARIABLE ) ||
+ ( $last_item == TOKEN_VARIABLE && $type == TOKEN_PARENTHRIGHT ) ||
+ ( $last_item == TOKEN_PARENTHRIGHT && $type == TOKEN_BOOLOP )
+ )
+ {
+ // sequence is good, continue
+ }
+ else
+ {
+ // sequence is invalid, break out
+ return 5;
+ }
+ $last_item = $type;
+ }
+ // passed all checks
+ $seqcheck = implode(' ', $seqcheck);
+ $result = eval("return ( $seqcheck ) ? true : false;");
+ return ( $result ) ? 2 : 1;
+ }
+
+ /**
* Print a text field that auto-completes a username entered into it.
* @param string $name - the name of the form field
* @return string
@@ -1977,6 +2017,25 @@
$left = '';
$right = '';
+ // check the cache
+ $cache_enable = getConfig('cache_thumbs') == '1' && !$session->user_logged_in;
+ $cache_file = ENANO_ROOT . "/cache/cache_anon_sidebar.php";
+ $cache_fresh = intval(getConfig('sidebar_anon_cache_time') + 600) >= time();
+ if ( $cache_enable && $cache_fresh )
+ {
+ @include($cache_file);
+ if ( isset($sidebar_cache) )
+ {
+ // we loaded the cache!
+ foreach ( $sidebar_cache as $i => $_ )
+ {
+ $block =& $sidebar_cache[$i];
+ $block = str_replace('$USERNAME$', $session->username, $block);
+ }
+ return $sidebar_cache;
+ }
+ }
+
if ( !$this->fetch_block('Links') )
$this->initLinksWidget();
@@ -1988,9 +2047,11 @@
if(isset($vars['sidebar_top']))
{
- $left .= $this->parse($vars['sidebar_top']);
- $right .= $this->parse($vars['sidebar_top']);
+ $top = $this->parse($vars['sidebar_top']);
+ $left .= $top;
+ $right .= $top;
}
+
while($row = $db->fetchrow())
{
switch($row['block_type'])
@@ -2033,19 +2094,42 @@
$db->free_result();
if(isset($vars['sidebar_bottom']))
{
- $left .= $this->parse($vars['sidebar_bottom']);
- $right .= $this->parse($vars['sidebar_bottom']);
+ $bottom = $this->parse($vars['sidebar_bottom']);
+ $left .= $bottom;
+ $right .= $bottom;
}
$min = '';
if(isset($vars['sidebar_top']))
{
- $min .= $this->parse($vars['sidebar_top']);
+ $min .= $top;
}
if(isset($vars['sidebar_bottom']))
{
- $min .= $this->parse($vars['sidebar_bottom']);
+ $min .= $bottom;
}
- return Array($left, $right, $min);
+ $return = Array($left, $right, $min);
+ if ( $cache_enable )
+ {
+ $cachestore = Language::var_export_string($return);
+ $cachestore = str_replace($session->username, '$USERNAME$', $cachestore);
+ $cachestore = <<<EOF
+<?php
+/**
+ * Automatically generated cache of the sidebar for guests.
+ * Do not modify this, it is refreshed every 15 minutes.
+ */
+
+\$sidebar_cache = $cachestore;
+EOF;
+ $fh = @fopen($cache_file, 'w');
+ if ( $fh )
+ {
+ fwrite($fh, $cachestore);
+ fclose($fh);
+ }
+ setConfig('sidebar_anon_cache_time', time());
+ }
+ return $return;
}
function initLinksWidget()
@@ -2053,6 +2137,7 @@
global $db, $session, $paths, $template, $plugins; // Common objects
// SourceForge/W3C buttons
$ob = Array();
+ // FIXME: l10n
$admintitle = ( $session->user_level >= USER_LEVEL_ADMIN ) ? 'title="You may disable this button in the admin panel under General Configuration."' : '';
if(getConfig('sflogo_enabled')=='1')
{
@@ -2676,11 +2761,8 @@
function process_template($file)
{
- profiler_log("[template_nodb] STARTED eval of file $file");
$compiled = $this->compile_template($file);
- profiler_log("[template_nodb] COMPILED file $file");
$result = eval($compiled);
- profiler_log("[template_nodb] FINISHED eval of file $file");
return $result;
}