PHP Classes

File: class.InTemplate.php

Recommend this page to a friend!
  Classes of Eris Ristemena   InTemplate   class.InTemplate.php   Download  
File: class.InTemplate.php
Role: ???
Content type: text/plain
Description: InTemplate Class
Class: InTemplate
Modified version of CDI's Fast Template
Author: By
Last change:
Date: 22 years ago
Size: 30,421 bytes
 

Contents

Class file image Download
<?php /** * This is a modified version of CDI's FastTemplates * * FastTemplates was originally written by some nice guys from * CDI <cdi@thewebmasters.net>, you can find the sources * here : http://www.thewebmasters.net/php/ * * Since it was written back then when we still using PHP3, * there are many 'old' function that should be replaced * to gain a faster yet reliable templating system. Which * I (and you) despradly need. * * So, one day (many days actually), I push myself to sit down * and try to crank it down. * * Anyway, InTemplate goes to InArtS Multimedia (http://www.inartsmultimedia.com) * the place where i get the real money ... :) * * @author Eris Ristemena <eristemena@yahoo.com> * @vesion $Id: class.InTemplate.php,v 0.3 2002/01/10 07:07:39 eris Exp $ */ class InTemplate { /** * Holds the array of filehandles mFileList[HANDLE] == "fileName" * * @var array */ var $mFileList = array(); /** * Holds the array of dynamic blocks, * and the fileHandles they live in. * * @var array */ var $mDynamic = array(); /** * Holds the array of Variable handles. * mParseVars[HANDLE] == "value" * * @var array */ var $mParseVars = array(); /** * We only want to load a template once - when it's used. * mLoaded[FILEHANDLE] == 1 if loaded undefined if not loaded yet. * * @var array */ var $mLoaded = array(); /** * Holds the handle names assigned by a call to parse() * * @var array */ var $mHandle = array(); /** * Holds the handle names for selang-seling * * @var array */ var $mSeling = array(); /** * Holds path-to-templates * * @var string */ var $mRoot = ""; /** * Set to true if this is a WIN32 server * * @var boolean */ var $mWin32 = false; /** * Holds the last error message * * @var string */ var $mError = ""; /** * Holds the HANDLE to the last template parsed by parse() * * @var string */ var $mLast = ""; /** * Strict template checking. * If it's set to true then unresolved vars in templates will generate a warning when found. * For some reasons, i made this default to false. * * @var boolean */ var $mStrict = false; /** * Set the directory which all templates reside * * @param string $pathToTemplates path to templates */ function InTemplate( $pathToTemplates = "" ) { if(!empty($pathToTemplates)) { $this->SetRoot($pathToTemplates); } } // end InTemplate /** * All templates will be loaded from this "root" directory. * Can be changed in mid-process by re-calling with a new * value. * * @param string $root root directory */ function SetRoot( $root ) { $trailer = substr($root,-1); if(!$this->mWin32) { if( (ord($trailer)) != 47 ) { $root = "$root". chr(47); } if(is_dir($root)) { $this->mRoot = $root; } else { $this->mRoot = ""; $this->Error("Specified ROOT dir [$root] is not a directory"); } } else { // WIN32 box - no testing if( (ord($trailer)) != 92 ) { $root = "$root" . chr(92); } $this->mRoot = $root; } } // End SetRoot /** * A quick check of the template file before reading it. * This should check if the file is safe to read, * it means the file really exists and the permission * allowed us to read it. [UNFINISHED] * * @param string $fileName file name for checking * @return boolean */ function IsSafe( $fileName ) { if(file_exists($fileName)) { return true; } else { $this->Error("[$fileName] does not exist",0); return false; } } // end IsSafe /** * Grabs a template from the root dir and * reads it into a (potentially REALLY) big string * * @param string $template name of template's file * @return string $contents contents of the template */ function GetTemplate( $template ) { if (empty($this->mRoot)) { $this->Error("Cannot open template. Root not valid.",1); return false; } $file_name = "$this->mRoot"."$template"; if ($this->IsSafe($file_name)) { $contents = implode("",(@file($file_name))); if( (!$contents) or (empty($contents)) ) { $this->Error("GetTemplate() failure: [$filename] $php_errormsg",1); } return $contents; } } // end GetTemplate /** * Maps a template filename to a (usually shorter) name. * This new name is the name that you will use to refer to the templates. * Let's just call it 'file tag'. * In InTemplate, this routine will also search any dynamic block which * resides in the associated file. And defines them using $this->DefineDynamic(). * Cute isn't it ? *_* * * @param array $fileList array of template files * @return boolean * @access public */ function Define( $fileList ) { while ( list ($FileTag,$FileName) = each ($fileList) ) { $this->mFileList["$FileTag"] = $FileName; preg_match_all("/<!-- BEGIN DYNAMIC BLOCK: (.+) -->.*\{(.+)\}.*<!-- END DYNAMIC BLOCK: (.+) -->/sm",$this->GetTemplate($FileName),$matches); for ($i=0; $i< count($matches[0]); $i++) { $this->DefineDynamic($matches[2][$i],$FileTag); } } } // end Define /** * A dynamic block lives inside another template file. * It will be stripped from the template when parsed * and replaced with the {$Tag}. * * @param string $Macro macro's name for dynamic block * @param string $fileTag file tag where the block resides * @access public */ function DefineDynamic( $Macro, $fileTag ) { $this->mDynamic["$Macro"] = $fileTag; } // end DefineDynamic /** * Assigns values for var. * * @param array $parseVars array(var,value) or just a var (with value in trailer) * @param string $trailer the value used only if $parseVars is not an array * @access public */ function Assign($parseVars, $trailer="") { if(gettype($parseVars) == "array") { while ( list ($var,$val) = each ($parseVars) ) { if (!(empty($var))) { // Empty values are allowed // Empty Keys are NOT $this->mParseVars["$var"] = $val; } } } else { // Empty values are allowed in non-array context now. if (!empty($parseVars)) { $this->mParseVars["$parseVars"] = $trailer; } } } // end Assign /** * This routine does the actual {VAR} to VALUE conversion within the template. * I made a 'crucial' change here, i used str_replace instead of ereg_replace. * That's why this class should go faster than the old InTemplates. * * @param string $template the template befor parsing * @param array $parseVars array(var,value) * @return string $template the template after parsing * @see Parse() */ function ParseTemplate( $template, $parseVars ) { while ( list ($key,$val) = each ($parseVars) ) { if (!(empty($key))) { if(gettype($val) != "string") { settype($val,"string"); } $template = str_replace("\{$key}","$val","$template"); } } return $template; } // end ParseTemplate /** * The meat of the whole class. The magic happens here. * * @param string $ReturnVar the return variable * @param array $FileTags file tags * @param array $lowerVar lower var, for cascading block * @see Define() * @see DefineDynamic() * @see ParseTemplate() * @access public */ function Parse( $ReturnVar, $FileTags, $lowerVar = "" ) { $append = false; $this->mLast = $ReturnVar; $this->mHandle[$ReturnVar] = $FileTags; // this conditional block is used for cascading block with lower var = $lowerVar if (!empty($lowerVar)) { // reset the lower macro $this->ClearParse($lowerVar); // if the lower Tag is a dynamic alternating block then reset the index $lower_tag = $this->mHandle[$lowerVar]; if( (substr($lower_tag,0,1)) == '+' ) { $lower_tag = substr($lower_tag,1); $this->mSeling[$lower_tag][index] = 0; } } if (gettype($FileTags) == "array") { unset($this->$ReturnVar); // Clear any previous data while ( list ( $key , $file_tag ) = each ( $FileTags ) ) { if ( (!isset($this->$file_tag)) || (empty($this->$file_tag)) ) { $this->mLoaded["$file_tag"] = 1; // file tag $file_tag has been loaded if(isset($this->mDynamic["$file_tag"])) { $this->ParseDynamic($file_tag,$ReturnVar); } else { $file_name = $this->mFileList["$file_tag"]; $this->$file_tag = $this->GetTemplate($file_name); } } // Array context implies overwrite $this->$ReturnVar = $this->ParseTemplate($this->$file_tag,$this->mParseVars); // For recursive calls. $this->Assign( array( $ReturnVar => $this->$ReturnVar ) ); } } else { // FileTags is not an array $file_tag = $FileTags; // look dummy? ya but it has some points if( (substr($file_tag,0,1)) == '.') // dynamic block { // Append this template to a previous ReturnVar $append = true; $file_tag = substr($file_tag,1); } if( (substr($file_tag,0,1)) == '+' ) // dynamic alternation block { // Append this template to a previous ReturnVar $append = true; $file_tag = substr($file_tag,1); // set as alternation (the first time altered) and increment for indexing purpose $this -> mSeling[$file_tag][index] += 1; // sorry, this is for cascading puspose only $this -> mSeling[$file_tag][macro] = $ReturnVar; } if ( (!isset($this->$file_tag)) || (empty($this->$file_tag)) ) { $this->mLoaded["$file_tag"] = 1; if (isset($this->mDynamic["$file_tag"]) && isset($this->mSeling[$file_tag][index])) { $this->ParseDynamic($ReturnVar, $file_tag, 1); } elseif (isset($this->mDynamic["$file_tag"]) && !isset($this -> mSeling[$file_tag][index])) { $this->ParseDynamic($ReturnVar, $file_tag); } else { $fileName = $this->mFileList["$file_tag"]; $this->$file_tag = $this->GetTemplate($fileName); } } if($append) { if ( isset($this -> mSeling[$file_tag][index]) ) { ($this->mSeling[$file_tag][index] % 2) ? $macro = $this->mSeling[$file_tag][selang] : $macro = $this->mSeling[$file_tag][seling]; $this->$ReturnVar .= $this->ParseTemplate($macro,$this->mParseVars); } else { $this->$ReturnVar .= $this->ParseTemplate($this->$file_tag,$this->mParseVars); } } else { $this->$ReturnVar = $this->ParseTemplate($this->$file_tag,$this->mParseVars); } // For recursive calls. $this->assign( array($ReturnVar => $this->$ReturnVar) ); } return; } // End Parse /** * Parse a dynamic block * * @param string $MacroName name of the new var for the replacement of dynamic block * @param string $Macro name of the parent's tag * @param string $alt set if alternation mode is used * @see DefineDynamic() */ function ParseDynamic( $MacroName, $Macro, $alt = "" ) { // The file must already be in memory. $ParentTag = $this->mDynamic["$Macro"]; if( (!$this->$ParentTag) or (empty($this->$ParentTag)) ) { $fileName = $this->mFileList[$ParentTag]; $this->$ParentTag = $this->GetTemplate($fileName); $this->mLoaded[$ParentTag] = 1; } if($this->$ParentTag) { $template = $this->$ParentTag; $DataArray = split("\n",$template); $newMacro = ""; $newParent = ""; $outside = true; $start = false; $end = false; while ( list ($lineNum,$lineData) = each ($DataArray) ) { $lineTest = trim($lineData); if("<!-- BEGIN DYNAMIC BLOCK: $Macro -->" == "$lineTest" ) { $start = true; $end = false; $outside = false; } if("<!-- END DYNAMIC BLOCK: $Macro -->" == "$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 if (!empty($alt)) { // this is where the alternating does the work ... *ting* $_newMacro = explode("<!-- ALTERNATING -->", $newMacro); $this->mSeling[$Macro][selang] = $_newMacro[0]; $this->mSeling[$Macro][seling] = $_newMacro[1]; $this->$Macro = ((($indexSelangSeling % 2) == 0) ? $_newMacro[0] : $_newMacro[1]); } else { $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; } // end ParseDynamic /** * Print the templates which has been modified. * * @param $template * @access public */ function InPrint( $template = "" ) { if(empty($template)) { $template = $this->mLast; } if( (!(isset($this->$template))) || (empty($this->$template)) ) { $this->Error("Nothing parsed, nothing printed",0); return; } else { if ( !$this->mStrict ) { // Silently removes any unparsed dynamic blocks $this->ClearAllDynamic(); // Silently removes any InTemplate Vars that has been resolved $this->$template = preg_replace("|\{([A-Za-z0-9_]+)}|","",$this->$template); } else { // Warn about unresolved InTemplate Vars preg_match_all("/\{([A-Za-z0-9_]+)\}/",$this->$template,$unresolved); for ($i=0;$i<count($unresolved[0]);$i++) { $this->ShowUnknowns($unresolved[1][$i]); } } print $this->$template; } return; } // end InPrint /** * Returns the raw data from a parsed handle. * * @param string $template name of the templates * @access public */ function Fetch( $template = "" ) { if(empty($template)) { $template = $this->mLast; } if( (!(isset($this->$template))) || (empty($this->$template)) ) { $this->Error("Nothing parsed, nothing printed",0); return ""; } if ( !$this->mStrict ) { // Silently removes any unparsed dynamic blocks $this->ClearAllDynamic(); // Silently removes any InTemplate Vars that has been resolved $this->$template = preg_replace("|\{([A-Za-z0-9_]+)}|","",$this->$template); } return($this->$template); } // end Fetch /** * Strips a DYNAMIC BLOCK from a template. * * @param string $Macro * @return boolean * @access public */ function ClearDynamic( $Macro = "" ) { if(empty($Macro)) { return false; } else { // The file must already be in memory. $ParentTag = $this->mDynamic["$Macro"]; if( (!$this->$ParentTag) or (empty($this->$ParentTag)) ) { $fileName = $this->mFileList[$ParentTag]; $this->$ParentTag = $this->GetTemplate($fileName); $this->mLoaded[$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("<!-- BEGIN DYNAMIC BLOCK: $Macro -->" == "$lineTest" ) { $start = true; $end = false; $outside = false; } if("<!-- END DYNAMIC BLOCK: $Macro -->" == "$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; } } // end ClearDynamic /** * Strips all unparsed DYNAMIC BLOCK from the last parsed template. * Silly ? nope, if you use this routine last before you print the * final templates. * * @access public */ function ClearAllDynamic() { // strips all dynamic block that hasnt been parsed $template = $this->mLast; $this->$template = preg_replace("/<!-- BEGIN DYNAMIC BLOCK: (.+) -->.*\{(.+)\}.*<!-- END DYNAMIC BLOCK: (.+) -->/sm","",$this->$template); } // end ClearAllDynamic /** * Removes a given reference from the list of refs that is built using: $tpl->Assign(KEY = val); * * If called with no arguments, it removes all references from the array. * * @param string $returnVar clear any parsed variable from Assign() * @see Assign() * @see Clear() * @access public */ function ClearParse( $returnVar = "") { $this->clear($returnVar); } // end ClearParse /** * General clearance * * @param string $returnVar macro, filetag or var * @see ClearParse() * @see ClearDefine() */ 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->mHandle) ) { $KEY = $key; unset($this->$KEY); } return; } // end Clear /** * Clear all * * @access public */ function ClearAll() { $this->Clear(); $this->clear_assign(); $this->clear_define(); $this->clear_tpl(); return; } // end ClearAll /** * Clear templates * * @param $fileHandle * @access public */ function ClearTemplate( $fileHandle = "" ) { if(empty($this->mLoaded)) { // Nothing loaded, nothing to clear return true; } if(empty($fileHandle)) { // Clear ALL fileHandles while ( list ($key, $val) = each ($this->mLoaded) ) { unset($this->$key); } unset($this->mLoaded); return true; } else { if( (gettype($fileHandle)) != "array") { if( (isset($this->$fileHandle)) || (!empty($this->$fileHandle)) ) { unset($this->mLoaded[$fileHandle]); unset($this->$fileHandle); return true; } } else { while ( list ($Key, $Val) = each ($fileHandle) ) { unset($this->mLoaded[$Key]); unset($this->$Key); } return true; } } return false; } // end ClearTemplate /** * Clears the internal list that stores data passed to $tpl->define(); * * @param string $fileTag file tag * @access public */ function ClearDefine( $fileTag = "" ) { if(empty($fileTag)) { unset($this->mFileList); return; } if( (gettype($Files)) != "array") { unset($this->mFileList[$fileTag]); return; } else { while ( list ( $Tag, $Val) = each ($fileTag) ) { unset($this->mFileList[$Tag]); } return; } } // end ClearDefine /** * Clears all variables set by assign() * * @access public */ function ClearAssign() { if(!(empty($this->mParseVars))) { while(list($Ref,$Val) = each ($this->mParseVars) ) { unset($this->mParseVars["$Ref"]); } } } // end ClearAssign /** * Clears all href * * @param string $href href * @class public */ function ClearHref( $href ) { if(!empty($href)) { if( (gettype($href)) != "array") { unset($this->mParseVars[$href]); return; } else { while (list ($Ref,$val) = each ($href) ) { unset($this->mParseVars[$Ref]); } return; } } else { // Empty - clear them all $this->clear_assign(); } return; } // end ClearHref /** * Prints the warnings for unresolved InTemplate variable. * Used if mStrict is set true * * @param string $unkVar the unknownvars * @access public */ function ShowUnknowns( $unkVar ) { @error_log("[InTemplate] Warning: no value found for variable: $unkVar ",0); } // end ShowUnknowns /** * Prints any error message. * * @param string $errorMsg Error messages * @param boolean $die whether exit or not after prints */ function Error( $errorMsg, $die = 0 ) { $this->mError = $errorMsg; echo "ERROR: $this->mError <BR> \n"; if ($die == 1) { exit; } return; } // end Error /** * 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. * * @param string $root root directory */ function utime () { $time = explode( " ", microtime()); $usec = (double)$time[0]; $sec = (double)$time[1]; return $sec + $usec; } // end utime /** * 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. * * @access public */ function Strict () { $this->mStrict = true; } // end Strict /** * Silently discards (removes) undefined variable references * found in templates * * @access public */ function NoStrict() { $this->mStrict = false; } // end NoStrict /** * Return the value of an assigned variable. * * @param string $tpl_name template name * @return boolean * @access public */ function GetAssigned($tpl_name = "") { if(empty($tpl_name)) { return false; } if(isset($this->mParseVars["$tpl_name"])) { return ($this->mParseVars["$tpl_name"]); } else { return false; } } // end GetAssigned /** * Handle any included file using include() * I'm sure there are some other better ways to do this * * @param string $Macro current macro * @param string $includeFile included file * @param array $passedVars passed vars * @access public * */ function AssignInclude ( $Macro, $includeFile, $passedVars = '' ) { global $HTTP_POST_VARS, $HTTP_GET_VARS; ob_start(); if ( is_array($passedVars) ) { foreach( $passedVars as $k=>$v ) { $$k = $v; } } include $includeFile; $fp=ob_get_contents(); ob_end_clean(); $this->assign ( $Macro, $fp ); } // end AssignInclude } // End class InTemplate ?>