Location: PHPKode > scripts > TPLManager > tplmanager/tplmanager.class.php
<?php
/**
 * Class TPLManager
 * Created on Wed Jan 10 13:15:02 EST 2007 By Gregory Patmore
 * 
 * Lightweight Template File Processor
 * 
 * @author Gregory Patmore (mail at gregorypatmore dot com)
 * @version 1.0
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 * @package TPLManager
 * @access public
 * 
 */
class TPLManager {

	/**
	 * The contents of the unprocessed template file
	 *
	 * @var string
	 */
	protected $raw_text;
	
	/**
	 * The resulting hypertext output after variable processing
	 * has occurred.
	 *
	 * @var string
	 */
	protected $procd_text;

	/**
	 * The path to the template file
	 *
	 * @var string
	 */
	protected $file_path;

	/**
	 * An associative array containing the template variable names
	 * and the text string to replace in the template file
	 * set as such:
	 * $hotspots['VARNAME'] = '{VARNAME}';
	 *
	 * @var array
	 */
	protected $hotspots = array();

	/**
	 * An associative array that holds the values that will replace the
	 * template variables in the output
	 * set as such:
	 * $replacements['VARNAME'] = 'replacement value';
	 *
	 * each key should correspond to a value in the $hot_spots array
	 * or the replacement will not occur
	 *
	 * @var array
	 */
	protected $replacements = array();

	/**
	 * The Regular Expression used to find template Hotspots
	 *
	 */
	protected static $HOTSPOT_REGEX = '#\{([a-zA-Z0-9_]+)\}#';
	
	/**
	 * The regular expression to use if compacting the final text
	 *
	 * @var string
	 */
	protected static $COMPACT_REGEX = '#\s{2,}|\n|\r#';
	
	/**
	 * The value to replace the text found with the $COMPACT_REGEX 
	 *
	 * @var string
	 */
	protected static $COMPACT_REPLACE = ' ';

	/**
	 * Boolean flag noting whether to compress the processed output after parsing
	 *
	 * @var unknown_type
	 */
	protected static $COMPACT_RESULTS = false;
	
	/**
	 * Notes whether to check defined constants when trying to fill template hotspots
	 * true to check, false (default) to not check
	 * 
	 * Intialize as false for security. Enabling this function when you dont know what 
	 * constants are defined creates a potential security threat and should be avoided 
	 * if possible.  Nice feature if your the only one on the server though :)
	 *
	 * @var bool 
	 */
	protected static $CHECK_CONST = false;

	/**
	 * Class Constructor
	 * $tplPath - the path to the template file to use
	 * $valAry - an array of key=>value pairs representing the value to assign for each hotspot you want to fill in the template
	 *			 the format of the array is:
	 * 			 $valAry = array(
	 * 				'NAMEOFHOTSPOT' => <value>,
	 * 				'NAMEOFHOTSPOT2' => <value>
	 * 			 );
	 * @param string $tplpath
	 * @param array $vals
	 * @param boolean $proccess
	 * @return TPLManager
	 */
	public function __construct($tplPath, $valAry = false, $proccess = true) {
		
		/* Ensure that it is a good template file path */
		if(!$this->isValidTPLFile($tplPath))
			trigger_error('TPLManager:: invalid template path', E_USER_ERROR);
		
		/* ok, we got a good path, save it. */	
		else $this->file_path = $tplPath;		

		/* load the values array if passed */
		if($valAry !== false) 
			$this->loadValArray($valAry);

		/* Process the template if requested */
		if($proccess === true) 
			if(!$this->parse()) 
				trigger_error('TPLManager:: failed to process template',E_USER_ERROR);
	}
	
	/**
	 * Enables constant checking during template parsing
	 *
	 */
	public static function enableConstChecking(){
		self::$CHECK_CONST = true;
	}
	
	/**
	 * Prevents constant checking during template parsing
	 *
	 */
	public static function disableConstChecking(){
		self::$CHECK_CONST = false;
	}
	
	/**
	 * Enables compacting of the processed text after hotspot processing
	 *
	 */
	public static function enableCompacting(){
		self::$COMPACT_RESULTS = true;
	}
	
	/**
	 * Disables compacting of the processed text after hotspot processing
	 *
	 */
	public static function disableCompacting(){
		self::$COMPACT_RESULTS = false;
	}	
	
	/**
	 * Checks to see if a given file path leads to a valid file that we can use
	 *
	 * @param string $path The path to the template file
	 * @return bool whether it is a valid useable template file
	 */
	public function isValidTPLFile($path = false){
		$f = ($path !== false) ? $path : $this->file_path;
		return file_exists($f) && is_readable($f);
	}
	
	/**
	 * Checks to see whether a given value is a known hotspot for the current template
	 * NOTE : Hotspot values are checked in as case sensitive 
	 * 
	 * @param string $key
	 * @return bool 
	 */
	public function isHotspot($key){
		if(empty($this->hotspots)) $this->findHotspots();			
		return array_key_exists($key, $this->hotspots);
	}
	
