Вход Регистрация
Файл: IPBMafia.ru_IPB_3.4.6_Final_Rus _Nulled/board/upload/ips_kernel/classTemplateEngine.php
Строк: 1246
<?php

/**
 * <pre>
 * Invision Power Services
 * IP.Board v3.4.6
 * Template Parser : Converts HTML "logic" into PHP code
 * Last Updated: $Date: 2012-10-18 10:27:08 -0400 (Thu, 18 Oct 2012) $
 * </pre>
 *
 * @author         $Author: bfarber $
 * @copyright    (c) 2001 - 2009 Invision Power Services, Inc.
 * @license        http://www.invisionpower.com/company/standards.php#license
 * @package        IP.Board
 * @subpackage    Kernel
 * @link        http://www.invisionpower.com
 * @since        Wednesday 23rd February 2005 13:53
 * @version        $Revision: 11481 $
 * 
 */

define'IPS_TEMPLATE_DEBUG'     );
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   @e array
    */
    
public function getPluginInfo();
    
    
/**
    * Actually run the modifiers and return the code to insert into the template
    *
    * @param    mixed         Data to pass to plugin
    * @param    mixed        Options to pass to plugin
    * @return    @e string
    */
    
public function runPlugin$data$options );
}
 
class 
classTemplate
{
    
/**
     * Root path
     *
     * @var        string
     */
    
public $root_path        './';
    
    
/**
     * Skin cache files directory
     *
     * @var        string
     */
    
public $cache_dir        'skin_cache';
    
    
/**
     * Current ID of skinset
     *
     * @var        integer
     */
    
public $cache_id        1;
    
    
/**
     * Skin set id in database
     *
     * @var        integer
     */
    
public $database_id        1;
    
    
/**
     * Cache path
     *
     * @var        string
     */
    
public $IPS_CACHE_PATH  '';
    
    
/**
     * Foreach function blocks
     * Holds the foreach code
     *
     * @var      array
     */
    
protected $foreach_blocks = array();
    
    
/**
     * Allow PHP code to execute
     *
     * @var      boolean
     */
    
public $allow_php_code    true;
    
    
/**
     * Modifiers path
     *
     * @var      string
     */
    
static protected $template_plugins_class_path;
    
    
/**
     * Modifiers clases
     *
     * @var      array
     */
    
static protected $template_plugin_classes = array();
    
    
/**
     * Current skin group
     *
     * @var      array
     */
    
protected $_skinGroup '';
    
    
/**
     * Escaped double quote replacement
     * Part of a hackish fix to retain manual escpaes in PHP code blocks
     * but not elsewhere in the code
     *
     * @var        string
     */
    
protected $_dqReplacement '{{^|^escapedDQ^|^}}';
    
    
/**
     * Constructor
     *
     * @param    string        Path to template plugins directory
     * @return    @e boolean
     */
    
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;
    }
    
    
/**
     * Set current skin group
     *
     * @param    string        Skin group name
     * @return    @e void
     */
    
public function setWorkingGroup$group )
    {
        
$this->_skinGroup $group;
    } 

    
/**
     * Takes raw PHP data (from a MASTER cache class) and formats it ready
     * for eval'ing in the scripts.
     *
     * @param    string        The actual contents of the class, php tags 'an all.
     * @param    string        Full class name
     * @param    integer        ID to use
     * @return    @e string
     */
    
public function convertCacheToEval$data=''$full_class_name=''$id=)
    {
        
//-----------------------------------------
        // 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} extends skinMaster {nn";
        
$out .=
<<<EOF
/**
* Construct
*/
function __construct( ipsRegistry 
$registry )
{
    parent::__construct( 
$registry );
    
    
{$funcHooks}
}

EOF;
        
$out .= $final_content;
        
$out .= "nn}";

        return 
$out;
    }
    
    
/**
     * Extracts function data
     *
     * @param    string        The actual contents of the class, php tags 'an all.
     * @param    array         Functions to find
     * @return    @e string
     */
    
protected function _returnFunctionData$data=''$function_find=array() )
    {
        
//-----------------------------------------
        // INIT
        //-----------------------------------------
        
        
$final_content '';
        
        
//-----------------------------------------
        // Remove PHP tags
        //-----------------------------------------

        
$data preg_replace"#<".'?phpn+?(.*)n+?(?>|$)#is'"\1"$data );

        
//-----------------------------------------
        // Pick through and get all function names
        //-----------------------------------------
        
        
$data str_replace"r"  "n"$data );
        
$data str_replace"nn""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"/<script/i"$f ) )
            {
                
$script_token 1;
            }
            
            if ( 
preg_match'/</script>/i'$f ) )
            {
                
$script_token 0;
            }
            
            
//-----------------------------------------
            // NOT IN JS
            //-----------------------------------------
            
            
if ( $script_token == )
            {
                if ( 
preg_match'/^functions*([w_]+)s*((.*))/i'$f$matches ) )
                {
                    
$functions$matches[1] ] = '';
                    
$config$matches[1] ]    = $matches[2];
                    
$flag                     $matches[1];
                    continue;
                }
            }
            
            if ( 
$flag )
            {
                
$functions$flag ] .= $f."n";
                continue;
            }
        }
    

        
//-----------------------------------------
        // Build the file...
        //-----------------------------------------
        
        
foreach( $functions as $fname => $ftext )
        {
            if ( 
is_array$function_find ) AND count$function_find ) )
            {
                if ( ! 
in_array$fname$function_find ) )
                {
                    continue;
                }
            }
            
            
$func_data trim$config[$fname] );
            
            
# IPB 3.0 Addition:
            # Preserve magic methods
            
