<?php
/**
* Project: Gedar Template Engine: a PHP template engine
* File: GedarTemplate.inc.php
* Copyright (C) 2005 Ali Masoudi<hide@address.com>
*
* 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.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* @link http://Gedar.alimasoudi.com
* @authur Ali Masoudi <hide@address.com>
* @version 1.0.1
* @package Gedar
*/
/**#@+
* set main constant
*/
// DIR_SEP: is DIRECTORY_SPARATOR ,for diffrence in windows and unix style directory separator
if(!defined('DIR_SEP'))
define('DIR_SEP', DIRECTORY_SEPARATOR);
// CURRENT_DIR: PHP Script directory,current file's directory that include and execute template engine
if(!defined('CURRENT_DIR'))
define('CURRENT_DIR',dirname($_SERVER['SCRIPT_FILENAME']).DIRECTORY_SEPARATOR);
// GEDAR_MAINDIR: absolute path to gedar directory,absolute path to template engine directory
if(!defined('GEDAR_MAINDIR'))
define('GEDAR_MAINDIR',dirname(__FILE__).DIRECTORY_SEPARATOR);
/**#@+
* Template Compiling Class
* @package Gedar
*/
class Template
{
/**#@+
* Internal Variable
*/
/**
* Determine the realase version of Gedar
* Template Engien
* @var string
*/
var $_Gversion = "1.0.1";
/**
* Determine name of file must parsed
*
* @var string
*/
var $_TplFileName = "";
/**
* Determine directory of template file
*
* @see $_TplFileName
* @var string
*/
var $_TplDirectory = "";
/**
* Determine That template directory path is relative
* from php file ( the file includes template engine
* class )
*
* @var bool
*/
var $_TplTemplatePathRealtiveFromPhpFile = false;
/**
* Determine that need cache create or rebuild
*
* @var bool
*/
var $_TplCache = true;
/**
* Directory of cache file relative from
* this class directory
*
* @var string
*/
var $_TplCacheDirectory = "./cache/";
/**
* time in second for rebuilding cache file
*
* @var int
*/
var $_TplCacheLifeTime = 300;
/**
* determine must write in cache now or not
*
* @var bool
*/
var $_TplCacheWrite = true;
/**
* encrypted name of cache file
*
* @var string
*/
var $_TplCacheFileName = "";
/**
* start prefix for regulare expression
*
* @var string
*/
var $_TplStartPrefix = "\{";
/**
* end prefix for regulare expression
*
* @var string
*/
var $_TplEndPrefix = "\}";
/**
* start prefix for template engine tag
*
* @var string
*/
var $_TplStartTag = "{";
/**
* end prefix for template engine tag
*
* @var string
*/
var $_TplEndTag = "}";
/**
* type of output; array("capture","show")
* capture: return a variable of translated template
* show: echo translated template
*
* @var string
*/
var $_TplOutputType = "show";
/**
* array of directories that include plugin files
*
* @var array
*/
var $_TplPluginDirectory = array("./gPlugins");
/**
*
* @var array
*/
var $_TplPlugins = array();
/**
* template generation mode
* '0': no cache
* '1': default; when cache recreate that the source file change
* '2': make cache per time
*
* @var string
*/
var $_TplGenerationMode = "1";
/**
* stores template variable
*
* @var array
*/
var $_TplVars = array();
/**
* stores template special variable
*
* @var array
*/
var $_TplSpecialVars = array();
/**
* current page information
* ['query']: all url query in variable mode
* ['directory']: main php file directory
*
* @var array
*/
var $_page = array();
/**
* Predefiend variable
* stores all predefiend variable
* each element contains array['name','value']
* @see setPredefiendVar()
*
* @var array
*/
var $_gedarPredefiendVar = array();
/**
* outputting tag
*
* @var array
*/
var $_outputTag = array(
"header"=>array() ,
"content"
);
/**
* store all occured error
*
* @var array
*/
var $_error = array();
/**
* timestamp that start engineing
*
* @var string
*/
var $_startTimeStamp = "";
/**
* temporary variable
*
* @var mixed
*/
var $_tmpVar = "";
/**
* set template values
*
* set the template essential variable<br/>
* $pathAddressingMode define that templte directory is
* relative from php file that load template engine
* @param string $srcFileName
* @param string $srcFileDir
* @param bool $pathAddressingMode
* @return true
*/
function Template($srcFileName,$srcFileDir,$pathAddressingMode=true,$cacheDir=false,$pluginDir=false)
{
$this->_TplFileName = $srcFileName;
$this->_TplTemplatePathRealtiveFromPhpFile = $pathAddressingMode;
$this->Initialize($srcFileDir,$cacheDir,$pluginDir);
}
/**
* Initialize Template Requirement
* Initialize source , cache and plugin directory
* address and specefic, and set all regulare
* expressions that will needed in class
* @param string $srcFileDir
* @param String $cacheDir
* @param string pluginDir
* @return true
*/
function Initialize($srcFileDir,$cacheDir,$pluginDir)
{
$this->_startTimeStamp=microtime();
$this->setDirectory($srcFileDir,$cacheDir);
$this->setPluginDirectory($pluginDir);
$this->setPredefiendVar();
$this->regExpDefenition();
}
/**
* Set template directory variable
* set source directory and cache diretory
* for current file
* @param string $srcFileDir
* @param string $cacheDir
* @return true
*/
function setDirectory($srcFileDir,$cacheDir)
{
if (@strlen($srcFileDir))
{
if(substr($srcFileDir,0,1)!="/" || substr($srcFileDir,0,1)!="\\")
{
$srcFileDir="/".$srcFileDir;
}
$this->_TplDirectory=($this->_TplTemplatePathRealtiveFromPhpFile)
?
$this->real_path($this->real_path(dirname($_SERVER['SCRIPT_FILENAME'])).$srcFileDir)
:
$this->real_path(GEDAR_MAINDIR.$this->_TplDirectory.DIRECTORY_SEPARATOR.$srcFileDir);
}
else
{
$this->_TplDirectory = $this->real_path(GEDAR_MAINDIR.DIRECTORY_SEPARATOR.$this->_TplDirectory.DIRECTORY_SEPARATOR);
}
if ($cacheDir)
$this->_TplCacheDirectory = $this->real_path($this->real_path(dirname($_SERVER['SCRIPT_FILENAME'])).DIR_SEP.$cacheDir);
else
$this->_TplCacheDirectory = $this->real_path(GEDAR_MAINDIR.DIR_SEP.$this->_TplCacheDirectory.DIR_SEP);
return true;
}
/**
* Set Plugin Directory
* set directory that contains
* plugins in itself
* @param string $pluginDir
* @return true
*/
function setPluginDirectory($pluginDir)
{
if (@$pluginDir)
$this->_TplPluginDirectory[] = $pluginDir;
foreach($this->_TplPluginDirectory as $dir)
{
$this->_TplPluginDirectory[] = $this->real_path(GEDAR_MAINDIR.DIR_SEP.$dir);
}
return true;
}
/**
* Set Predefined Variable
* When class start working this method
* set initial predefined variable
* @return true
*/
function setPredefiendVar()
{
$this->addPredefiendVar("ldel","{");
$this->addPredefiendVar("rdel","}");
$this->addPredefiendVar("date",date("Y-m-d"));
$this->addPredefiendVar("time",date("H:i:s"));
}
/**
* Regular Expression Defenition
* Duty of this method is defining required
* regular expression in this class
* @return true
*/
function regExpDefenition()
{
// -Double qoute string-
// "Gedar \"is a template engine"
$this->_regExpDblQuoteStr = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
// -Single qoute string-
// 'Gedar \'is simple to use'
$this->_regExpSingleQuoteStr = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
// -String-
// 'ali'
// "ali"
$this->_regExpString = '(?:' . $this->_regExpDblQuoteStr . '|' . $this->_regExpSingleQuoteStr . ')';
// -Bracket Element-
// ['ali']
// [$var]
$this->_regExpBracket = '\[(?:(?:\$[a-zA-Z_]\w*)|(?:'.$this->_regExpString.'))\]';
// -Numbers-
// 9.2
// -4
$this->_regExpNumber = '\-?\d+(?:\.\d+)?';
// -Mathematic Operator-
// + - % * /
$this->_regExpMathOp = '[\+\-\*\/\%]';
$this->_regExpMathTogether = '[\$\w\+\-\*\/\%\d\>\[\]]';
// -Variable minus initial dollar-
// hassan['reza']['karim']
// ahmad[$var]
$this->_regExpVarAfterDollar = '\w+(?:' . $this->_regExpBracket
. ')*(?:\.\$?\w+(?:' . $this->_regExpBracket . ')*)*(?:' . $this->_regExpMathOp
. '(?:' . $this->_regExpNumber . '|' . $this->_regExpMathTogether . ')*)?';
// -Variable Defintion-
// $hassan['reza']['lar']
// $karim[$var]
$this->_regExpVar = '\$' . $this->_regExpVarAfterDollar;
$this->_regExpAssign = '(?:'. $this->_regExpString . '|'. $this->_regExpNumber .')';
// -Var Name-
// $hassan
// $karim
$this->_regExpVarName = '\$\w*';
// -All Variable Type-
// 12
// $akbar['reza']
// Karim
$this->_regExpVariable = '(?:' . $this->_regExpVar . '|' . $this->_regExpNumber . '|' . $this->_regExpString . ')';
// -Function-
// --Function Name--
// funcName
$this->_regExpFuncName = '[a-zA-Z_]\w*';
// --Function Calling--
// funcname( param1 , param2 , ... )
$this->_regExpFunction = '(?:' . $this->_regExpFuncName . '\s*\((?:\s*'.$this->_regExpVariable.'\s*,?\s*)*\))';
$this->_regExpFunctionValue = '(?:'.$this->_regExpVar.')|(?:'.$this->_regExpAssign.')';
}
/**
* Add Predefiend Variable
* Add new predefiend variable to
* current gedar template engine
* @param string $name
* @param string $value
* @return true
*/
function addPredefiendVar($name,$value)
{
$this->_gedarPredefiendVar[$name]=$value;
}
/*
* Script Inormation
* Set main Information about main script
* such as queries , directory , filename ,
* ... that will be needed in script
* @return true
*/
function _ScriptInfo()
{
parse_str($_SERVER['QUERY_STRING'], $query);
$directory = substr($this->_TplVars['_GSCRIPT_NAME'] , 0 , strrpos( $this->_TplVars['_GSCRIPT_NAME'] , '/' ))."/";
$this->_page['query']=$query;
$this->_page['directory']=$directory;
$this->assign("_GSERVER",$_SERVER);
$this->assign("_GSCRIPT_NAME",$_SERVER['SCRIPT_NAME']);
$this->assign("_GSELF",$_SERVER['PHP_SELF']);
$this->assign("_GQUERY",$query);
$this->assign( 'SCRIPT_DIRECTORY' , $directory);
return true;
}
/**
* Compile Template File
* Check if translated resource
* expired , make it from initial
* @param string $fileName
* @return true
*/
function _compile($fileName)
{
/* Do not need to recompile */
if(!$this->cacheFileIsExpired($fileName))
return true;
/* Need to recompile */
$resource=$this->_compileResourceFile($fileName);
$header=implode("\n",$this->_outputTag['header']);
$content = $header."\n".$resource;
$this->makeCacheFile($fileName,$content);
return true;
}
/**
* Compile Template
* Gather source from a template and make
* translated resource from it
* $fileName is the name of file with the
* complete path
* @param string $fileName
* @return true;
*/
function _compileResourceFile($fileName)
{
$this->_templateComiplingHeaderInfo();
$source=$this->_readFile($fileName);
/* first change source section format to be specefied */
$changedSource=preg_replace( '~'.$this->_TplStartPrefix.'([^'.$this->_TplEndPrefix.']+)'.$this->_TplEndPrefix.'~i',"\n"."^".
$this->_TplStartTag.$this->_TplEndTag."^"."\n"."$1$2$3"."\n"."~".$this->_TplStartTag.
$this->_TplEndTag."~"."\n"
,$source
);
$sourceLines = explode( "\n" , $changedSource );
foreach( $sourceLines as $key=>$eachLine )
{
if (@$sourceLines[$key-1]=="^".$this->_TplStartTag.$this->_TplEndTag."^" && @$sourceLines[$key+1]=="~".$this->_TplStartTag.$this->_TplEndTag."~")
{
$transTag.=$this->_convertTag("{".$eachLine."}");
}
elseif(@$sourceLines[$key-1]=="~".$this->_TplStartTag.$this->_TplEndTag."~")
{
$transTag.=$eachLine;
}
elseif ($eachLine=="^".$this->_TplStartTag.$this->_TplEndTag."^" || $eachLine=="~".$this->_TplStartTag.$this->_TplEndTag."~" )
{
$transTag.= "";
}
else
{
@$transTag.= "\n".$eachLine;
}
}
return $transTag;
}
/**
* Convert Source Tag
* Convert source tag to synonym php tag
*
* @param string $tag
* @return string
*/
function _convertTag($tag)
{
/* convert gedar predefined variable
every #name# translated to its value */
foreach($this->_gedarPredefiendVar as $preVar)
{
if(preg_match('~'.$this->_TplStartPrefix.'\#'.$this->_gedarPredefiendVar.'\#'.$this->_TplEndPrefix.'~i',$tag ,$match))
{
$translatedTag = $this->_TplStartTag;
return $translatedTag;
}
}
/* Match {var} and convert them to
<start_php_tag print var; end_php_tag> */
if(preg_match('~^\s*'.$this->_TplStartPrefix.'\s*('.$this->_regExpVariable.')\s*'.$this->_TplEndPrefix.'\s*$~i',$tag ,$match))
{
$ret="<?php print ".($match[1])."; ?>";
return $this->_makeVariable($ret);
}
/* check for main function like if, else, for
and other functions that defines in main dir*/
$translatedTag=$this->_checkFunction($tag);
/* check for end function tag like /if,/foreach
and other functions */
$translatedTag=$this->_checkEndFunction($translatedTag);
/* make variable name as acceptable state
in template */
$translatedTag=$this->_makeVariable($translatedTag);
return $translatedTag;
}
/**
* Check Function
* check if is it built-on function or
* external plugin and load it if it
* is an external plugin and set
* output displaying
*
* @param string $tag
* @return string
*/
function _checkFunction($tag)
{
$st = $this->_TplStartPrefix;
$en = $this->_TplEndPrefix;
$pattern = '~^'.$st.'\s*([a-z0-9_]+)(\s+.*)'.$en.'$~i';
if(!preg_match($pattern,$tag,$match))
return $tag;
$function = $match[1];
$params=$this->_getParams($match[2]);
$wholeParams=$match[2];
if($this->_isPredefiendFunction($function))
eval('$output=$this->_compile'.$function.'Tag($params,$wholeParams);');
else
$output=$this->_setupPlugin($function,$params);
return $output;
}
/**
* Check End Function
* check if is it built-on finish function or
* external plugin and load it if it
* is an external plugin and set
* output displaying
* @param string $tag
* @return string
*/
function _checkEndFunction($tag)
{
$st = $this->_TplStartPrefix;
$en = $this->_TplEndPrefix;
$pattern = '~^'.$st.'\s*/([a-z0-9_]+)\s*'.$en.'$~i';
if(!preg_match($pattern,$tag,$match))
return $tag;
$function = "end".$match[1];
$params="array()";
$wholeParams="";
if($this->_isPredefiendFunction($function))
eval('$output=$this->_compile'.$function.'Tag($params,$wholeParams);');
else
$output=$this->_setupPlugin($function,$param);
return $output;
}
/**
* Check Is Predefiend
* Check that specefic function is predefiend
* and built-on function or not
* @param string $function
* @return bool
*/
function _isPredefiendFunction($function)
{
$methodeName = "_compile".$function."Tag";
/* gather all defined methode */
$definedMethode = get_class_methods($this);
/* get all of existing method and check
is the method with '_compile{functionName}Tag'
name is exist or not */
foreach($definedMethode as $methode)
if(strtolower($methode)==strtolower($methodeName))
return true;
return false;
}
/**
* Get Parameters
* Get parameters from an involved
* parantheses tag source
* @syntax ( paramName1= "param value1" , paramName2=$value2 , .... )
* @param string $paramSrc
* @return true;
*/
function _getParams($paramSrc)
{
/* Check every paramName=Value between
parantheses */
if(preg_match_all('~'."([a-zA-Z0-9_]*)\s*=\s*(".$this->_regExpVariable.")~i" , $paramSrc , $m))
{
$array = array();
foreach( $m[1] as $key=>$v)
{
$array[$v]=$m[2][$key];
}
$paramKey = 'array(';
$i=1;
foreach( $array as $key=>$v)
{
$paramKey .= (count($array)>$i)? "'".$key."'".'=>\''.addslashes($v).'\',' : "'".$key."'".'=>\''.addslashes($v).'\'';
$i++;
}
$paramKey .= ')';
}
else
$paramKey="array()";
/* we make a expression like this array('ex'=>'nn' , ..)
and assign it to $tmp_var with eval */
eval('$tmp_var='.$paramKey.';');
return $tmp_var;
}
/**
* Setup Plugin
* Setup a plugin for using in current
* template and get output tag for it if
* needed
* function name that give output tag is like
* @returntag gedar_{plugin_name}_excute()
* @param string $function
* @param array $param
* @return string
*/
function _setupPlugin($function,$param)
{
$this->setPluginHeader($function);
$functionName="gedar_".$function."_excute";
include_once($this->pluginCompleteAddress($function));
eval('$output='.$functionName.'($param,$this);');
return $output;
}
/**
* Set Plugin Header
* set all header information like including
* files and ... for this plugin in header
* @param string $function
* @return true
*/
function setPluginHeader($function)
{
$pluginFile=$this->pluginCompleteAddress($function);
if(!$pluginFile)
$this->_error[]=$function.'(): Requested plugin doesn`t exist!';
$this->addHeaderIfNotExist('<?php include_once "'.$pluginFile.'"; ?>');
}
/**
* Plugin Complete Address
* give a plugin name and return its complete
* main file`s address
* @param string $function
* @return string
*/
function pluginCompleteAddress( $function )
{
$function=strtolower($function);
foreach ( $this->_TplPluginDirectory as $dir )
{
$completeAddress=$this->real_path(GEDAR_MAINDIR.$dir."/")."gPlugin.".$function.'.inc.php';
if(file_exists($completeAddress))
return $completeAddress;
}
return false;
}
/**
* Complete Template Address From Main Template Address
* return complete address of a template from
* main template address
* @param string $address
* @return string
*/
function completeTemplateAddressFromMainTemplate($address)
{
if(substr($this->_TplDirectory,strlen($this->_TplDirectory),1)=="/")
$ds="/";
else
$ds="";
return $this->real_path($this->_TplDirectory.$ds.$address);
}
/**
* If Callback Methode
* compile if tags
* @syntax {if (conditions)}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileIfTag($params,$wholeParamsPar)
{
$output = "<?php if $wholeParamsPar { ?>";
return $output;
}
/**
* for Callback Methode
* compile for tags
* @syntax {for (from,to,step)}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileForTag($params,$wholeParamsPar)
{
$output = "<?php for $wholeParamsPar { ?>";
return $output;
}
/**
* while Callback Methode
* compile while tags
* @syntax {while (condition)}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileWhileTag($params,$wholeParamsPar)
{
$output = "<?php while $wholeParamsPar { ?>";
return $output;
}
/**
* Foreach Callback Methode
* compile foreach tags
* @syntax {for ($array as $key=>$element)}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileForeachTag($params,$wholeParamsPar)
{
$output = "<?php foreach $wholeParamsPar { ?>";
return $output;
}
/**
* Endfor Callback Methode
* compile Endfor tags
* @syntax {/for}||{endfor}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileEndForTag($params,$wholeParamsPar)
{
$output = "<?php } ?>";
return $output;
}
/**
* EndIF Callback Methode
* compile EndIf tags
* @syntax {/if}||{endif}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileEndIfTag($params,$wholeParamsPar)
{
$output = "<?php } ?>";
return $output;
}
/**
* EndWhile Callback Methode
* compile endWhile tags
* @syntax {/while}||{endwhile}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileEndWhileTag($params,$wholeParamsPar)
{
$output = "<?php } ?>";
return $output;
}
/**
* EndForeach Callback Methode
* compile endforeach tags
* @syntax {/foreach}||{endforeach}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileEndForeachTag($params,$wholeParamsPar)
{
$output = "<?php } ?>";
return $output;
}
/**
* else Callback Methode
* compile else tags
* @syntax {else}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileElseTag($params,$wholeParamsPar)
{
$output = "<?php } else { ?>";
return $output;
}
/**
* Elseif Callback Methode
* compile elseif tags
* @syntax {elseif(condition)}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileElseIfTag($params,$wholeParamsPar)
{
$output = "<?php } elseif $wholeParamsPar { ?>";
return $output;
}
/**
* include Callback Methode
* compile include tags
* @syntax {include (file='filename')}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileIncludeTag($params,$wholeParamsPar)
{
$file=$this->_getParamValue($params,"file");
eval('$file='.$file.';');
$fileAddress=$this->completeTemplateAddressFromMainTemplate($file);
/* make cache file if not exist */
$this->_compile($fileAddress);
/* get its cache file name */
$cacheName=$this->_makeCacheName($fileAddress);
$output="<?php include '$cacheName'; ?>";
return $output;
}
/**
* Assign Callback Methode
* compile assign tags
* @syntax {assign (name="var_name" value="var_value")}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileAssignTag($params,$wholeParamsPar)
{
$varName=$this->_getParamValue($params,"name");
$varValue=$this->_getParamValue($params,"value");
$pluginFile=$this->pluginCompleteAddress('assign');
$this->addHeaderIfNotExist("<?php include_once '$pluginFile'; ?>");
$output="<?php gedar_assign_do($varName,$varValue,\$this); ?>";
return $output;
}
/**
* Cycle Callback Methode
* compile Cycle tags
* @syntax {cycle (name="name" elements="elm1,elm2,...")}
* @param array $params
* @param string wholeParamsPar
* @return string
*/
function _compileCycleTag($params,$wholeParamsPar)
{
$name=$this->_getParamValue($params,"name")?
$this->_getParamValue($params,"name"):
"'___DEFAULT__'";
$elements=stripslashes($this->_getParamValue($params,"elements"));
$pluginFile=$this->pluginCompleteAddress('cycle');
$this->addHeaderIfNotExist("<?php include_once '$pluginFile'; ?>");
$this->addHeaderIfNotExist("<?php \$this->_TplSpecialVars['_cycle']['$name']['elements']='".$this->_checkString($elements)."'; ?>");
$output="<?php echo gedar_cycle_do('$name',\$this); ?>";
return $output;
}
/**
* Get Parameter Value
* give a parameter array and an element name
* and return the value of it if exists
* @param string $params
* @param string $elem
* @return var
*/
function _getParamValue($params,$elem)
{
if(!$params[$elem])
return false;
$val=$params[$elem];
if(!trim($val))
$val='""';
$ret=stripslashes($this->_makeVariable($val));
return $ret;
}
/**
* Make Variable
* make variable as template variable for
* examplae $var -> $_TplVars['var']
* i use tokenizer in default if loaded
* @param string $expr
* @return string
*/
function _makeVariable($expr)
{
$tokens = @token_get_all($expr);
foreach ($tokens as $key=>$token)
{
if (is_array($token))
{
if ($token[0]==T_VARIABLE)
$trans= @$token[1]!='$this' ? '$this->_TplVars["'.(substr($token[1],1)).'"]' : '$this';
else
$trans=$token[1];
}
else
$trans=$token;
@$return.=$trans;
}
return $return;
}
/**
* Header Compiling Information
* insert information about template comiling
* time and date ,...
*
* @return true
*/
function _templateComiplingHeaderInfo()
{
$this->addHeaderIfNotExist('<?php /* Established by : <Gedar Template Engine>'.
' version ('.$this->_Gversion.')'
.', Created on '.date("Y-m-d").'@ '.date("H:i:s")
.' Compiled from '.$this->_TplFileName.' */ ?>');
}
/**
* Add Line To Header
* Add new line to header if there is
* not exist
* @param string $htxt
* @return true
*/
function addHeaderIfNotExist($htxt)
{
if(!in_array($htxt,$this->_outputTag['header']))
$this->_outputTag['header'][]=$htxt;
}
/**
* Is Expired Cache File
* Check that cache file is expired
* or it is validate
* @param string fileName
* @return bool
*/
function cacheFileIsExpired($fileName)
{
$cacheFileName=$this->_TplCacheDirectory.$this->_makeCacheName($fileName);
if (!file_exists($cacheFileName))
return $this->_TplCacheWrite=true;
else
{
switch ($this->_TplGenerationMode)
{
case "0":
$this->_TplCacheWrite=false;
break;
case "1":
if (filemtime($fileName)<filemtime($cacheFileName))
$this->_TplCacheWrite=false;
else
return $this->_TplCacheWrite=true;
break;
case "2":
if ( (time()-filemtime($cacheFileName)) < $this->_TplCacheLifeTime )
$this->_TplCacheWrite = false;
else
return $this->_TplCacheWrite = true;
break;
}
}
return $this->_TplCacheWrite;
}
/**
* Make Cache File
* Make a cache file in cache directory
* the directory of cache file is one
* that specified with $_TplCacheDirectory
* note: $filename is filename with it`s
* complete address
* @param string $fileName
* @param string $content
* return bool
*/
function makeCacheFile($fileName,$content)
{
$this->makeDirIfNotExist($this->_TplCacheDirectory,"0775");
$this->makeDirectorySecure($this->_TplCacheDirectory);
$cacheName = $this->_makeCacheName($fileName);
return $this->_writeToFile($this->_TplCacheDirectory.$cacheName,$content);
}
/**
* Make Directory If Not Exist
* check is a directory exist and
* make it if it wasnt exist
* @param string $directory
* @param string $mode
* @return bool
*/
function makeDirIfNotExist($directory,$mode)
{
$directory=$this->real_path($directory);
if(@file_exists($directory))
return true;
$return = mkdir($directory);
if(!$return)
return false;
return $this->changeFileMode($directory , $mode);
}
/**
* Make Directory Secure
* put an empty index.html file and a
* .htaccess into specified directory
* and maked it out of overriding
* @param string directory
* @return bool
*/
function makeDirectorySecure($directory)
{
$ret=$this->_writeToFile( $directory.".htaccess" , '<FilesMatch ".">'."\n".'order allow,deny'."\n".'deny from all'."\n".'</FilesMatch>');
if(!$ret)
return false;
$ret=$this->_writeToFile( $directory."index.html" , '');
if(!$ret)
return false;
return true;
}
/**
* Write to File
* writting or appending content to
* specefied file
* @param string $file
* @param string $content
* @param bool $append
* @return bool
*/
function _writeToFile($file,$content,$append=false)
{
$mode = $append ? "a+" : "w";
$fh=fopen($file,$mode);
$ret=fwrite($fh,$content);
fclose($fh);
return $ret;
}
/**
* Read File Content
* read content of file
* @param string filename
* @return string
*/
function _readFile($file)
{
$fh=fopen($file,"r");
$content = @fread($fh ,filesize($file));
@fclose($fh);
return $content;
}
/**
* Change File Mode
* change mode of file
* @see CHMOD
* @param string $path
* @param string $mode
* @return true
*/
function changeFileMode($path,$mode)
{
$cmd = "chmod ('$path',$mode);";
eval($cmd);
return true;
}
/**
* Assign Variable
* Assign a value to a variable name
* @param string $tplVarNamr
* @param string $tplVarValue
* @return true
*/
function assign( $tplVarName , $tplVarValue )
{
if (is_array($tplVarName)){
foreach ($tplVarName as $key => $val) {
if ($key != '') {
$this->_TplVars[$val] = $tplVarValue[$key];
}
}
} else {
if ($tplVarName != '')
$this->_TplVars[$tplVarName] = $tplVarValue;
}
}
/**
* Append to Variable Value
* merge append new value to old value
* @param string $tplVarName
* @param string $tplVarValue
* $return true
*/
function append( $tplVarName , $tplVarValue )
{
if ( isset( $this->_TplVars[$tplVarName] ) )
{
$this->_TplVars[$tplVarName] .= $tplVarValue;
}
else
{
$this->_TplVars[$tplVarName] = $tplVarValue;
}
}
/**
* Clear Template Varaible Value
* clear value of a template variable
* @param string $tplVarName
* @return true
*/
function clearTemplateVariable( $tplVarName )
{
if (is_array($tplVarName))
foreach ($tplVarName as $curr_var)
unset($this->_Tpl_Vars[$curr_var]);
else
unset($this->_Tpl_Vars[$tpl_var]);
}
/**
* Make Name For Cached File
* This method makeing a name from a file with
* path of itself, that can used for name of
* it`s cached file
* @param string $filename
* @return string
*/
function _makeCacheName($fileName)
{
$templateFilename = str_replace('/','%%',$fileName); /* this changes / in path to %% */
return '^^'.$templateFilename.'.php';
}
/**
* Real Path
* return real path with same slashes in windows and unix styles platform
* special thanx to carlosreche at yahoo dot com
* see complete information about realpath function in Manual
* @link http://www.php.net/manual/en/function.realpath.php
* @param string $path
* return string
*/
function real_path($path)
{
if ($path == "")
{
return false;
}
$path = trim(preg_replace("/\\\\/", "/", (string)$path));
if (!preg_match("/(\.\w{1,4})$/", $path) &&
!preg_match("/\?[^\\/]+$/", $path) &&
!preg_match("/\\/$/", $path))
{
$path .= '/';
}
$pattern = "/^(\\/|\w:\\/|https?:\\/\\/[^\\/]+\\/)?(.*)$/i";
preg_match_all($pattern, $path, $matches, PREG_SET_ORDER);
$path_tok_1 = $matches[0][1];
$path_tok_2 = $matches[0][2];
$path_tok_2 = preg_replace(
array("/^\\/+/", "/\\/+/"),
array("", "/"),
$path_tok_2);
$path_parts = explode("/", $path_tok_2);
$real_path_parts = array();
for ($i = 0, $real_path_parts = array(); $i < count($path_parts); $i++)
{
if ($path_parts[$i] == '.')
{
continue;
}
else if ($path_parts[$i] == '..')
{
if ( (isset($real_path_parts[0]) && $real_path_parts[0] != '..')
|| ($path_tok_1 != "") )
{
array_pop($real_path_parts);
continue;
}
}
array_push($real_path_parts, $path_parts[$i]);
}
return $path_tok_1 . implode('/', $real_path_parts);
}
/**
* Eval Command
* get an expression and do it with
* php interpreter
* @param string $cmd
* @return true;
*/
function _evalExp($cmd)
{
eval($cmd);
}
/**
* Check String
*
* @param string $str
* @return string
*/
function _checkString($str)
{
if (!get_magic_quotes_gpc())
$str=addslashes($str);
return $str;
}
/**
* Add New Unacceppted Word
* add new censor keyword , when $censorShipEnable is
* true in $this->show ,swap these word with swap word
* @param string $cWord
* @param string $sWord
* @return true
*/
function _addCensorWord($cWord,$sWord)
{
$_TplSpecialVars["_censor"][]=array("censor"=>$cWord,"swap"=>$sWord);
}
/**
* Add New Unicode Transferring
*
* @param string $from
* @param string $to
* @return true
*/
function _addUnicodeConverting($from,$to)
{
$_TplSpecialVars["_unicode"][]=array("from"=>$from,"to"=>$to);
}
/**
* Show Translated Template
* return the translated template,
* gzEnable send external as gz output buffer
* captureFile send external print to file
* $censorShip enable censoring output according
* to $this->_censorWord
* @param bool $gzEnable
* @param string|bool $captureFile
* @param bool $censorShipEnable
* @param bool $unicodeConver
* @return var
*/
function show($gzEnable=false,$captureFile=false,$censorShipEnable=false,$unicodeConvert=false)
{
$srcFile = $this->_TplDirectory.$this->_TplFileName;
$this->_compile($srcFile);
$cacheName = $this->_TplCacheDirectory.$this->_makeCacheName( $this->_TplDirectory.$this->_TplFileName );
if($captureFile && trim($captureFile)>"")
{
$this->_capture($captureFile,$censorShipEnable,$unicodeConvert);
return true;
}
else
{
$content = $this->_fetch($gzEnable,$censorShipEnable,$unicodeConvert);
print($content);
return true;
}
}
/**
* Capture OutPut
* Capture output of translated source to
* specefic file
* @param string $file
* @param bool $censorShipEnable
* @param bool $unicodeConver
* $return true
*/
function _capture($file,$censorShipEnable,$unicodeConvert)
{
$content = $this->_fetch(false,$censorShipEnable,$unicodeConvert);
$file=$this->real_path(GEDAR_MAINDIR.$file);
$this->_writeToFile($file,$content);
return true;
}
/**
* Fetch Output
* get output buffer
* @param bool $gzEnable
* @param bool $censorShipEnable
* @param bool $unicodeConver
* @return string
*/
function _fetch($gzEnable=false,$censorShipEnable,$unicodeConvert)
{
$srcFile=$this->_TplDirectory.$this->_TplFileName;
$cacheName = $this->_TplCacheDirectory.$this->_makeCacheName($srcFile);
/* start buffering ... */
if($gzEnable)
ob_start('ob_gzhandler');
else
ob_start();
include $cacheName;
$content = ob_get_contents();
ob_end_clean(); /* finish buffering. */
/* censorshiping... */
if($censorShipEnable)
{
foreach($_TplSpecialVars['_censor'] as $censor)
{
$content=str_replace($censor["censor"],$censor["swap"],$content);
}
}
if($unicodeConvert)
{
foreach($_TplSpecialVars['_unicode'] as $unicode)
{
$content=iconv($unicode['from'],$unicode['to'],$content);
}
}
return $content;
}
}
?>