<?php
/*
* @package : PowerBBTemplate
* @author : Mohammed Q. Hussain <hide@address.com>
* @version : 0.30 (Special Version For PowerBB)
* @start : 20/4/2006 , 7:00 PM (GMT+3)
* @last update : 16/09/2008 05:55:24 AM
* @under : GNU LGPL
*/
class PowerBBTemplate
{
var $templates_dir;
var $compiler_dir;
var $templates_ex;
var $template;
var $while_num;
var $while_array = null;
var $foreach_array = null;
var $_vars = null;
var $method = 'file';
var $x_loop = 0; // Private
var $size_loop = 0; // Private
var $_while_var = null;
var $_while_var_num = 0;
var $_foreach_var = null;
var $_foreach_var_num = 0;
function PowerBBTemplate()
{
$this->while_array = array();
$this->foreach_array = array();
$this->_vars = array();
$this->_while_var = array();
$this->_foreach_var = array();
}
/**
* Set the information
*/
function SetInformation($templates_dir,$compiler_dir,$templates_ex,$method)
{
$this->templates_dir = $templates_dir;
$this->compiler_dir = $compiler_dir;
$this->templates_ex = $templates_ex;
$this->method = $method;
}
function GetTemplateDir()
{
return $this->templates_dir;
}
function GetCompilerDir()
{
return $this->compilter_dir;
}
function GetTemplateExtention()
{
return $this->templates_ex;
}
/**
* Display the template after compile it
*/
function display($template_name)
{
global $PowerBB;
if ($this->method == 'file')
{
if ($PowerBB->_GET['debug'] != 1)
{
$this->_TemplateFromFile($template_name);
}
}
else
{
trigger_error('ERROR::BAD_VALUE_OF_METHOD_VARIABLE',E_USER_ERROR);
}
}
function content($template_name)
{
if ($this->method == 'file')
{
return $this->_TemplateFromFile($template_name,true);
}
}
/**
* If the template isn't compiled , we search it in template directory and if we found it we will compile it
*/
function _TemplateFromFile($template_name,$content=false)
{
if (filesize($this->templates_dir . $template_name . $this->templates_ex) > 0)
{
if (file_exists($this->compiler_dir . $template_name . '-compiler.php'))
{
if (filectime($this->compiler_dir . $template_name . '-compiler.php') < filectime($this->templates_dir . $template_name . $this->templates_ex))
{
$fp = fopen($this->templates_dir . $template_name . $this->templates_ex,'r');
if (!$fp)
{
return 'ERROR::CAN_NOT_OPEN_THE_FILE';
}
$fr = fread($fp,filesize($this->templates_dir . $template_name . $this->templates_ex));
fclose($fp);
$this->_CompileTemplate($fr,$template_name);
}
}
else
{
$fp = fopen($this->templates_dir . $template_name . $this->templates_ex,'r');
if (!$fp)
{
trigger_error('ERROR::CAN_NOT_OPEN_THE_FILE',E_USER_ERROR);
}
$fr = fread($fp,filesize($this->templates_dir . $template_name . $this->templates_ex));
fclose($fp);
$this->_CompileTemplate($fr,$template_name);
}
if (!$content)
{
$this->_GetCompiledFile($template_name,$content);
}
else
{
return $this->_GetCompiledFile($template_name,$content);
}
}
else
{
trigger_error('ERROR::FILE_SIZE_IS_ZERO',E_USER_ERROR);
}
}
/**
* Can I call it "The Compiler" ? :)
*/
function _CompileTemplate($string,$filename)
{
// We have loop
if (preg_match('~\{Des::while}{([^[<].*?)}~',$string)
or preg_match('~\{Des::while::complete}~',$string))
{
$string = $this->_ProccessWhile($string);
}
if (preg_match('~\{Des::foreach}{([^[<].*?)}~',$string))
{
$string = $this->_ProccessForeach($string);
}
if (preg_match('~\{if (.*)\}~',$string))
{
$string = $this->_ProccessIfStatement($string);
}
$search_array = array();
$replace_array = array();
//////////
/**
* Array
*/
// 2D Array (Without print) :
// {$array['0']} -> $array['0']
/*$search_array[] = '~\{{\$([^[<].*?)\[\'([^[<].*?)\'\]\[\'([^[<].*?)\'\]\}}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\'][\'\\3\']';*/
// 2D Array :
// {$array['0']} -> $array['0']
$search_array[] = '~\{\$([^[<].*?)\[\'([^[<].*?)\'\]\[\'([^[<].*?)\'\]\}~';
$replace_array[] = '<?php echo $PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\'][\'\\3\']; ?>';
// 2D Array (Without print) :
// {$array[0]} -> $array[0]
/*$search_array[] = '~\{{\$([^[<].*?)\[([^[<].*?)\]\[([^[<].*?)\]\}}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\'][\'\\3\']';*/
// 2D Array :
// {$array[0]} -> $array[0]
$search_array[] = '~\{\$([^[<].*?)\[([^[<].*?)\]\[([^[<].*?)\]\}~';
$replace_array[] = '<?php echo $PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\'][\'\\3\']; ?>';
// Array (Without print) :
// {$array['0']} -> $array['0']
/*$search_array[] = '~\{{\$([^[<].*?)\[\'([^[<].*?)\'\]\}}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\']';*/
// Array :
// {$array['0']} -> $array['0']
$search_array[] = '~\{\$([^[<].*?)\[\'([^[<].*?)\'\]\}~';
$replace_array[] = '<?php echo $PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\']; ?>';
// Array (Without print) :
// {$array[0]} -> $array[0]
/*$search_array[] = '~\{{\$([^[<].*?)\[([^[<].*?)\]\}}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\']';*/
// Array :
// {$array[0]} -> $array[0]
$search_array[] = '~\{\$([^[<].*?)\[([^[<].*?)\]\}~';
$replace_array[] = '<?php echo $PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\']; ?>';
//////////
/**
* Variable
*/
// Variable (Without print) :
// {$var} -> $var
/*$search_array[] = '~\{{\$([^[<].*?)\}}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'\\1\']';*/
// Variable :
// {$var} -> $var
$search_array[] = '~\{\$([^[<].*?)\}~';
$replace_array[] = '<?php echo $PowerBB->_CONF[\'template\'][\'\\1\']; ?>';
//////////
/**
* Misc
*/
// Fetch another template in work template
// {template}template_name{/template}
$search_array[] = '~\{template}([^[<].*?){/template}~';
$replace_array[] = '<?php $this->display(\'\\1\'); ?>';
// Include anther file in template
// {include}style.css{/include}
$search_array[] = '~\{include}([^[<].*?){/include}~';
$replace_array[] = '<?php include(\\1); ?>';
//////////
$string = preg_replace($search_array,$replace_array,$string);
$create = fopen($this->compiler_dir . $filename . '-compiler.php','w+');
if (!$create)
{
trigger_error('ERROR::CAN_NOT_OPEN_THE_FILE',E_USER_ERROR);
}
$write = fwrite($create,$string);
if (!$write)
{
trigger_error('ERROR::CAN_NOT_WRITE_TO_THE_FILE',E_USER_ERROR);
}
fclose($create);
}
/**
* We have {Des::while} loop , that's mean probably we will fetch information from database
*/
function _ProccessWhile($string)
{
$search_array = array();
$replace_array = array();
// I am sorry, but we _must_ do that
$string = preg_replace('~\{Des::while}{([^[<].*?)}~ise','$this->_StoreWhileVarName(\'\\1\');',$string);
// If statement _must_ be first
if (preg_match('~\{if (.*)\}~',$string)
or preg_match('~if (.*) {~',$string))
{
$string = $this->_ProccessIfStatement($string,'while');
}
foreach ($this->_while_var as $var_name)
{
$search_array[] = '~\{\{\$' . $var_name . '\[([^[<].*?)\]\}\}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'while\'][\'' . $var_name . '\'][$this->x_loop][\\1]';
$search_array[] = '~\{\$' . $var_name . '\[([^[<].*?)\]\}~';
$replace_array[] = '<?php echo $PowerBB->_CONF[\'template\'][\'while\'][\'' . $var_name . '\'][$this->x_loop][\\1]; ?>';
}
$string = preg_replace($search_array,$replace_array,$string);
$string = str_replace('{/Des::while}','<?php $this->x_loop = $this->x_loop + 1; } ?>',$string);
$string = str_replace('{Des::while::complete}','',$string);
$string = str_replace('{/Des::while::complete}','',$string);
$this->_while_var = null;
$this->_while_var_num = 0;
return $string;
}
function _StoreWhileVarName($varname)
{
$this->_while_var[$this->_while_var_num] = $varname;
$this->_while_var_num += 1;
return '<?php $this->x_loop = 0; $this->size_loop = sizeof($PowerBB->_CONF[\'template\'][\'while\'][\'' . $varname . '\']); while ($this->x_loop < $this->size_loop) { ?>';
}
function _ProccessForeach($string)
{
$search_array = array();
$replace_array = array();
$string = preg_replace('~\{Des::foreach}{([^[<].*?)}{([^[<].*?)}~ise','$this->_StoreForeachVarName(\'\\2\',\'\\1\');',$string);
if (preg_match('~\{if (.*)\}~',$string)
or preg_match('~if (.*) {~',$string))
{
$string = $this->_ProccessIfStatement($string,'foreach');
}
foreach ($this->_foreach_var as $var_name)
{
// Variable (Without print) :
// {$var} -> $var
$search_array[] = '~\{{\$' . $var_name . '\}}~';
$replace_array[] = '$' . $var_name;
$search_array[] = '~\{{\$' . $var_name . '\[([^[<].*?)\]}}~';
$replace_array[] = '$' . $var_name . '[\\1]';
// Variable :
// {$var} -> $var
$search_array[] = '~\{\$' . $var_name . '\}~';
$replace_array[] = '<?php echo $' . $var_name . '; ?>';
$search_array[] = '~\{\$' . $var_name . '\[([^[<].*?)\]\}~';
$replace_array[] = '<?php echo $' . $var_name . '[\\1]; ?>';
}
$search_array[] = '~\{counter}~';
$replace_array[] = '<?php echo $this->x_loop ?>';
$search_array[] = '~\{{counter}}~';
$replace_array[] = '$this->x_loop';
$string = preg_replace($search_array,$replace_array,$string);
$string = str_replace('{/Des::foreach}','<?php $this->x_loop += 1; } ?>',$string);
return $string;
}
function _StoreForeachVarName($varname,$oldname)
{
$this->_foreach_var[$this->_foreach_var_num] = $varname;
$this->_foreach_var_num += 1;
return '<?php foreach ($PowerBB->_CONF[\'template\'][\'foreach\'][\'' . $oldname . '\'] as $' . $varname . ') { ?>';
}
function _ProccessIfStatement($string,$type = null)
{
$search_array = array();
$replace_array = array();
// If statement :
// {if $i == 1} Hi {/if}
// if ($i == 1) { echo 'Hi'; }
$search_array[] = '~\{if (.*)}(.*){/if}~'; // SEE : We have a problem here, \\2 may contain "else" or "elseif"
$replace_array[] = '<?php if (\\1) { ?> \\2 <?php } ?>';
$search_array[] = '~\{if (.*)}~';
$replace_array[] = '<?php if (\\1) { ?>';
$search_array[] = '~\{/if}~';
$replace_array[] = '<?php } ?>';
// Elseif statement
$search_array[] = '~\{elseif (.*)}(.*){/if}~';
$replace_array[] = '<?php elseif (\\1) { ?> \\2 <?php } ?>';
$search_array[] = '~\{elseif (.*)}~';
$replace_array[] = '<?php } elseif (\\1) { ?>';
// Else statement
$search_array[] = '~\{else}~';
$replace_array[] = '<?php } else { ?>';
$string = preg_replace($search_array,$replace_array,$string);
$string = preg_replace('~\if (.*) \{~ie','$this->_ProccessIfStatementVariables(\'\\1\',\'' . $type . '\');',$string);
return $string;
}
function _ProccessIfStatementVariables($input,$type = null)
{
$string = 'if ' . $input . ' { ';
if ($type == 'while')
{
foreach ($this->_while_var as $var_name)
{
$search_array[] = '~\{\$' . $var_name . '\[([^[<].*?)\]\}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'while\'][\'' . $var_name . '\'][$this->x_loop][\\1]';
}
}
elseif ($type == 'foreach')
{
foreach ($this->_foreach_var as $var_name)
{
// Variable (Without print) :
// {$var} -> $var
$search_array[] = '~\{\$' . $var_name . '\}~';
$replace_array[] = '$' . $var_name;
$search_array[] = '~\{\$' . $var_name . '\[([^[<].*?)\]}~';
$replace_array[] = '$' . $var_name . '[\\1]';
}
}
// 2D Array (Without print) :
// {$array['0']} -> $array['0']
$search_array[] = '~\{\$([^[<].*?)\[\'([^[<].*?)\'\]\[\'([^[<].*?)\'\]\}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\'][\'\\3\']';
// 2D Array (Without print) :
// {$array[0]} -> $array[0]
$search_array[] = '~\{\$([^[<].*?)\[([^[<].*?)\]\[([^[<].*?)\]\}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\'][\'\\3\']';
// Array (Without print) :
// {$array['0']} -> $array['0']
$search_array[] = '~\{\$([^[<].*?)\[\'([^[<].*?)\'\]\}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\']';
// Array (Without print) :
// {$array[0]} -> $array[0]
$search_array[] = '~\{\$([^[<].*?)\[([^[<].*?)\]\}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'\\1\'][\'\\2\']';
//////////
/**
* Variable
*/
// Variable (Without print) :
// {$var} -> $var
$search_array[] = '~\{\$([^[<].*?)\}~';
$replace_array[] = '$PowerBB->_CONF[\'template\'][\'\\1\']';
$string = preg_replace($search_array,$replace_array,$string);
return $string;
}
/**
* If the template is already compiled , so include it
*/
function _GetCompiledFile($template_name,$content=false)
{
global $PowerBB;
// Yeah it's here , include it .
if (file_exists($this->compiler_dir . $template_name . '-compiler.php'))
{
if (!$content)
{
include($this->compiler_dir . $template_name . '-compiler.php');
// Don't forget return true :)
return true;
}
else
{
$fp = fopen($this->compiler_dir . $template_name . '-compiler.php','r');
if (!$fp)
{
trigger_error('ERROR::CAN_NOT_OPEN_THE_FILE',E_USER_ERROR);
}
$fr = fread($fp,filesize($this->templates_dir . $template_name . $this->templates_ex));
if (!$fr)
{
trigger_error('ERROR::CAN_NOT_READ_FROM_THE_FILE',E_USER_ERROR);
}
fclose($fp);
return $fr;
}
}
// it's not here , so return false
else
{
return false;
}
}
// Define variable to use it in template
function assign($varname,$value)
{
global $PowerBB;
$PowerBB->_CONF['template'][$varname] = $value;
}
// Stop script
function _error($msg)
{
die($msg);
}
}
?>