array(), 'replace' => array());
public $language = array();//语言列表
public $file = '';
public $default_language = '';//默认语言设置
public $templateNotMust = false;//模板是否必须,如果为true,则模板不存在返回空字符串,不出现错误提示
private $includeTemplate = array();//记录模版更新时间和路径
private $tplkey = '';
private $tplname = '';//模板名称
//获取模板语言
public function check_language(){
$this->default_language = getglobal('language');
}
public function fetch_template($tplfile, $tpldir,$templateNotMust){
$this->tplname = $tplfile;
$this->templateNotMust = $templateNotMust;
$tplfile = $this->parse_tplfile($tplfile,$tpldir,true);
$this->check_language();
$cachefile = './data/template/'.$this->tplkey. '_'.str_replace('/', '_', $this->tplname).'_'.$this->default_language.'.tpl.php';
$this->includeTemplate[$tplfile] = filemtime($tplfile);
if(!$this->chakcacahefile($cachefile)){
$content = file_get_contents($tplfile);
$parsefile = $this->compiler($content,$cachefile);
}else{
$parsefile =DZZ_ROOT.'/'.$cachefile;
}
return $parsefile;
}
private function compiler($content,$cachefile){
$this->parse_include($content);//解析include
$this->parse_template($content);//解析模板
//加入安全代码和模版记录
$content = "includeTemplate)."*/?>\n".$content;
$this->includeTemplate = array();
if (!@$fp = fopen(DZZ_ROOT . $cachefile, 'w')) {
$this -> error('directory_notfound', dirname(DZZ_ROOT . $cachefile));
}
flock($fp, 2);
fwrite($fp, $content);
fclose($fp);
return DZZ_ROOT.'/' . $cachefile;
}
private function chakcacahefile($cachefile){
//判断是否存在编译文件
if(!is_file($cachefile)){
return false;
}
//读取编译文件失败
if(!$handle = @fopen($cachefile,"r")){
return false;
}
//读取编译文件第一行
preg_match('/\/\*(.+?)\*\//', fgets($handle), $matches);
if (!isset($matches[1])) {
return false;
}
$includeFile = unserialize($matches[1]);
if (!is_array($includeFile)) {
return false;
}
// 检查模板文件是否有更新
foreach ($includeFile as $path => $time) {
if (is_file($path) && filemtime($path) > $time) {
// 模板文件如果有更新则缓存需要更新
return false;
}
}
return true;
}
//解析template包含的模板
/*private function parse_include(&$content){
// 替换模板中的include标签
$this->parse_include_sub($content);
return;
}*/
private function parse_include(&$content){
$tplreg = "/[\n\r\t]*(\<\!\-\-)?\{template\s+(.+?)\}(\-\-\>)?[\n\r\t]*/is";
if (preg_match_all($tplreg, $content, $matches)) {
foreach($matches[2] as $k=>$match) {
// 分析模板文件名并读取内容
$parestr = $this->parse_template_include($match);
$content = str_replace($matches[0][$k], $parestr, $content);
// 再次对包含文件进行模板分析
$this->parse_include($content);
}
unset($matches);
}
}
//解析模板路径
private function parse_tplfile($tplfile, $tpldir = '',$master_template = false,$nomasttplfile = false){
if(!$tpldir){
if( defined('CURSCRIPT') && defined('CURMODULE') && file_exists (DZZ_ROOT.'./'.CURSCRIPT.'/'.CURMODULE.'/template/'.$tplfile.'.htm')){
$tpldir= './'.CURSCRIPT.'/'.CURMODULE.'/template/';
if($master_template)$this->tplkey=CURSCRIPT.'_'.str_replace('/','_',CURMODULE);
}elseif(defined('CURSCRIPT') && file_exists (DZZ_ROOT.'./'.CURSCRIPT.'/template/'.$tplfile.'.htm')){
$tpldir= './'.CURSCRIPT.'/template/';
if($master_template)$this->tplkey=CURSCRIPT;
}elseif(file_exists (DZZ_ROOT.'./core/template/default/'.$tplfile.'.htm')){
$tpldir= './core/template/default/';
if($master_template)$this->tplkey='core';
}elseif(file_exists (DZZ_ROOT.'./core/template/default/common/'.$tplfile.'.htm')){
$tpldir= './core/template/default/common/';
if($master_template)$this->tplkey='corecommon';
}
}
$file = $tplfile;
$tplfile = $tpldir.$tplfile.'.htm';
$basefile = basename(DZZ_ROOT . $tplfile, '.htm');
$tplfile == 'common/header' && defined('CURMODULE') && CURMODULE && $file = 'common/header_' . CURMODULE;
if (is_file(DZZ_ROOT.$tplfile)) {
$tplfile =DZZ_ROOT.'/'.$tplfile;
} elseif (is_file(substr(DZZ_ROOT . $tplfile, 0, -4).'.php')) {
$tplfile = substr(DZZ_ROOT . $tplfile, 0, -4).'.php';
} else {
$tpl = $tpldir . '/' . $file . '.htm';
$tplfile = $tplfile != $tpl ? $tpl.', '. $tplfile : $tplfile;
if($this->templateNotMust || $nomasttplfile){
return '';
}else{
$this -> error('template_notfound', $tplfile);
}
}
return $tplfile;
}
//读取模板内容
private function parse_template_include($tpl){
$template = $this->parse_tplfile($tpl,'',false,true);
$this->includeTemplate[$template] = filemtime($template);
if(!is_file($template) || !$fp = fopen($template, 'r')){
return;
}
$content = fread($fp, filesize($template));
return $content;
}
function parse_template(&$template) {
$var_regexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\-\>)?[a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)";
$const_regexp = "([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)";
$template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template);
$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
// js的lang替换
$template = preg_replace_callback("/';
$return .= preg_replace_callback("/";
},$matches[0]);
unset($_G['template_extra-replace_val']);
unset($_G['template_src_replace_val']);
return $return;
}
function stripblock($var, $s) {
$s = str_replace('\\"', '"', $s);
$s = preg_replace("/<\?=\\\$(.+?)\?>/", "{\$\\1}", $s);
preg_match_all("/<\?=(.+?)\?>/", $s, $constary);
$constadd = '';
$constary[1] = array_unique($constary[1]);
foreach ($constary[1] as $const) {
$constadd .= '$__' . $const . ' = ' . $const . ';';
}
$s = preg_replace("/<\?=(.+?)\?>/", "{\$__\\1}", $s);
$s = str_replace('?>', "\n\$$var .= <<";
}
function error($message, $tplname) {
dzz_error::template_error($message, $tplname);
}
}
?>