	/**
	 * Sets a single replacement value for a hotspot in the current template
	 *
	 * @param string $key The name of the hotspot you want to replace
	 * @param string $val The value you want to replace the hotspot with
	 * @param bool $process Flag to trigger template processing after the replacements are updated
	 * @return bool Whether or not it was successful
	 */
	public function setVal($key, $val, $process = true){
		if(!$this->isHotspot($key))return false;
		else $this->replacements[$key] = strval($val);		
		return ($process === true) ? $this->parse() : true;
	}
	
	/**
	 * Processes an associative array of hotspot=>replacement pairs
	 *
	 * @param array $valAry the array of hotspot=>replacement pairs to process
	 * @param bool $process Flag to trigger template processing after the replacements are updated
	 * @return bool Whether or not it was successful
	 */
	public function loadValArray($valAry, $process = true){
		if(!is_array($valAry)){
			trigger_error('TPLManager::loadValArray - invalid array passed as argument', E_USER_ERROR);
			return false;	
		}			
		foreach($valAry as $k=>$v) $this->setVal($k,$v,false);				
		return ($process === true) ? $this->parse() : true;
	}
	
	/**
	 * Returns a string to replace a template hotspot with.
	 * Function first looks in the $replacements array
	 * then it checks to see if there is a defined constant to use (if enabled)
	 * otherwise it will return an empty string
	 *
	 * @param string $key The hotspot to find a replacement for
	 * @return string empty string if no replacement was found
	 */
	public function getCurrVal($key){
		if($v = $this->getLocalReplacement($key)) 
			return $v;
		
		return  (self::$CHECK_CONST === true && defined($key)) 
				? constant($key) 
				: '';
	}
	
	/**
	 * If the template file has been processed,
	 * it returns the processed hypertext output
	 * otherwise it returns false
	 *
	 * @return string
	 */
	public function getParsed(){
		if(empty($this->procd_text)) 
			if(!$this->parse())
				trigger_error('TPLManager::getParsed - failed to parse template',E_USER_ERROR);
		return self::$COMPACT_RESULTS ? $this->compact($this->procd_text) :  $this->procd_text ;
	}
	
	/**
	 * Returns an array of all the hotspot names in the template
	 *
	 * @return array|bool array of hotspot names or false if none are found
	 */
	public function getHotspotList(){		
		return (!empty($this->hotspots)) 
				? array_keys($this->hotspots)
				: ($this->findHotspots())
					? array_keys($this->hotspots)
					: false;
	}
	
	/**
	 * Returns the raw unprocessed text of the template file
	 *
	 * @return string the contents of the template file
	 */
	public function getRawTemplate(){
		if(empty($this->raw_text)){
			if(!$t = file_get_contents($this->file_path))
				throw new Exception('TPLManager::getRawTemplate - failed to retrieve the template contents');			
			$this->raw_text = $t;
		}		
		return $this->raw_text;
	}
	
	
	/**
	 * ******************************************************
	 * ******************************************************
	 * END PUBLIC INTERFACE  ********************************
	 * PROTECTED INTERFACE BELOW ****************************
	 * ******************************************************
	 * ******************************************************
	 */
	 
	
	/**
	 * removes extra spaces and returns out of the text
	 *
	 * @param string $pTxt
	 * @return string
	 */
	protected function compact($pTxt = false){
		if($pTxt === false)
			if(empty($this->procd_text))
				if(!$this->parse())	
					return false;
				else $pTxt = $this->procd_text;	
		return preg_replace(self::$COMPACT_REGEX,self::$COMPACT_REPLACE,$pTxt);
	}
	
	/**
	 * Returns the value in the $replacements array matching the given key
	 *
	 * @param string $key
	 * @return string|bool the current replacement value, or false if not found
	 */
	protected function getLocalReplacement($key){
		return array_key_exists($key, $this->replacements) 
			 ? $this->replacements[$key] 
			 : false;
	}		
	
	/**
	 * Finds all the hotspots in the current template and loads them into the $hotspots array
	 * 
	 * @return boolean Whether or not the operation succeeded
	 */
	protected function findHotspots(){
		if(preg_match_all(self::$HOTSPOT_REGEX, $this->getRawTemplate(), $out)){
			foreach($out[1] as $k=>$v) 
				if(!array_key_exists($v,$this->hotspots))
					$this->hotspots[$v] = $out[0][$k];
			return true;
		}else return false;
	}
	
	/**
	 * Processes the template file text by replacing the
	 * template variables with the replacement values
	 *
	 * @return bool true if the template processed without incident
	 */
	protected function parse(){
		
		/* locate the hotspots if we havent already */
		if(empty($this->hotspots)) 
			$this->findHotspots();
		
		$fRepl = array();		
		foreach($this->hotspots as $h=>$spot)
			$fRepl[$spot] = $this->getCurrVal($h);
			
		$this->procd_text = 
			str_replace(
				array_keys($fRepl),
				array_values($fRepl),
				$this->getRawTemplate()
			);
			
		return (!empty($this->procd_text))? true : false;
	}
}
?>
Return current item: TPLManager