Source for file PHPLIB.php

Documentation is available at PHPLIB.php

  1. <?php
  2. // vim: set expandtab tabstop=4 shiftwidth=4:
  3. // This code that was derived from the original PHPLIB Template class
  4. // is copyright by Kristian Koehntopp, NetUSE AG and was released
  5. // under the LGPL.
  6. //
  7. // Authors: Kristian Koehntopp <kris@koehntopp.de> (original from PHPLIB)
  8. //          Bjoern Schotte <bjoern@rent-a-phpwizard.de> (PEARification)                
  9. //          Martin Jansen <mj@php.net> (PEAR conformance)            
  10. //
  11. // $Id: PHPLIB.php,v 1.3 2006/09/17 06:22:04 wurley Exp $
  12. //
  13.  
  14. //require_once "PEAR.php";
  15.  
  16. /**
  17.  * Converted PHPLIB Template class
  18.  *
  19.  * For those who want to use PHPLIB's fine template class,
  20.  * here's a PEAR conforming class with the original PHPLIB
  21.  * template code from phplib-stable CVS. Original author
  22.  * was Kristian Koehntopp <kris@koehntopp.de>
  23.  *
  24.  * @author  Bjoern Schotte <bjoern@rent-a-phpwizard.de>
  25.  * @author  Martin Jansen <mj@php.net> (PEAR conformance)
  26.  * @version 1.0
  27.  */
  28. {
  29.     /**
  30.      * If set, echo assignments
  31.      * @var bool 
  32.      */
  33.     public $debug     = false;
  34.  
  35.     /**
  36.      * $file[handle] = "filename";
  37.      * @var array 
  38.      */
  39.     public $file  = array();
  40.  
  41.     /**
  42.      * fallback paths that should be defined in a child class
  43.      * @var array 
  44.      */
  45.     public $file_fallbacks = array();
  46.  
  47.     /**
  48.      * Relative filenames are relative to this pathname
  49.      * @var string 
  50.      */
  51.     public $root   = "";
  52.  
  53.     /*
  54.      * $_varKeys[key] = "key"
  55.      * @var array
  56.      */
  57.     public $_varKeys = array();
  58.     
  59.     /**
  60.      * $_varVals[key] = "value";
  61.      * @var array 
  62.      */
  63.     public $_varVals = array();
  64.  
  65.     /**
  66.      * "remove"  => remove undefined variables
  67.      * "comment" => replace undefined variables with comments
  68.      * "keep"    => keep undefined variables
  69.      * @var string 
  70.      */
  71.     public $unknowns = "remove";
  72.   
  73.     /**
  74.      * "yes" => halt, "report" => report error, continue, "no" => ignore error quietly
  75.      * @var string 
  76.      */
  77.     public $haltOnError  = "report";
  78.   
  79.     /**
  80.      * The last error message is retained here
  81.      * @var string 
  82.      * @see halt
  83.      */
  84.     public $_lastError     = "";
  85.  
  86.  
  87.     /**
  88.      * Constructor
  89.      *
  90.      * @access public
  91.      * @param  string template root directory
  92.      * @param  string how to handle unknown variables
  93.      * @param  array fallback paths
  94.      */
  95.     function Template_PHPLIB($root "."$unknowns "remove"$fallback="")
  96.     {
  97.         $this->setRoot($root);
  98.         $this->setUnknowns($unknowns);
  99.         if (is_array($fallback)) $this->file_fallbacks = $fallback;
  100.     }
  101.  
  102.     /**
  103.      * Sets the template directory
  104.      *
  105.      * @access public
  106.      * @param  string new template directory
  107.      * @return bool 
  108.      */
  109.     function setRoot($root)
  110.     {
  111.         if (!is_dir($root)) {
  112.             $this->halt("setRoot$root is not a directory.");
  113.             return false;
  114.         }
  115.     
  116.         $this->root = $root;
  117.     
  118.         return true;
  119.     }
  120.  
  121.     /**
  122.      * What to do with unknown variables
  123.      *
  124.      * three possible values:
  125.      *
  126.      * - "remove" will remove unknown variables
  127.      *   (don't use this if you define CSS in your page)
  128.      * - "comment" will replace undefined variables with comments
  129.      * - "keep" will keep undefined variables as-is
  130.      *
  131.      * @access public
  132.      * @param  string unknowns
  133.      */
  134.     function setUnknowns($unknowns "keep")
  135.     {
  136.         $this->unknowns = $unknowns;
  137.     }
  138.  
  139.     /**
  140.      * Set appropriate template files
  141.      *
  142.      * With this method you set the template files you want to use.
  143.      * Either you supply an associative array with key/value pairs
  144.      * where the key is the handle for the filname and the value
  145.      * is the filename itself, or you define $handle as the file name
  146.      * handle and $filename as the filename if you want to define only
  147.      * one template.
  148.      *
  149.      * @access public
  150.      * @param  mixed handle for a filename or array with handle/name value pairs
  151.      * @param  string name of template file
  152.      * @return bool 
  153.      */
  154.     function setFile($handle$filename "")
  155.     {
  156.         if (!is_array($handle)) {
  157.     
  158.             if ($filename == ""{
  159.                 $this->halt("setFileFor handle $handle filename is empty.");
  160.                 return false;
  161.             }
  162.       
  163.             $this->file[$handle$this->_filename($filename);
  164.       
  165.         else {
  166.     
  167.             reset($handle);
  168.             while (list($h$feach($handle)) {
  169.                 $this->file[$h$this->_filename($f);
  170.             }
  171.         }
  172.     }
  173.  
  174.     /**
  175.      * Set a block in the appropriate template handle
  176.      *
  177.      * By setting a block like that:
  178.      *
  179.      * &lt;!-- BEGIN blockname --&gt;
  180.      * html code
  181.      * &lt;!-- END blockname --&gt;
  182.      *
  183.      * you can easily do repeating HTML code, i.e. output
  184.      * database data nice formatted into a HTML table where
  185.      * each DB row is placed into a HTML table row which is
  186.      * defined in this block.
  187.      * It extracts the template $handle from $parent and places
  188.      * variable {$name} instead.
  189.      *
  190.      * @access public
  191.      * @param  string parent handle
  192.      * @param  string block name handle
  193.      * @param  string variable substitution name
  194.      */
  195.     function setBlock($parent$handle$name "")
  196.     {
  197.         if (!$this->_loadFile($parent)) {
  198.             $this->halt("setBlockunable to load $parent.");
  199.             return false;
  200.         }
  201.     
  202.         if ($name == ""{
  203.             $name $handle;
  204.         }
  205.  
  206.         $str $this->getVar($parent);
  207.         $reg "/[ \t]*<!--\s+BEGIN $handle\s+-->\s*?\n?(\s*.*?\n?)\s*<!--\s+END $handle\s+-->\s*?\n?/sm";
  208.         preg_match_all($reg$str$m);
  209.         $str preg_replace($reg"{" "$name}"$str);
  210.  
  211.         if (isset($m[1][0])) $this->setVar($handle$m[1][0]);
  212.         $this->setVar($parent$str);
  213.     }
  214.  
  215.     /**
  216.      * Set corresponding substitutions for placeholders
  217.      *
  218.      * @access public
  219.      * @param  string name of a variable that is to be defined or an array of variables with value substitution as key/value pairs
  220.      * @param  string value of that variable
  221.      * @param  boolean if true, the value is appended to the variable's existing value
  222.      */
  223.     function setVar($varname$value ""$append false)
  224.     {
  225.         if (!is_array($varname)) {
  226.  
  227.             if (!empty($varname))
  228.                 if ($this->debugprint "scalarset *$varnameto *$value*<br>\n";
  229.  
  230.             $this->_varKeys[$varname$this->_varname($varname);
  231.             ($append$this->_varVals[$varname.= $value $this->_varVals[$varname$value;
  232.  
  233.         else {
  234.             reset($varname);
  235.  
  236.             while (list($k$veach($varname)) {
  237.                 if (!empty($k))
  238.                     if ($this->debugprint "arrayset *$kto *$v*<br>\n";
  239.  
  240.                 $this->_varKeys[$k$this->_varname($k);
  241.                 ($append$this->_varVals[$k.= $v $this->_varVals[$k$v;
  242.             }
  243.         }
  244.     }
  245.  
  246.     /**
  247.      * Substitute variables in handle $handle
  248.      *
  249.      * @access public
  250.      * @param  string name of handle
  251.      * @return mixed string substituted content of handle
  252.      */
  253.     function subst($handle)
  254.     {
  255.         if (!$this->_loadFile($handle)) {
  256.             $this->halt("substunable to load $handle.");
  257.             return false;
  258.         }
  259.  
  260.         return @str_replace($this->_varKeys$this->_varVals$this->getVar($handle));
  261.     }
  262.   
  263.     /**
  264.      * Same as subst but printing the result
  265.      *
  266.      * @access  public
  267.      * @brother subst
  268.      * @param   string handle of template
  269.      * @return  bool always false
  270.      */
  271.     function pSubst($handle)
  272.     {
  273.         print $this->subst($handle);
  274.         return false;
  275.     }
  276.  
  277.     /**
  278.      * Parse handle into target
  279.      *
  280.      * Parses handle $handle into $target, eventually
  281.      * appending handle at $target if $append is defined
  282.      * as TRUE.
  283.      *
  284.      * @access public
  285.      * @param  string target handle to parse into
  286.      * @param  string which handle should be parsed
  287.      * @param  boolean append it to $target or not?
  288.      * @return string parsed handle
  289.      */
  290.     function parse($target$handle$append false)
  291.     {
  292.         if (!is_array($handle)) {
  293.             $str $this->subst($handle);
  294.  
  295.             ($append$this->setVar($target$this->getVar($target$str$this->setVar($target$str);
  296.         else {
  297.             reset($handle);
  298.  
  299.             while (list($heach($handle)) {
  300.                 $str $this->subst($h);
  301.                 $this->setVar($target$str);
  302.             }
  303.         }
  304.  
  305.         return $str;
  306.     }
  307.  
  308.     /**
  309.      * Same as parse, but printing it.
  310.      *
  311.      * @access  public
  312.      * @brother parse
  313.      * @param   string target to parse into
  314.      * @param   string handle which should be parsed
  315.      * @param   should $handle be appended to $target?
  316.      * @return  bool 
  317.      */
  318.     function pParse($target$handle$append false)
  319.     {
  320.         print $this->finish($this->parse($target$handle$append));
  321.         return false;
  322.     }
  323.   
  324.     /**
  325.      * Return all defined variables and their values
  326.      *
  327.      * @access public
  328.      * @return array with all defined variables and their values
  329.      */
  330.     function getVars()
  331.     {
  332.         reset($this->_varKeys);
  333.  
  334.         while (list($keach($this->_varKeys)) {
  335.             $result[$k$this->getVar($k);
  336.         }
  337.  
  338.         return $result;
  339.     }
  340.  
  341.     /**
  342.      * Return one or more specific variable(s) with their values.
  343.      *
  344.      * @access public
  345.      * @param  mixed array with variable names or one variable name as a string
  346.      * @return mixed array of variable names with their values or value of one specific variable
  347.      */
  348.     function getVar($varname)
  349.     {
  350.         if (!is_array($varname)) {
  351.             if (isset($this->_varVals[$varname])) {
  352.                 return $this->_varVals[$varname];
  353.             else {
  354.                 return "";
  355.             }
  356.         else {
  357.             reset($varname);
  358.     
  359.             while (list($keach($varname)) {
  360.                 $result[$k(isset($this->_varVals[$k])) $this->_varVals[$k"";
  361.             }
  362.  
  363.             return $result;
  364.         }
  365.     }
  366.   
  367.     /**
  368.      * Get undefined values of a handle
  369.      *
  370.      * @access public
  371.      * @param  string handle name
  372.      * @return mixed  false if an error occured or the undefined values
  373.      */
  374.     function getUndefined($handle)
  375.     {
  376.         if (!$this->_loadFile($handle)) {
  377.             $this->halt("getUndefinedunable to load $handle.");
  378.             return false;
  379.         }
  380.     
  381.         preg_match_all("/{([^ \t\r\n}]+)}/"$this->getVar($handle)$m);
  382.         $m $m[1];
  383.         if (!is_array($m)) {
  384.             return false;
  385.         }
  386.  
  387.         reset($m);
  388.         while (list($veach($m)) {
  389.             if (!isset($this->_varKeys[$v])) {
  390.                 $result[$v$v;
  391.             }
  392.         }
  393.     
  394.         if (isset($result&& count($result)) {
  395.             return $result;
  396.         else {
  397.             return false;
  398.         }
  399.     }
  400.  
  401.     /**
  402.      * Finish string
  403.      *
  404.      * @access public
  405.      * @param  string string to finish
  406.      * @return finished, i.e. substituted string
  407.      */
  408.     function finish($str)
  409.     {
  410.         switch ($this->unknowns{
  411.             case "remove":
  412.                 $str preg_replace('/{[^ \t\r\n}]+}/'""$str);
  413.                 break;
  414.  
  415.             case "comment":
  416.                 $str preg_replace('/{([^ \t\r\n}]+)}/'"<!-- Template $handleVariable \\1 undefined -->"$str);
  417.                 break;
  418.         }
  419.  
  420.         return $str;
  421.     }
  422.  
  423.     /**
  424.      * Print variable to the browser
  425.      *
  426.      * @access public
  427.      * @param  string name of variable to print
  428.      */
  429.     function p($varname)
  430.     {
  431.         print $this->finish($this->getVar($varname));
  432.     }
  433.  
  434.     /**
  435.      * Get finished variable
  436.      *
  437.      * @access public public
  438.      * @param  string variable to get
  439.      * @return string string with finished variable
  440.      */
  441.     function get($varname)
  442.     {
  443.         return $this->finish($this->getVar($varname));
  444.     }
  445.  
  446.     /**
  447.      * Complete filename
  448.      *
  449.      * Complete filename, i.e. testing it for slashes
  450.      *
  451.      * @access private
  452.      * @param  string filename to be completed
  453.      * @return string completed filename
  454.      */
  455.     function _filename($filename)
  456.     {
  457. //        if (substr($filename, 0, 1) != "/") {
  458. //            $filename = $this->root."/".$filename;
  459. //        }
  460.  
  461.         if (file_exists($filename)) return $filename;
  462.         if (is_array($this->file_fallbacks&& count($this->file_fallbacks0{
  463.             reset($this->file_fallbacks);
  464.             while (list(,$veach($this->file_fallbacks)) {
  465.                 if (file_exists($v.basename($filename))) return $v.basename($filename);
  466.             }
  467.             $this->halt(sprintf("filename: file %s does not exist in the fallback paths %s.",$filename,implode(",",$this->file_fallbacks)));
  468.             return false;
  469.         else {
  470.             $this->halt(sprintf("filename: file %s does not exist.",$filename));
  471.             return false;
  472.         }
  473.  
  474.         return $filename;
  475.     }
  476.  
  477.     /**
  478.      * Protect a replacement variable
  479.      *
  480.      * @access private
  481.      * @param  string name of replacement variable
  482.      * @return string replaced variable
  483.      */
  484.     function _varname($varname)
  485.     {
  486.         return "{".$varname."}";
  487.     }
  488.  
  489.     /**
  490.      * load file defined by handle if it is not loaded yet
  491.      *
  492.      * @access private
  493.      * @param  string handle
  494.      * @return bool   FALSE if error, true if all is ok
  495.      */
  496.     function _loadFile($handle)
  497.     {
  498.         if (isset($this->_varKeys[$handle]and !empty($this->_varVals[$handle])) {
  499.             return true;
  500.         }
  501.  
  502.         if (!isset($this->file[$handle])) {
  503.             $this->halt("loadfile$handle is not a valid handle.");
  504.             return false;
  505.         }
  506.  
  507.         $filename $this->file[$handle];
  508.         if (function_exists("file_get_contents")) {
  509.             $str file_get_contents($filename);
  510.         else {
  511.             if (!$fp @fopen($filename,"r")) {
  512.                 $this->halt("loadfilecouldn't open $filename");
  513.                 return false;
  514.             }
  515.  
  516.             $str fread($fp,filesize($filename));
  517.             fclose($fp);
  518.         }
  519.  
  520.         if ($str==''{
  521.             $this->halt("loadfileWhile loading $handle$filename does not exist or is empty.");
  522.             return false;
  523.         }
  524.  
  525.         $this->setVar($handle$str);
  526.  
  527.         return true;
  528.     }
  529.  
  530.     /**
  531.      * Error function. Halt template system with message to show
  532.      *
  533.      * @access public
  534.      * @param  string message to show
  535.      * @return bool 
  536.      */
  537.     function halt($msg)
  538.     {
  539.         $this->_lastError = $msg;
  540.  
  541.         if ($this->haltOnError != "no"{
  542. //            return $this->haltMsg($msg);
  543.             $this->haltMsg($msg);
  544.         }
  545.  
  546.         if ($this->haltOnError == "yes"{
  547.             die("<b>Halted.</b>");
  548.         }
  549.  
  550.         return false;
  551.     }
  552.   
  553.     /**
  554.      * printf error message to show
  555.      *
  556.      * @access public
  557.      * @param  string message to show
  558.      * @return object PEAR error object
  559.      */
  560.     function haltMsg($msg)
  561.     {
  562. //        PEAR::raiseError(sprintf("<b>Template Error:</b> %s<br>\n", $msg));
  563.         printf("<b>Template Error:</b> %s<br>\n"$msg);
  564.     }
  565. }
  566. ?>

Documentation generated on Fri, 22 May 2009 19:10:16 +1000 by phpDocumentor 1.4.1