* Invision Power Services * IP.Board v3.1.4 * Template Parser : Converts HTML "logic" into PHP code * Last Updated: $Date: 2010-10-12 18:11:26 -0400 (Tue, 12 Oct 2010) $ * * * @author $Author: bfarber $ * @copyright (c) 2001 - 2009 Invision Power Services, Inc. * @license http://www.invisionpower.com/community/board/license.html * @package IP.Board * @subpackage Kernel * @link http://www.invisionpower.com * @since Wednesday 23rd February 2005 13:53 * @version $Revision: 476 $ * * @todo [Future] Explore converting this to an XSLT parser (ala Digi) */ define( 'IPS_TEMPLATE_DEBUG' , 0 ); define( 'IPS_TEMPLATE_DEBUG_FILE', dirname( __FILE__ ) . '/../cache/template_debug.cgi' ); /** * INTERFACE: Template plugins * @author Matt Mecham * @since IPB 3.0.0 */ interface interfaceTemplatePlugins { /** * Return information about this modifier * * It MUST contain an array of available options in 'options'. If there are no allowed options, then use an empty array. * Failure to keep this up to date will most likely break your template tag. * @return array */ public function getPluginInfo(); /** * Actually run the modifiers * * @param mixed Data to pass to plugin * @param mixed Options to pass to plugin */ public function runPlugin( $data, $options ); } class classTemplate { /** * Root path * * @access public * @var string Root path */ public $root_path = './'; /** * Skin cache files directory * * @access public * @var string Directory name to put skin cache files in */ public $cache_dir = 'skin_cache'; /** * Current ID of skinset * * @access public * @var integer Skin set id */ public $cache_id = 1; /** * Skin set id in database * * @access public * @var integer Skin set id */ public $database_id = 1; /** * Cache path * * @access public * @var string Cache path for skin sets */ public $IPS_CACHE_PATH = ''; /** * Foreach function blocks * Holds the foreach code * * @access private * @var array Holds foreach blocks */ private $foreach_blocks = array(); /** * Allow PHP code to execute * * @access public * @var boolean Execute php code */ public $allow_php_code = true; /** * Modifiers path * * @access private * @var string Path to modifiers directory */ static private $template_plugins_class_path; /** * Modifiers clases * * @access private * @var array Array of modifier classes */ static private $template_plugin_classes = array(); private $_skinGroup = ''; /** * Escaped double quote replacement * Part of a hackish fix to retain manual escpaes in PHP code blocks * but not elsewhere in the code * * @access private * @var string */ private $_dqReplacement = '{{^|^escapedDQ^|^}}'; /** * Constructor * * @access public * @param string Path to template plugins directory * @return boolean Construction successful */ public function __construct( $template_plugins_class_path='' ) { self::$template_plugins_class_path = $template_plugins_class_path; $this->IPS_CACHE_PATH = $this->root_path . $this->cache_dir . '/cacheid_' . $this->cache_id; return true; } public function setWorkingGroup( $group ) { $this->_skinGroup = $group; } /** * convert_cache_to_eval * * Takes raw PHP data (from a MASTER cache class) and formats it ready * for eval'ing in the scripts. * * @access public * @param string The actual contents of the class, php tags 'an all. * @param string Full class name * @param integer ID to use * @return string Ready to eval PHP code */ public function convertCacheToEval($data='', $full_class_name='', $id=1) { //----------------------------------------- // INIT //----------------------------------------- $this->_skinGroup = preg_replace( '#^(.*)_\d+?$#', "\\1", $full_class_name ); $final_content = $this->_returnFunctionData( $data ); //----------------------------------------- // Function Hooks //------------------------------------------ $funcHooks = '$this->_funcHooks = array();' . "\n"; if( is_array( $this->_hookIds[ $this->_skinGroup ] ) ) { foreach( $this->_hookIds[ $this->_skinGroup ] as $func_name => $hookIds ) { if( is_array( $hookIds ) && count( $hookIds ) ) { $funcHooks .= "\$this->_funcHooks['{$func_name}'] = array(".implode( ',', $hookIds ).");\n"; } } } //----------------------------------------- // Return the stuff... //----------------------------------------- $out = "class {$full_class_name} {\n\n"; $out .= <<registry = \$registry; \$this->DB = \$this->registry->DB(); \$this->settings =& \$this->registry->fetchSettings(); \$this->request =& \$this->registry->fetchRequest(); \$this->lang = \$this->registry->getClass('class_localization'); \$this->member = \$this->registry->member(); \$this->memberData =& \$this->registry->member()->fetchMemberData(); \$this->cache = \$this->registry->cache(); \$this->caches =& \$this->registry->cache()->fetchCaches(); {$funcHooks} } EOF; $out .= $final_content; $out .= "\n\n}"; return $out; } /** * _returnFunctionData * * Extracts function data * * @access private * @param string The actual contents of the class, php tags 'an all. * @param array Functions to find * @return string Converted content */ private function _returnFunctionData( $data='', $function_find=array() ) { //----------------------------------------- // INIT //----------------------------------------- $final_content = ''; //----------------------------------------- // Remove PHP tags //----------------------------------------- $data = preg_replace( "#<".'\?php\n+?(.*)\n+?\?>#is', "\\1", $data ); //----------------------------------------- // Pick through and get all function names //----------------------------------------- $data = str_replace( "\r" , "\n", $data ); $data = str_replace( "\n\n", "\n", $data ); //----------------------------------------- // Continue... //----------------------------------------- $farray = explode( "\n", $data ); //----------------------------------------- // Functions... //----------------------------------------- $functions = array(); $script_token = 0; $flag = 0; foreach( $farray as $f ) { //----------------------------------------- // Skip javascript functions... //----------------------------------------- if ( preg_match( "/