/*
* @(#)Class.Fasttemplate.php 1.1.1 2002/05/10
* Original Perl module CGI::FastTemplate by Jason Moore jmoore@sober.com
* PHP3 port by CDI cdi@thewebmasters.net
* PHP3 Version Copyright (c) 1999 CDI, cdi@thewebmasters.net,
* All Rights Reserved.
* Perl Version Copyright (c) 1998 Jason Moore jmoore@sober.com.
* All Rights Reserved.
* This program is free software; you can redistribute it and/or modify it
* under the GNU General Artistic License, with the following stipulations:
* Changes or modifications must retain these Copyright statements. Changes
* or modifications must be submitted to both AUTHORS.
* This program is released under the General Artistic License.
* 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 Artistic
* License for more details. This software is distributed AS-IS.
*
* AiK' modifications:
* -- more strict dynamic templates handling, including "silently removing"
* of unassigned dynamic blocks
* -- showDebugInfo() method that print into html conole some debug info
*/
/**
* The FastTemplate
class provides easy and quite fast
* template handling functionality.
* @author Jason Moore jmoore@sober.com.
* @author CDI cdi@thewebmasters.net
* @author Artyem V. Shkondin aka AiK artvs@clubpro.spb.ru
* @version 1.1.2
*/
class FastTemplate {
var $FILELIST = array(); // Holds the array of filehandles
// FILELIST[HANDLE] == "fileName"
var $DYNAMIC = array(); // Holds the array of dynamic
// blocks, and the fileHandles they
// live in.
var $PARSEVARS = array(); // Holds the array of Variable
// handles.
// PARSEVARS[HANDLE] == "value"
var $LOADED = array(); // We only want to load a template
// once - when it's used.
// LOADED[FILEHANDLE] == 1 if loaded
// undefined if not loaded yet.
var $HANDLE = array(); // Holds the handle names assigned
// by a call to parse()
var $ROOT = ""; // Holds path-to-templates
var $WIN32 = false; // Set to true if this is a WIN32 server
var $ERROR = ""; // Holds the last error message
var $LAST = ""; // Holds the HANDLE to the last
// template parsed by parse()
var $STRICT = true; // Strict template checking.
// Unresolved vars in templates will
// generate a warning when found.
//by AiK
var $start; // holds time of start generation
/**
* Constructor.
* @param $pathToTemplates template root.
* @return FastTemplate
*/
function FastTemplate ($pathToTemplates = ""){
global $php_errormsg;
if(!empty($pathToTemplates)){
$this->set_root($pathToTemplates);
}
// by AiK
$this->start = $this->utime();
} // end (new) FastTemplate ()
/**
* Sets template root
* All templates will be loaded from this "root" directory
* Can be changed in mid-process by re-calling with a new
* value.
* @param $root path to templates dir
* @return void
*/
function set_root ($root){
$trailer = substr($root,-1);
if(!$this->WIN32){
if( (ord($trailer)) != 47 ){
$root = "$root". chr(47);
}
if(is_dir($root)){
$this->ROOT = $root;
}else{
$this->ROOT = "";
$this->error("Specified ROOT dir [$root] is not a directory");
}
}else{
// WIN32 box - no testing
if( (ord($trailer)) != 92 ){
$root = "$root" . chr(92);
}
$this->ROOT = $root;
}
} // End set_root()
/**
* Calculates current microtime
* I throw this into all my classes for benchmarking purposes
* It's not used by anything in this class and can be removed
* if you don't need it.
* @return void
*/
function utime () {
$time = explode( " ", microtime());
$usec = (double)$time[0];
$sec = (double)$time[1];
return $sec + $usec;
}
/**
* Strict template checking, if true sends warnings to STDOUT when
* parsing a template with undefined variable references
* Used for tracking down bugs-n-such. Use no_strict() to disable.
* @return void
*/
function strict (){
$this->STRICT = true;
}
/**
* Silently discards (removes) undefined variable references
* found in templates
* @return void
*/
function no_strict (){
$this->STRICT = false;
}
/**
* A quick check of the template file before reading it.
* This is -not- a reliable check, mostly due to inconsistencies
* in the way PHP determines if a file is readable.
* @return boolean
*/
function is_safe ($filename){
if(!file_exists($filename)){
$this->error("[$filename] does not exist",0);
return false;
}
return true;
}
/**
* Grabs a template from the root dir and
* reads it into a (potentially REALLY) big string
* @param $template template name
* @return string
*/
function get_template ($template){
if(empty($this->ROOT)){
$this->error("Cannot open template. Root not valid.",1);
return false;
}
$filename = "$this->ROOT"."$template";
$contents = implode("",(@file($filename)));
if( (!$contents) or (empty($contents)) ){
$this->error("get_template() failure: [$filename] $php_errormsg",1);
}
return $contents;
} // end get_template
/**
* Prints the warnings for unresolved variable references
* in template files. Used if STRICT is true
* @param $Line string for variable references checking
* @return void
*/
function show_unknowns ($Line){
$unknown = array();
if (ereg("({[A-Z0-9_]+})",$Line,$unknown)) {
$UnkVar = $unknown[1];
if(!(empty($UnkVar))){
@error_log("[FastTemplate] Warning: no value found for variable: $UnkVar ",0);
}
}
} // end show_unknowns()
/**
* This routine get's called by parse() and does the actual
* {VAR} to VALUE conversion within the template.
* @param $template string to be parsed
* @param $tpl_array array of variables
* @return string
* @author CDI cdi@thewebmasters.net
* @author Artyem V. Shkondin artvs@clubpro.spb.ru
* @version 1.1.1
*/
function parse_template ($template, $tpl_array){
while ( list ($key,$val) = each ($tpl_array) ){
if (!(empty($key))){
if(gettype($val) != "string"){
settype($val,"string");
}
//php4 doesn't like '{$' combinations.
$key = '{'."$key".'}';
$template = ereg_replace("$key","$val","$template");
//$template = str_replace("$key","$val","$template");
}
}
if(!$this->STRICT){
// Silently remove anything not already found
$template = ereg_replace("{([A-Z0-9_]+)}","",$template);
//by AiK: remove dynamic blocks
$lines = split("\n",$template);
$inside_block = false;
$template="";
while (list ($num,$line) = each($lines) ){
if (substr_count($line, "" == "$lineTest" )
{
$start = true;
$end = false;
$outside = false;
}
if("" == "$lineTest" )
{
$start = false;
$end = true;
$outside = true;
}
if( (!$outside) and (!$start) and (!$end) )
{
$newMacro .= "$lineData\n"; // Restore linebreaks
}
if( ($outside) and (!$start) and (!$end) )
{
$newParent .= "$lineData\n"; // Restore linebreaks
}
if($end)
{
$newParent .= '{'."$MacroName}\n";
}
// Next line please
if($end) { $end = false; }
if($start) { $start = false; }
} // end While
$this->$Macro = $newMacro;
$this->$ParentTag = $newParent;
return true;
} // $ParentTag NOT loaded - MAJOR oopsie
else
{
@error_log("ParentTag: [$ParentTag] not loaded!",0);
$this->error("ParentTag: [$ParentTag] not loaded!",0);
}
return false;
}
// ************************************************************
// Strips a DYNAMIC BLOCK from a template.
function clear_dynamic ($Macro="")
{
if(empty($Macro)) { return false; }
// The file must already be in memory.
$ParentTag = $this->DYNAMIC["$Macro"];
if( (!$this->$ParentTag) or (empty($this->$ParentTag)) )
{
$fileName = $this->FILELIST[$ParentTag];
$this->$ParentTag = $this->get_template($fileName);
$this->LOADED[$ParentTag] = 1;
}
if($this->$ParentTag)
{
$template = $this->$ParentTag;
$DataArray = split("\n",$template);
$newParent = "";
$outside = true;
$start = false;
$end = false;
while ( list ($lineNum,$lineData) = each ($DataArray) )
{
$lineTest = trim($lineData);
if("" == "$lineTest" )
{
$start = true;
$end = false;
$outside = false;
}
if("" == "$lineTest" )
{
$start = false;
$end = true;
$outside = true;
}
if( ($outside) and (!$start) and (!$end) )
{
$newParent .= "$lineData\n"; // Restore linebreaks
}
// Next line please
if($end) { $end = false; }
if($start) { $start = false; }
} // end While
$this->$ParentTag = $newParent;
return true;
} // $ParentTag NOT loaded - MAJOR oopsie
else
{
@error_log("ParentTag: [$ParentTag] not loaded!",0);
$this->error("ParentTag: [$ParentTag] not loaded!",0);
}
return false;
}
// ************************************************************
function define ($fileList)
{
while ( list ($FileTag,$FileName) = each ($fileList) )
{
$this->FILELIST["$FileTag"] = $FileName;
}
return true;
}
// ************************************************************
function clear_parse ( $ReturnVar = "")
{
$this->clear($ReturnVar);
}
// ************************************************************
function clear ( $ReturnVar = "" )
{
// Clears out hash created by call to parse()
if(!empty($ReturnVar))
{
if( (gettype($ReturnVar)) != "array")
{
unset($this->$ReturnVar);
return;
}
else
{
while ( list ($key,$val) = each ($ReturnVar) )
{
unset($this->$val);
}
return;
}
}
// Empty - clear all of them
while ( list ( $key,$val) = each ($this->HANDLE) )
{
$KEY = $key;
unset($this->$KEY);
}
return;
} // end clear()
// ************************************************************
function clear_all ()
{
$this->clear();
$this->clear_assign();
$this->clear_define();
$this->clear_tpl();
return;
} // end clear_all
// ************************************************************
function clear_tpl ($fileHandle = "")
{
if(empty($this->LOADED))
{
// Nothing loaded, nothing to clear
return true;
}
if(empty($fileHandle))
{
// Clear ALL fileHandles
while ( list ($key, $val) = each ($this->LOADED) )
{
unset($this->$key);
}
unset($this->LOADED);
return true;
}
else
{
if( (gettype($fileHandle)) != "array")
{
if( (isset($this->$fileHandle)) || (!empty($this->$fileHandle)) )
{
unset($this->LOADED[$fileHandle]);
unset($this->$fileHandle);
return true;
}
}
else
{
while ( list ($Key, $Val) = each ($fileHandle) )
{
unset($this->LOADED[$Key]);
unset($this->$Key);
}
return true;
}
}
return false;
} // end clear_tpl
// ************************************************************
function clear_define ( $FileTag = "" )
{
if(empty($FileTag))
{
unset($this->FILELIST);
return;
}
if( (gettype($Files)) != "array")
{
unset($this->FILELIST[$FileTag]);
return;
}
else
{
while ( list ( $Tag, $Val) = each ($FileTag) )
{
unset($this->FILELIST[$Tag]);
}
return;
}
}
// ************************************************************
// Aliased function - used for compatibility with CGI::FastTemplate
/* function clear_parse ()
{
$this->clear_assign();
}
*/
// ************************************************************
// Clears all variables set by assign()
function clear_assign ()
{
if(!(empty($this->PARSEVARS)))
{
while(list($Ref,$Val) = each ($this->PARSEVARS) )
{
unset($this->PARSEVARS["$Ref"]);
}
}
}
// ************************************************************
function clear_href ($href)
{
if(!empty($href))
{
if( (gettype($href)) != "array")
{
unset($this->PARSEVARS[$href]);
return;
}
else
{
while (list ($Ref,$val) = each ($href) )
{
unset($this->PARSEVARS[$Ref]);
}
return;
}
}
else
{
// Empty - clear them all
$this->clear_assign();
}
return;
}
// ************************************************************
/**
* assign variables
*/
function assign ($tpl_array, $trailer="")
{
if(gettype($tpl_array) == "array")
{
while ( list ($key,$val) = each ($tpl_array) )
{
if (!(empty($key)))
{
// Empty values are allowed
// Empty Keys are NOT
$this->PARSEVARS["$key"] = $val;
}
}
}
else
{
// Empty values are allowed in non-array context now.
if (!empty($tpl_array))
{
$this->PARSEVARS["$tpl_array"] = $trailer;
}
}
}
// ************************************************************
// Return the value of an assigned variable.
// Christian Brandel cbrandel@gmx.de
function get_assigned($tpl_name = "")
{
if(empty($tpl_name)) { return false; }
if(isset($this->PARSEVARS["$tpl_name"]))
{
return ($this->PARSEVARS["$tpl_name"]);
}
else
{
return false;
}
}
// ************************************************************
function error ($errorMsg, $die = 0)
{
$this->ERROR = $errorMsg;
echo "ERROR: $this->ERROR
\n";
if ($die == 1)
{
exit;
}
return;
} // end error()
// ************************************************************
/**
* Prints debug info into console
* @return void
* @author AiK
* @since 1.1.1
*/
function showDebugInfo(){
$tm = $this->utime() - $this->start;
// print time
print "
";
}//end of showDebugInfo()
/**
*
*/
function printarray($arr,$caption){
if (count($arr)!=0){
print "
_debug_console.document.write('$caption ');\n
_debug_console.document.write(\"
key | value |
---|---|
$key | $val |