if ( preg_match"#^__(.*)$#"$fname ) )
            {
                
$final_content .= "function {$fname}({$func_data})n" .  $ftext;
            }
            else
            {
                
preg_match"/".'$'.'IPBHTMLs+?.?=s+?<<<EOF(.+?)EOF;s?/si'$ftext$matches );
                
                
$final_content .= $this->convertHtmlToPhp$fname$func_data, isset( $matches[1] ) ? $matches[1] : '' );
            }
        }
        
        
//-----------------------------------------
        // Return...
        //-----------------------------------------
        
        
return $final_content;
    }
    
    
/**
     * Converts HTML logic to PHP code
     *
     * @param    string        Function name
     * @param    string         Function parameters
     * @param    string         Function HTML content
     * @param    string         Function description
     * @param    boolean        Trigger skin update
     * @param    boolean     Compile into php code
     * @return    @e string
     */
    
public function convertHtmlToPhp$func_name$func_data$func_html$func_desc=""$com_bit_update_trigger=''$compile=)
    {
        
//-------------------------------
        // INIT
        //-------------------------------
        
        
$this->foreach_blocks = array();
        
        
//-----------------------------------------
        // Debug?
        //-----------------------------------------
        
        
$this->_addDebug"Preparing to convert: $func_name"n" $func_html );
        
        
/* Slashes in JS are problematic */
        
$func_html $this->_preMakeJsSlashesSafe$func_html );
        
        
//-------------------------------
        // Make sure we have ="" on each
        // func data
        //-------------------------------
        
        
$func_html str_replace'\\"'$this->_dqReplacement$func_html );

        
// or not...Bug 8570
        //$func_data = preg_replace( "#".'$'."(w+)(,|$)#i", "$\1=""\2", str_replace( " ", "", $func_data ) );
        
        
if ( $compile )
        {
            
$_func_code '"' $this->compileHtmlToPhptrim$func_html ), $func_data$func_name ) . '"';
        }
        else
        {
            
$_func_code "<<<EOFn" $this->unconvertTags$func_html ) . "nEOF";
        }
        
        
//-----------------------------------------
        // Plug in tags
        //-----------------------------------------
        
        
$_func_code $this->_processPluginTags$_func_code );
        
        
//-----------------------------------------
        // Fix up {IPSText::xxxxx}
        //-----------------------------------------
        
        
$_func_code preg_replace'#{IPS(Member|Lib|Text)::([^}]+?)}#''" . ' "IPS\1::\2"      ' . "'$_func_code );
        
$_func_code preg_replace'#{\$this->(settings|request)->([^}]+?)}#'     '" . ' "$this->\1->\2" ' . "'$_func_code );
        
        
//-----------------------------------------
        // Clear up manual escapes not in PHP blocks
        // Step One
        //-----------------------------------------
        
        
$_func_code preg_replace'#\{1,}"#s''\"'$_func_code );
        
        
//-----------------------------------------
        // Continue...
        //-----------------------------------------
        
        /*$top    = "//===========================================================================n".
                  "// <ips:{$func_name}:desc:{$func_desc}:trigger:{$com_bit_update_trigger}>n".
                  "//===========================================================================n";*/
        
$top "/* -- {$func_name} --*/n";
        
$start  "function {$func_name}($func_data) {n$IPBHTML = "";n";
        
$middle '$IPBHTML .= '.$_func_code.';';
                
        
$end    "nreturn $IPBHTML;n}n";

        
//-------------------------------
        // Add foreach blocks...
        //-------------------------------
        
        
if ( count$this->foreach_blocks ) )
        {
            
$end .= "nn" implode"nn"$this->foreach_blocks ) . "n";
            
            
//-----------------------------------------
            // Plug in tags
            //-----------------------------------------

            
$end $this->_processPluginTags$end );
            
            
/* #todo: we don't use any IPSData or IPSActiveMember that I can remember of. We can remove it I think? */
            
$end preg_replace'#{IPS(Member|Lib|Text)::([^}]+?)}#''" . ' "IPS\1::\2"      ' . "'$end );
            
$end preg_replace'#{\$this->(settings|request)->([^}]+?)}#'     '" . ' "$this->\1->\2" ' . "'$end );
            
            
//----------------------------------------
            // Check embedded foreach blocks
            //----------------------------------------
            
            
if ( strstr$end"<xxforeach" ) )
            {
                
$end preg_replace"#[nr]{0,}<xxforeach_([^>]+?)xx>(.+?)</xxforeach_\1xx>[nr]{0,}#si""".\2.""$end );
            }
            
            
//-----------------------------------------
            // Remove raw PHP tags
            //-----------------------------------------

            
$end preg_replace"#([nr]{0,})?<php>(.+?)</php>([nr]{0,})?#si"""$end );
        }
        
        
//-----------------------------------------
        // Sort out the rest of the PHP tags
        //-----------------------------------------
        
        
$php_tags   $this->_processPhpTags$_func_code );
        
        
//-----------------------------------------
        // Clear up manual escapes not in PHP blocks
        // Step Two
        //-----------------------------------------

        
$middle str_replace$this->_dqReplacement'\"'$middle );
        
        
//-----------------------------------------
        // Remove raw PHP tags
        //-----------------------------------------
        
        
$middle preg_replace"#([nr]{0,})?<php>(.+?)</php>([nr]{0,})?#si"""$middle );
        
        
//-----------------------------------------
        // Empty if statements lead to a lot of newlines in the source
        // Try to clean em up a little
        //-----------------------------------------

        
$middle $this->_trimEmptyIfs$middle );
        
        
/* Slashes in JS are problematic (part 2) */
        
