<?php
/***
*
*@package binzcms
*@version $id:TplClass.php, v 1.0
*@author 斌子
*@Thu Jan 01 22:30:21 CST 2009
*@copyright (c) 2009-2010 binzcms
*
*/
if(!defined("BINZCMS")) {
	die("hacking");
}
/**
 *
 * TplClass
 * 用于解析binzcms的模板类
 * 
 */
class TplClass {

	public $temp_dir	= '';			//模板文件目录
	public $temp_cache	= '';			//缓存文件生成目录
	public $temp_ex		= '.html';		//模板文件后缀
	public $cache_state	= true;			//是否开启缓存
	public $cache_time	= 3600;			//缓存更新时间
	public $left_tag	= '<tpl>';		//模板标记开始
	public $right_tag	= '</tpl>';		//模板标价结束

	public $var_all	= array();			//变量
	/**
	 * __construct()
	 *
	 * 构造函数
	 * @access  public（权限）
	 */
	public function __construct() {

	}
	/**
	 * set_content
	 *
	 * 解析模板标签
	 * @access  private（权限）
	 * @param   string 	$content	模板内容
	 * @return  string	$html		解析后的模板
	 */
	private function set_content($content) {

		/*去掉php标记，模板内不能包含有php原始标记*/
		$content = preg_replace("/<\?.*\?>/sU","",$content);
		$content = preg_replace("/<%.*%>/sU","",$content);
		$content = preg_replace("/<\s*script[^>]+php.*>.*<\/\s*script\s*>/sU","",$content);
		preg_match_all("/".$this->left_tag."(.*)".$this->right_tag."/Us",$content,$var_content,PREG_PATTERN_ORDER);

		/*将非模板标记的html划分为数组，用模板标记分开*/
		$split_html	= preg_split("/".$this->left_tag.".*".$this->right_tag."/Us",$content);

		/*对模板内容和标签进行处理*/
		$html		= '';
		for ($i=0;$i<count($split_html);$i++) {
			$html	.= $split_html[$i];
			if(!empty($var_content[1][$i])) {
				if (strstr($var_content[1][$i],'include')) {
					$html	.= $this->include_tpl(substr(trim($var_content[1][$i]),8));
					continue;
				}
				$html	.= '<?php ';
				if($var_content[1][$i] == '/foreach' or $var_content[1][$i] == '/if') {
					$html	.= '}';
				} elseif(strstr($var_content[1][$i],'elseif')) {
					$html	.= ' } elseif ('.substr($var_content[1][$i],6).') {';
				} elseif($var_content[1][$i] == 'else') {
					$html	.= ' } else {';
				}elseif(strstr($var_content[1][$i],'foreach')) {
					$html	.= ' foreach ('.substr($var_content[1][$i],7).') {';
				} elseif(strstr($var_content[1][$i],'if')) {
					$html	.= ' if ('.substr($var_content[1][$i],2).') {';
				}else {
					$html	.= ' echo '.$var_content[1][$i].';';
				}
				$html	.= ' ?>';
			}
		}
		return $html;
	}
	/**
	 * set_var
	 *
	 * 解析变量
	 * @access  private（权限）
	 * @param   string/array	标签名称
	 * @param   string/array 	传入变量
	 * @return  void	返回类型
	 */
	public function set_var($name,$value='') {
		if (is_array($name)){
			foreach ($name as $key => $val) {
				if ($key != '') $this->var_all[$key] = $val;
			}
		} else if ($name != '') $this->var_all[$name] = $value;
	}
	/**
	 * set_tag
	 *
	 * 载入模板文件，载入输出变量
	 * @access  public（权限）
	 * @param   string	$temp_file		模板文件
	 * @return  null
	 */
	public function set_tag($temp_file) {

		$this->left_tag		= str_replace('/','\/',$this->left_tag);
		$this->right_tag	= str_replace('/','\/',$this->right_tag);

		if(file_exists($this->temp_dir."/".$temp_file.$this->temp_ex)) {
			$content = @file_get_contents($this->temp_dir."/".$temp_file.$this->temp_ex);
		}

		/*解析标签*/
		$content		= $this->set_content($content);

		/*生成缓存文件*/
		$inclue_file	= $this->make_cache($temp_file,$content);

		extract($this->var_all);
		/*载入缓存文件*/
		include_once($inclue_file);
		
		if(WEB_GZIP == '1' and function_exists('ob_gzhandler')) {
			ob_end_flush();
		}
	}
	/**
	 * make_cache
	 *
	 * 生成缓存文件
	 * @access  private（权限）
	 * @param   string	$html_file		文件名称，生成后的名称是经过处理的
	 * @param 	string	$content		解析后的模板内容
	 * @return  string	$cache_file		缓存文件地址
	 */
	private function make_cache($html_file,$content) {
		$cache_file	= $this->temp_cache."/".$html_file."_".md5($html_file).".php";
		if($this->cache_state == false or ($this->cache_state == true and time()-(file_exists($cache_file) ? filemtime($cache_file) : 0 ) >= $this->cache_time)) {
			if(is_dir($this->temp_cache) and ($fp = @fopen($cache_file,'wb'))) {
				@flock($fp,LOCK_EX);
				@fwrite($fp,$content);
				@flock($fp,LOCK_UN);
				@fclose($fp);
			}
		}
		return $cache_file;
	}
	/**
	 * include_tpl
	 *
	 * include模板
	 * @access  private
	 * @param   string	$file		模板文件
	 * @return	string				内容
	 */
	private function include_tpl($file) {
		$file_content = @file_get_contents($this->temp_dir.'/'.$file);
		return $this->set_content($file_content);
	}

	public function clear_var() {
		unset($this->var_all);
	}
}
?>