# HG changeset patch # User mortenp # Date 1263129603 -39600 # Node ID 6d354f3a8d90937a1fc27f38ac811c77b365ece6 # Parent 2cb6a707f2bc7111a63bd0dd8fe7987c4cb4494f Replaced class.FastTemplate.php with class.rFastTemplate.php in contrib/web/php-admin (Christoph Thiel) diff -r 2cb6a707f2bc -r 6d354f3a8d90 ChangeLog --- a/ChangeLog Mon Dec 21 17:49:16 2009 +1100 +++ b/ChangeLog Mon Jan 11 00:20:03 2010 +1100 @@ -1,3 +1,6 @@ + o Replaced class.FastTemplate.php with class.rFastTemplate.php in + contrib/web/php-admin (Christoph Thiel) +1.2.17-RC1 o Added information about digest and nomail to listhelp (Robin H. Johnson) o Fixed bug in mlmmj-maintd which caused loss of archive files in some requeue cases (Robin H. Johnson) diff -r 2cb6a707f2bc -r 6d354f3a8d90 contrib/web/php-admin/htdocs/class.FastTemplate.php --- a/contrib/web/php-admin/htdocs/class.FastTemplate.php Mon Dec 21 17:49:16 2009 +1100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,737 +0,0 @@ - - * - * PHP3 port by CDI - * Copyright (c) 1999 CDI - * - * PHP4 support added by Christoph Thiel for mlmmj's php-admin - * Copyright (c) 2004 Christoph Thiel - * - * This program is released under the General Artistic License. - * - * 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 all AUTHORS. - * - * - * 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. - */ - -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 $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. - */ - -/******************************************************************************/ - - function FastTemplate($pathToTemplates = "") - { - global $php_errormsg; - - if(!empty($pathToTemplates)) - { - $this->set_root($pathToTemplates); - } - - } - - /* - * All templates will be loaded from this "root" directory - * Can be changed in mid-process by re-calling with a new - * value. - */ - - function set_root($root) - { - $trailer = substr($root,-1); - - 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"); - } - } - - - /* 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. - */ - - 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. - */ - - function strict() - { - $this->STRICT = true; - } - - - /* Silently discards (removes) undefined variable references - * found in templates - */ - - 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. - */ - - 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 - */ - - 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; - - } - - - /* Prints the warnings for unresolved variable references - * in template files. Used if STRICT is true - */ - - 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); - } - } - } - - - /* This routine get's called by parse() and does the actual - * {VAR} to VALUE conversion within the template. - */ - - function parse_template($template, $tpl_array) - { - while ( list ($key,$val) = each ($tpl_array) ) - { - if (!(empty($key))) - { - if(gettype($val) != "string") - { - settype($val,"string"); - } - - $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); - } - else - { - // Warn about unresolved template variables - if (ereg("({[A-Z0-9_]+})",$template)) - { - $unknown = split("\n",$template); - while (list ($Element,$Line) = each($unknown) ) - { - $UnkVar = $Line; - if(!(empty($UnkVar))) - { - $this->show_unknowns($UnkVar); - } - } - } - } - return $template; - - } - - - /* The meat of the whole class. The magic happens here. */ - - function parse($ReturnVar, $FileTags) - { - $append = false; - $this->LAST = $ReturnVar; - $this->HANDLE[$ReturnVar] = 1; - - if (gettype($FileTags) == "array") - { - unset($this->$ReturnVar); // Clear any previous data - - while ( list ( $key , $val ) = each ( $FileTags ) ) - { - if ( (!isset($this->$val)) || (empty($this->$val)) ) - { - $this->LOADED["$val"] = 1; - if(isset($this->DYNAMIC["$val"])) - { - $this->parse_dynamic($val,$ReturnVar); - } - else - { - $fileName = $this->FILELIST["$val"]; - $this->$val = $this->get_template($fileName); - } - } - - // Array context implies overwrite - - $this->$ReturnVar = $this->parse_template($this->$val,$this->PARSEVARS); - - // For recursive calls. - - $this->assign( array( $ReturnVar => $this->$ReturnVar ) ); - - } - } // end if FileTags is array() - else - { - // FileTags is not an array - - $val = $FileTags; - - if( (substr($val,0,1)) == '.' ) - { - // Append this template to a previous ReturnVar - - $append = true; - $val = substr($val,1); - } - - if ( (!isset($this->$val)) || (empty($this->$val)) ) - { - $this->LOADED["$val"] = 1; - if(isset($this->DYNAMIC["$val"])) - { - $this->parse_dynamic($val,$ReturnVar); - } - else - { - $fileName = $this->FILELIST["$val"]; - $this->$val = $this->get_template($fileName); - } - } - - if($append) - { - $this->$ReturnVar .= $this->parse_template($this->$val,$this->PARSEVARS); - } - else - { - $this->$ReturnVar = $this->parse_template($this->$val,$this->PARSEVARS); - } - - // For recursive calls. - - $this->assign(array( $ReturnVar => $this->$ReturnVar) ); - - } - return; - } - - - function FastPrint($template = "") - { - if(empty($template)) - { - $template = $this->LAST; - } - - if( (!(isset($this->$template))) || (empty($this->$template)) ) - { - $this->error("Nothing parsed, nothing printed",0); - return; - } - else - { - print $this->$template; - } - return; - } - - - function fetch($template = "") - { - if(empty($template)) - { - $template = $this->LAST; - } - if( (!(isset($this->$template))) || (empty($this->$template)) ) - { - $this->error("Nothing parsed, nothing printed",0); - return ""; - } - - return($this->$template); - } - - - function define_dynamic($Macro, $ParentName) - { - // A dynamic block lives inside another template file. - // It will be stripped from the template when parsed - // and replaced with the {$Tag}. - - $this->DYNAMIC["$Macro"] = $ParentName; - return true; - } - - - function parse_dynamic($Macro,$MacroName) - { - // 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); - $newMacro = ""; - $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) ) - { - $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; - - } - - - function clear_all () - { - $this->clear(); - $this->clear_assign(); - $this->clear_define(); - $this->clear_tpl(); - - return; - - } - - - 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; - - } - - - 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; - } - } - - /* 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; - } - - - 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; - - if($die == 1) - die("ERROR: $this->ERROR
\n"); - else - echo "ERROR: ".$this->ERROR."
\n"; - } -} - -?> diff -r 2cb6a707f2bc -r 6d354f3a8d90 contrib/web/php-admin/htdocs/class.rFastTemplate.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/web/php-admin/htdocs/class.rFastTemplate.php Mon Jan 11 00:20:03 2010 +1100 @@ -0,0 +1,1087 @@ + +// 2001 Alister Bulman Re-Port multi template-roots + more +// PHP3 Port: Copyright © 1999 CDI , All Rights Reserved. +// Perl Version: Copyright © 1998 Jason Moore , All Rights Reserved. +// +// RCS Revision +// @(#) $Id$ +// $Source$ +// +// Copyright Notice +// +// 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, or (at your option) +// any later version. +// +// class.rFastTemplate.php 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. +// +// Comments +// +// I would like to thank CDI for pointing out the +// copyright notice attached to his PHP3 port which I had blindly missed +// in my first release of this code. +// +// This work is derived from class.FastTemplate.php3 version 1.1.0 as +// available from http://www.thewebmasters.net/. That work makes +// reference to the "GNU General Artistic License". In correspondence +// with the author, the intent was to use the GNU General Public License; +// this work does the same. +// +// Authors +// +// Roland Roberts +// Alister Bulman (multi template-roots) +// Michal Rybarik (define_raw()) +// CDI , PHP3 port +// Jason Moore , original Perl version +// +// Synopsis +// +// require ("PATH-TO-TEMPLATE-CODE/class.Template.php"); +// $t = new Template("PATH-TO-TEMPLATE-DIRECTORY"); +// $t->define (array(MAIN => "diary.html")); +// $t->setkey (VAR1, "some text"); +// $t->subst (INNER, "inner") +// $t->setkey (VAR1, "some more text"); +// $t->subst (INNER, ".inner") +// $t->setkey (VAR2, "var2 text"); +// $t->subst (CONTENT, "main"); +// $t->print (CONTENT); +// +// Description +// +// This is a class.FastTemplate.php3 replacement that provides most of the +// same interface but has the ability to do nested dynamic templates. The +// default is to do dynamic template expansion and no special action is +// required for this to happen. +// +// class.FastTemplate.php3 Methods Not Implemented +// +// clear_parse +// Same as clear. In fact, it was the same as clear in FastTemplate. +// clear_all +// If you really think you need this, try +// unset $t; +// $t = new Template ($path); +// which gives the same effect. +// clear_tpl +// Use unload instead. This has the side effect of unloading all parent +// and sibling templates which may be more drastic than you expect and +// is different from class.FastTemplate.php3. This difference is +// necessary since the only way we can force the reload of an embedded +// template is to force the reload of the parent and sibling templates. +// +// class.FastTemplate.php3 Methods by Another Name +// +// The existence of these functions is a historical artifact. I +// originally had in mind to write a functional equivalent from scratch. +// Then I came my senses and just grabbed class.FastTemplate.php3 and +// started hacking it. So, you can use the names on the right, but the +// ones on the left are equivalent and are the names used in the original +// class.FastTemplate.php3. +// +// parse --> subst +// get_assiged --> getkey +// assign --> setkey +// clear_href --> unsetkey +// clear_assign --> unsetkey +// FastPrint --> xprint +// + +class rFastTemplate { + + // File name to be used for debugging output. Needs to be set prior to + // calling anything other than option setting commands (debug, debugall, + // strict, dynamic) because once the file has been opened, this is ignored. + var $DEBUGFILE = '/tmp/class.rFastTemplate.php.dbg'; + + // File descriptor for debugging output. + var $DEBUGFD = -1; + + // Array for individual member functions. You can turn on debugging for a + // particular member function by calling $this->debug(FUNCTION_NAME) + var $DEBUG = array (); + + // Turn this on to turn on debugging in all member functions via + // $this->debugall(). Turn if off via $this->debugall(false); + var $DEBUGALL = false; + + // Names of actual templates. Each element will be an array with template + // information including is originating file, file load status, parent + // template, variable list, and actual template contents. + var $TEMPLATE = array(); + + // Holds paths-to-templates (See: set_root and FindTemplate) + var $ROOT = array(); + + // Holds the HANDLE to the last template parsed by parse() + var $LAST = ''; + + + // Strict template checking. Unresolved variables in templates will generate a + // warning. + var $STRICT = true; + + // If true, this suppresses the warning generated by $STRICT=true. + var $QUIET = false; + + // If true, throw an error if the template file is empty. This was previously the default + // behavior. I'm not sure how this compares to the original FastTemplate(). + var $NOEMPTY = false; + + // If true, a non-existent directory in the template path will not + // generate an error. This was added to allow a directory to be + // prepended to the template path array based on where in the directory + // tree we are. If the template path is non-existent, it is skipped. + var $MISSING_DIR_OKAY = false; + + // Holds handles assigned by a call to parse(). + var $HANDLE = array(); + + // Holds all assigned variable names and values. + var $VAR = array(); + + // Set to true is this is a WIN32 server. This was part of the + // class.FastTemplate.php3 implementation and the only real place it kicks + // in is in setting the terminating character on the value of $ROOT, the + // path where all the templates live. + var $WIN32 = false; + + // Automatically scan template for dynamic templates and assign new values + // to TEMPLATE based on whatever names the HTML comments use. This can be + // changed up until the time the first parse() is called. Well, you can + // change it anytime, but it will have no effect on already loaded + // templates. Also, if you have dynamic templates, the first call to parse + // will load ALL of your templates, so changing it after that point will + // have no effect on any defined templates. + var $DYNAMIC = true; + + // Grrr. Don't try to break these extra long regular expressions into + // multiple lines for readability. PHP 4.03pl1 chokes on them if you do. + // I'm guessing the reason is something obscure with the parenthesis + // matching, the same sort of thing Tcl might have, but I'm not sure. + + // Regular expression which matches the beginning of a dynamic/inferior + // template. The critical bit is that we need two parts: (1) the entire + // match, and (2) the name of the dynamic template. The first part is + // required because will do a strstr() to split the buffer into two + // pieces: everything before the dynamic template declaration and + // everything after. The second is needed because after finding a BEGIN + // we will search for an END and they both have to have the same name of + // we consider the template malformed and throw and error. + + // Both of these are written with PCRE (Perl-Compatible Regular + // Expressions) because we need the non-greedy operators to insure that + // we don't read past the end of the HTML comment marker in the case that + // the BEGIN/END block have trailing comments after the tag name. + var $REGEX_DYNBEG = '/()/s'; + + // Regular expression which matches the end of a dynamic/inferior + // template; see the comment about on the BEGIN match. + var $REGEX_DYNEND = '/()/s'; + // Regular expression which matches a variable in the template. + + var $REGEX_VAR = '/\{[A-Za-z][-_A-Za-z0-9]*\}/'; + // + // Description + // Constructor. + // + function rFastTemplate ($pathToTemplates = '') { + + // $pathToTemplates can also be an array of template roots, handled in set_root + global $php_errormsg; + if (!empty($pathToTemplates)) { + $this->set_root ($pathToTemplates); + } + $this->DEBUG = array ('subst' => false, + 'parse_internal' => false, + 'parse_internal_1' => false, + 'parsed' => false, + 'clear' => false, + 'clear_dynamic' => false, + 'load' => false); + + return $this; + } + + // + // Description + // Set the name to be used for debugging output. If another file has + // already been opened, close it so the next call to logwrite will + // reopen under this name. + // + function debugfile ($name) { + $this->DEBUGFILE = $name; + } + + // + // Description + // Turn on/off debugging output of an individual member function. + // + function debug ($what, $on = true) { + $this->DEBUG[$what] = $on; + } + + // + // Description + // Turn on/off debugging output of all member functions. + // + function debugall ($on = true) { + $this->DEBUGALL = $on; + } + + // + // Description + // Turn on/off automatic dynamic template expansion. Note that a + // template with an inferior dynamic template embedded will still + // parse but only as if it were part of the main template. When this + // is turned on, it will be parsed out as as if it were a full-blown + // template and can thus be both parsed and appended to as a separate + // entity. + // + function dynamic ($on = true) { + $this->DYNAMIC = $on; + } + + // + // Description + // Turn on/off strict template checking. When on, all template tags + // must be assigned or we throw an error (but stilll parse the + // template). + // + function strict ($on = true) { + $this->STRICT = $on; + } + + function quiet ($on = true) { + $this->QUIET = $on; + } + + // + // Description + // For compatibility with class.FastTemplate.php3. + // + function no_strict () { + $this->STRICT = false; + } + + // + // Description + // Turn off errors for missing template directories. This allows you + // to specify a template path that may not yet exist. + // + function missing_dir_okay ($on = true) { + $this->MISSING_DIR_OKAY = $on; + } + + // + // Description + // Utility function for debugging. + // + function logwrite ($msg) { + if ($this->DEBUGFD < 0) { + $this->DEBUGFD = fopen ($this->DEBUGFILE, 'a'); + } + fputs ($this->DEBUGFD, + strftime ('%Y/%m/%d %H:%M:%S ') . $msg . "\n"); + } + + // + // Description + // This was lifted as-is from class.FastTemplate.php3. Based on what + // platform is in use, it makes sure the path specification ends with + // the proper path separator; i.e., a slash on unix systems and a + // back-slash on WIN32 systems. When we can run on Mac or VMS I guess + // we'll worry about other characters.... + // + // $root can now be an array of template roots which will be searched to + // find the first matching name. + function set_root ($root) { + + if (!is_array($root)) { + $trailer = substr ($root, -1); + if ($trailer != ($this->WIN32 ? '\\' : '/')) + $root .= ($this->WIN32 ? '\\' : '/'); + + if (!is_dir($root)) { + if (!$this->MISSING_DIR_OKAY) + $this->error ("Specified ROOT dir [$root] is not a directory", true); + return false; + } + $this->ROOT[] = $root; + } else { + reset($root); + while(list($k, $v) = each($root)) { + if (is_dir($v)) { + $trailer = substr ($v,-1); + if ($trailer != ($this->WIN32 ? '\\' : '/')) + $v .= ($this->WIN32 ? '\\' : '/'); + $this->ROOT[] = $v; + } else if (!$this->MISSING_DIR_OKAY) { + $this->error ("Specified ROOT dir [$v] is not a directory", true); + } + } + } + // FIXME: should add something here to make sure there is at least one + // entry in ROOT[]. + } + + // + // Description + // Associate files with a template names. + // + // Sigh. At least with the CVS version of PHP, $dynamic = false sets it + // to true. + // + function define ($fileList, $dynamic = 0) { + reset ($fileList); + while (list ($tpl, $file) = each ($fileList)) { + $this->TEMPLATE[$tpl] = array ('file' => $file, 'dynamic' => $dynamic); + } + return true; + } + + function define_dynamic ($tplList, $parent='') { + if (is_array($tplList)) { + reset ($tplList); + while (list ($tpl, $parent) = each ($tplList)) { + $this->TEMPLATE[$tpl]['parent'] = $parent; + $this->TEMPLATE[$tpl]['dynamic'] = true; + } + } else { + // $tplList is not an array, but a single child/parent pair. + $this->TEMPLATE[$tplList]['parent'] = $parent; + $this->TEMPLATE[$tplList]['dynamic'] = true; + } + } + + // + // Description + // Defines a template from a string (not a file). This function has + // not been ported from original PERL module to CDI's + // class.FastTemplate.php3, and it comebacks in rFastTemplate + // class. You can find it useful if you want to use templates, stored + // in database or shared memory. + // + function define_raw ($stringList, $dynamic = 0) { + reset ($stringList); + while (list ($tpl, $string) = each ($stringList)) { + $this->TEMPLATE[$tpl] = array ('string' => $string, 'dynamic' => $dynamic, 'loaded' => 1); + } + return true; + } + + // + // Description + // Try each directory in our list of possible roots in turn until we + // find a matching template + // + function FindTemplate ($file) { + // first try for a template in the current directory short path for + // absolute filenames + if (substr($file, 0, 1) == '/') { + if (file_exists($file)) { + return $file; + } + } + + // search path for a matching file + reset($this->ROOT); + while(list($k, $v) = each($this->ROOT)) { + $f = $v . $file; + if (file_exists($f)) { + return $f; + } + } + + $this->error ("FindTemplate: file $file does not exist anywhere in " . implode(' ', $this->ROOT), true); + return false; + } + + + // + // Description + // Load a template into memory from the underlying file. + // + function &load ($file) { + $debug = $this->DEBUGALL || $this->DEBUG['load']; + if (! count($this->ROOT)) { + if ($debug) + $this->logwrite ("load: cannot open template $file, template base directory not set"); + $this->error ("cannot open template $file, template base directory not set", true); + return false; + } else { + $contents = ''; + unset ($contents); + + $filename = $this->FindTemplate ($file); + + if ($filename) + @ $contents = implode ('', (@file($filename))); + // This is inconsistent and depends on the setting of track_errors. First, with no + // @-directive above, the error will be reported immediately. Second, if the template + // is empty, it may be that no error occurred and we still end up here. To get around + // this, we explicitly unset $contents and then check to see if it isset(). If so, + // the template was empty and we treat that as a non-error. + if (isset($contents) && ($this->NOEMPTY && empty($contents)) ) { + if ($debug) + $this->logwrite ("load($file): empty template file"); + $this->error ("load($file): empty template file", true); + } else if (!isset($contents)) { + if ($debug) + $this->logwrite ("load($file) failure: $php_errormsg"); + $this->error ("load($file): failure: $php_errormsg", true); + } else { + if ($debug) + $this->logwrite ("load: found $filename"); + return $contents; + } + } + } + + // + // Description + // Recursive internal parse routine. This will recursively parse a + // template containing dynamic inferior templates. Each of these + // inferior templates gets their own entry in the TEMPLATE array. + // + function &parse_internal_1 ($tag, $rest = '') { + $debug = $this->DEBUGALL || $this->DEBUG['parse_internal_1']; + if (empty($tag)) { + $this->error ("parse_internal_1: empty tag invalid", true); + } + if ($debug) + $this->logwrite ("parse_internal_1 (tag=$tag, rest=$rest)"); + while (!empty($rest)) { + if ($debug) + $this->logwrite ('parse_internal_1: REGEX_DYNBEG search: rest => ' . $rest); + if (preg_match ($this->REGEX_DYNBEG, $rest, $dynbeg)) { + // Found match, now split into two pieces and search the second + // half for the matching END. The string which goes into the + // next element includes the HTML comment which forms the BEGIN + // block. + if ($debug) + $this->logwrite ('parse_internal_1: match beg => ' . $dynbeg[1]); + $pos = strpos ($rest, $dynbeg[1]); + + // See if the text on either side of the BEGIN comment is only + // whitespace. If so, we delete the entire line. + $okay = false; + for ($offbeg = $pos - 1; $offbeg >= 0; $offbeg--) { + $c = $rest{$offbeg}; + if ($c == "\n") { + $okay = true; + $offbeg++; + break; + } + if (($c != ' ') && ($c != "\t")) { + $offbeg = $pos; + break; + } + } + if (! $okay) { + $offend = $pos + strlen($dynbeg[1]); + } else { + $l = strlen ($rest); + for ($offend = $pos + strlen($dynbeg[1]); $offend < $l; $offend++) { + $c = $rest{$offend}; + if ($c == "\n") { + $offend++; + break; + } + if (($c != ' ') && ($c != "\t")) { + $offend = $pos + strlen($dynbeg[1]); + break; + } + } + } + + // This includes the contents of the REGEX_DYNBEG in the output + // $part[] = substr ($rest, 0, $pos); + // This preserves whitespace on the END block line(s). + // $part[] = substr ($rest, 0, $pos+strlen($dynbeg[1])); + // $rest = substr ($rest, $pos+strlen($dynbeg[1])); + // Catch case where BEGIN block is at position 0. + if ($offbeg > 0) + $part[] = substr ($rest, 0, $offbeg); + $rest = substr ($rest, $offend); + $sub = ''; + if ($debug) + $this->logwrite ("parse_internal_1: found at pos = $pos"); + // Okay, here we are actually NOT interested in just the next + // END block. We are only interested in the next END block that + // matches this BEGIN block. This is not the most efficient + // because we really could do this in one pass through the + // string just marking BEGIN and END blocks. But the recursion + // makes for a simple algorithm (if there was a reverse + // preg...). + $found = false; + while (preg_match ($this->REGEX_DYNEND, $rest, $dynend)) { + if ($debug) + $this->logwrite ('parse_internal_1: REGEX_DYNEND search: rest => ' . $rest); + if ($debug) + $this->logwrite ('parse_internal_1: match beg => ' . $dynend[1]); + $pos = strpos ($rest, $dynend[1]); + if ($dynbeg[2] == $dynend[2]) { + $found = true; + // See if the text on either side of the END comment is + // only whitespace. If so, we delete the entire line. + $okay = false; + for ($offbeg = $pos - 1; $offbeg >= 0; $offbeg--) { + $c = $rest{$offbeg}; + if ($c == "\n") { + $offbeg++; + $okay = true; + break; + } + if (($c != ' ') && ($c != "\t")) { + $offbeg = $pos; + break; + } + } + if (! $okay) { + $offend = $pos + strlen($dynend[1]); + } else { + $l = strlen ($rest); + for ($offend = $pos + strlen($dynend[1]); $offend < $l; $offend++) { + $c = $rest{$offend}; + if ($c == "\n") { + $offend++; + break; + } + if (($c != ' ') && ($c != "\t")) { + $offend = $pos + strlen($dynend[1]); + break; + } + } + } + // if ($debug) + // $this->logwrite ("parse_internal_1: DYNAMIC BEGIN: (pos,len,beg,end) => ($pos, " . strlen($dynbeg[1]) . ", $offbeg, $offend) + // This includes the contents of the REGEX_DYNEND in the output + // $rest = substr ($rest, $pos); + // This preserves whitespace on the END block line(s). + // $rest = substr ($rest, $pos+strlen($dynend[1])); + // $sub .= substr ($rest, 0, $pos); + $sub .= substr ($rest, 0, $offbeg); + $rest = substr ($rest, $offend); + // Already loaded templates will not be reloaded. The + // 'clear' test was actually hiding a bug in the clear() + // logic.... + if (false && isset($this->TEMPLATE[$dynend[2]]['clear']) + && $this->TEMPLATE[$dynend[2]]['clear']) { + $this->TEMPLATE[$dynend[2]]['string'] = ''; + $this->TEMPLATE[$dynend[2]]['result'] = ''; + $this->TEMPLATE[$dynend[2]]['part'] = + $this->parse_internal_1 ($dynend[2], ' '); + } else if (!isset($this->TEMPLATE[$dynend[2]]['loaded']) + || !$this->TEMPLATE[$dynend[2]]['loaded']) { + // Omit pathological case of empty dynamic template. + if (strlen($sub) > 0) { + $this->TEMPLATE[$dynend[2]]['string'] = $sub; + $this->TEMPLATE[$dynend[2]]['part'] = + $this->parse_internal_1 ($dynend[2], $sub); + $this->TEMPLATE[$dynend[2]]['part']['parent'] = $tag; + } + } + $this->TEMPLATE[$dynend[2]]['loaded'] = true; + $part[] = &$this->TEMPLATE[$dynend[2]]; + $this->TEMPLATE[$dynend[2]]['tag'] = $dynend[2]; + break; + } else { + $sub .= substr ($rest, 0, $pos+strlen($dynend[1])); + $rest = substr ($rest, $pos+strlen($dynend[1])); + if ($debug) + $this->logwrite ("parse_internal_1: $dynbeg[2] != $dynend[2]"); + } + } + if (!$found) { + $this->error ("malformed dynamic template, missing END
\n" . + "$dynbeg[1]
\n", true); + } + } else { + // Although it would appear to make sense to check that we don't + // have a dangling END block, we will, in fact, ALWAYS appear to + // have a dangling END block. We stuff the BEGIN string in the + // part before the inferior template and the END string in the + // part after the inferior template. So for this test to work, + // we would need to look just past the final match. + if (preg_match ($this->REGEX_DYNEND, $rest, $dynend)) { + // $this->error ("malformed dynamic template, dangling END
\n" . + // "$dynend[1]
\n", 1); + } + $part[] = $rest; + $rest = ''; + } + } + return $part; + } + + // + // Description + // Parse the template. If $tag is actually an array, we iterate over + // the array elements. If it is a simple string tag, we may still + // recursively parse the template if it contains dynamic templates and + // we are configured to automatically load those as well. + // + function parse_internal ($tag) { + $debug = $this->DEBUGALL || $this->DEBUG['parse_internal']; + $append = false; + if ($debug) + $this->logwrite ("parse_internal (tag=$tag)"); + + // If we are handed an array of tags, iterate over all of them. This + // is really a holdover from the way class.FastTemplate.php3 worked; + // I think subst() already pulls that array apart for us, so this + // should not be necessary unless someone calls the internal member + // function directly. + if (gettype($tag) == 'array') { + reset ($tag); + foreach ($tag as $t) { + $this->parse_internal ($t); + } + } else { + // Load the file if it hasn't already been loaded. It might be + // nice to put in some logic that reloads the file if it has + // changed since we last loaded it, but that probably gets way too + // complicated and only makes sense if we start keeping it floating + // around between page loads as a persistent variable. + if (!isset($this->TEMPLATE[$tag]['loaded'])) { + if ($this->TEMPLATE[$tag]['dynamic']) { + // Template was declared via define_dynamic(). + if ($this->TEMPLATE[$tag]['parent']) + $tag = $this->TEMPLATE[$tag]['parent']; + else { + // Try to find a non-dynamic template with the same file. + // This would have been defined via define(array(), true) + reset ($this->TEMPLATE); + foreach (array_keys($this->TEMPLATE) as $ptag) { + if ($debug) + $this->logwrite ("parse_internal: looking for non-dynamic parent, $ptag"); + if (!$this->TEMPLATE[$ptag]['dynamic'] + && ($this->TEMPLATE[$ptag]['file'] == $this->TEMPLATE[$tag]['file'])) { + $tag = $ptag; + break; + } + } + } + } + $this->TEMPLATE[$tag]['string'] = &$this->load($this->TEMPLATE[$tag]['file']); + $this->TEMPLATE[$tag]['loaded'] = 1; + } + + // If we are supposed to automatically detect dynamic templates and the dynamic + // flag is not set, scan the template for dynamic sections. Dynamic sections + // markers have a very rigid syntax as HTML comments.... + if ($this->DYNAMIC) { + $this->TEMPLATE[$tag]['tag'] = $tag; + if (!isset($this->TEMPLATE[$tag]['parsed']) + || !$this->TEMPLATE[$tag]['parsed']) { + $this->TEMPLATE[$tag]['part'] = $this->parse_internal_1 ($tag, $this->TEMPLATE[$tag]['string']); + $this->TEMPLATE[$tag]['parsed'] = true; + } + } + } + } + + // + // Description + // class.FastTemplate.php3 compatible interface. + // + // Notes + // I prefer the name `subst' to `parse' since during this phase we are + // really doing variable substitution into the template. However, at + // some point we have to load and parse the template and `subst' will + // do that as well... + // + function parse ($handle, $tag, $autoload = true) { + return $this->subst ($handle, $tag, $autoload); + } + + // + // Description + // Perform substitution on the template. We do not really recurse + // downward in the sense that we do not do subsitutions on inferior + // templates. For each inferior template which is a part of this + // template, we insert the current value of their results. + // + // Notes + // Do I want to make this return a reference? + function subst ($handle, $tag, $autoload = true) { + $append = false; + $debug = $this->DEBUGALL || $this->DEBUG['subst']; + $this->LAST = $handle; + + if ($debug) + $this->logwrite ("subst (handle=$handle, tag=$tag, autoload=$autoload)"); + + // For compatibility with FastTemplate, the results need to overwrite + // for an array. This really only seems to be useful in the case of + // something like + // $t->parse ('MAIN', array ('array', 'main')); + // Where the 'main' template has a variable named MAIN which will be + // set on the first pass (i.e., when parasing 'array') and used on the + // second pass (i.e., when parsing 'main'). + if (gettype($tag) == 'array') { + foreach (array_values($tag) as $t) { + if ($debug) + $this->logwrite ("subst: calling subst($handle,$t,$autoload)"); + $this->subst ($handle, $t, $autoload); + } + return $this->HANDLE[$handle]; + } + + // Period prefix means append result to pre-existing value. + if (substr($tag,0,1) == '.') { + $append = true; + $tag = substr ($tag, 1); + if ($debug) + $this->logwrite ("subst (handle=$handle, tag=$tag, autoload=$autoload) in append mode"); + } + // $this->TEMPLATE[$tag] will only be set if it was explicitly + // declared via define(); i.e., inferior templates will not have an + // entry. + if (isset($this->TEMPLATE[$tag])) { + if (!isset($this->TEMPLATE[$tag]['parsed']) + || !$this->TEMPLATE[$tag]['parsed']) + $this->parse_internal ($tag); + } else { + if (!$this->DYNAMIC) { + $this->error ("subst (handle=$handle, tag=$tag, autoload=$autoload): " . + 'no such tag and dynamic templates are turned off', true); + } + if ($autoload) { + if ($debug) + $this->logwrite ("subst: TEMPLATE[tag=$tag] not found, trying autoload"); + foreach (array_keys($this->TEMPLATE) as $t) { + if ($debug) + $this->logwrite ("subst: calling parse_internal (tag=$t)"); + if (!isset($this->TEMPLATE[$tag]['parsed']) + || !$this->TEMPLATE[$tag]['parsed']) + $this->parse_internal ($t); + } + if ($debug) + $this->logwrite ('subst: retrying with autoload = false'); + $this->subst ($handle, $tag, false); + if ($debug) + $this->logwrite ('subst: completed with autoload = false'); + return; + } else { + $this->error ("subst (handle=$handle, tag=$tag, autoload=$autoload): no such tag", true); + } + } + if (!$append) { + $this->TEMPLATE[$tag]['result'] = ''; + if ($debug) + $this->logwrite ("subst (handle=$handle, tag=$tag, autoload=$autoload) in overwrite mode"); + } + if ($debug) + $this->logwrite ('subst: type(this->TEMPLATE[$tag][\'part\']) => ' . + gettype($this->TEMPLATE[$tag]['part'])); + // Hmmm, clear() called before subst() seems to result in this not + // being defined which leaves me a bit confused.... + $result = ''; + if (isset($this->TEMPLATE[$tag]['part'])) { + reset ($this->TEMPLATE[$tag]['part']); + foreach (array_keys($this->TEMPLATE[$tag]['part']) as $p) { + if ($debug) + $this->logwrite ("subst: looking at TEMPLATE[$tag]['part'][$p]"); + $tmp = $this->TEMPLATE[$tag]['part'][$p]; + // Don't try if ($p == 'parent').... + if (strcmp ($p, 'parent') == 0) { + if ($debug) + $this->logwrite ("subst: skipping part $p"); + $tmp = ''; + } else if (gettype($this->TEMPLATE[$tag]['part'][$p]) == 'string') { + if ($debug) + $this->logwrite ("subst: using part $p"); + reset ($this->VAR); + // Because we treat VAR and HANDLE separately (unlike + // class.FastTemplate.php3), we have to iterate over both or we + // miss some substitutions and are not 100% compatible. + while (list($key,$val) = each ($this->VAR)) { + if ($debug) + $this->logwrite ("subst: substituting VAR $key = $val in $tag"); + $key = '{'.$key.'}'; + $tmp = str_replace ($key, $val, $tmp); + } + reset ($this->HANDLE); + while (list($key,$val) = each ($this->HANDLE)) { + if ($debug) + $this->logwrite ("subst: substituting HANDLE $key = $val in $tag"); + $key = '{'.$key.'}'; + $tmp = str_replace ($key, $val, $tmp); + } + $result .= $tmp; + } else { + $xtag = $this->TEMPLATE[$tag]['part'][$p]['tag']; + if ($debug) { + $this->logwrite ("subst: substituting other tag $xtag result in $tag"); + } + // The assignment is a no-op if the result is not set, but when + // E_ALL is in effect, a warning is generated without the + // isset() test. + if (isset ($this->TEMPLATE[$xtag]['result'])) + $result .= $this->TEMPLATE[$xtag]['result']; + } + } + } + if ($this->STRICT) { + // If quiet-mode is turned on, skip the check since we're not going + // to do anything anyway. + if (!$this->QUIET) { + if (preg_match ($this->REGEX_VAR, $result)) { + $this->error ("unmatched tags still present in $tag
"); + } + } + } else { + $result = preg_replace ($this->REGEX_VAR, '', $result); + } + if ($append) { + if ($debug) { + $this->logwrite ("subst: appending TEMPLATE[$tag]['result'] = $result"); + $this->logwrite ("subst: old HANDLE[$handle] = {$this->HANDLE[$handle]}"); + $this->logwrite ("subst: old TEMPLATE[$tag]['result'] = {$this->TEMPLATE[$tag]['result']}"); + } + // The isset() tests are to suppresss warning when E_ALL is in effect + // and the variables have not actually been set yet (even though the + // user specified append-mode). + if (isset ($this->HANDLE[$handle])) + $this->HANDLE[$handle] .= $result; + else + $this->HANDLE[$handle] = $result; + if (isset ($this->TEMPLATE[$tag]['result'])) + $this->TEMPLATE[$tag]['result'] .= $result; + else + $this->TEMPLATE[$tag]['result'] = $result; + if ($debug) { + $this->logwrite ("subst: new HANDLE[$handle] = {$this->HANDLE[$handle]}"); + $this->logwrite ("subst: new TEMPLATE[$tag]['result'] = {$this->TEMPLATE[$tag]['result']}"); + } + + } else { + if ($debug) + $this->logwrite ("subst: setting TEMPLATE[$tag]['result'] = $result"); + $this->HANDLE[$handle] = $result; + $this->TEMPLATE[$tag]['result'] = $result; + } + return $this->HANDLE[$handle]; + } + + // + // Description + // Clear a block from a template. The intent is to remove an inferior + // template from a parent. This works even if the template has already + // been parsed since we go straight to the specified template and clear + // the results element. If the given template has not yet been + // loaded, the load is forced by calling parse_internal(). + // + function clear_dynamic ($tag = NULL) { + $debug = $this->DEBUGALL || $this->DEBUG['clear_dynamic']; + if (is_null ($tag)) { + // Clear all result elements. Uhm, needs to be tested. + if ($debug) + $this->logwrite ("clear_dynamic (NULL)"); + foreach (array_values ($this->TEMPLATE) as $t) { + $this->clear_dynamic ($t); + } + return; + } else if (gettype($tag) == 'array') { + if ($debug) + $this->logwrite ("clear_dynamic ($tag)"); + foreach (array_values($tag) as $t) { + $this->clear_dynamic ($t); + } + return; + } + else if (!isset($this->TEMPLATE[$tag])) { + if ($debug) + $this->logwrite ("clear_dynamic ($tag) --> $tag not set, calling parse_internal"); + $this->parse_internal ($tag); + // $this->TEMPLATE[$tag] = array (); + } + if ($debug) + $this->logwrite ("clear_dynamic ($tag)"); + // $this->TEMPLATE[$tag]['loaded'] = true; + // $this->TEMPLATE[$tag]['string'] = ''; + $this->TEMPLATE[$tag]['result'] = ''; + // $this->TEMPLATE[$tag]['clear'] = true; + } + + // + // Description + // Clear the results of a handle set by parse(). The input handle can + // be a single value, an array, or the PHP constant NULL. For the + // last case, all handles cleared. + // + function clear ($handle = NULL) { + $debug = $this->DEBUGALL || $this->DEBUG['clear']; + if (is_null ($handle)) { + // Don't bother unsetting them, just set the whole thing to a new, + // empty array. + if ($debug) + $this->logwrite ("clear (NULL)"); + $this->HANDLE = array (); + } else if (gettype ($handle) == 'array') { + if ($debug) + $this->logwrite ("clear ($handle)"); + foreach (array_values ($handle) as $h) { + $this->clear ($h); + } + } else if (isset ($this->HANDLE[$handle])) { + if ($debug) + $this->logwrite ("clear ($handle)"); + unset ($this->HANDLE[$handle]); + } + } + + // + // Description + // Clears all information associated with the specified tag as well as + // any information associated with embedded templates. This will force + // the templates to be reloaded on the next call to subst(). + // Additionally, any results of previous calls to subst() will also be + // cleared. + // + // Notes + // This leaves dangling references in $this->HANDLE. Or does PHP do + // reference counting so they are still valid? + // + function unload ($tag) { + if (!isset($this->TEMPLATE[$tag])) + return; + if (isset ($this->TEMPLATE[$tag]['parent'])) { + $ptag = $this->TEMPLATE[$tag]['parent']; + foreach (array_keys($this->TEMPLATE) as $t) { + if ($this->TEMPLATE[$t]['parent'] == $ptag) { + unset ($this->TEMPLATE[$t]); + } + } + } + unset ($this->TEMPLATE[$tag]); + return; + } + + // + // Description + // class.FastTemplate.php3 compatible interface. + // + function assign ($tplkey, $rest = '') { + $this->setkey ($tplkey, $rest); + } + + // + // Description + // Set a (key,value) in our internal variable array. These will be + // used during the substitution phase to replace template variables. + // + function setkey ($tplkey, $rest = '') { + if (gettype ($tplkey) == 'array') { + reset ($tplkey); + while (list($key,$val) = each ($tplkey)) { + if (!empty($key)) { + $this->VAR[$key] = $val; + } + } + } else { + if (!empty($tplkey)) { + $this->VAR[$tplkey] = $rest; + } + } + } + + function append ($tplkey, $rest = '') { + if (gettype ($tplkey) == 'array') { + reset ($tplkey); + while (list($key,$val) = each ($tplkey)) { + if (!empty($key)) { + $this->VAR[$key] .= $val; + } + } + } else { + if (!empty($tplkey)) { + $this->VAR[$tplkey] .= $rest; + } + } + } + + // + // Description + // class.FastTemplate.php3 compatible interface + // + function get_assigned ($key = '') { + return $this->getkey ($key); + } + + // + // Description + // Retrieve a value from our internal variable array given the key name. + // + function getkey ($key = '') { + if (empty($key)) { + return false; + } else if (isset ($this->VAR[$key])) { + return $this->VAR[$key]; + } else { + return false; + } + } + + function fetch ($handle = '') { + if (empty($handle)) { + $handle = $this->LAST; + } + return $this->HANDLE[$handle]; + } + + function xprint ($handle = '') { + if (empty($handle)) { + $handle = $this->LAST; + } + print ($this->HANDLE[$handle]); + } + + function FastPrint ($handle = '') { + $this->xprint ($handle); + } + + function clear_href ($key = '') { + $this->unsetkey ($key); + } + + function unsetkey ($key = '') { + if (empty($key)) { + unset ($this->VAR); + $this->VAR = array (); + } else if (gettype($key) == 'array') { + reset ($key); + foreach (array_values($key) as $k) { + unset ($this->VAR[$k]); + } + } else { + unset ($this->VAR[$key]); + } + } + + function define_nofile ($stringList, $dynamic = 0) { + $this->define_raw ($stringList, $dynamic); + } + // + // Description + // Member function to control explicit error messages. We don't do + // real PHP error handling. + // + function error ($errorMsg, $die = 0) { + $this->ERROR = $errorMsg; + echo "ERROR: {$this->ERROR}
\n"; + if ($die) { + exit; + } + return; + } +} diff -r 2cb6a707f2bc -r 6d354f3a8d90 contrib/web/php-admin/htdocs/edit.php --- a/contrib/web/php-admin/htdocs/edit.php Mon Dec 21 17:49:16 2009 +1100 +++ b/contrib/web/php-admin/htdocs/edit.php Mon Jan 11 00:20:03 2010 +1100 @@ -27,7 +27,7 @@ */ require("../conf/config.php"); -require("class.FastTemplate.php"); +require("class.rFastTemplate.php"); function mlmmj_boolean($name, $nicename, $text) { @@ -97,7 +97,7 @@ function encode_entities($str) { return htmlentities($str); } -$tpl = new FastTemplate($templatedir); +$tpl = new rFastTemplate($templatedir); $list = $HTTP_GET_VARS["list"]; diff -r 2cb6a707f2bc -r 6d354f3a8d90 contrib/web/php-admin/htdocs/index.php --- a/contrib/web/php-admin/htdocs/index.php Mon Dec 21 17:49:16 2009 +1100 +++ b/contrib/web/php-admin/htdocs/index.php Mon Jan 11 00:20:03 2010 +1100 @@ -26,10 +26,10 @@ * IN THE SOFTWARE. */ -require("class.FastTemplate.php"); +require("class.rFastTemplate.php"); require("../conf/config.php"); -$tpl = new FastTemplate($templatedir); +$tpl = new rFastTemplate($templatedir); $tpl->define(array("main" => "index.html")); diff -r 2cb6a707f2bc -r 6d354f3a8d90 contrib/web/php-admin/htdocs/save.php --- a/contrib/web/php-admin/htdocs/save.php Mon Dec 21 17:49:16 2009 +1100 +++ b/contrib/web/php-admin/htdocs/save.php Mon Jan 11 00:20:03 2010 +1100 @@ -27,7 +27,7 @@ */ require("../conf/config.php"); -require("class.FastTemplate.php"); +require("class.rFastTemplate.php"); function mlmmj_boolean($name, $nicename, $text) { @@ -72,7 +72,7 @@ function encode_entities($str) { return htmlentities($str); } -$tpl = new FastTemplate($templatedir); +$tpl = new rFastTemplate($templatedir); $list = $HTTP_POST_VARS["list"];