<?php


/* + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
 +                                                                   +
 * Integrated Templates (IT)                                         *
 +                                                                   +
 * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */

require_once('HTML/Template/IT.php');

/**
 * Abstract class for IT templates
 *
 * This class has just one method show() which should return the completed
 * template. All the data and blocks are feed to the template engine
 * prior to calling this method. The method takes the template engine
 * instance as the only parameter.
 * This is to put all the logic of the template in just one single place.
 *
 * @package HTML_Template_ITInterfaced
 * @subpackage HTML_Template_IT_Template
 **/
abstract class HTML_Template_IT_Template
{
    
/**
     * To hold the template file name or template content
     *
     * @access protected
     * @var string
     **/
    
protected $_template;

    
/**
     * To hold the template type
     *
     * @access protected
     * @var string
     **/
    
protected $_templateType;

    
/**
     * To hold a options to use for the constructor
     *
     * @access protected
     * @var array
     */
    
protected $_options;

    
/**
     * Class constructor
     *
     * @param string  $template Template file name or template content
     * @param string  $type Type of $template. Either 'file' or 'var'
     * @param boolean $removeUnknownVariables remove unknown/unused variables?
     * @param boolean $removeEmptyBlocks remove empty blocks?
     * @see HTML_Template_IT::loadTemplateFile()
     * @see HTML_Template_IT::setTemplate()
     **/
    
function __construct($template$type 'file'$removeUnknownVariables true$removeEmptyBlocks true)
    {
        
$this->_template $template;
        
$this->_templateType $type;
        
$this->_options = array(
            
'removeUnknownVariables' => $removeUnknownVariables,
            
'removeEmptyBlocks'      => $removeEmptyBlocks);
    }

    
/**
     * Initialize object
     *
     * The template engine object must be passed by reference.
     * This is the default behavior in PHP 5.
     *
     * @access protected
     * @param object $t A HTML_Template_ITInterfaced object
     * @return mixed TRUE or PEAR_Error object on error
     **/
    
protected function _init(HTML_Template_ITInterfaced $t)
    {
        
$removeUnknownVariables $this->_options['removeUnknownVariables'];
        
$removeEmptyBlocks      $this->_options['removeEmptyBlocks'];
        if (
$this->_templateType == 'file') {
           
$result $t->loadTemplateFile($this->_template,
               
$removeUnknownVariables$removeEmptyBlocks);
        } else {
           
$result $t->setTemplate($this->_template,
               
$removeUnknownVariables$removeEmptyBlocks);
        }
        if (
PEAR::isError($result)) {
           return 
$result;
        }
        return 
true;
    }

    
/**
     * Build and output the result of the template
     *
     * Typical implementation (given a block named "table_row" in $template):
     * <code>
     *  // Initialization
     *  $result = $this->_init($t);
     *  if (PEAR::isError($result)) {
     *      return $result;
     *  }
     *  $data =& $t->getData();
     *
     *  // Build template
     *  foreach ($data as $name => $value) {
     *      $t->setVariable($name, $value);
     *      $result = $t->parse('table_row');
     *      if (PEAR::isError($result)) {
     *          return $result;
     *      }
     *  }
     *
     *  // Output result
     *  $t->show();
     *
     *  return true;
     * </code>
     *
     * @param object $t A HTML_Template_ITInterfaced object
     * @return mixed TRUE or PEAR_Error object on error
     **/
    
abstract public function show(HTML_Template_ITInterfaced $t);

// End [CLASS] HTML_Template_IT_Template


/**
 * Implementation of the interface for Integrated Templates
 *
 * @package HTML_Template_ITInterfaced
 * @link http://pear.php.net/package/HTML_Template_ IT
 **/
class HTML_Template_ITInterfaced extends HTML_Template_IT implements Template_Interface
{
    
/**
     * To hold data to be used in template
     *
     * @access private
     * @var array
     */
    
private $_templateData;

    
/**
     * To hold a reference to a HTML_Template_IT_Template instance
     *
     * @access private
     * @var object
     */
    
private $_templateReference;

    
/**
     * Class constructor
     **/
    
function __construct($root '')
    {
        require_once(
'PEAR.php');

        
parent::HTML_Template_IT($root);
        
$this->_templateReference null;
        
$this->_templateData = array();
    }

    
/**
     * Open the template to be used.
     *
     * @access public
     * @param  object $template An instance of HTML_Template_IT_Template
     * @return mixed TRUE or a PEAR_Error object on error
     **/
    
public function openTemplate($template)
    {
        
// Type hinting can't be used here due to interface
        // declaration
        
if (!($template instanceof HTML_Template_IT_Template)) {
            return 
PEAR::raiseError('Argument 1 must be an object of class HTML_Template_IT_Template');
        }
        
$this->_templateReference $template;
        return 
true;
    }

    
/**
     * Set one or more value to be used by the template
     *
     * @access public
     * @param  mixed  $name Associative array or name/identifier of data
     * @param  mixed  $data Data associated identified by $name, when $name
     *                      is not an associative array.
     **/
    
public function setData($name$data null)
    {
        if (
is_array($name)) {
            
$this->_templateData array_merge($this->_templateData$name);
        } else {
            
$this->_templateData[$name] = $data;
        }
    }

    
/**
     * Set one value (by reference) to be used by the template
     *
     * @access public
     * @param  string $name Name/identifier of data
     * @param  mixed  $data Reference to data associated identified by $name
     **/
    
public function setDataByRef($name, &$data)
    {
        
$this->_templateData[$name] =& $data;
    }

    
/**
     * Clear all previously set data
     *
     * @access public
     **/
    
public function clearData()
    {
        
$this->_templateData = array();
    }

    
/**
     * Return all previously set data
     *
     * Return a reference to an associative array
     *
     * @access public
     * @return array All data
     **/
    
public function &getData()
    {
        return 
$this->_templateData;
    }

    
/**
     * Return the MIME type of the result generated by the template
     *
     * @access public
     * @return string MIME type
     **/
    
public function getMimeType() {
        if (
is_null($this->_templateReference)) {
            return 
PEAR::raiseError('You must call openTemplate() first.');
        }
        return 
$this->_templateReference->getMimeType();
    }

    
/**
     * Output the result of the template
     *
     * @access public
     * @return mixed TRUE or PEAR_Error on error
     **/
    
public function output()
    {
        if (
is_null($this->_templateReference)) {
            return 
PEAR::raiseError('You must call openTemplate() first.');
        }
        
$this->_templateReference->show($this);
        return 
true;
    }

    
/**
     * Output the result of the template to a file
     *
     * @access public
     * @param  mixed  $filename Path to file or file resource
     * @return mixed  How many bytes where put or PEAR_Error object on error
     * @see fopen()
     **/
    
public function toFile($filename)
    {
        
$output $this->toString();
        if (
PEAR::isError($output)) {
            return 
$output;
        }

        if (
is_resource($filename)) {
            
$file $filename;

        } else {
            
$file = @fopen($filename'wb');
            if (!
$file) {
                return 
PEAR::raiseError('Couldn\'t open file to write template result to.');
            }
        }

        
$mgc get_magic_quotes_runtime();
        
set_magic_quotes_runtime(0);
        
$length = @fwrite($file$output);
        
set_magic_quotes_runtime($mgc);

        if (
$length === false) {
            
$return PEAR::raiseError('Couldn\'t write template result to file.');
        } else {
            
$return $length;
        }

        if (!
is_resource($filename)
            && !@
fclose($file)
            && 
is_integer($return)) {
            
$return PEAR::raiseError('Couldn\'t close file with template result.');
        }

        return 
$return;
    }

    
/**
     * Return the result of the template as a string
     *
     * @access public
     * @return mixed String or PEAR_Error object on error
     **/
    
public function toString()
    {
        
ob_start();
        
$return $this->output();
        if (
PEAR::isError($return)) {
            
ob_end_clean();
            return 
$return;
        }
        return 
ob_get_clean();
    }

// End [CLASS] HTML_Template_ITInterfaced

?>