$middle $this->_postMakeJsSlashesSafe$middle );
        
        
//-----------------------------------------
        // Figure out if we're saving hook data
        //-----------------------------------------

        
$functionArguments    explode','$func_data );

        
$_funcDataNames = array();
        
        if( 
is_array$functionArguments ) )
        {
            foreach( 
$functionArguments as $r )
            {
                if( 
trim($r) )
                {
                    
/* Clean */
                    
$r str_replace'$'''trim($r) );
                    
                    if( 
strpos$r'=' ) )
                    {
                        
$r    trimsubstr$r0strpos$r'=' ) ) );
                    }
                    
                    
/* Try to fix fatal errors caused by type-hinting */
                    
if( strpos$r' ' ) )
                    {
                        
$r    trimsubstr$rstrpos$r' ' ) ) );
                    }
                    
                    
$_funcDataNames[] = trim$r );
                }
            }
        }
        
        
$hookPHP '';
        
        if( isset(
$this->_hookIds$this->_skinGroup ][ $func_name ]) AND is_array$this->_hookIds$this->_skinGroup ][ $func_name ] ) )
        {
            
$__count '$count_'md5$func_name str_replace'.''_'uniqidmt_rand(), TRUE ) ) );
            
            
$hookPHP = <<<EOF
if( IPSLib::locationHasHooks( '{$this->_skinGroup}', $this->_funcHooks['{$func_name}'] ) )
{
{$__count} = is_array($this->functionData['{$func_name}']) ? count($this->functionData['{$func_name}']) : 0;n
EOF;
            foreach( 
$_funcDataNames as $k => $v )
            {
                
$hookPHP .= "$this->functionData['{$func_name}'][{$__count}]['{$v}'] = ${$v};n";
            }
    
$hookPHP .= <<<EOF
}n
EOF;
        }

        
//-----------------------------------------
        // Debug?
        //-----------------------------------------
        
        
$this->_addDebug"FINISHED: $func_name"n" $top.$start.$php_tags.$middle.$end );
        
        
//-------------------------------
        // Return
        //-------------------------------

        
return $top.$start.$hookPHP.$php_tags.$middle.$end;
    }
    
    
    
/**
     * Compiles ready to cache PHP code
     *
     * @param    string        Content
     * @param    string         Normal function parameters
     * @param    string        Function name
     * @return    @e string
     */
    
public function compileHtmlToPhp$text$normal_func_data=''$func_name='' )
    {
        
//----------------------------------------
        // INIT
        //----------------------------------------
        
        
$do_foreach 0;
        
$do_if      0;
        
        
//----------------------------------------
        // First pass...
        //----------------------------------------
        
        
if ( strstr$text"<foreach loop=" ) )
        {
            
$do_foreach 1;
        }
        
        
//----------------------------------------
        // Second pass...
        //----------------------------------------
        
        
if ( strstr$text"<if test=" ) )
        {
            
$do_if 1;
        }
        
        
//----------------------------------------
        // Add slashes if required
        //----------------------------------------
        
        
if ( $do_if OR $do_foreach )
        {
            
$text addslashes$text );
        }
        else
        {
            return 
str_replace'"''\"'$text );
        }
        
        
//----------------------------------------
        // HTML FOREACH logic...
        //----------------------------------------
            
        
if ( $do_foreach )
        {
            
$text $this->_processForeachLogic$text$normal_func_data$func_name );
        }
        
        
//----------------------------------------
        // HTML IF/ELSE logic...
        //----------------------------------------
            
        
if ( $do_if )
        {
            
$text $this->_processHtmlLogic$text$func_name );
        }
        
        
//----------------------------------------
        // Last pass...
        //----------------------------------------
        
        
if ( $do_foreach )
        {
            if ( 
strstr$text"<xxforeach" ) )
            {
                
$text preg_replace"#[nr]{0,}<xxforeach_([^>]+?)xx>(.+?)</xxforeach_\1xx>[nr]{0,}#si""".\2.""$text );
            }
        }
        
        
//----------------------------------------
        // Make code OK
        //----------------------------------------
        
        
if ( $do_if OR $do_foreach )
        {
            
$text str_replace('\\$''\$'$text);
        }

        return 
$text;
    }
    
    
/**
     * Process the HTML logic 'foreach' tags
     *
     * @param    string        Content
     * @param    string         Normal function parameters
     * @param    string        Function name
     * @return    @e string
     */
    
protected function _processForeachLogic$text$normal_func_data=''$func_name='' )
    {
        
//----------------------------------------
        // INIT
        //----------------------------------------
        
        
$total_length strlen$text );
        
$template     $text;
        
$statement    "";
        
$arg_true     "";
        
$arg_false    "";
        
        
# Tag specifics
        
$tag_foreach       '<foreach loop=';
        
$found_foreach     = -1;
        
$tag_end_foreach   '</foreach>';
        
