(original from PHPLIB) // Bjoern Schotte (PEARification) // Martin Jansen (PEAR conformance) // //require_once "PEAR.php"; /** * Converted PHPLIB Template class * * For those who want to use PHPLIB's fine template class, * here's a PEAR conforming class with the original PHPLIB * template code from phplib-stable CVS. Original author * was Kristian Koehntopp * * @author Bjoern Schotte * @author Martin Jansen (PEAR conformance) * @version 1.0 */ class Template_PHPLIB { /** * If set, echo assignments * @var bool */ var $debug = false; /** * $file[handle] = "filename"; * @var array */ var $file = array(); /** * fallback paths that should be defined in a child class * @var array */ var $file_fallbacks = array(); /** * Relative filenames are relative to this pathname * @var string */ var $root = ""; /* * $_varKeys[key] = "key" * @var array */ var $_varKeys = array(); /** * $_varVals[key] = "value"; * @var array */ var $_varVals = array(); /** * "remove" => remove undefined variables * "comment" => replace undefined variables with comments * "keep" => keep undefined variables * @var string */ var $unknowns = "remove"; /** * "yes" => halt, "report" => report error, continue, "no" => ignore error quietly * @var string */ var $haltOnError = "report"; /** * The last error message is retained here * @var string * @see halt */ var $_lastError = ""; /** * Constructor * * @access public * @param string template root directory * @param string how to handle unknown variables * @param array fallback paths */ function Template_PHPLIB($root = ".", $unknowns = "remove", $fallback="") { $this->setRoot($root); $this->setUnknowns($unknowns); if (is_array($fallback)) $this->file_fallbacks = $fallback; } /** * Sets the template directory * * @access public * @param string new template directory * @return bool */ function setRoot($root) { if (!is_dir($root)) { $this->halt("setRoot: $root is not a directory."); return false; } $this->root = $root; return true; } /** * What to do with unknown variables * * three possible values: * * - "remove" will remove unknown variables * (don't use this if you define CSS in your page) * - "comment" will replace undefined variables with comments * - "keep" will keep undefined variables as-is * * @access public * @param string unknowns */ function setUnknowns($unknowns = "keep") { $this->unknowns = $unknowns; } /** * Set appropriate template files * * With this method you set the template files you want to use. * Either you supply an associative array with key/value pairs * where the key is the handle for the filname and the value * is the filename itself, or you define $handle as the file name * handle and $filename as the filename if you want to define only * one template. * * @access public * @param mixed handle for a filename or array with handle/name value pairs * @param string name of template file * @return bool */ function setFile($handle, $filename = "") { if (!is_array($handle)) { if ($filename == "") { $this->halt("setFile: For handle $handle filename is empty."); return false; } $this->file[$handle] = $this->_filename($filename); } else { reset($handle); while (list($h, $f) = each($handle)) { $this->file[$h] = $this->_filename($f); } } } /** * Set a block in the appropriate template handle * * By setting a block like that: * * <!-- BEGIN blockname --> * html code * <!-- END blockname --> * * you can easily do repeating HTML code, i.e. output * database data nice formatted into a HTML table where * each DB row is placed into a HTML table row which is * defined in this block. * It extracts the template $handle from $parent and places * variable {$name} instead. * * @access public * @param string parent handle * @param string block name handle * @param string variable substitution name */ function setBlock($parent, $handle, $name = "") { if (!$this->_loadFile($parent)) { $this->halt("setBlock: unable to load $parent."); return false; } if ($name == "") { $name = $handle; } $str = $this->getVar($parent); $reg = "/[ \t]*\s*?\n?(\s*.*?\n?)\s*\s*?\n?/sm"; preg_match_all($reg, $str, $m); $str = preg_replace($reg, "{" . "$name}", $str); if (isset($m[1][0])) $this->setVar($handle, $m[1][0]); $this->setVar($parent, $str); } /** * Set corresponding substitutions for placeholders * * @access public * @param string name of a variable that is to be defined or an array of variables with value substitution as key/value pairs * @param string value of that variable * @param boolean if true, the value is appended to the variable's existing value */ function setVar($varname, $value = "", $append = false) { if (!is_array($varname)) { if (!empty($varname)) if ($this->debug) print "scalar: set *$varname* to *$value*
\n"; $this->_varKeys[$varname] = $this->_varname($varname); ($append) ? $this->_varVals[$varname] .= $value : $this->_varVals[$varname] = $value; } else { reset($varname); while (list($k, $v) = each($varname)) { if (!empty($k)) if ($this->debug) print "array: set *$k* to *$v*
\n"; $this->_varKeys[$k] = $this->_varname($k); ($append) ? $this->_varVals[$k] .= $v : $this->_varVals[$k] = $v; } } } /** * Substitute variables in handle $handle * * @access public * @param string name of handle * @return mixed string substituted content of handle */ function subst($handle) { if (!$this->_loadFile($handle)) { $this->halt("subst: unable to load $handle."); return false; } return @str_replace($this->_varKeys, $this->_varVals, $this->getVar($handle)); } /** * Same as subst but printing the result * * @access public * @brother subst * @param string handle of template * @return bool always false */ function pSubst($handle) { print $this->subst($handle); return false; } /** * Parse handle into target * * Parses handle $handle into $target, eventually * appending handle at $target if $append is defined * as TRUE. * * @access public * @param string target handle to parse into * @param string which handle should be parsed * @param boolean append it to $target or not? * @return string parsed handle */ function parse($target, $handle, $append = false) { if (!is_array($handle)) { $str = $this->subst($handle); ($append) ? $this->setVar($target, $this->getVar($target) . $str) : $this->setVar($target, $str); } else { reset($handle); while (list(, $h) = each($handle)) { $str = $this->subst($h); $this->setVar($target, $str); } } return $str; } /** * Same as parse, but printing it. * * @access public * @brother parse * @param string target to parse into * @param string handle which should be parsed * @param should $handle be appended to $target? * @return bool */ function pParse($target, $handle, $append = false) { print $this->finish($this->parse($target, $handle, $append)); return false; } /** * Return all defined variables and their values * * @access public * @return array with all defined variables and their values */ function getVars() { reset($this->_varKeys); while (list($k, ) = each($this->_varKeys)) { $result[$k] = $this->getVar($k); } return $result; } /** * Return one or more specific variable(s) with their values. * * @access public * @param mixed array with variable names or one variable name as a string * @return mixed array of variable names with their values or value of one specific variable */ function getVar($varname) { if (!is_array($varname)) { if (isset($this->_varVals[$varname])) { return $this->_varVals[$varname]; } else { return ""; } } else { reset($varname); while (list($k, ) = each($varname)) { $result[$k] = (isset($this->_varVals[$k])) ? $this->_varVals[$k] : ""; } return $result; } } /** * Get undefined values of a handle * * @access public * @param string handle name * @return mixed false if an error occured or the undefined values */ function getUndefined($handle) { if (!$this->_loadFile($handle)) { $this->halt("getUndefined: unable to load $handle."); return false; } preg_match_all("/{([^ \t\r\n}]+)}/", $this->getVar($handle), $m); $m = $m[1]; if (!is_array($m)) { return false; } reset($m); while (list(, $v) = each($m)) { if (!isset($this->_varKeys[$v])) { $result[$v] = $v; } } if (isset($result) && count($result)) { return $result; } else { return false; } } /** * Finish string * * @access public * @param string string to finish * @return finished, i.e. substituted string */ function finish($str) { switch ($this->unknowns) { case "remove": $str = preg_replace('/{[^ \t\r\n}]+}/', "", $str); break; case "comment": $str = preg_replace('/{([^ \t\r\n}]+)}/', "", $str); break; } return $str; } /** * Print variable to the browser * * @access public * @param string name of variable to print */ function p($varname) { print $this->finish($this->getVar($varname)); } /** * Get finished variable * * @access public public * @param string variable to get * @return string string with finished variable */ function get($varname) { return $this->finish($this->getVar($varname)); } /** * Complete filename * * Complete filename, i.e. testing it for slashes * * @access private * @param string filename to be completed * @return string completed filename */ function _filename($filename) { // if (substr($filename, 0, 1) != "/") { // $filename = $this->root."/".$filename; // } if (file_exists($filename)) return $filename; if (is_array($this->file_fallbacks) && count($this->file_fallbacks) > 0) { reset($this->file_fallbacks); while (list(,$v) = each($this->file_fallbacks)) { if (file_exists($v.basename($filename))) return $v.basename($filename); } $this->halt(sprintf("filename: file %s does not exist in the fallback paths %s.",$filename,implode(",",$this->file_fallbacks))); return false; } else { $this->halt(sprintf("filename: file %s does not exist.",$filename)); return false; } return $filename; } /** * Protect a replacement variable * * @access private * @param string name of replacement variable * @return string replaced variable */ function _varname($varname) { return "{".$varname."}"; } /** * load file defined by handle if it is not loaded yet * * @access private * @param string handle * @return bool FALSE if error, true if all is ok */ function _loadFile($handle) { if (isset($this->_varKeys[$handle]) and !empty($this->_varVals[$handle])) { return true; } if (!isset($this->file[$handle])) { $this->halt("loadfile: $handle is not a valid handle."); return false; } $filename = $this->file[$handle]; if (function_exists("file_get_contents")) { $str = file_get_contents($filename); } else { if (!$fp = @fopen($filename,"r")) { $this->halt("loadfile: couldn't open $filename"); return false; } $str = fread($fp,filesize($filename)); fclose($fp); } if ($str=='') { $this->halt("loadfile: While loading $handle, $filename does not exist or is empty."); return false; } $this->setVar($handle, $str); return true; } /** * Error function. Halt template system with message to show * * @access public * @param string message to show * @return bool */ function halt($msg) { $this->_lastError = $msg; if ($this->haltOnError != "no") { // return $this->haltMsg($msg); $this->haltMsg($msg); } if ($this->haltOnError == "yes") { die("Halted."); } return false; } /** * printf error message to show * * @access public * @param string message to show * @return object PEAR error object */ function haltMsg($msg) { // PEAR::raiseError(sprintf("Template Error: %s
\n", $msg)); printf("Template Error: %s
\n", $msg); } } ?>