<?php 
/******************************************************************************
 * class.TemTab.php
 *
 * This class creates output text from a file template and given values.
 * The template contains variables that are replaced with the given values
 * The default variable name delimiters are '~!' in front and '~' at end
 * So a variable in the template file should appear like '~!variable_name~'
 *
 * Basic usage is
 *    TemTab            create an new object from a template file
 *    Replace_Var        replace a variable with its value
 *    Replace_Loop_Vars    replace a loop with an array of values
 *    Get_Output        get the parsed template
 *
 * Files index.php and test-template.html provides detailed examples.
 * 
 * See file CHANGES for version history.
 *
 * 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
 * of the License, or (at your option) any later version.
 *
 * 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
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA,
 * or go to http://www.gnu.org/copyleft/gpl.html
 *
 * Copyright © 2002 Antoine Delvaux
 *****************************************************************************/

/******************************************************************************
 * Class:    TemTab
 * Function Listing:
 *    Public methods :
 *        TemTab            Constructor
 *        Replace_Var        Replace all occurences of a variable
 *        Replace_Loop_Vars    Replace all occurences of a loop and associated variables
 *        Remove_All_Vars        Remove all unused variables still present
 *        Get_Output        Return the parsed template
 *    Private methods :
 *        load_template        Load the template file provided
 *****************************************************************************/
class TemTab
{
  
//---Static
  
var $Version        "1.0";
  var 
$Ver_Str          "v1.0 by <antoine(at)delvaux(dot)net>";

  
//---Public properties

  //---Private properties
  
var $template;        // the template to be/being parsed
  
var $var_delim_start;        // the front variable name delimiter
  
var $var_delim_end;        // the back variable name delimiter
  
var $do_counts;        // flag, if set, counts the number of replaces

  /****************************************************************************
   * TemTab($file, $dc, $delim_s, $delim_e)
   *
   * Desc:    constructor
   * Type:    public
   * Args:    $file : the template file to use
   *        $dc : flags, if set the class counts the number of replaces for each variable
   *        $delim_s : the starting delimiter for variable or loop names
   *        $delim_e : the ending delimiter for variable of loop names
   * Returns:    true if the file is loaded
   ***************************************************************************/
  
function TemTab($file$dc="false"$delim_s="~!"$delim_e="~") {
    
// default is false to improve performance
    
$this->do_counts $dc;
    
$this->var_delim_start $delim_s;
    
$this->var_delim_end $delim_e;
    return 
$this->load_template($file);
  }

  
/****************************************************************************
   * load_template($file_name)
   *
   * Desc:    load a template file to parse
   * Type:    public
   * Args:    $file_name
   * Returns:    true if loaded
   ***************************************************************************/
  
function load_template($file_name) {
    if (
$fd fopen($file_name,"r")) {
      
// load whole file into a variable, normally this shouldn't be too big...
      
$this->template fread($fdfilesize($file_name));
      
fclose ($fd);
      return 
true;
    } else {
      return 
false;
    }
  }

  
/****************************************************************************
   * Replace_Var($name, $value)
   *
   * Desc:    replace all occurences of a variable
   * Type:    public
   * Args:    $name : the variable name
   *        $value : the variable value
   * Returns:    number of occurences replaced (if $do_counts set) or -1 if error
   ***************************************************************************/
  
function Replace_Var($name$value) {
    if (
$this->do_counts) {
      
$count substr_count($this->template$this->var_delim_start.$name.$this->var_delim_end);
    } else {
      
$count 0;
    }
    
$this->template str_replace($this->var_delim_start.$name.$this->var_delim_end$value$this->template);
    return 
$count;
  }

  
/****************************************************************************
   * Replace_Loop_Vars($loop_name, $values, [$var_names])
   *
   * Desc:    replace all occurences of a loop with array of variables provided
   * Type:    public
   * Args:    $loop_name : the loop name
   *        $values : the values as array of arrays, called lines (if only one variable in the loop, needs an array of one array)
   *        $var_names : the name of the variable inside the loop (optional), array, if not used, numbers are used
   * Returns:    number of occurences replaced or -1 if error
   ***************************************************************************/
  
function Replace_Loop_Vars($loop_name$values$var_names "") {
    
// start with the whole template
    
$remaining $this->template;
    
$this->template "";
    
$count 0;
    while (
preg_match("/\s*<!--.*".$this->var_delim_start."begin-".$loop_name.$this->var_delim_end.".*-->/",$remaining)) {
      
// split the remaining of template at first loop boundaries
      
list ($begin$loop$remaining) = preg_split("/\s*<!--.*".$this->var_delim_start."(begin|end)-".$loop_name.$this->var_delim_end.".*-->/",$remaining,3);
      
$count++;
      
$this->template .= $begin;
      foreach (
$values as $line) {
    
// take the loop and replace all variables with this line values
    
$line_output $loop;
    for (
$i=0$i<count($line); $i++) {
      
// loops on the values of the current line
      
if ($var_names == "") {
        
$name $loop_name."-var-".$i;
      } else {
        
$name $loop_name."-".$var_names[$i];
      }
      
$line_output str_replace($this->var_delim_start.$name.$this->var_delim_end$line[$i], $line_output);
    }
    
$this->template .= $line_output;
      }
    }
    
$this->template .= $remaining;
    return 
$count;
  }

  
/****************************************************************************
   * Remove_All_Vars()
   *
   * Desc:    remove all remaining variables remaining in the template
   * Type:    public
   * Args:    
   * Returns:    number of variables removed (if $do_counts set) or -1 if error
   ***************************************************************************/
  
function Remove_All_Vars() {
    if (
$this->do_counts) {
      
$count preg_match_all("/".$this->var_delim_start.".*".$this->var_delim_end."/"$this->template$unused);
    } else {
      
$count 0;
    }
    
$this->template preg_replace("/".$this->var_delim_start.".*".$this->var_delim_end."/"""$this->template);
    return 
$count;
  }

  
/****************************************************************************
   * Get_Output()
   *
   * Desc:    get output of template
   * Type:    public
   * Args:    
   * Returns:    the template with replaced values as a string
   ***************************************************************************/
  
function Get_Output() {
    return 
$this->template;
  }

}
?>