$found_end_foreach = -1;
        
        
$allow_delim  = array( '"'''' );
        
        $_tmp_func_data    = explode( ",", $normal_func_data );
        $_final            = array();
        $clean_func_data   = '';
        
        //----------------------------------------
        // Get function arguments
        //----------------------------------------
        
        foreach( $_tmp_func_data as $_i )
        {
            preg_match( "#".'
$'.'(w+)s*(=|,|$)#i', $_i, $match );
            
            
if( count($match) )
            {
                
$_final[] = '$'.$match[1];
            }
        }

        
$clean_func_data implode","$_final );

        
//----------------------------------------
        // Keep the server busy for a while
        //----------------------------------------
        
        
while ( == )
        {
            
$_end 0;
            
            
//----------------------------------------
            // Look for opening <if tag...
            //----------------------------------------
            
            
$found_foreach strpos$template$tag_foreach$found_end_foreach );
            
            
//----------------------------------------
            // No logic found? 
            //----------------------------------------
            
            
if ( $found_foreach === FALSE )
            {
                break;
            }
            
            
//----------------------------------------
            // Beginning of the logic...
            //----------------------------------------
            
            
$_start $found_foreach strlen($tag_foreach) + 2;
            
            
$delim  $template$_start ];
            
            
//----------------------------------------
            // Make sure we have statement wrapped in
            // either ' or "
            //----------------------------------------
            
            
if ( ! in_array$delim$allow_delim ) )
            {
                
$found_end_foreach $found_foreach 1;
                continue;
            }
            
            
//----------------------------------------
            // End statement?
            //----------------------------------------
            
            
$found_end_foreach strpos($template$tag_end_foreach$_end 3);
            
            
//----------------------------------------
            // No end statement found
            //----------------------------------------
            
            
if ( $found_end_foreach === FALSE )
            { 
                return 
str_replace("\'"''', $template);
            }
            
            //----------------------------------------
            // Find end of statement
            //----------------------------------------
            
            for ( $i = $_start; $i < $total_length; $i++ )
            {
                if ( $template[ $i ] == $delim AND $template[$i - 2] != '
\' AND $template[$i + 1] == '>' )
                {
                    //----------------------------------------
                    // Unescaped end delimiter
                    //----------------------------------------
                    
                    $_end = $i - 1;
                    break;
                }
            }
            
            //----------------------------------------
            // No end statement found
            //----------------------------------------
            
            if ( ! $_end )
            {
                return str_replace("\'", '''
$template);
            }
            
            
//----------------------------------------
            // Get statement
            //----------------------------------------
            
            
$statement $this->unconvertTagssubstr$template$_start$_end $_start ) );
            
            
//----------------------------------------
            // Not got?
            //----------------------------------------
            
            
if ( empty($statement) )
            {
                
$found_end_foreach $found_foreach 1;
                continue;
            }
            
            
//----------------------------------------
            // No closing > on logic?
            //----------------------------------------
    
            
if ( $template[$_end 2] != '>' )
            {
                
$found_end_foreach $found_foreach 1;
                continue;
            }
    
            
//----------------------------------------
            // Check recurse
            //----------------------------------------
            
            
$if_found_recurse $found_foreach;
            
$__i_count        0;
            
            while ( 
== )
            {
                
//----------------------------------------
                // Got an IF?
                //----------------------------------------
                
                
$if_found_recurse strpos$template$tag_foreach$if_found_recurse );
                
                
//----------------------------------------
                // None found...
                //----------------------------------------
                
                
if ( $if_found_recurse === FALSE OR $if_found_recurse >= $found_end_foreach )
                {
                    break;
                }
                
                
$if_end_recurse      $found_end_foreach;
                
$found_end_foreach   strpos$template$tag_end_foreach$if_end_recurse );
                
                
//----------------------------------------
                // None found...
                //----------------------------------------
                
                
if ( $found_end_foreach === FALSE )
                {
                    return 
str_replace("\'""'"$template);
                }
            }
            
            
            
$rlen   $found_end_foreach strlen($tag_end_foreach) + $_end 1;
            
$block  substr($template$_end 3$rlen 5);
            
            
//----------------------------------------
            // Recurse
            //----------------------------------------
            
            
if ( strpos$block$tag_foreach ) !== FALSE )
            {
                
//----------------------------------------
                // Add in any extra new vars...
                //----------------------------------------
                
                
$_normal_func_data $normal_func_data;
                
                if ( 
strstrstrtolower($statement), 'as' ) )
                {
                    
# Get the last part of the argument
                    
list( $_trash$keep ) = explode' as'$statement );
                    
$keep trim($keep);
                    
                    if ( 
strstr$keep'=>' ) )
                    {
                        list( 
$one$two ) = explode'=>'$keep );
                        
$one trim$one );
                        
$two trim$two );
                        
                        
$_normal_func_data .= ",{$one}='',{$two}=''";
                    }
                    else
                    {
                        
$_normal_func_data .= ",{$keep}=''";
                    }
                }
                    
                
$block $this->_processForeachLogic($blocktrim($_normal_func_data','), $func_name);
            }
            
            
//----------------------------------------
            // Clean up...
            //----------------------------------------
            
            
$str_find    = array('\"''\\');
            
$str_replace = array('"'  '\'  );
            
            $str_find[]    = "\'";
            $str_replace[] = "'";
            
            
$str_find[]    = '\$delim';
            
$str_replace[] =  $delim;
            
            //----------------------------------------
            // ...statement
            //----------------------------------------
            
            
$statement = str_replace($str_find$str_replace$statement);
            
$block     = str_replace($str_find$str_replace$block);
            
            //----------------------------------------
            // Create PHP statement
            //----------------------------------------
            
$__i_count++;
            
            
$function_name = '__f__'. md5( $__i_count . str_replace( '.', '_', uniqid( mt_rand(), TRUE ) ) );            
            
$php_statement = '<xxforeach_'.$function_name.'xx>$this->'.$function_name.'('.$clean_func_data.')</xxforeach_'.$function_name.'xx>';
            
$php_block     = $this->_processHtmlLogic( addslashes($block), $func_name );

            //-----------------------------------------
            // PHP tags?
            //-----------------------------------------
            
            
$php_block = $this->_processPluginTags$php_block );
            
            
$php_tags  = $this->_processPhpTags$php_block );
            
            /* Got a prefix? */
            
$pre_foreach_hook  = '';
            
$post_foreach_hook = '';
            
            if ( strstr( 
$statement, ':' ) )
            {
                list( 
$prefix$statement ) = explode( ':', $statement );
                
$prefix    = trim( $prefix );
                
$statement = trim( $statement );
                                
                
$pre_foreach_hook  = "<!--hook.foreach.{$this->_skinGroup}.{$func_name}.{$prefix}.outer.pre-->";
                
$post_foreach_hook = "<!--hook.foreach.{$this->_skinGroup}.{$func_name}.{$prefix}.outer.post-->";
                
                
$php_block = "<!--hook.foreach.{$this->_skinGroup}.{$func_name}.{$prefix}.inner.pre-->" .
                             
$php_block .
                             "
<!--hook.foreach.{$this->_skinGroup}.{$func_name}.{$prefix}.inner.post-->";
                
                
$this->_hookIds$this->_skinGroup ][ $func_name ][] = "'{$prefix}'";
            }
            
            /* Store foreach data */
        //    
$_tmp    = explode( 'as', $statement );
        //    
$_saveV    = trim( $_tmp[0] );
            
            
$this->foreach_blocks[] = <<<EOF
function 
{$function_name}($normal_func_data)
{
    
$_ips___x_retval = '{$pre_foreach_hook}';
    
$__iteratorCount = 0;
    foreach( 
$statement )
    {
        
{$php_tags}
        
$__iteratorCount++;
        
$_ips___x_retval .= "{$php_block}n";
    }
    
$_ips___x_retval .= '{$post_foreach_hook}';
    unset( 
$__iteratorCount );
    return 
$_ips___x_retval;
}
EOF;
            
$template     = substr_replace( $template$php_statement$found_foreach$found_end_foreach + strlen($tag_end_foreach) - $found_foreach);
            
            /* Reset total length */
            
$total_length = strlen( $template );
            
            
$found_end_foreach = $found_foreach + strlen($php_statement) - 1;
        }
        
        return str_replace("
\'", "'", $template);
    }
    
    /**
     * Process the HTML logic 'php' tags
     *
     * @param    string        Content
     * @return    @e string
     */
    protected function _processPhpTags( 
$text )
    {
        //-----------------------------------------
        // INIT
        //-----------------------------------------
        
        
$php = "";
        
        //-----------------------------------------
        // EXTRACT!
        //-----------------------------------------
        
        preg_match_all( "
#<php>(.+?)</php>#si", $text, $match );
        
        
for ( $i 0$i count($match[0]); $i++ )
        {
            
$php_code     trim$match[1][$i] );
            
$complete_tag $match[0][$i];
            
            
$str_find    = array('\"''\\');
            
$str_replace = array('"'  '\'  );
            
            $str_find[]    = "\'";
            $str_replace[] = "'";
            
            /* allow manual escapes */
            
$str_find[]    = $this->_dqReplacement;
            
$str_replace[] = '\"';
            
            
$php_code = str_replace($str_find$str_replace$php_code);
            
            
$php .= "n".$php_code."n";
        }
        
        return 
$php;
    }
    
    /**
     * Process the template modifier tags
     * Convert {parse ...} tags
     *
     * @param    string        Content
     * @return    @e string
     */
    protected function _processPluginTags( 
$text )
    {
        
$text = IPSText::replaceRecursively( $text, '{parse', '"}', array( 'classTemplate', '_processPluginTagsCallback' ) );
        //print "nn========nn".$text."nn========nn";
        return $text;
    }
    
    /**
     * Call back from the replaceRecursively function
     *
     * @param    string        Matched text string
     * @param    string        Opening delimiter
     * @param    string        Closing delimiter
     * @return    @e string
     */
    static public function _processPluginTagsCallback( $text, $textOpen, $textClose )
    {
        //-----------------------------------------
        // Ok, extract options
        //-----------------------------------------
        
        $raw_tag      = trim( $text ) . '"';
        
$complete_tag = $textOpen . $text . $textClose;
        
$options      = array();
        
$return       = '';    
        
        
$str_find     = array('\"', '\\', "\'");
        $str_replace  = array('"'  , '\'  , "'"  );
        
        $raw_tag       = str_replace($str_find, $str_replace, $raw_tag);
        $_lowestKeyPos = strlen( $raw_tag );
        
        $_plugin = substr( $raw_tag, 0, strpos( $raw_tag, '
=' ) );
        
        if ( ! isset( self::$template_plugin_classes[ $_plugin ] ) || ! is_object( self::$template_plugin_classes[ $_plugin ] ) )
        {
            $filepath  = self::$template_plugins_class_path . '
/tp_' . $_plugin . '.php';
            
            if ( is_file( $filepath ) )
            {  
                $classname = IPSLib::loadLibrary( $filepath, '
tp_' . $_plugin );
                
                if ( class_exists( $classname ) )
                {
                    $_class = new ReflectionClass( $classname );

                    if ( $_class->implementsInterface( '
interfaceTemplatePlugins' ) )
                    {
                        self::$template_plugin_classes[ $_plugin ] = $_class->newInstance( ipsRegistry::instance() );
                    }
                    else
                    {
                        throw new Exception("$classname does not implement the correct interface");
                    }
                }
            }
        }
        
        //-----------------------------------------
        // Not got a class? Then return
        //-----------------------------------------
        
        if ( ! is_object( self::$template_plugin_classes[ $_plugin ] ) )
        {
            return $text;
        }
        
        //-----------------------------------------
        // Get the allowed options
        //-----------------------------------------
        
        $_info          = self::$template_plugin_classes[ $_plugin ]->getPluginInfo();
        $allowedOptions = $_info['
options'];
        
        //-----------------------------------------
        // Got any further parsing to do?
        //-----------------------------------------
        
        if ( ! is_array( $allowedOptions ) OR ! count( $allowedOptions ) )
        {
            # Data is what'
s between the first quote and the last
            $_first   
strpos$raw_tag'"' ) + 1;
            
$mainData substr$raw_tag$_first strrpos$raw_tag'"' ) - $_first );
        }
        else
        {
            foreach( 
$allowedOptions as $key )
            {
                if ( 
stristr$raw_tag' ' $key '=' ) )
                {
                    
# Get the position of this key
                    
$_keyPos strpos$raw_tag' ' $key '=' ) + 1;
                    
                    
# Is this the lowest?
                    
if ( $_keyPos $_lowestKeyPos )
                    {
                        
$_lowestKeyPos $_keyPos;
                    }
                    
                    
# Get character position of the quote (+1) of this key.
                    # We use + 2 to get past the =" part of the string
                    
$_firstQuote     $_keyPos strlen$key ) + 2;
                    
$_lastQuote      strpos$raw_tag'"'$_firstQuote );
                    
$options$key ] = substr$raw_tag$_firstQuote$_lastQuote $_firstQuote );
                }
                
                
# Now, to figure out the initial data...
                # Get the very first quote of this raw tag
                
$_first strpos$raw_tag'"' ) + 1;
                
                
# Now, get the last quote BEFORE the lowest keyPos (ie the very first option in the raw tag)
                
$_last  strrpos$raw_tag'"', -( strlen$raw_tag ) - $_lowestKeyPos ) );
                
                
$mainData substr$raw_tag$_first, ( $_last $_first ) );
            }
        }
        
        
/*print "nRaw Tag = " . $raw_tag;
        print "nPlug In = " . $_plugin;
        print "ndata = " . $mainData;
        print "n_last = "; print ( $_keyPos ) - strlen( $raw_tag );
        print "nlowestKeyPos = "; print $_lowestKeyPos;
        print "n";
        print_r( $options );*/
        
        
$text self::$template_plugin_classes$_plugin ]->runPlugin$mainData$options );
        
        return 
$text;
    }
    
    
/**
     * Process the normal HTML logic (if, else)
     *
     * @param    string        Content
     * @param    string        Function name
     * @return    @e string
     */
    
protected function _processHtmlLogic$text$func_name='' )
    {
        
//----------------------------------------
        // INIT
        //----------------------------------------
        
        
$total_length strlen$text );
        
$template     $text;
        
$statement    "";
        
$arg_true     "";
        
$arg_false    "";
        
        
# Tag specifics
        
$tag_if       '<if test=';
        
$found_if     = -1;
        
$tag_end_if   '</if>';
        
$found_end_if = -1;
        
$tag_else     '<else />';
        
$found_else   = -1;
        
        
$allow_delim  = array( '"'''' );
        
        //----------------------------------------
        // Keep the server busy for a while
        //----------------------------------------
        
        while ( 1 )
        {
            //-----------------------------------------
            // Update template length
            //-----------------------------------------
            
            $total_length = strlen( $template );
            
            $_end = 0;
            
            //----------------------------------------
            // Look for opening <if tag...
            //----------------------------------------
            
            $found_if = strpos( $template, $tag_if, $found_end_if + 1 );
            
            #$this->_addDebug( "Found <if>: $found_if" );
            
            //----------------------------------------
            // No logic found? 
            //----------------------------------------
            
            if ( $found_if === FALSE )
            {
                break;
            }
            
            //----------------------------------------
            // Beginning of the logic...
            //----------------------------------------
            
            $_start = $found_if + strlen($tag_if) + 2;
            
            $delim  = $template[ $_start - 1 ];
            
            //----------------------------------------
            // Make sure we have statement wrapped in
            // either ' 
or "
            //----------------------------------------
            
            if ( ! in_array( 
$delim$allow_delim ) )
            {
                
$found_end_if = $found_if + 1;
                continue;
            }
            
            //----------------------------------------
            // End statement?
            //----------------------------------------
            
            
$found_end_if = strpos($template$tag_end_if$_start + 3);
            
            #
$this->_addDebug( "Found </if>: $found_end_if" );
            
            //----------------------------------------
            // No end statement found
            //----------------------------------------
            
            if ( 
$found_end_if === FALSE )
            { 
                return str_replace("
\'", '''$template);
            }
            
            
//----------------------------------------
            // Find end of statement
            //----------------------------------------
            
            
for ( $i $_start$i $total_length$i++ )
            {
                if ( 
$template$i ] == $delim AND $template[$i 2] != '\' AND $template[$i + 1] == '>' )
                {
                    //----------------------------------------
                    // Unescaped end delimiter
                    //----------------------------------------
                    
                    $_end = $i - 1;
                    break;
                }
            }
            
            //----------------------------------------
            // No end statement found
            //----------------------------------------
            
            if ( ! $_end )
            {
                return str_replace("\'", '''
$template);
            }
            
            
//----------------------------------------
            // Get statement
            //----------------------------------------
            
            
$statement $this->unconvertTagssubstr$template$_start$_end $_start ) );
             
            
//----------------------------------------
            // Not got?
            //----------------------------------------
            
            
if ( empty($statement) )
            {
                
$found_end_if $found_if 1;
                continue;
            }
            
            
//----------------------------------------
            // No closing > on logic?
            //----------------------------------------
    
            
if ( $template[$_end 2] != '>' )
            {
                
$found_end_if $found_if 1;
                continue;
            }
    
            
//----------------------------------------
            // Check recurse
            //----------------------------------------
            
            
$if_found_recurse $found_if;
            
            while ( 
)
            {
                
//----------------------------------------
                // Got an IF?
                //----------------------------------------
                
                
$if_found_recurse strpos$template$tag_if$if_found_recurse );
                
                
#$this->_addDebug( "Found recurse <if>: $if_found_recurse" );
                
                //----------------------------------------
                // None found...
                //----------------------------------------
                
                
if ( $if_found_recurse === FALSE OR $if_found_recurse >= $found_end_if )
                {
                    break;
                }
                
                
$if_end_recurse $found_end_if;
                
$found_end_if   strpos$template$tag_end_if$if_end_recurse );
                
                
//----------------------------------------
                // None found...
                //----------------------------------------
                
                #$this->_addDebug( "Found recurse </if>: $found_end_if" );
                
                
if ( $found_end_if === FALSE )
                {
                    return 
str_replace("\'""'"$template);
                }
            }
    
            
$found_else strpos($template$tag_else$_end 3);
    
            
//----------------------------------------
            // Handle the else tags
            //----------------------------------------
            
            
while ( )
            {
                
//----------------------------------------
                // None found...
                //----------------------------------------
                
                
if ( $found_else === FALSE OR $found_else >= $found_end_if )
                {
                    
$found_else = -1;
                    break;
                }
    
                
$tmp substr($template$_end 3$found_else $_end 3);
                
                
//----------------------------------------
                // IF tag opened
                //----------------------------------------
                
                
$opened_if substr_count($tmp$tag_if);
                
                
//----------------------------------------
                // IF closed
                //----------------------------------------
                
                
$closed_if substr_count($tmp$tag_end_if);
                
                if ( 
$opened_if == $closed_if )
                {
                    break;
                }
                else
                {
                    
$found_else strpos($template$tag_else$found_else 1);
                }
            }
            
            
//----------------------------------------
            // No else
            //----------------------------------------
            
            
if ( $found_else == -)
            { 
                
$rlen   $found_end_if strlen($tag_end_if) + $_end 1;
                
$_true  substr($template$_end 3$rlen);
                
$_false '';
            }
            else
            {
                
$rlen   $found_else $_end 3;
                
$_true  substr($template$_end 3$rlen);
    
                
$rlen   $found_end_if strlen($tag_end_if) - $found_else 3;
                
$_false substr($template$found_else strlen($tag_else), $rlen);
            }
            
            
//----------------------------------------
            // Recurse
            //----------------------------------------
            
            
if ( strpos$_true$tag_if ) !== FALSE )
            {
                
$_true trim$this->_processHtmlLogic($_true$func_name) );
            }
            if ( 
strpos$_false$tag_if ) !== FALSE )
            {
                
$_false trim$this->_processHtmlLogic($_false$func_name) );
            }
    
            
//----------------------------------------
            // Clean up...
            //----------------------------------------
            
            
$str_find    = array('\"''\\');
            
$str_replace = array('"'  '\'  );
            
            if ( $delim == "'" )
            {
                
$str_find[]    = "\'";
                $str_replace[] = "'";
            }
    
            
$str_find[]    = '\$delim';
            
$str_replace[] =  $delim;
            
            //----------------------------------------
            // ...statement
            //----------------------------------------
            
            
$statement = str_replace($str_find$str_replace$statement);
            
            /* Got a prefix? */
            
$hook_pre_startif  = '';
            
$hook_post_startif = '';
            
$hook_pre_else     = '';
            
$hook_post_else    = '';
            
$hook_pre_endif    = '';
            
$hook_post_endif   = '';
        
            if ( strstr( 
$statement, ':|:' ) )
            {
                list( 
$prefix$statement ) = explode( ':|:', $statement );
                
$prefix    = trim( $prefix );
                
$statement = trim( $statement );
                                
                
$hook_pre_startif   = "<!--hook.if.{$this->_skinGroup}.{$func_name}.{$prefix}.pre.startif-->";
                
$hook_post_startif  = "<!--hook.if.{$this->_skinGroup}.{$func_name}.{$prefix}.post.startif-->";
                
$hook_pre_else      = "<!--hook.if.{$this->_skinGroup}.{$func_name}.{$prefix}.pre.else-->";
                
$hook_post_else     = "<!--hook.if.{$this->_skinGroup}.{$func_name}.{$prefix}.post.else-->";
                
$hook_pre_endif     = "<!--hook.if.{$this->_skinGroup}.{$func_name}.{$prefix}.pre.endif-->";
                
$hook_post_endif    = "<!--hook.if.{$this->_skinGroup}.{$func_name}.{$prefix}.post.endif-->";
                
                
$this->_hookIds$this->_skinGroup ][ $func_name ][] = "'{$prefix}'";
            }            
            
            //----------------------------------------
            // Create PHP statement
            //----------------------------------------
            
            /* Strip newlines */
            //
$_true  = trim( $_true );
            //
$_false = trim( $_false );
            
            
$php_statement = "{$hook_pre_startif}" . (($statement) ? ("{$hook_post_startif}{$_true}{$hook_pre_endif}") : ("{$hook_pre_else}{$_false}{$hook_post_else}")) . "{$hook_post_endif}";
            
            
$template = substr_replace( $template$php_statement$found_if$found_end_if + strlen($tag_end_if) - $found_if);
            
            
$found_end_if = $found_if + strlen($php_statement) - 1;
        }
    
        return str_replace("
\'", "'", $template);
    }
    
    
    /**
     * Convert special tags into HTML safe versions
     *
     * @param    string        Content
     * @return    @e string
     * @deprecated
     */
    public function convertTags( 
$t="" )
    {
        //----------------------------------------
        // Make some tags safe..
        //----------------------------------------
        
        
$t = preg_replace( '/{ipb.vars[(['"])?(sql_driver|sql_host|sql_database|sql_pass|sql_user|sql_port|sql_tbl_prefix|smtp_host|smtp_port|smtp_user|smtp_pass|html_dir|base_dir|upload_dir)(['"])?]}/'"" $t );
                
        return 
$t;
    }
    
    
/**
     * UN-Convert special tags from the HTML safe versions
     *
     * @param    string        Content
     * @return    @e string
     * @deprecated
     */
    
public function unconvertTags$t="" )
    {
        
//----------------------------------------
        // Make some tags safe..
        //----------------------------------------
        
        
$t preg_replace'/{ips.vars[(['"])?(sql_driver|sql_host|sql_database|sql_pass|sql_user|sql_port|sql_tbl_prefix|smtp_host|smtp_port|smtp_user|smtp_pass|html_dir|base_dir|upload_dir)(['"])?]}/', "" , $t );
        
        # IPB 2.1+ Kernel
        $t = preg_replace( '
/{ip(s|b|d).script_url}/i'           , ipsRegistry::$settings['base_url']  , $t);
        $t = preg_replace( '
/{ip(s|b|d).session_id}/i'           , '{$this->member->session_id }', $t);
        //$t = preg_replace( "#ip(?:s|b|d).(member|vars|skin|lang|input)#i", '
$this->ipsclass->\1'         , $t );
        
        return $t;
    }
    
    /**
     * Convert PHP code to html logic
     *
     * @param    string        Raw PHP content
     * @return    @e string
     */
    public function convertPhpToHtml( $php )
    {
        $php = $this->_reverseIpsHtml( $this->convertTags( $php ) );
        
        return $php;
    }
    
    /**
     * Convert IPB Heredoc PHP code to html logic
     *
     * @param    string        Raw PHP content
     * @return    @e string
     */
    protected function _reverseIpsHtml( $code )
    {
        $code = $this->_trimSlashes($code);
        
        $code = preg_replace("/".'
$'.'IPBHTMLs+?.?=s+?<<<EOF(.+?)EOF;s?/si', "\1", $code );
        
        $code = trim($code);
        $code = $this->_trimNewlines($code);
        
        return $code;
    }
    
    /**
     * Trim newlines
     *
     * @param    string        Raw code
     * @return    @e string
     */
    protected function _trimNewlines( $code )
    {
        $code = preg_replace("/^n{1,}/s", "", $code );
        $code = preg_replace("/n{1,}$/s", "", $code );
        return $code;
    }
    
    /**
     * Trim empty if tag newlines
     *
     * @param    string        Raw code
     * @return    @e string
     */
    protected function _trimEmptyIfs( $code )
    {
        return preg_replace('
/"ns+?"/s', """", $code );
    }
    
    /**
     * Trim slashes
     *
     * @param    string        Raw code
     * @return    @e string
     */
    protected function _trimSlashes( $code )
    {
        $code = str_replace( '"' , '"', $code );
        $code = str_replace( "\'", "'", 
$code );
        return 
$code;
    }
    
    /**
     * Slashes and escaped quotes are a PAIN (part two)
     *
     * @param    string        Content
     * @return    @e string
     */
    protected function _postMakeJsSlashesSafe( 
$code )
    {
        preg_match_all( '#<script(.+?)(?<!</script>)</script>#is', 
$code$matches );
        
        if ( count( 
$matches[1] ) )
        {
            foreach( 
$matches[1] as $m )
            {
                
$new = $m;
            
                
$new = str_replace( '-|(bs)|--|(q)|-' , '\"' , $new );
                
$new = str_replace( '-|(q)|-' , '"' , $new );
                $new = str_replace( '
-|(bs)|-', '\\' , $new );
            
                $code = str_replace( $m, $new, $code );
            }
        }
        
        /* Now make safe escaped strings */
        $code = preg_replace( '
#\\$#', "\$", $code );
    
        
return $code;
    }
    
    
/**
     * Slashes and escaped quotes are a PAIN (part one)
     *
     * @param    string        Content
     * @return    @e string
     */
    
protected function _preMakeJsSlashesSafe$code )
    { 
        
preg_match_all'#<script(.+?)(?<!</script>)</script>#is'$code$matches );
        
        if ( 
count$matches[1] ) )
        {
            
            foreach( 
$matches[1] as $m )
            {
                
$new str_replace'\"' '-|(q)|-' $m );
                
$new str_replace'\'  , '-|(bs)|-', $new );
                
                $code = str_replace( $m, $new, $code );
            }
        }
        
        return $code;
    }
    
    /**
     * Add a debug message if debugging enabled
     *
     * @param    string        Message
     * @return    @e mixed
     */
    protected function _addDebug( $msg )
    {
        if ( IPS_TEMPLATE_DEBUG AND IPS_TEMPLATE_DEBUG_FILE )
        {
            $full_msg = "==================================================================n"
                       . "Date: " . gmdate( '
r' ) . ' ' . $_SERVER['REMOTE_ADDR'] . "n"
                       . $msg . "n"
                       . "==================================================================n";
            
            if ( $FH = @fopen( IPS_TEMPLATE_DEBUG_FILE, '
a+' ) )
            {
                fwrite( $FH, $full_msg, strlen( $full_msg ) );
                fclose( $FH );
            }
            
            return TRUE;
        }
    }
}
Онлайн: 1
Реклама