<?php

//////
/////  Template Engine $Id: template.php,v 1.3 2001/04/30 19:08:11 aj Exp $
////
///
// Modulename Template
// Moduledependencies Config

/* 
 * Template Engine provides an easy syntax for powerful 
 * symbol substitution. 
 *
 * Usage: 
 *   Listing of example.tpl:
 *     <HTML>
 *      <HEAD><title>#{title}</title></HEAD>
 *      <BODY>#{main}</BODY>
 *     </HTML>
 * 
 *   Listing of main.tpl:
 *     <TABLE>
 *      #{table}</TR>
 *     </TABLE>
 *
 *   Listing of table.tpl
 *     <TR>
 *      <TD>#{col1}</TD>
 *      <TD>#{col2}</TD>
 *     </TR>
 * 
 *   Code:
 *     $tpl = new Template('example.tpl');
 *     $tpl->assign('title', 'Using template engine - example');
 *     $tpl->assignFile('main', 'main.tpl');
 *     $subTable = array(0 => array('col1' => 'First col, first run',
 *                                  'col2' => 'Second col, first run'),
 *                       1 => array('col1' => 'First col, second run',
 *                                            'Second col, second run')
 *                       );
 *
 *     $tpl->assignBlockFile('table', 'table.tpl', $subTable);
 *     $tpl->execute();
 * 
 *   Produces:
 *     <HTML>
 *      <HEAD><title>Using template engine - example</title></HEAD>
 *      <BODY>
 *       <TABLE>
 *        <TR>
 *          <TD>First col, first run</TD>
 *          <TD>Second col, first run</TD>
 *        </TR>
 *        <TR>
 *          <TD>First col, second run</TD>
 *          <TD>Second col, second run</TD>
 *        </TR>
 *       </TABLE>
 *      </BODY>
 *     </HTML>
 *
 */


class Template {

    var $template = "";
    var $subTable = array();
    var $debug = true;
    var $regExp = "/#{([a-zA-Z0-9.-:]*)}/";

    /* Constructor. Load file as template */
    function Template($file) {
	$this->template = $this->getFile($file);
    }

    /* Set debug mode */
    function setDebug($mode) {
	$this->debug = $mode;
    }

    /* Get debug mode */
    function getDebug() {
	return empty($this->debug);
    }
    
    /* Assign a value to a symbol */
    function assign() {
	if (func_num_args() == 1) {
	    if (!is_array(func_get_arg(0)))
		return false;

	    $args = func_get_arg(0);
	    
	    foreach ($args as $symbol => $value) {
		$this->subTable[$symbol]['type']  = 'sub';
		$this->subTable[$symbol]['value'] = $value;
	    }
	    

	    $this->subTable = array_merge($this->subTable, $arg);

	} else if (func_num_args() == 2) {
	    $this->subTable[func_get_arg(0)]['type']  = 'sub';
	    $this->subTable[func_get_arg(0)]['value'] = func_get_arg(1);

	} else {
	    return false;
	}
    }

    /* Assign a file to a symbol */
    function assignFile($symbol, $filename) {
	$this->subTable[$symbol]['type']  = 'file';
	$this->subTable[$symbol]['value'] = $filename;

    }

    
    /* Assign a block to a symbol */
    function assignBlock($symbol, $content, $subs) {
	$this->subTable[$symbol]['type']    = 'block';
	$this->subTable[$symbol]['content'] = $content;
	$this->subTable[$symbol]['value']   = $subs; 
    }

    /* Assign a file including a block to a symbol */
    function assignBlockFile($symbol, $filename, $subs) {
	$this->subTable[$symbol]['type']    = 'block';
	$this->subTable[$symbol]['content'] = $this->getFile($filename);
	$this->subTable[$symbol]['value']   = $subs; 
    }

    /* Read file */
    function getFile($file) {
	$file = INCLUDE_PATH.'/'.TEMPLATE_PATH.'/'.$file;

	if (is_file($file)) {
	    $fp = fopen($file, 'r');

	    $buf = fread($fp, filesize($file));

	    fclose($fp);

	    return $buf;

	} else if (!$this->getDebug()) {
	    return "File not found (".$file.")";

	} else {
	    return "";
	}
    }
    
    /* Make all substitutions */
    function execute() {
	return $this->replace($this->template);
    }

    /* Make substitutions for input */
    function replace($input) {
	return preg_replace_callback($this->regExp, array($this, 'substitute'), $input);
    }
    
    /* Callback function for replace */
    function substitute($match) {
	$symbol = $match[1];
	
	if (is_array($this->subTable[$symbol])) {
	    
	    switch ($this->subTable[$symbol]['type']) {
		
	    case 'file':
		return $this->replace($this->getFile($this->subTable[$symbol]['value']));
		
	    case 'sub':
		return $this->subTable[$symbol]['value'];
		
	    case 'block':
		for ($i = 0; $i < sizeof($this->subTable[$symbol]['value']); $i++) {
		    foreach($this->subTable[$symbol]['value'][$i] as $key => $value) {
			$acc .= str_replace("#\{$key}", $value, $this->subTable[$symbol]['content']);
 		    }
		}

		return $acc;
	    }
	    
	} else {
	    if (!$this->getDebug())
		return "Warning: No such symbol (".$symbol.")";
	}
	
    }
}


?>





