+++ /dev/null
-<?php
-
-/***************************************************************************
- * template.php
- * ------------------
- * copyright : (C) 2001 The phpBB Group
- * email : support@phpbb.com
- *
- * phpBB version : 2.0.x
- * eXtreme Styles mod : 2.0.1
- * Support : http://www.phpbbstyles.com
- *
- * file revision : 48
- * project revision : 51
- * last modified : 25 Aug 2004 11:51:47
- *
- ***************************************************************************/
-
-/***************************************************************************
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- ***************************************************************************/
-
-/**
- *
- * Template class. By Nathan Codding of the phpBB group.
- * The interface was originally inspired by PHPLib templates,
- * and the template file formats are quite similar.
- *
- * eXtreme Styles mod by CyberAlien.
- *
- * IF, ELSEIF, ENDIF tags are backported from phpBB 2.2
- *
- * Documentation for this mod can be found here:
- * http://www.phpbbstyles.com
- *
- * Support for eXtreme Styles mod is provided at http://www.phpbbstyles.com
- *
- * Thanks to DMaJ007 for idea on how to include some extra tags.
- *
- */
-
-define('XS_SEPARATOR', '.');
-define('XS_DIR_CACHE', 'cache');
-define('XS_USE_ISSET', '1');
-
-// cache filenames prefix
-define('XS_TPL_PREFIX', 'tpl_');
-define('XS_TPL_PREFIX2', 'tpl2_');
-
-// templates directory
-define('XS_TPL_START', 'templates/');
-define('XS_TPL_ANY', '/templates/');
-
-// internal xs mod definitions. do not edit.
-define('XS_TAG_NONE', 0);
-define('XS_TAG_PHP', 1);
-define('XS_TAG_BEGIN', 2);
-define('XS_TAG_END', 3);
-define('XS_TAG_INCLUDE', 4);
-define('XS_TAG_IF', 5);
-define('XS_TAG_ELSE', 6);
-define('XS_TAG_ELSEIF', 7);
-define('XS_TAG_ENDIF', 8);
-define('XS_TAG_DEFINE', 9);
-define('XS_TAG_UNDEFINE', 10);
-
-
-class Template {
- var $classname = "Template";
-
- // variable that holds all the data we'll be substituting into
- // the compiled templates.
- // ...
- // This will end up being a multi-dimensional array like this:
- // $this->_tpldata[block.][iteration#][child.][iteration#][child2.][iteration#][variablename] == value
- // if it's a root-level variable, it'll be like this:
- // $this->vars[varname] == value or $this->_tpldata['.'][0][varname] == value
- // array "vars" is added for easier access to data
- var $_tpldata = array('.' => array(0 => array()));
- var $vars;
-
- // Hash of filenames for each template handle.
- var $files = array();
- var $files_cache = array(); // array of cache files that exists
- var $files_cache2 = array(); // array of cache files (exists or not exists)
-
- // Root template directory.
- var $root = '';
-
- // Cache directory (compatible with default cache mod)
- var $cachedir = '';
-
- // Search/replace for unknown files
- var $cache_search = array();
- var $cache_replace = array();
-
- // Template root directory (generated by set_rootdir)
- var $tpldir = '';
- var $tpldir_len = 0;
-
- // Default template directory.
- // If file for default template isn't found file from this template is used.
- var $tpldef = 'subSilver';
-
- // this will hash handle names to the compiled code for that handle.
- var $compiled_code = array();
-
- // This will hold the uncompiled code for that handle.
- var $uncompiled_code = array();
-
- // Cache settings
- var $use_cache = 1;
- var $cache_writable = 1;
-
- // Auto-compile setting
- var $auto_compile = 1;
-
- // Current template name
- var $tpl = '';
-
- // List of replacements. tpl files in this list will be replaced with other tpl files
- // according to configuration in xs.cfg
- var $replace = array();
-
- // counter for include
- var $include_count = 0;
-
- // php extension. will be replaced by $phpEx in Template() function unless you disable it there
- var $php = 'php';
-
- // True if check switches
- var $xs_check_switches = 1;
-
- // eXtreme Styles variables
- var $xs_started = 0;
- var $xs_version = 5; // number version. internal. do not change.
- var $xs_versiontxt = '2.0.1'; // text version
-
- // These handles will be parsed if pparse() is executed.
- // Can be used to automatically include header/footer if there is any content.
- var $preparse = '';
- var $postparse = '';
-
- // subtemplates mod detection
- var $subtemplates = false;
-
- // list of switches that are known typos in some mods.
- // when error checking is enabled these errors will be auto-fixed.
- // format:
- // array(start_tag, end_tag)
- var $bugs = array(
- // ezportal typo:
- array('fetchpost_row', 'fetch_post_row'),
- // mycalendar 2.2.7 typos:
- array('date_cell', 'date_cells'),
- array('date_row', 'date_rows'),
- // history mod typo:
- array('site_today', 'site_week'),
- );
-
- /**
- * Constructor. Installs XS mod on first run or updates it and sets the root dir.
- */
- function Template($root = '.')
- {
- // setting pointer "vars"
- $this->vars = &$this->_tpldata['.'][0];
- // load configuration
- $this->load_config($root, true);
- }
-
- /**
- * Load mod configuration
- */
- function load_config($root, $edit_db)
- {
- global $board_config, $phpbb_root_path, $phpEx;
- // getting mod version from config and comparing with real data
- $ver = isset($board_config['xs_version']) ? $board_config['xs_version'] : 0;
- // check configuration
- // set config values if there aren't any
- $add = array();
- $del = array();
- $up = array();
- // list of outdated variables
- $outdated = array(
- 'xs_versoin', // was a typo in one of previous versions
- 'xs_separator', // no longer used
- 'xs_cache_dir_absolute', // no longer used
- 'xs_cache_dir', // no longer used
- 'xs_use_isset', // no longer used
- );
- // list of default values
- $default = array(
- 'xs_auto_compile' => 1,
- 'xs_auto_recompile' => 1,
- 'xs_use_cache' => 1,
- 'xs_php' => $phpEx,
- 'xs_def_template' => 'subSilver',
- 'xs_check_switches' => 1,
- 'xs_warn_includes' => 1,
- 'xs_add_comments' => 0,
- 'xs_ftp_host' => '',
- 'xs_ftp_login' => '',
- 'xs_ftp_path' => '',
- 'xs_downloads_count' => '0',
- 'xs_downloads_default' => '0',
- 'xs_shownav' => '1',
- 'xs_template_time' => '0',
- );
- // checking if all variables exist
- foreach($default as $var => $value)
- {
- if(!isset($board_config[$var]))
- {
- $board_config[$var] = $value;
- $add[] = $var;
- }
- }
- // checking if there are any outdated variables that should be deleted
- for($i=0; $i<count($outdated); $i++)
- {
- if(isset($board_config[$outdated[$i]]))
- {
- $del[] = $outdated[$i];
- }
- }
- if(!isset($board_config['xs_version']))
- {
- $board_config['xs_version'] = $this->xs_version;
- $add[] = 'xs_version';
- }
- elseif($board_config['xs_version'] != $this->xs_version)
- {
- $board_config['xs_version'] = $this->xs_version;
- $up[] = 'xs_version';
- }
- // check config
- if(!empty($board_config['xs_auto_recompile']))
- {
- if(!$board_config['xs_auto_compile'])
- {
- $board_config['xs_auto_compile'] = 1;
- if(!in_array('xs_auto_compile', $up) && !in_array('xs_auto_compile', $add))
- {
- $up[] = 'xs_auto_compile';
- }
- }
- }
- // install/upgrade
- if($edit_db && ((count($add) > 0) || (count($up) > 0) || (count($del) > 0)))
- {
- $board_config['xs_template_time'] = time();
- if(!in_array('xs_template_time', $up))
- {
- $up[] = 'xs_template_time';
- }
- global $db;
- if(isset($db) && (@get_class($db) === 'sql_db'))
- {
- // adding new config values
- for($i=0; $i<count($add); $i++)
- {
- $sql = "INSERT INTO " . CONFIG_TABLE . " (config_name, config_value) VALUES ('" . $add[$i] . "', '" . str_replace("'", "''", $board_config[$add[$i]]) . "')";
- $db->sql_query($sql);
- }
- // removing old configuration variables that aren't used
- for($i=0; $i<count($del); $i++)
- {
- $sql = "DELETE FROM " . CONFIG_TABLE . " WHERE config_name='" . $del[$i] . "'";
- $db->sql_query($sql);
- }
- // updating variables that should be overwritten
- for($i=0; $i<count($up); $i++)
- {
- $sql = "UPDATE " . CONFIG_TABLE . " SET config_value='" . str_replace("'", "''", $board_config[$up[$i]]) . "' WHERE config_name='" . $up[$i] . "'";
- $db->sql_query($sql);
- }
- }
- }
- $this->php = $board_config['xs_php'];
- $this->tpldef = $board_config['xs_def_template'];
- $this->use_cache = $board_config['xs_use_cache'];
- $this->auto_compile = $board_config['xs_auto_compile'];
- $this->xs_check_switches = $board_config['xs_check_switches'];
- $this->cache_search = array('.', '\\', '/', '_tpl');
- $this->cache_replace = array('_', XS_SEPARATOR, XS_SEPARATOR, '.'.$this->php);
- $old_root = $this->root;
- $this->set_rootdir($root);
- if(!empty($this->tpl))
- {
- $this->load_replacements($this->tpldir . $this->tpl . '/xs.cfg');
- }
- if($old_root !== $this->root)
- {
- $this->clear_files();
- }
- }
-
- /**
- * Sets the template root directory for this Template object.
- */
- function set_rootdir($dir)
- {
- global $board_config, $phpbb_root_path;
- if (!@is_dir($dir))
- {
- return false;
- }
- $dir = str_replace('\\', '/', $dir);
- // creating absolute path for cache
- $this->cachedir = $phpbb_root_path . XS_DIR_CACHE . '/';
- // creating absolute path for current template and root dir
- $this->tpldir = $phpbb_root_path . 'templates/';
- $this->tpldir_len = strlen($this->tpldir);
- $this->root = $dir;
- $this->tpl = $this->template_name($dir);
- // check subtemplates mod
- $sub_templates_cfg = $this->root . '/sub_templates.cfg';
- if(defined('LANG_EXTEND_DONE') && @file_exists($sub_templates_cfg))
- {
- $this->subtemplates = true;
- }
- return true;
- }
-
- /**
- * Destroys this template object. Should be called when you're done with it, in order
- * to clear out the template data so you can load/parse a new template set.
- */
- function destroy()
- {
- $this->_tpldata = array('.' => array(0 => array()));
- $this->vars = &$this->_tpldata['.'][0];
- $this->xs_started = 0;
- }
-
- /**
- * Clears list of compiled files.
- */
- function clear_files()
- {
- $this->files = array();
- $this->files_cache = array();
- $this->files_cache2 = array();
- $this->compiled_code = array();
- $this->uncompiled_code = array();
- }
-
- /**
- * Loads replacements from .cfg file
- */
- function load_replacements($file)
- {
- if(@file_exists($file))
- {
- $replace = array();
- @include($file);
- $this->replace = array_merge($this->replace, $replace);
- }
- }
-
- /**
- * Extracts template name from path
- */
- function template_name($dir)
- {
- $tpl = XS_TPL_ANY; // can start at any position
- $tpl_null = XS_TPL_START; // can start only at zero position
- // searching for 'templates/' and removing everything before it
- $pos = strpos($dir, $tpl);
- if($pos === false)
- {
- if(substr($dir, 0, strlen($tpl_null)) !== $tpl_null)
- {
- return '';
- }
- $str = substr($dir, strlen($tpl_null), strlen($dir));
- }
- else
- {
- $str = substr($dir, $pos + strlen($tpl), strlen($dir));
- }
- // searching for one more 'templates/'
- // that can happen if full path is like /home/some_dude/templates/phpbb/templates/subSilver/
- $dir = $this->template_name($str);
- if(!$dir)
- {
- $dir = $str;
- }
- if(strpos($str, $tpl) !== false)
- {
- $dir = $this->template_name($str);
- }
- // check for another subdirectory
- $pos = strpos($dir, '/');
- if($pos)
- {
- $dir = substr($dir, 0, $pos);
- }
- return $dir;
- }
-
- function subtemplates_make_filename($filename)
- {
- global $HTTP_GET_VARS, $HTTP_POST_VARS, $db, $board_config, $images, $theme;
- global $sub_template_key_image, $sub_templates;
- global $tree;
-
- // initiate the sub-template image pack that will be use
- $sub_template_key_image = POST_CAT_URL . '0';
-
- // Check if sub_templates are defined for this theme
- if ( $board_config['version'] > '.0.5' )
- {
- $sub_templates_cfg = @phpbb_realpath($this->root . '/sub_templates.cfg');
- }
- else
- {
- $sub_templates_cfg = $this->root . '/sub_templates.cfg';
- }
- @include($sub_templates_cfg);
- if ( isset($sub_templates) )
- {
- // search an id
- $cat_id = 0;
- $forum_id = 0;
- $topic_id = 0;
- $post_id = 0;
-
- if ( !defined('IN_PRIVMSG') && ( isset($HTTP_GET_VARS[POST_POST_URL]) || isset($HTTP_POST_VARS[POST_POST_URL]) ) )
- {
- $post_id = isset($HTTP_GET_VARS[POST_POST_URL]) ? intval($HTTP_GET_VARS[POST_POST_URL]) : intval($HTTP_POST_VARS[POST_POST_URL]);
- }
-
- if ( isset($HTTP_GET_VARS[POST_TOPIC_URL]) || isset($HTTP_POST_VARS[POST_TOPIC_URL]) )
- {
- $topic_id = intval($HTTP_GET_VARS[POST_TOPIC_URL]) ? intval($HTTP_GET_VARS[POST_TOPIC_URL]) : intval($HTTP_POST_VARS[POST_TOPIC_URL]);
- }
-
- if ( isset($HTTP_GET_VARS[POST_FORUM_URL]) || isset($HTTP_POST_VARS[POST_FORUM_URL]) )
- {
- $forum_id = isset($HTTP_GET_VARS[POST_FORUM_URL]) ? intval($HTTP_GET_VARS[POST_FORUM_URL]) : intval($HTTP_POST_VARS[POST_FORUM_URL]);
- }
-
- if ( isset($HTTP_GET_VARS[POST_CAT_URL]) || isset($HTTP_POST_VARS[POST_CAT_URL]) )
- {
- $cat_id = isset($HTTP_GET_VARS[POST_CAT_URL]) ? intval($HTTP_GET_VARS[POST_CAT_URL]) : intval($HTTP_POST_VARS[POST_CAT_URL]);
- }
-
- if ( isset($HTTP_GET_VARS['selected_id']) || isset($HTTP_POST_VARS['selected_id']) )
- {
- $selected_id = isset($HTTP_GET_VARS['selected_id']) ? $HTTP_GET_VARS['selected_id'] : $HTTP_POST_VARS['selected_id'];
- $type = substr($selected_id, 0, 1);
- $id = intval(substr($selected_id, 1));
- if (!empty($id)) switch ($type)
- {
- case POST_CAT_URL:
- $cat_id = $id;
- break;
- case POST_FORUM_URL:
- $forum_id = $id;
- break;
- case POST_TOPIC_URL:
- $topic_id = $id;
- break;
- case POST_POST_URL:
- if ( !defined('IN_PRIVMSG') )
- {
- $post_id = $id;
- break;
- }
- default:
- break;
- }
- }
-
- // find the forum
- if ( ($forum_id <= 0) && ($cat_id <= 0) )
- {
- if ($post_id > 0)
- {
- $sql = "SELECT * FROM " . POSTS_TABLE . " WHERE post_id=$post_id";
- if ( !($result = $db->sql_query($sql)) )
- {
- message_die(GENERAL_ERROR, 'Wasn\'t able to access posts', '', __LINE__, __FILE__, $sql);
- }
- if ( $row = $db->sql_fetchrow($result) )
- {
- $forum_id = $row['forum_id'];
- }
- }
-
- if ($topic_id > 0)
- {
- $sql = "SELECT * FROM " . TOPICS_TABLE . " WHERE topic_id=$topic_id";
- if ( !($result = $db->sql_query($sql)) )
- {
- message_die(GENERAL_ERROR, 'Wasn\'t able to access topics', '', __LINE__, __FILE__, $sql);
- }
- if ( $row = $db->sql_fetchrow($result) )
- {
- $forum_id = $row['forum_id'];
- }
- }
- }
-
- // is the categories hierarchy v 2 installed ?
- $cat_hierarchy = function_exists(get_auth_keys);
-
- // get the ids (forums and cats)
- $fids = array();
- if (!$cat_hierarchy)
- {
- if ($forum_id > 0)
- {
- // add the forum_id
- $fids[] = POST_FORUM_URL . $forum_id;
-
- // get the cat_id
- $sql = "SELECT * FROM " . FORUMS_TABLE . " WHERE forum_id=$forum_id";
- if ( !($result = $db->sql_query($sql)) )
- {
- message_die(GENERAL_ERROR, 'Wasn\'t able to access forums', '', __LINE__, __FILE__, $sql);
- }
- if ( $row = $db->sql_fetchrow($result) )
- {
- $cat_id = $row['cat_id'];
- }
- }
-
- // add the cat_id
- if ($cat_id > 0)
- {
- $fids[] = POST_CAT_URL . $cat_id;
- }
-
- // add the root level
- $fids[] = 'Root';
- }
- else
- {
- // categories hierarchy v 2 compliancy
- $cur = 'Root';
- if ($forum_id > 0)
- {
- $cur = POST_FORUM_URL . $forum_id;
- }
- else if ($cat_id > 0)
- {
- $cur = POST_CAT_URL . $cat_id;
- }
-
- // add start
- $fids[] = $cur;
- while ( ($cur != 'Root') && !empty($cur) )
- {
- // get parent level
- $cur = (isset($tree['main'][ $tree['keys'][$cur] ])) ? $tree['main'][ $tree['keys'][$cur] ] : 'Root';
-
- // add the parent level
- if ( !empty($cur) )
- {
- $fids[] = $cur;
- }
- }
- }
-
- // search if this file is part of a sub-template
- $sub_tpl_file = '';
- $sub_css_file = '';
- $sub_img_file = '';
- $sub_img_path = '';
- $template_path = 'templates/';
- $template_name = substr( $this->root, strpos($this->root, $template_path) + strlen($template_path) );
- $real_root = $this->root;
- if ( $board_config['version'] > '.0.5' )
- {
- $real_root = @phpbb_realpath($this->root);
- }
- if (substr($filename, 0, 1) != '/')
- {
- $found = false;
- $num_fids = count($fids);
- for ($i = 0; !$found && ($i < $num_fids); $i++)
- {
- $key = $fids[$i];
-
- // convert root into c0 category
- if ( ($key == 'Root') || empty($key) )
- {
- $key = POST_CAT_URL . '0';
- }
-
- if ( isset($sub_templates[$key]) )
- {
- // get the sub-template path
- $current_template_path = $template_path . $template_name . '/' . $sub_templates[$key]['dir'];
- $root_template_path = $real_root . '/' . $sub_templates[$key]['dir'];
-
- // set the filename
- if ( empty($sub_tpl_file) && file_exists($root_template_path . '/' . $filename) )
- {
- $found = true;
- $sub_tpl_file = $sub_templates[$key]['dir'] . '/' . $filename;
- break;
- }
- }
- }
-
- // set the css file name
- $found = false;
- $num_fids = count($fids);
- for ($i = 0; !$found && ($i < $num_fids); $i++)
- {
- $key = $fids[$i];
-
- // convert root into c0 category
- if ( ($key == 'Root') || empty($key) )
- {
- $key = POST_CAT_URL . '0';
- }
-
- if ( isset($sub_templates[$key]) )
- {
- // get the sub-template path
- $current_template_path = $template_path . $template_name . '/' . $sub_templates[$key]['dir'];
- $root_template_path = $real_root . '/' . $sub_templates[$key]['dir'];
- if ( empty($sub_css_file) && isset($sub_templates[$key]['head_stylesheet']) && file_exists($root_template_path . '/' . $sub_templates[$key]['head_stylesheet']) )
- {
- $found = true;
- $sub_css_file = $sub_templates[$key]['dir'] . '/' . $sub_templates[$key]['head_stylesheet'];
- break;
- }
- }
- }
-
- // set the img file name
- $found = false;
- $num_fids = count($fids);
- for ($i = 0; !$found && ($i < $num_fids); $i++)
- {
- $key = $fids[$i];
-
- // convert root into c0 category
- if ( ($key == 'Root') || empty($key) )
- {
- $key = POST_CAT_URL . '0';
- }
-
- if ( isset($sub_templates[$key]) )
- {
- // get the sub-template path
- $current_template_path = $template_path . $template_name . '/' . $sub_templates[$key]['dir'];
- $root_template_path = $real_root . '/' . $sub_templates[$key]['dir'];
- if ( isset($sub_templates[$key]['imagefile']) && file_exists($root_template_path . '/' . $sub_templates[$key]['imagefile']) )
- {
- $sub_img_path = $sub_templates[$key]['dir'];
- $sub_img_file = $sub_templates[$key]['imagefile'];
-
- // send back the lowest level of the images file
- $found = true;
- $sub_template_key_image = $key;
- break;
- }
- }
- }
- }
-
- // set the tpl file
- if ( !empty($sub_tpl_file) )
- {
- $filename = $sub_tpl_file;
- }
-
- // set the css file
- if ( !empty($sub_css_file) )
- {
- $theme['head_stylesheet'] = $sub_css_file;
- }
-
- // get the root level images
- $key = POST_CAT_URL . '0';
- if ( isset($sub_templates[$key]) )
- {
- // get the sub-template path
- $current_template_path = $template_path . $template_name . '/' . $sub_templates[$key]['dir'];
- $root_template_path = $real_root . '/' . $sub_templates[$key]['dir'];
- if ( isset($sub_templates[$key]['imagefile']) && file_exists($root_template_path . '/' . $sub_templates[$key]['imagefile']) )
- {
- $sav_images = $images;
- $images = array();
- @include($root_template_path . '/' . $sub_templates[$key]['imagefile']);
- $img_lang = ( file_exists($root_template_path . '/images/lang_' . $board_config['default_lang']) ) ? $board_config['default_lang'] : 'english';
- foreach($images as $key => $value)
- {
- if ( !is_array($value) )
- {
- $images[$key] = str_replace('{LANG}', 'lang_' . $img_lang, $value);
- }
- $sav_images[$key] = $images[$key];
- }
- $images = $sav_images;
- $sav_images = array();
- }
- }
-
- // get the current images
- if ( !empty($sub_template_key_image) && ($sub_template_key_image != POST_CAT_URL . '0') )
- {
- $key = $sub_template_key_image;
-
- // get the sub-template path
- $current_template_path = $template_path . $template_name . '/' . $sub_templates[$key]['dir'];
- $root_template_path = $real_root . '/' . $sub_templates[$key]['dir'];
- if ( isset($sub_templates[$key]['imagefile']) && file_exists($root_template_path . '/' . $sub_templates[$key]['imagefile']) )
- {
- $sav_images = $images;
- $images = array();
- @include($root_template_path . '/' . $sub_templates[$key]['imagefile']);
- $img_lang = ( file_exists($root_template_path . '/images/lang_' . $board_config['default_lang']) ) ? $board_config['default_lang'] : 'english';
- foreach($images as $key => $value)
- {
- if ( !is_array($value) )
- {
- $images[$key] = str_replace('{LANG}', 'lang_' . $img_lang, $value);
- }
- $sav_images[$key] = $images[$key];
- }
- $images = $sav_images;
- $sav_images = array();
- }
- }
- }
- return $filename;
- }
-
- /**
- * Generates a full path+filename for the given filename, which can either
- * be an absolute name, or a name relative to the rootdir for this Template
- * object.
- */
- function make_filename($filename, $xs_include = false)
- {
- if($this->subtemplates)
- {
- $filename = $this->subtemplates_make_filename($filename);
- }
- // Check replacements list
- if(!$xs_include && isset($this->replace[$filename]))
- {
- $filename = $this->replace[$filename];
- }
- // Check if it's an absolute or relative path.
- if ((substr($filename, 0, 1) !== '/') && (substr($filename, 1, 1) !== ':'))
- {
- return $this->root . '/' . $filename;
- }
- else
- {
- return str_replace('\\', '/', $filename);
- }
- }
-
- /**
- * Converts template filename to cache filename.
- * Returns empty string if non-cachable (for tpl files outside of root dir).
- * $file should be absolute filename
- */
- function make_filename_cache($file)
- {
- $str = str_replace($this->cache_search, $this->cache_replace, $file);
- if(substr($file, 0, $this->tpldir_len) !== $this->tpldir || empty($this->tpl))
- {
- return $this->cachedir . XS_TPL_PREFIX2 . $str;
- }
- // removing not needed part
- $file = substr($file, $this->tpldir_len, strlen($file));
- // creating filename
- return $this->cachedir . XS_TPL_PREFIX . str_replace($this->cache_search, $this->cache_replace, $file);
- }
-
- /**
- * Sets the template filenames for handles. $filename_array
- * should be a hash of handle => filename pairs.
- */
- function set_filenames($filename_array)
- {
- if (!is_array($filename_array))
- {
- return false;
- }
-
- foreach($filename_array as $handle => $filename)
- {
- $this->set_filename($handle, $filename);
- }
-
- return true;
- }
-
-
- /**
- * Assigns template filename for handle.
- */
- function set_filename($handle, $filename, $xs_include = false, $quiet = false)
- {
- global $board_config;
- $can_cache = $this->use_cache;
- if(strpos($filename, '..') !== false)
- {
- $can_cache = false;
- }
- $this->files[$handle] = $this->make_filename($filename, $xs_include);
- $this->files_cache[$handle] = '';
- $this->files_cache2[$handle] = '';
- // check if we are in admin control panel and override extreme styles mod controls if needed
- if(defined('XS_ADMIN_OVERRIDE') && XS_ADMIN_OVERRIDE === true && @function_exists('xs_admin_override'))
- {
- xs_admin_override();
- }
- // checking if we have valid filename
- if(!$this->files[$handle])
- {
- if($xs_include || $quiet)
- {
- return false;
- }
- else
- {
- die("Template->make_filename(): Error - invalid template $filename");
- }
- }
- // creating cache filename
- if($can_cache)
- {
- $this->files_cache2[$handle] = $this->make_filename_cache($this->files[$handle]);
- if(@file_exists($this->files_cache2[$handle]))
- {
- $this->files_cache[$handle] = $this->files_cache2[$handle];
- }
- }
- // checking if tpl and/or php file exists
- if(empty($this->files_cache[$handle]) && !@file_exists($this->files[$handle]))
- {
- // trying to load alternative filename (usually subSilver)
- if(!empty($this->tpldef) && !empty($this->tpl) && ($this->tpldef !== $this->tpl))
- {
- $this->files[$handle] = '';
- // save old configuration
- $root = $this->root;
- $tpl_name = $this->tpl;
- // set temporary configuration
- $this->root = $this->tpldir . $this->tpldef;
- $this->tpl = $this->tpldef;
- // recursively run set_filename
- $res = $this->set_filename($handle, $filename, $xs_include, $quiet);
- // restore old configuration
- $this->root = $root;
- $this->tpl = $tpl_name;
- return $res;
- }
- if($quiet)
- {
- return false;
- }
- if($xs_include)
- {
- if($board_config['xs_warn_includes'])
- {
- die('Template->make_filename(): Error - included template file not found: ' . $filename);
- }
- return false;
- }
- else
- {
- die('Template->make_filename(): Error - template file not found: ' . $filename);
- }
- }
- // checking if we should recompile cache
- if(!empty($this->files_cache[$handle]) && !empty($board_config['xs_auto_recompile']))
- {
- $cache_time = @filemtime($this->files_cache[$handle]);
- if(@filemtime($this->files[$handle]) > $cache_time || $board_config['xs_template_time'] > $cache_time)
- {
- // file was changed. don't use cache file (will be recompled if configuration allowes it)
- $this->files_cache[$handle] = '';
- }
- }
- return true;
- }
-
- /**
- * includes file or executes code
- */
- function execute($filename, $code, $handle)
- {
- global $lang, $theme, $board_config;
- $template = $theme['template_name'];
- global $$template;
- $theme_info = &$$template;
- if($board_config['xs_add_comments'] && $handle)
- {
- echo '<!-- template ', $this->files[$handle], ' start -->';
- }
- if($filename)
- {
- include($filename);
- }
- else
- {
- eval($code);
- }
- if($board_config['xs_add_comments'] && $handle)
- {
- echo '<!-- template ', $this->files[$handle], ' end -->';
- }
- return true;
- }
-
- /**
- * Load the file for the handle, compile the file,
- * and run the compiled code. This will print out
- * the results of executing the template.
- */
- function pparse($handle)
- {
- global $board_config;
- // parsing header if there is one
- if($this->preparse || $this->postparse)
- {
- $preparse = $this->preparse;
- $postparse = $this->postparse;
- $this->preparse = $this->postparse = '';
- if($preparse)
- {
- $this->pparse($preparse);
- }
- if($postparse)
- {
- $str = $handle;
- $handle = $postparse;
- $this->pparse($str);
- }
- }
- // checking if handle exists
- if (empty($this->files[$handle]) && empty($this->files_cache[$handle]))
- {
- die("Template->loadfile(): No files found for handle $handle");
- }
- $this->xs_startup();
- $force_recompile = empty($this->uncompiled_code[$handle]) ? false : true;
- // checking if php file exists.
- if (!empty($this->files_cache[$handle]) && !$force_recompile)
- {
- // php file exists - running it instead of tpl
- $this->execute($this->files_cache[$handle], '', $handle);
- return true;
- }
- if (!$this->loadfile($handle))
- {
- die("Template->pparse(): Couldn't load template file for handle $handle");
- }
- // actually compile the template now.
- if (empty($this->compiled_code[$handle]))
- {
- // Actually compile the code now.
- if(!empty($this->files_cache2[$handle]) && empty($this->files_cache[$handle]) && !$force_recompile)
- {
- $this->compiled_code[$handle] = $this->compile2($this->uncompiled_code[$handle], $handle, $this->files_cache2[$handle]);
- }
- else
- {
- $this->compiled_code[$handle] = $this->compile2($this->uncompiled_code[$handle], '', '');
- }
- }
- // Run the compiled code.
- if (empty($this->files_cache[$handle]) || $force_recompile)
- {
- $this->execute('', $this->compiled_code[$handle], $handle);
- }
- else
- {
- $this->execute($this->files_cache[$handle], '', $handle);
- }
- return true;
- }
-
- /**
- * Precompile file
- */
- function precompile($template, $filename)
- {
- global $precompile_num, $board_config;
- if(empty($precompile_num))
- {
- $precompile_num = 0;
- }
- $precompile_num ++;
- $handle = 'precompile_' . $precompile_num;
- // save old configuration
- $root = $this->root;
- $tpl_name = $this->tpl;
- $old_config = $this->use_cache;
- $old_autosave = $this->auto_compile;
- // set temporary configuration
- $this->root = $this->tpldir . $template;
- $this->tpl = $template;
- $this->use_cache = 1;
- $this->auto_compile = 1;
- // set filename
- $res = $this->set_filename($handle, $filename, true, true);
- if(!$res || !$this->files_cache2[$handle])
- {
- $this->root = $root;
- $this->tpl = $tpl_name;
- $this->use_cache = $old_config;
- $this->auto_compile = $old_autosave;
- return false;
- }
- $this->files_cache[$handle] = '';
- // load template
- $res = $this->loadfile($handle);
- if(!$res || empty($this->uncompiled_code[$handle]))
- {
- $this->root = $root;
- $this->tpl = $tpl_name;
- $this->use_cache = $old_config;
- $this->auto_compile = $old_autosave;
- return false;
- }
- // compile the code
- $this->compile2($this->uncompiled_code[$handle], $handle, $this->files_cache2[$handle]);
- // restore confirugation
- $this->root = $root;
- $this->tpl = $tpl_name;
- $this->use_cache = $old_config;
- $this->auto_compile = $old_autosave;
- return true;
- }
-
- /**
- * Inserts the uncompiled code for $handle as the
- * value of $varname in the root-level. This can be used
- * to effectively include a template in the middle of another
- * template.
- * Note that all desired assignments to the variables in $handle should be done
- * BEFORE calling this function.
- */
- function assign_var_from_handle($varname, $handle)
- {
- ob_start();
- $res = $this->pparse($handle);
- $this->vars[$varname] = ob_get_contents();
- ob_end_clean();
- return $res;
- }
-
- /**
- * Block-level variable assignment. Adds a new block iteration with the given
- * variable assignments. Note that this should only be called once per block
- * iteration.
- */
- function assign_block_vars($blockname, $vararray)
- {
- if (strstr($blockname, '.'))
- {
- // Nested block.
- $blocks = explode('.', $blockname);
- $blockcount = sizeof($blocks) - 1;
-
- $str = &$this->_tpldata;
- for($i = 0; $i < $blockcount; $i++)
- {
- $str = &$str[$blocks[$i].'.'];
- $str = &$str[sizeof($str)-1];
- }
- // Now we add the block that we're actually assigning to.
- // We're adding a new iteration to this block with the given
- // variable assignments.
- $str[$blocks[$blockcount].'.'][] = $vararray;
- }
- else
- {
- // Top-level block.
- // Add a new iteration to this block with the variable assignments
- // we were given.
- $this->_tpldata[$blockname.'.'][] = $vararray;
- }
-
- return true;
- }
-
- /**
- * Root-level variable assignment. Adds to current assignments, overriding
- * any existing variable assignment with the same name.
- */
- function assign_vars($vararray)
- {
- foreach($vararray as $key => $val)
- {
- $this->vars[$key] = $val;
- }
- return true;
- }
-
- /**
- * Root-level variable assignment. Adds to current assignments, overriding
- * any existing variable assignment with the same name.
- */
- function assign_var($varname, $varval)
- {
- $this->vars[$varname] = $varval;
-
- return true;
- }
-
- /**
- * If not already done, load the file for the given handle and populate
- * the uncompiled_code[] hash with its code. Do not compile.
- */
- function loadfile($handle)
- {
- global $board_config;
- // If cached file exists do nothing - it will be included via include()
- if(!empty($this->files_cache[$handle]))
- {
- return true;
- }
-
- // If the file for this handle is already loaded and compiled, do nothing.
- if (!empty($this->uncompiled_code[$handle]))
- {
- return true;
- }
-
- // If we don't have a file assigned to this handle, die.
- if (empty($this->files[$handle]))
- {
- die("Template->loadfile(): No file specified for handle $handle");
- }
-
- $filename = $this->files[$handle];
-
- $str = implode('', @file($filename));
- if (empty($str))
- {
- die("Template->loadfile(): File $filename for handle $handle is empty");
- }
-
- $this->uncompiled_code[$handle] = $str;
-
- return true;
- }
-
-
-
- /**
- * Generates a reference to the given variable inside the given (possibly nested)
- * block namespace. This is a string of the form:
- * ' . $this->_tpldata['parent.'][$_parent_i]['$child1.'][$_child1_i]['$child2.'][$_child2_i]...['varname'] . '
- * It's ready to be inserted into an "echo" line in one of the templates.
- * NOTE: expects a trailing "." on the namespace.
- */
- function generate_block_varref($namespace, $varname, $use_isset = true)
- {
- // Strip the trailing period.
- $namespace = substr($namespace, 0, strlen($namespace) - 1);
-
- // Get a reference to the data block for this namespace.
- $varref = $this->generate_block_data_ref($namespace, true);
- // Prepend the necessary code to stick this in an echo line.
-
- // Append the variable reference.
- $varref .= '[\'' . $varname . '\']';
-
- if($use_isset)
- {
- $varref = '<'.'?php echo isset(' . $varref . ') ? ' . $varref . ' : \'\'; ?'.'>';
- }
- else
- {
- $varref = '<'.'?php echo ' . $varref . '; ?'.'>';
- }
-
- return $varref;
-
- }
-
-
- /**
- * Generates a reference to the array of data values for the given
- * (possibly nested) block namespace. This is a string of the form:
- * $this->_tpldata['parent.'][$_parent_i]['$child1.'][$_child1_i]['$child2.'][$_child2_i]...['$childN.']
- *
- * If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above.
- * NOTE: does not expect a trailing "." on the blockname.
- */
- function generate_block_data_ref($blockname, $include_last_iterator, $defop = false)
- {
- // Get an array of the blocks involved.
- $blocks = explode('.', $blockname);
- $blockcount = sizeof($blocks) - 1;
- if($defop)
- {
- $varref = '$this->_tpldata[\'DEFINE\']';
- // Build up the string with everything but the last child.
- for ($i = 0; $i < $blockcount; $i++)
- {
- $varref .= "['" . $blocks[$i] . ".'][\$" . $blocks[$i] . '_i]';
- }
- // Add the block reference for the last child.
- $varref .= "['" . $blocks[$blockcount] . ".']";
- // Add the iterator for the last child if requried.
- if ($include_last_iterator)
- {
- $varref .= '[$' . $blocks[$blockcount] . '_i]';
- }
- return $varref;
- }
- if($include_last_iterator)
- {
- return '$'. $blocks[$blockcount]. '_item';
- }
- else
- {
- return '$'. $blocks[$blockcount-1]. '_item[\''. $blocks[$blockcount]. '.\']';
- }
- }
-
- function compile_code($filename, $code, $use_isset = false)
- {
- // $filename - file to load code from. used if $code is empty
- // $code - tpl code
- // $use_isset - if false then compiled code looks more beautiful and easier
- // to understand and it adds error_reporting() to supress php warnings.
- // if true then isset() is used to check variables instead of supressing
- // php warnings. note: for extreme styles mod 2.x it works only for
- // block variables and for usual variables its always true.
-
- // load code from file
- if(!$code && !empty($filename))
- {
- $code = @implode('', @file($filename));
- }
-
- // Replace phpBB 2.2 <!-- (END)PHP --> tags
- $search = array('<!-- PHP -->', '<!-- ENDPHP -->');
- $replace = array('<'.'?php ', ' ?'.'>');
- $code = str_replace($search, $replace, $code);
-
- // Break it up into lines and put " -->" back.
- $code_lines = explode(' -->', $code);
- $count = count($code_lines);
- for ($i = 0; $i < ($count - 1); $i++)
- {
- $code_lines[$i] .= ' -->';
- }
-
- $block_nesting_level = 0;
- $block_names = array();
- $block_names[0] = ".";
- $block_items = array();
- $count_if = 0;
-
- // prepare array for compiled code
- $compiled = array();
- $count_bugs = count($this->bugs);
-
- // array of switches
- $sw = array();
-
- // replace all short php tags
- $new_code = array();
- $line_count = count($code_lines);
- for($i=0; $i<$line_count; $i++)
- {
- $line = $code_lines[$i];
- $pos = strpos($line, '<?');
- if($pos === false)
- {
- $new_code[] = $line;
- continue;
- }
- if(substr($line, $pos, 5) === '<?php')
- {
- // valid php tag. skip it
- $new_code[] = substr($line, 0, $pos + 5);
- $code_lines[$i] = substr($line, $pos + 5);
- $i --;
- continue;
- }
- // invalid php tag
- $new_code[] = substr($line, 0, $pos) . '<?php echo \'<?\'; ?>';
- $code_lines[$i] = substr($line, $pos + 2);
- $i --;
- }
- $code_lines = $new_code;
-
- // main loop
- $line_count = count($code_lines);
- for($i=0; $i<$line_count; $i++)
- {
- $line = $code_lines[$i];
- // reset keyword type
- $keyword_type = XS_TAG_NONE;
- // check if we have valid keyword in current line
- $pos1 = strpos($line, '<!-- ');
- if($pos1 === false)
- {
- // no keywords in this line
- $compiled[] = $this->_compile_text($line, $use_isset);
- continue;
- }
- // find end of html comment
- $pos2 = strpos($line, ' -->', $pos1);
- if($pos2 !== false)
- {
- // find end of keyword in comment
- $pos3 = strpos($line, ' ', $pos1 + 5);
- if($pos3 !== false && $pos3 <= $pos2)
- {
- $keyword = substr($line, $pos1 + 5, $pos3 - $pos1 - 5);
- // check keyword against list of supported keywords. case-sensitive
- if($keyword === 'BEGIN')
- {
- $keyword_type = XS_TAG_BEGIN;
- }
- elseif($keyword === 'END')
- {
- $keyword_type = XS_TAG_END;
- }
- elseif($keyword === 'INCLUDE')
- {
- $keyword_type = XS_TAG_INCLUDE;
- }
- elseif($keyword === 'IF')
- {
- $keyword_type = XS_TAG_IF;
- }
- elseif($keyword === 'ELSE')
- {
- $keyword_type = XS_TAG_ELSE;
- }
- elseif($keyword === 'ELSEIF')
- {
- $keyword_type = XS_TAG_ELSEIF;
- }
- elseif($keyword === 'ENDIF')
- {
- $keyword_type = XS_TAG_ENDIF;
- }
- elseif($keyword === 'DEFINE')
- {
- $keyword_type = XS_TAG_DEFINE;
- }
- elseif($keyword === 'UNDEFINE')
- {
- $keyword_type = XS_TAG_UNDEFINE;
- }
- }
- }
- if(!$keyword_type)
- {
- // not valid keyword. process the rest of line
- $compiled[] = $this->_compile_text(substr($line, 0, $pos1 + 4), $use_isset);
- $code_lines[$i] = substr($line, $pos1 + 4);
- $i --;
- continue;
- }
- // remove code before keyword
- if($pos1 > 0)
- {
- $compiled[] = $this->_compile_text(substr($line, 0, $pos1), $use_isset);
- }
- // remove keyword
- $keyword_str = substr($line, $pos1, $pos2 - $pos1 + 4);
- $params_str = $pos2 == $pos3 ? '' : substr($line, $pos3 + 1, $pos2 - $pos3 - 1);
- $code_lines[$i] = substr($line, $pos2 + 4);
- $i--;
- // Check keywords
-
- /*
- * <!-- BEGIN -->
- */
- if($keyword_type == XS_TAG_BEGIN)
- {
- $params = explode(' ', $params_str);
- $num_params = count($params);
- // get variable name
- if($num_params == 1)
- {
- $var = $params[0];
- }
- elseif($num_params == 2)
- {
- if($params[0] === '')
- {
- $var = $params[1];
- }
- elseif($params[1] === '')
- {
- $var = $params[0];
- }
- else
- {
- // invalid tag
- $compiled[] = $keyword_str;
- continue;
- }
- }
- else
- {
- // invalid tag
- $compiled[] = $keyword_str;
- continue;
- }
- // check variable for matching end
- if($this->xs_check_switches)
- {
- $found = 0;
- $str = '<!-- END ' . $var . ' -->';
- for ($j = $i+1; ($j < $line_count) && !$found; $j++)
- {
- $pos = strpos($code_lines[$j], $str);
- if($pos !== false)
- {
- $found = 1;
- $found_var = $var;
- }
- }
- if(!$found && ($this->xs_check_switches == 1))
- {
- // checking list of known buggy switches
- $item = -1;
- for($j=0; $j<$count_bugs; $j++)
- {
- if($this->bugs[$j][0] === $var)
- {
- $item = $j;
- }
- }
- if($item >= 0)
- {
- $str1 = '<!-- END ' . $this->bugs[$item][1] . ' -->';
- for ($j = $i+1; ($j < $line_count) && !$found; $j++)
- {
- $pos = strpos($code_lines[$j], $str1);
- if($pos !== false)
- {
- $found_var = $this->bugs[$item][1];
- $found = 1;
- $code_lines[$j] = str_replace($str, $str1, $code_lines[$j]);
- }
- }
- }
- }
- if(!$found)
- {
- $compiled[] = $keyword_str;
- continue;
- }
- // adding to list of switches
- if(isset($sw[$found_var]))
- {
- $sw[$found_var] ++;
- }
- else
- {
- $sw[$found_var] = 1;
- }
- }
- // adding code
- $block_nesting_level++;
- $block_names[$block_nesting_level] = $var;
- if(isset($block_items[$var]))
- {
- $block_items[$var] ++;
- }
- else
- {
- $block_items[$var] = 1;
- }
- if ($block_nesting_level < 2)
- {
- // Block is not nested.
- $line = '<'."?php\n\n";
- if($use_isset)
- {
- $line .= '$'. $var. '_count = ( isset($this->_tpldata[\''. $var. '.\']) ) ? sizeof($this->_tpldata[\''. $var. '.\']) : 0;';
- }
- else
- {
- $line .= '$'. $var. '_count = sizeof($this->_tpldata[\''. $var. '.\']);';
- }
- $line .= "\n" . 'for ($'. $var. '_i = 0; $'. $var. '_i < $'. $var. '_count; $'. $var. '_i++)';
- $line .= "\n". '{'. "\n";
- $line .= ' $'. $var. '_item = &$this->_tpldata[\''. $var. '.\'][$'. $var. '_i];'."\n";
- $line .= " \${$var}_item['S_ROW_COUNT'] = \${$var}_i;\n";
- $line .= " \${$var}_item['S_NUM_ROWS'] = \${$var}_count;\n";
- $line .= "\n?".">";
- }
- else
- {
- // This block is nested.
- // Generate a namespace string for this block.
- $namespace = implode('.', $block_names);
- // strip leading period from root level..
- $namespace = substr($namespace, 2);
- // Get a reference to the data array for this block that depends on the
- // current indices of all parent blocks.
- $varref = $this->generate_block_data_ref($namespace, false);
- // Create the for loop code to iterate over this block.
- $line = '<'."?php\n\n";
- if($use_isset)
- {
- $line .= '$'. $var. '_count = ( isset('. $varref. ') ) ? sizeof('. $varref. ') : 0;';
- }
- else
- {
- $line .= '$'. $var. '_count = sizeof('. $varref. ');';
- }
- $line .= "\n". 'for ($'. $var. '_i = 0; $'. $var. '_i < $'. $var. '_count; $'. $var. '_i++)';
- $line .= "\n". '{'. "\n";
- $line .= ' $'. $var. '_item = &'. $varref. '[$'. $var. '_i];'."\n";
- $line .= " \${$var}_item['S_ROW_COUNT'] = \${$var}_i;\n";
- $line .= " \${$var}_item['S_NUM_ROWS'] = \${$var}_count;\n";
- $line .= "\n?".">";
- }
- $compiled[] = $line;
- continue;
- }
- /*
- * <!-- END -->
- */
- if($keyword_type == XS_TAG_END)
- {
- $params = explode(' ', $params_str);
- $num_params = count($params);
- if($num_params == 1)
- {
- $var = $params[0];
- }
- elseif($num_params == 2 && $params[0] === '')
- {
- $var = $params[1];
- }
- elseif($num_params == 2 && $params[1] === '')
- {
- $var = $params[0];
- }
- else
- {
- $compiled[] = $keyword_str;
- continue;
- }
- if($this->xs_check_switches)
- {
- // checking if this switch was opened
- if(!isset($sw[$var]) || ($sw[$var] < 1))
- {
- // there is no opening switch
- $compiled[] = $keyword_str;
- continue;
- }
- $sw[$var] --;
- }
- // We have the end of a block.
- $line = '<'."?php\n\n";
- $line .= '} // END ' . $var . "\n\n";
- $line .= 'if(isset($' . $var . '_item)) { unset($' . $var . '_item); } ';
- $line .= "\n\n?".">";
- if(isset($block_items[$var]))
- {
- $block_items[$var] --;
- }
- else
- {
- $block_items[$var] = -1;
- }
- unset($block_names[$block_nesting_level]);
- $block_nesting_level--;
- $compiled[] = $line;
- continue;
- }
- /*
- * <!-- INCLUDE -->
- */
- if($keyword_type == XS_TAG_INCLUDE)
- {
- $params = explode(' ', $params_str);
- $num_params = count($params);
- if($num_params != 1)
- {
- $compiled[] = $keyword_str;
- continue;
- }
- $line = '<'.'?php ';
- $line .= ' $this->set_filename(\'xs_include' . $this->include_count . '\', \'' . $params_str .'\', true); ';
- $line .= ' $this->pparse(\'xs_include' . $this->include_count . '\'); ';
- $line .= ' ?'.'>';
- $this->include_count ++;
- $compiled[] = $line;
- continue;
- }
- /*
- * <!-- IF -->
- */
- if($keyword_type == XS_TAG_IF || $keyword_type == XS_TAG_ELSEIF)
- {
- if(!$count_if)
- {
- $keyword_type = XS_TAG_IF;
- }
- $str = $this->compile_tag_if($params_str, $keyword_type == XS_TAG_IF ? false : true);
- if($str)
- {
- $compiled[] = '<?php ' . $str . ' ?>';
- if($keyword_type == XS_TAG_IF)
- {
- $count_if ++;
- }
- }
- else
- {
- $compiled[] = $keyword_str;
- }
- continue;
- }
- /*
- * <!-- ELSE -->
- */
- if($keyword_type == XS_TAG_ELSE && $count_if > 0)
- {
- $compiled[] = '<?php } else { ?>';
- continue;
- }
- /*
- * <!-- ENDIF -->
- */
- if($keyword_type == XS_TAG_ENDIF && $count_if > 0)
- {
- $compiled[] = '<?php } ?>';
- $count_if --;
- continue;
- }
- /*
- * <!-- DEFINE -->
- */
- if($keyword_type == XS_TAG_DEFINE)
- {
- $str = $this->compile_tag_define($params_str);
- if($str)
- {
- $compiled[] = '<?php ' . $str . ' ?>';
- }
- else
- {
- $compiled[] = $keyword_str;
- }
- }
- /*
- * <!-- UNDEFINE -->
- */
- if($keyword_type == XS_TAG_UNDEFINE)
- {
- $str = $this->compile_tag_undefine($params_str);
- if($str)
- {
- $compiled[] = '<?php ' . $str . ' ?>';
- }
- else
- {
- $compiled[] = $keyword_str;
- }
- }
- }
-
- // bring it back into a single string.
- $code_header = '';
- $code_footer = '';
- if(!$use_isset)
- {
- $code_header = "<". "?php\n\$old_level = @error_reporting(E_ERROR | E_WARNING | E_PARSE); \n?".">";
- $code_footer = '<'."?php @error_reporting(\$old_level); ?".'>';
- }
-
- return $code_header . implode('', $compiled) . $code_footer;
- }
-
- /*
- * Compile code between tags
- */
- function _compile_text($code, $use_isset)
- {
- if(strlen($code) < 3)
- {
- return $code;
- }
- // change template varrefs into PHP varrefs
- // This one will handle varrefs WITH namespaces
- $varrefs = array();
- preg_match_all('#\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}#is', $code, $varrefs);
- $varcount = sizeof($varrefs[1]);
- $search = array();
- $replace = array();
- for ($i = 0; $i < $varcount; $i++)
- {
- $namespace = $varrefs[1][$i];
- $varname = $varrefs[3][$i];
- $new = $this->generate_block_varref($namespace, $varname, $use_isset);
- $search[] = $varrefs[0][$i];
- $replace[] = $new;
- }
- if(count($search) > 0)
- {
- $code = str_replace($search, $replace, $code);
- }
- // This will handle the remaining root-level varrefs
- $code = preg_replace('#\{([a-z0-9\-_]*?)\}#is', '<'.'?php echo isset($this->vars[\'\1\']) ? $this->vars[\'\1\'] : $this->lang(\'\1\'); ?'.'>', $code);
- $code = preg_replace('#\{\$([a-z0-9\-_]*?)\}#is', '<'.'?php echo isset($this->_tpldata[\'DEFINE\'][\'.\'][\'\\1\']) ? $this->_tpldata[\'DEFINE\'][\'.\'][\'\\1\'] : \'\'; ?'.'>', $code);
- return $code;
- }
-
- //
- // Compile IF tags - much of this is from Smarty with
- // some adaptions for our block level methods
- //
- function compile_tag_if($tag_args, $elseif)
- {
- /* Tokenize args for 'if' tag. */
- preg_match_all('/(?:
- "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" |
- \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' |
- [(),] |
- [^\s(),]+)/x', $tag_args, $match);
-
- $tokens = $match[0];
- $is_arg_stack = array();
-
- for ($i = 0; $i < count($tokens); $i++)
- {
- $token = &$tokens[$i];
-
- switch ($token)
- {
- case '!':
- case '%':
- case '!==':
- case '==':
- case '===':
- case '>':
- case '<':
- case '!=':
- case '<>':
- case '<<':
- case '>>':
- case '<=':
- case '>=':
- case '&&':
- case '||':
- case '|':
- case '^':
- case '&':
- case '~':
- case ')':
- case ',':
- case '+':
- case '-':
- case '*':
- case '/':
- case '@':
- break;
-
- case 'eq':
- $token = '==';
- break;
-
- case 'ne':
- case 'neq':
- $token = '!=';
- break;
-
- case 'lt':
- $token = '<';
- break;
-
- case 'le':
- case 'lte':
- $token = '<=';
- break;
-
- case 'gt':
- $token = '>';
- break;
-
- case 'ge':
- case 'gte':
- $token = '>=';
- break;
-
- case 'and':
- $token = '&&';
- break;
-
- case 'or':
- $token = '||';
- break;
-
- case 'not':
- $token = '!';
- break;
-
- case 'mod':
- $token = '%';
- break;
-
- case '(':
- array_push($is_arg_stack, $i);
- break;
-
- case 'is':
- $is_arg_start = ($tokens[$i-1] == ')') ? array_pop($is_arg_stack) : $i-1;
- $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
-
- $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
-
- array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
-
- $i = $is_arg_start;
-
- default:
- if (preg_match('#^(([a-z0-9\-_]+?\.)+?)?(\$)?([A-Z]+[A-Z0-9\-_]+)$#s', $token, $varrefs))
- {
- $token = (!empty($varrefs[1])) ? $this->generate_block_data_ref(substr($varrefs[1], 0, -1), true, $varrefs[3]) . '[\'' . $varrefs[4] . '\']' : (($varrefs[3]) ? '$this->_tpldata[\'DEFINE\'][\'.\'][\'' . $varrefs[4] . '\']' : '$this->vars[\'' . $varrefs[4] . '\']');
- }
- break;
- }
- }
-
- $code = (($elseif) ? '} elseif (' : 'if (') . (implode(' ', $tokens) . ') { ');
-
- return $code;
- }
-
- // This is from Smarty
- function _parse_is_expr($is_arg, $tokens)
- {
- $expr_end = 0;
- $negate_expr = false;
-
- if (($first_token = array_shift($tokens)) == 'not')
- {
- $negate_expr = true;
- $expr_type = array_shift($tokens);
- }
- else
- {
- $expr_type = $first_token;
- }
-
- switch ($expr_type)
- {
- case 'even':
- if (@$tokens[$expr_end] == 'by')
- {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "!(($is_arg / $expr_arg) % $expr_arg)";
- }
- else
- {
- $expr = "!($is_arg % 2)";
- }
- break;
-
- case 'odd':
- if (@$tokens[$expr_end] == 'by')
- {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "(($is_arg / $expr_arg) % $expr_arg)";
- }
- else
- {
- $expr = "($is_arg % 2)";
- }
- break;
-
- case 'div':
- if (@$tokens[$expr_end] == 'by')
- {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "!($is_arg % $expr_arg)";
- }
- break;
-
- default:
- break;
- }
-
- if ($negate_expr)
- {
- $expr = "!($expr)";
- }
-
- array_splice($tokens, 0, $expr_end, $expr);
-
- return $tokens;
- }
-
-
- function compile_tag_define($tag_args)
- {
- preg_match('#^(([a-z0-9\-_]+?\.)+?)?\$([A-Z][A-Z0-9_\-]*?) = (\'?)(.*?)(\'?)$#', $tag_args, $match);
-
- if (empty($match[3]) || empty($match[5]))
- {
- return '';
- }
-
- // Are we a string?
- if ($match[4] && $match[6])
- {
- $match[5] = "'" . addslashes(str_replace(array('\\\'', '\\\\'), array('\'', '\\'), $match[5])) . "'";
- }
- else
- {
- preg_match('#(true|false|\.)#i', $match[5], $type);
-
- switch (strtolower($type[1]))
- {
- case 'true':
- case 'false':
- $match[5] = strtoupper($match[5]);
- break;
- case '.';
- $match[5] = doubleval($match[5]);
- break;
- default:
- $match[5] = intval($match[5]);
- break;
- }
- }
-
- return (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[3] . '\']' : '$this->_tpldata[\'DEFINE\'][\'.\'][\'' . $match[3] . '\']') . ' = ' . $match[5] . ';';
- }
-
- function compile_tag_undefine($tag_args)
- {
- preg_match('#^(([a-z0-9\-_]+?\.)+?)?\$([A-Z][A-Z0-9_\-]*?)$#', $tag_args, $match);
- if (empty($match[3]))
- {
- return '';
- }
- return 'unset(' . (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[3] . '\']' : '$this->_tpldata[\'DEFINE\'][\'.\'][\'' . $match[3] . '\']') . ');';
- }
-
- /**
- * Compiles code and writes to cache if needed
- */
- function compile2($code, $handle, $cache_file)
- {
- $code = $this->compile_code('', $code, XS_USE_ISSET);
- if($cache_file && !empty($this->use_cache) && !empty($this->auto_compile))
- {
- $res = $this->write_cache($cache_file, $code);
- if($handle && $res)
- {
- $this->files_cache[$handle] = $cache_file;
- }
- }
- $code = '?'.'>'.$code.'<'."?php\n";
- return $code;
- }
-
- /**
- * Compiles the given string of code, and returns
- * the result in a string.
- * If "do_not_echo" is true, the returned code will not be directly
- * executable, but can be used as part of a variable assignment
- * for use in assign_code_from_handle().
- * This function isn't used and kept only for compatibility with original template.php
- */
- function compile($code, $do_not_echo = false, $retvar = '')
- {
- $code = ' ?'.'>' . $this->compile_code('', $code, true) . '<'."?php \n";
- if($do_not_echo)
- {
- $code = "ob_start();\n". $code. "\n\${$retvar} = ob_get_contents();\nob_end_clean();\n";
- }
- return $code;
- }
-
- /**
- * Write cache to disk
- */
- function write_cache($filename, $code)
- {
- // check if cache is writable
- if(!$this->cache_writable)
- {
- return false;
- }
- // check if filename is valid
- if(substr($filename, 0, strlen($this->cachedir)) !== $this->cachedir)
- {
- return false;
- }
- // try to open file
- $file = @fopen($filename, 'w');
- if(!$file)
- {
- // try to create directories
- $dir = substr($filename, strlen($this->cachedir), strlen($filename));
- $dirs = explode('/', $dir);
- $path = $this->cachedir;
- @umask(0);
- if(!@is_dir($path))
- {
- if(!@mkdir($path))
- {
- $this->cache_writable = 0;
- return false;
- }
- else
- {
- @chmod($path, 0777);
- }
- }
- $count = count($dirs);
- if($count > 0)
- for($i=0; $i<$count-1; $i++)
- {
- if($i>0)
- {
- $path .= '/';
- }
- $path .= $dirs[$i];
- if(!@is_dir($path))
- {
- if(!@mkdir($path))
- {
- $this->cache_writable = 0;
- return false;
- }
- else
- {
- @chmod($path, 0777);
- }
- }
- }
- // try to open file again after directories were created
- $file = @fopen($filename, 'w');
- }
- if(!$file)
- {
- $this->cache_writable = 0;
- return false;
- }
- fputs($file, "<?php\n\n// eXtreme Styles mod cache. Generated on " . date('r') . " (time=" . time() . ")\n\n?>");
- fputs($file, $code);
- fclose($file);
- @chmod($filename, 0777);
- return true;
- }
-
- function xs_startup()
- {
- global $phpEx, $board_config, $phpbb_root_path;
- if(empty($this->xs_started))
- { // adding predefined variables
- $this->xs_started = 1;
- // file extension with session ID (eg: "php?sid=123&" or "php?")
- // can be used to make custom URLs without modding phpbb
- // contains "&" or "?" at the end so you can easily append paramenters
- $php = append_sid($phpEx);
- if(strpos($php, '?'))
- {
- $php .= '&';
- }
- else
- {
- $php .= '?';
- }
- $this->vars['PHP'] = $php;
- // adding language variable (eg: "english" or "german")
- // can be used to make truly multi-lingual templates
- $this->vars['LANG'] = $board_config['default_lang'];
- // adding current template
- $tpl = $this->root . '/'; // $phpbb_root_path . 'templates/' . $this->tpl . '/';
- if(substr($tpl, 0, 2) === './')
- {
- $tpl = substr($tpl, 2, strlen($tpl));
- }
- $this->vars['TEMPLATE'] = $tpl;
- $this->vars['TEMPLATE_NAME'] = $this->tpl;
- $this->_tpldata['switch_xs_enabled.'] = array(array('version' => $this->xs_versiontxt));
- }
- }
-
- /**
- * Checks for empty variable and shows language variable if possible.
- */
- function lang($var)
- {
- global $lang;
- if(substr($var, 0, 2) === 'L_')
- {
- $var = substr($var, 2);
- // check variable as it is
- if(isset($lang[$var]))
- {
- return $lang[$var];
- }
- // check variable in lower case
- if(isset($lang[strtolower($var)]))
- {
- return $lang[strtolower($var)];
- }
- // check variable with first letter in upper case
- $str = ucfirst(strtolower($var));
- if(isset($lang[$str]))
- {
- return $lang[$str];
- }
- return ''; //str_replace('_', ' ', $var);
- }
- return '';
- }
-
- //
- //
- // Functions added for USERGROUP MOD (optimized)
- //
- //
- function append_var_from_handle_to_block($blockname, $varname, $handle)
- {
- $this->assign_var_from_handle('_tmp', $handle);
- // assign the value of the generated variable to the given varname.
- $this->append_block_vars($blockname, array($varname => $this->vars['_tmp']));
- return true;
- }
-
- function append_block_vars($blockname, $vararray)
- {
- if(strstr($blockname, '.'))
- {
- // Nested block.
- $blocks = explode('.', $blockname);
- $blockcount = sizeof($blocks) - 1;
- $str = &$this->_tpldata;
- for($i = 0; $i < $blockcount; $i++)
- {
- $str = &$str[$blocks[$i].'.'];
- $str = &$str[sizeof($str)-1];
- }
- // Now we add the block that we're actually assigning to.
- // We're adding a new iteration to this block with the given
- // variable assignments.
- $str = &$str[$blocks[$blockcount].'.'];
- $count = sizeof($str) - 1;
- if($count >= 0)
- {
- // adding only if there is at least one item
- $str[$count] = array_merge($str[$count], $vararray);
- }
- }
- else
- {
- // Top-level block.
- // Add a new iteration to this block with the variable assignments
- // we were given.
- $str = &$this->_tpldata[$blockname.'.'];
- $count = sizeof($str) - 1;
- if($count >= 0)
- {
- // adding only if there is at least one item
- $str[$count] = array_merge($str[$count], $vararray);
- }
- }
- return true;
- }
-
- /*
- * Flush a root level block, so it becomes empty.
- */
- function flush_block_vars($blockname)
- {
- // Top-level block.
- // flush a existing block we were given.
- $current_iteration = sizeof($this->_tpldata[$blockname . '.']) - 1;
- unset($this->_tpldata[$blockname . '.']);
- return true;
- }
-}
-
-function xs_switch($tpl, $name)
-{
- return (isset($tpl->_tpldata[$name.'.']) && count($tpl->_tpldata[$name.'.']) > 0);
-}
-
-?>
\ No newline at end of file