+++ /dev/null
-<?php\r
-/**\r
-* Integrated Template - IT\r
-* \r
-* Well there's not much to say about it. I needed a template class that\r
-* supports a single template file with multiple (nested) blocks inside.\r
-* \r
-* Usage:\r
-* $tpl = new IntegratedTemplate( [string filerootdir] );\r
-* \r
-* // load a template or set it with setTemplate()\r
-* $tpl->loadTemplatefile( string filename [, boolean removeUnknownVariables, boolean removeEmptyBlocks] )\r
-*\r
-* // set "global" Variables meaning variables not beeing within a (inner) block\r
-* $tpl->setVariable( string variablename, mixed value );\r
-* \r
-* // like with the Isotopp Templates there's a second way to use setVariable()\r
-* $tpl->setVariable( array ( string varname => mixed value ) );\r
-* \r
-* // Let's use any block, even a deeply nested one\r
-* $tpl->setCurrentBlock( string blockname );\r
-*\r
-* // repeat this as often as you neer. \r
-* $tpl->setVariable( array ( string varname => mixed value ) );\r
-* $tpl->parseCurrentBlock();\r
-*\r
-* // get the parsed template or print it: $tpl->show()\r
-* $tpl->get();\r
-* \r
-* @author Ulf Wendel <uw@netuse.de>\r
-* @version $Id: IT.php,v 1.4 2000/12/03 20:30:42 uw Exp $\r
-* @access public\r
-* @package PHPDoc\r
-*/\r
-class IntegratedTemplate {\r
-\r
- /**\r
- * Contains the error objects\r
- * @var array\r
- * @access public\r
- * @see halt(), $printError, $haltOnError\r
- */\r
- var $err = array();\r
- \r
- /**\r
- * Print error messages?\r
- * @var boolean\r
- * @access public\r
- * @see halt(), $haltOnError, $err\r
- */\r
- var $printError = false;\r
- \r
- /**\r
- * Call die() on error?\r
- * @var boolean\r
- * @access public\r
- * @see halt(), $printError, $err\r
- */\r
- var $haltOnError = false;\r
- \r
- /**\r
- * Clear cache on get()? \r
- * @var boolean\r
- */ \r
- var $clearCache = false;\r
- \r
- /**\r
- * First character of a variable placeholder ( _{_VARIABLE} ).\r
- * @var string\r
- * @access public\r
- * @see $closingDelimiter, $blocknameRegExp, $variablenameRegExp\r
- */\r
- var $openingDelimiter = "{";\r
- \r
- /**\r
- * Last character of a variable placeholder ( {VARIABLE_}_ ).\r
- * @var string\r
- * @access public\r
- * @see $openingDelimiter, $blocknameRegExp, $variablenameRegExp\r
- */\r
- var $closingDelimiter = "}";\r
- \r
- /**\r
- * RegExp matching a block in the template. \r
- * Per default "sm" is used as the regexp modifier, "i" is missing.\r
- * That means a case sensitive search is done.\r
- * @var string\r
- * @access public\r
- * @see $variablenameRegExp, $openingDelimiter, $closingDelimiter\r
- */\r
- var $blocknameRegExp = "[0-9A-Za-z_-]+";\r
- \r
- /**\r
- * RegExp matching a variable placeholder in the template.\r
- * Per default "sm" is used as the regexp modifier, "i" is missing.\r
- * That means a case sensitive search is done.\r
- * @var string \r
- * @access public\r
- * @see $blocknameRegExp, $openingDelimiter, $closingDelimiter\r
- */\r
- var $variablenameRegExp = "[0-9A-Za-z_-]+";\r
- \r
- /**\r
- * Full RegExp used to find variable placeholder, filled by the constructor.\r
- * @var string Looks somewhat like @(delimiter varname delimiter)@\r
- * @see IntegratedTemplate()\r
- */\r
- var $variablesRegExp = "";\r
- \r
- /**\r
- * Full RegExp used to find blocks an their content, filled by the constructor.\r
- * @var string\r
- * @see IntegratedTemplate()\r
- */\r
- var $blockRegExp = "";\r
- \r
- /**\r
- * Name of the current block.\r
- * @var string\r
- */\r
- var $currentBlock = "__global__";\r
-\r
- /**\r
- * Content of the template.\r
- * @var string\r
- */ \r
- var $template = "";\r
- \r
- /**\r
- * Array of all blocks and their content.\r
- * \r
- * @var array\r
- * @see findBlocks()\r
- */ \r
- var $blocklist = array();\r
- \r
- /**\r
- * Array with the parsed content of a block.\r
- *\r
- * @var array\r
- */\r
- var $blockdata = array();\r
- \r
- /**\r
- * Array of variables in a block.\r
- * @var array\r
- */\r
- var $blockvariables = array();\r
-\r
- /**\r
- * Array of inner blocks of a block.\r
- * @var array\r
- */ \r
- var $blockinner = array();\r
- \r
- /**\r
- * Future versions will use this...\r
- * @var array\r
- */\r
- var $blocktypes = array();\r
- \r
- /**\r
- * Variable cache.\r
- *\r
- * Variables get cached before any replacement is done.\r
- * Advantage: empty blocks can be removed automatically.\r
- * Disadvantage: might take some more memory\r
- * \r
- * @var array\r
- * @see setVariable(), $clearCacheOnParse\r
- */\r
- var $variableCache = array();\r
- \r
- /**\r
- * @var boolean\r
- */\r
- var $clearCacheOnParse = true;\r
- \r
- /**\r
- * Controls the handling of unknown variables, default is remove.\r
- * @var boolean\r
- */\r
- var $removeUnknownVariables = true;\r
- \r
- /**\r
- * Controls the handling of empty blocks, default is remove.\r
- * @var boolean\r
- */\r
- var $removeEmptyBlocks = true;\r
- \r
- /**\r
- * Root directory for all file operations. \r
- * The string gets prefixed to all filenames given.\r
- * @var string\r
- * @see IntegratedTemplate(), setRoot()\r
- */\r
- var $fileRoot = "";\r
- \r
- /**\r
- * Internal flag indicating that a blockname was used multiple times.\r
- * @var boolean\r
- */\r
- var $flagBlocktrouble = false;\r
- \r
- /**\r
- * Flag indicating that the global block was parsed.\r
- * @var boolean\r
- */\r
- var $flagGlobalParsed = false;\r
- \r
- /**\r
- * Builds some complex regular expressions and optinally sets the file root directory.\r
- *\r
- * Make sure that you call this constructor if you derive your template \r
- * class from this one. \r
- *\r
- * @param string File root directory, prefix for all filenames given to the object.\r
- * @see setRoot()\r
- */\r
- function IntegratedTemplate($root = "") {\r
- \r
- $this->variablesRegExp = "@".$this->openingDelimiter."(".$this->variablenameRegExp.")".$this->closingDelimiter."@sm";\r
- $this->blockRegExp = '@!--\s+BEGIN\s+('.$this->blocknameRegExp.')\s+-->(.*)<!--\s+END\s+\1\s+-->@sm';\r
-\r
- $this->setRoot($root); \r
- \r
- } // end constructor\r
- \r
- /**\r
- * Print a certain block with all replacements done.\r
- * @brother get()\r
- */\r
- function show($block = "__global__") {\r
- print $this->get($block);\r
- } // end func show\r
- \r
- /**\r
- * Returns a block with all replacements done.\r
- * \r
- * @param string name of the block\r
- * @return string \r
- * @access public\r
- * @see show()\r
- */\r
- function get($block = "__global__") {\r
-\r
- if ("__global__" == $block && !$this->flagGlobalParsed)\r
- $this->parse("__global__");\r
- \r
- if (!isset($this->blocklist[$block])) {\r
- $this->halt("The block '$block' was not found in the template.", __FILE__, __LINE__);\r
- return true;\r
- }\r
- \r
- if ($this->clearCache) {\r
- \r
- $data = (isset($this->blockdata[$block])) ? $this->blockdata[$block] : "";\r
- unset($this->blockdata[$block]);\r
- return $data;\r
- \r
- } else {\r
- \r
- return (isset($this->blockdata[$block])) ? $this->blockdata[$block] : "";\r
- \r
- }\r
-\r
- } // end func get()\r
- \r
- /**\r
- * Parses the given block.\r
- * \r
- * @param string name of the block to be parsed\r
- * @access public\r
- * @see parseCurrentBlock()\r
- */\r
- function parse($block = "__global__", $flag_recursion = false) {\r
-\r
- if (!isset($this->blocklist[$block])) {\r
- $this->halt("The block '$block' was not found in the template.", __FILE__, __LINE__);\r
- return false;\r
- }\r
-\r
- if ("__global__" == $block)\r
- $this->flagGlobalParsed = true;\r
- \r
- $regs = array();\r
- $values = array();\r
-\r
- if ($this->clearCacheOnParse) {\r
- \r
- reset($this->variableCache);\r
- while (list($name, $value)=each($this->variableCache)) {\r
- $regs[] = "@".$this->openingDelimiter.$name.$this->closingDelimiter."@";\r
- $values[] = $value;\r
- }\r
- $this->variableCache = array();\r
- \r
- } else {\r
- \r
- reset($this->blockvariables[$block]);\r
- while (list($k, $allowedvar)=each($this->blockvariables[$block])) {\r
- \r
- if (isset($this->variableCache[$allowedvar])) {\r
- $regs[] = "@".$this->openingDelimiter.$allowedvar.$this->closingDelimiter."@";\r
- $values[] = $this->variableCache[$allowedvar];\r
- unset($this->variableCache[$allowedvar]);\r
- }\r
-\r
- } \r
- \r
- }\r
-\r
- $outer = (0 == count($regs)) ? $this->blocklist[$block] : preg_replace($regs, $values, $this->blocklist[$block]);\r
- $empty = (0 == count($values)) ? true : false;\r
-\r
- if (isset($this->blockinner[$block])) {\r
- \r
- reset($this->blockinner[$block]);\r
- while (list($k, $innerblock)=each($this->blockinner[$block])) {\r
-\r
- $this->parse($innerblock, true);\r
- if (""!=$this->blockdata[$innerblock])\r
- $empty = false;\r
-\r
- $placeholder = $this->openingDelimiter."__".$innerblock."__".$this->closingDelimiter; \r
- $outer = str_replace($placeholder, $this->blockdata[$innerblock], $outer);\r
- $this->blockdata[$innerblock] = ""; \r
- }\r
- }\r
-\r
- if ($this->removeUnknownVariables)\r
- $outer = preg_replace($this->variablesRegExp, "", $outer);\r
- \r
- if ($empty) {\r
- \r
- if (!$this->removeEmptyBlocks) \r
- $this->blockdata[$block].= $outer;\r
- \r
- } else {\r
- \r
- $this->blockdata[$block].= $outer;\r
- \r
- }\r
-\r
- return $empty;\r
- } // end func parse\r
-\r
- /**\r
- * Parses the current block\r
- * @see parse(), setCurrentBlock(), $currentBlock\r
- * @access public\r
- */\r
- function parseCurrentBlock() {\r
- return $this->parse($this->currentBlock);\r
- } // end func parseCurrentBlock\r
-\r
- /**\r
- * Sets a variable value.\r
- * \r
- * The function can be used eighter like setVariable( "varname", "value")\r
- * or with one array $variables["varname"] = "value" given setVariable($variables)\r
- * quite like phplib templates set_var().\r
- * \r
- * @param mixed string with the variable name or an array %variables["varname"] = "value"\r
- * @param string value of the variable or empty if $variable is an array.\r
- * @param string prefix for variable names\r
- * @access public\r
- */ \r
- function setVariable($variable, $value="") {\r
- \r
- if (is_array($variable)) {\r
- \r
- reset($variable);\r
- while (list($var, $value)=each($variable)) \r
- $this->variableCache[$var] = $value;\r
- \r
- } else {\r
- \r
- $this->variableCache[$variable] = $value;\r
- \r
- }\r
- \r
- } // end func setVariable\r
- \r
- /**\r
- * Sets the name of the current block that is the block where variables are added.\r
- *\r
- * @param string name of the block \r
- * @return boolean false on failure otherwise true\r
- * @access public\r
- */\r
- function setCurrentBlock($block = "__global__") {\r
- \r
- if (!isset($this->blocklist[$block])) {\r
- $this->halt("Can't find the block '$block' in the template.", __FILE__, __LINE__);\r
- return false;\r
- }\r
- \r
- $this->currentBlock = $block;\r
- \r
- return true;\r
- } // end func setCurrentBlock\r
- \r
- /**\r
- * Clears all datafields of the object and rebuild the internal blocklist\r
- * \r
- * LoadTemplatefile() and setTemplate() automatically call this function \r
- * when a new template is given. Don't use this function \r
- * unless you know what you're doing.\r
- *\r
- * @access public\r
- * @see free()\r
- */\r
- function init() {\r
- \r
- $this->free();\r
- $this->findBlocks($this->template);\r
- $this->buildBlockvariablelist();\r
- \r
- } // end func init\r
- \r
- /**\r
- * Clears all datafields of the object.\r
- * \r
- * Don't use this function unless you know what you're doing.\r
- *\r
- * @access public\r
- * @see init()\r
- */\r
- function free() {\r
- \r
- $this->err[] = "";\r
- \r
- $this->currentBlock = "__global__";\r
- \r
- $this->variableCache = array(); \r
- $this->blocklist = array();\r
- $this->blockvariables = array();\r
- $this->blockinner = array();\r
- $this->blockdata = array();\r
- $this->blocklookup = array();\r
- $this->blocktypes = array();\r
- \r
- $this->flagBlocktrouble = false;\r
- $this->flagGlobalParsed = false;\r
- \r
- } // end func free\r
- \r
- /**\r
- * Sets the template.\r
- * \r
- * You can eighter load a template file from disk with LoadTemplatefile() or set the\r
- * template manually using this function.\r
- * \r
- * @param string template content\r
- * @param boolean Unbekannte, nicht ersetzte Platzhalter entfernen?\r
- * @param boolean remove unknown/unused variables?\r
- * @param boolean remove empty blocks?\r
- * @see LoadTemplatefile(), $template\r
- * @access public\r
- */\r
- function setTemplate($template, $removeUnknownVariables = true, $removeEmptyBlocks = false) {\r
- if (""==$template) {\r
- $this->halt("The given string is empty.", __FILE__, __LINE__);\r
- return false;\r
- }\r
- \r
- $this->removeUnknownVariables = $removeUnknownVariables;\r
- $this->removeEmptyBlocks = $removeEmptyBlocks;\r
- \r
- $this->template = '<!-- BEGIN __global__ -->'.$template.'<!-- END __global__ -->';\r
- $this->init();\r
- \r
- if ($this->flagBlocktrouble)\r
- return false;\r
- \r
- return true;\r
- } // end func setTemplate\r
- \r
- /**\r
- * Reads a template file from the disk.\r
- *\r
- * @param string name of the template file, full path!\r
- * @param boolean remove unknown/unused variables?\r
- * @param boolean remove empty blocks?\r
- * @access public\r
- * @return boolean false on failure, otherwise true\r
- * @see $template, setTemplate()\r
- */\r
- function loadTemplatefile($filename, $removeUnknownVariables = true, $removeEmptyBlocks = true) {\r
- \r
- $template = $this->getfile($filename);\r
- \r
- return $this->setTemplate($this->getFile($filename), $removeUnknownVariables, $removeEmptyBlocks);\r
- } // end func LoadTemplatefile\r
- \r
- /**\r
- * Sets the file root. The file root gets prefixed to all filenames passed to the object.\r
- * \r
- * Make sure that you override this function when using the class\r
- * on windows.\r
- * \r
- * @param string\r
- * @see IntegratedTemplate()\r
- * @access public\r
- */\r
- function setRoot($root) {\r
- \r
- if (""!=$root && "/"!= substr($root, -1))\r
- $root.="/";\r
- \r
- $this->fileRoot = $root;\r
- \r
- } // end func setRoot\r
-\r
- /**\r
- * Build a list of all variables within a block\r
- */ \r
- function buildBlockvariablelist() {\r
-\r
- reset($this->blocklist);\r
- while (list($name, $content)=each($this->blocklist)) {\r
- preg_match_all( $this->variablesRegExp, $content, $regs );\r
- $this->blockvariables[$name] = $regs[1];\r
- } \r
- \r
- } // end func buildBlockvariablelist\r
- \r
- /**\r
- * Returns a list of all \r
- */\r
- function getGlobalvariables() {\r
-\r
- $regs = array();\r
- $values = array();\r
- \r
- reset($this->blockvariables["__global__"]);\r
- while (list($k, $allowedvar)=each($this->blockvariables["__global__"])) {\r
- \r
- if (isset($this->variableCache[$allowedvar])) {\r
- $regs[] = "@".$this->openingDelimiter.$allowedvar.$this->closingDelimiter."@";\r
- $values[] = $this->variableCache[$allowedvar];\r
- unset($this->variableCache[$allowedvar]);\r
- }\r
- \r
- }\r
- \r
- return array($regs, $values);\r
- } // end func getGlobalvariables\r
-\r
- /**\r
- * Recusively builds a list of all blocks within the template.\r
- *\r
- * @param string string that gets scanned\r
- * @access private\r
- * @see $blocklist\r
- */ \r
- function findBlocks($string) {\r
-\r
- $blocklist = array();\r
-\r
- if (preg_match_all($this->blockRegExp, $string, $regs, PREG_SET_ORDER)) {\r
- \r
- reset($regs);\r
- while (list($k, $match)=each($regs)) {\r
- \r
- $blockname = $match[1];\r
- $blockcontent = $match[2];\r
- \r
- if (isset($this->blocklist[$blockname])) {\r
- $this->halt("The name of a block must be unique within a template. Found '$blockname' twice. Unpredictable results may appear.", __FILE__, __LINE__);\r
- $this->flagBlocktrouble = true;\r
- } \r
-\r
- $this->blocklist[$blockname] = $blockcontent;\r
- $this->blockdata[$blockname] = "";\r
-\r
- $blocklist[] = $blockname;\r
- \r
- $inner = $this->findBlocks($blockcontent);\r
- reset($inner);\r
- while (list($k, $name)=each($inner)) {\r
-\r
- $pattern = sprintf('@<!--\s+BEGIN\s+%s\s+-->(.*)<!--\s+END\s+%s\s+-->@sm', \r
- $name,\r
- $name\r
- );\r
-\r
- $this->blocklist[$blockname] = preg_replace( $pattern, \r
- $this->openingDelimiter."__".$name."__".$this->closingDelimiter, \r
- $this->blocklist[$blockname]\r
- );\r
- $this->blockinner[$blockname][] = $name;\r
- $this->blockparents[$name] = $blockname;\r
- \r
- }\r
- \r
- }\r
- \r
- }\r
-\r
- return $blocklist;\r
- } // end func findBlocks\r
-\r
- /**\r
- * Reads a file from disk and returns its content.\r
- * @param string Filename\r
- * @return string Filecontent\r
- */ \r
- function getFile($filename) {\r
- \r
- if ("/" == substr($filename, 0, 1)) \r
- $filename = substr($filename, 1);\r
- \r
- $filename = $this->fileRoot.$filename;\r
- \r
- if ( !($fh = @fopen($filename, "r")) ) {\r
- $this->halt("Can't read '$filename'.", __FILE__, __LINE__);\r
- return "";\r
- }\r
- \r
- $content = fread($fh, filesize($filename));\r
- fclose($fh);\r
- \r
- return $content; \r
- } // end func getFile\r
- \r
- /**\r
- * Error Handling function.\r
- * @param string error message\r
- * @param mixed File where the error occured\r
- * @param int Line where the error occured\r
- * @see $err\r
- */\r
- function halt($message, $file="", $line=0) {\r
- \r
- $message = sprintf("IntegratedTemplate Error: %s [File: %s, Line: %d]",\r
- $message,\r
- $file,\r
- $line\r
- );\r
-\r
- $this->err[] = $message;\r
- \r
- if ($this->printError)\r
- print $message;\r
- \r
- if ($this->haltOnError)\r
- die($message); \r
-\r
- } // end func halt\r
- \r
-} // end class IntegratedTemplate\r
-?>
\ No newline at end of file