<?php
class
template {
private
$vars
=
array
();
private
$conf
= '';
private
$tpl_name
= 'index';
private
$tpl_suffix
= '.html';
private
$tpl_compile_suffix
= '.tpl.php';
private
$template_tag_left
= '<{';
private
$template_tag_right
= '}>';
private
$template_c
= '';
private
$template_path
= '';
private
$template_name
= '';
private
$tag_foreach
=
array
('from', 'item', 'key');
private
$tag_include
=
array
('file');
public
function
__construct(
$conf
) {
$this
->conf = &
$conf
;
$this
->template_c =
$this
->conf['template_config']['template_c'];
$this
->_tpl_suffix =
$this
->tpl_suffix();
}
private
function
str_replace
(
$search
,
$replace
,
$content
) {
if
(
empty
(
$search
) ||
empty
(
$replace
) ||
empty
(
$content
))
return
false;
return
str_replace
(
$search
,
$replace
,
$content
);
}
private
function
preg_match_all(
$pattern
,
$content
) {
if
(
empty
(
$pattern
) ||
empty
(
$content
)) core::show_error('查找模板标签失败!');
preg_match_all(
"/"
.
$this
->template_tag_left.
$pattern
.
$this
->template_tag_right.
"/is"
,
$content
,
$match
);
return
$match
;
}
public
function
tpl_suffix() {
$tpl_suffix
=
empty
(
$this
->conf['template_config']['template_suffix']) ?
$this
->tpl_suffix :
$this
->conf['template_config']['template_suffix'] ;
return
$tpl_suffix
;
}
public
function
assign(
$key
,
$value
) {
$this
->vars[
$key
] =
$value
;
}
public
function
display(
$filename
= '',
$view_path
= '') {
$tpl_path_arr
=
$this
->get_tpl(
$filename
,
$view_path
);
if
(!
$tpl_path_arr
) core::show_error(
$filename
.
$this
->_tpl_suffix.'模板不存在');
$this
->view_path_param =
$view_path
;
$this
->compile();
}
private
function
compile() {
$filepath
=
$this
->template_path.
$this
->template_name;
$compile_dirpath
=
$this
->check_temp_compile();
$vars_template_c_name
=
str_replace
(
$this
->_tpl_suffix, '',
$this
->template_name);
$include_file
=
$this
->template_replace(
$this
->read_file(
$filepath
),
$compile_dirpath
,
$vars_template_c_name
);
if
(
$include_file
) {
$this
->read_config() &&
$config
=
$this
->read_config();
extract(
$this
->vars, EXTR_SKIP);
[url=home.php?mod=space&uid=48608]@
include
[/url]
$include_file
;
}
}
protected
function
read_config() {
if
(
file_exists
(SYSTEM_PATH.'conf/config.php')) {
@
include
SYSTEM_PATH.'conf/config.php';
return
$config
;
}
return
false;
}
private
function
template_replace(
$str
,
$compile_dirpath
,
$vars_template_c_name
) {
if
(
empty
(
$str
)) core::show_error('模板内容为空!');
$compile_path
=
$compile_dirpath
.
$vars_template_c_name
.
$this
->tpl_compile_suffix;
if
(
is_file
(
$compile_path
)) {
$tpl_filemtime
=
filemtime
(
$this
->template_path.
$this
->template_name);
$compile_filemtime
=
filemtime
(
$compile_path
);
if
(
$tpl_filemtime
>
$compile_filemtime
|| DEBUG) {
$ret_file
=
$this
->compile_file(
$vars_template_c_name
,
$str
,
$compile_dirpath
);
}
else
{
$ret_file
=
$compile_path
;
}
}
else
{
$ret_file
=
$this
->compile_file(
$vars_template_c_name
,
$str
,
$compile_dirpath
);
}
return
$ret_file
;
}
private
function
body_content(
$str
) {
$str
=
$this
->parse(
$str
);
$header_comment
=
"Create On##"
.time().
"|Compiled from##"
.
$this
->template_path.
$this
->template_name;
$content
=
"<? if(!defined('IS_HEARTPHP')) exit('Access Denied');/*{$header_comment}*/?>\r\n$str"
;
return
$content
;
}
private
function
parse(
$content
) {
$content
=
$this
->parse_foreach(
$content
);
$content
=
$this
->parse_include(
$content
);
$content
=
$this
->parse_if(
$content
);
$content
=
$this
->parse_elseif(
$content
);
$content
=
$this
->parse_comm(
$content
);
$content
=
$this
->parse_php(
$content
);
return
$content
;
}
private
function
parse_echo(
$content
) {
}
private
function
parse_php(
$content
){
if
(
empty
(
$content
))
return
false;
$content
= preg_replace(
"/"
.
$this
->template_tag_left.
"(.+?)"
.
$this
->template_tag_right.
"/is"
,
"<?php $1 ?>"
,
$content
);
return
$content
;
}
private
function
parse_if(
$content
) {
if
(
empty
(
$content
))
return
false;
$match
=
$this
->preg_match_all(
"if\s+(.*?)"
,
$content
);
if
(!isset(
$match
[1]) || !
is_array
(
$match
[1]))
return
$content
;
foreach
(
$match
[1]
as
$k
=>
$v
) {
$content
=
str_replace
(
$match
[0][
$k
],
"<?php if({$v}) { ?>"
,
$content
);
}
return
$content
;
}
private
function
parse_elseif(
$content
) {
if
(
empty
(
$content
))
return
false;
$match
=
$this
->preg_match_all(
"elseif\s+(.*?)"
,
$content
);
if
(!isset(
$match
[1]) || !
is_array
(
$match
[1]))
return
$content
;
foreach
(
$match
[1]
as
$k
=>
$v
) {
$content
=
str_replace
(
$match
[0][
$k
],
"<?php } elseif ({$v}) { ?>"
,
$content
);
}
return
$content
;
}
private
function
parse_include(
$content
) {
if
(
empty
(
$content
))
return
false;
$match
=
$this
->preg_match_all(
"include\s+(.*?)"
,
$content
);
if
(!isset(
$match
[1]) || !
is_array
(
$match
[1]))
return
$content
;
foreach
(
$match
[1]
as
$match_key
=>
$match_value
) {
$a
= preg_split(
"/\s+/is"
,
$match_value
);
$new_tag
=
array
();
foreach
(
$a
as
$t
) {
$b
=
explode
('=',
$t
);
if
(in_array(
$b
[0],
$this
->tag_include)) {
if
(!
empty
(
$b
[1])) {
$new_tag
[
$b
[0]] =
str_replace
(
"\""
,
""
,
$b
[1]);
}
else
{
core::show_error('模板路径不存在!');
}
}
}
extract(
$new_tag
);
foreach
(
$this
->conf['view_path']
as
$v
){
$conf_view_tpl
=
$v
.
$file
;
if
(
is_file
(
$conf_view_tpl
)) {
$c
=
$this
->read_file(
$conf_view_tpl
);
$inc_file
=
str_replace
(
$this
->_tpl_suffix, '',
basename
(
$file
));
$this
->view_path_param = dirname(
$file
).'/';
$compile_dirpath
=
$this
->check_temp_compile();
$include_file
=
$this
->template_replace(
$c
,
$compile_dirpath
,
$inc_file
);
break
;
}
else
{
core::show_error('模板文件不存在,请仔细检查 文件:'.
$conf_view_tpl
);
}
}
$content
=
str_replace
(
$match
[0][
$match_key
], '<?php
include
(
"'.$include_file.'"
)?>',
$content
);
}
return
$content
;
}
private
function
parse_foreach(
$content
) {
if
(
empty
(
$content
))
return
false;
$match
=
$this
->preg_match_all(
"foreach\s+(.*?)"
,
$content
);
if
(!isset(
$match
[1]) || !
is_array
(
$match
[1]))
return
$content
;
foreach
(
$match
[1]
as
$match_key
=>
$value
) {
$split
= preg_split(
"/\s+/is"
,
$value
);
$split
=
array_filter
(
$split
);
$new_tag
=
array
();
foreach
(
$split
as
$v
) {
$a
=
explode
(
"="
,
$v
);
if
(in_array(
$a
[0],
$this
->tag_foreach)) {
$new_tag
[
$a
[0]] =
$a
[1];
}
}
$key
= '';
extract(
$new_tag
);
$key
= (
$key
) ? '$'.
$key
.' =>' : '' ;
$s
= '<?php
foreach
('.
$from
.'
as
'.
$key
.' $'.
$item
.') { ?>';
$content
=
$this
->
str_replace
(
$match
[0][
$match_key
],
$s
,
$content
);
}
return
$content
;
}
private
function
parse_comm(
$content
) {
$search
=
array
(
"/"
.
$this
->template_tag_left.
"\/foreach"
.
$this
->template_tag_right.
"/is"
,
"/"
.
$this
->template_tag_left.
"\/if"
.
$this
->template_tag_right.
"/is"
,
"/"
.
$this
->template_tag_left.
"else"
.
$this
->template_tag_right.
"/is"
,
);
$replace
=
array
(
"<?php } ?>"
,
"<?php } ?>"
,
"<?php } else { ?>"
);
$content
= preg_replace(
$search
,
$replace
,
$content
);
return
$content
;
}
private
function
check_temp_compile() {
$tpl_path
= (
$this
->view_path_param) ?
$this
->view_path_param :
$this
->get_tpl_path() ;
$all_tpl_apth
=
$this
->template_c.
$tpl_path
;
if
(!
is_dir
(
$all_tpl_apth
)) {
$this
->create_dir(
$tpl_path
);
}
return
$all_tpl_apth
;
}
private
function
read_file(
$path
) {
if
((
$r
= @
fopen
(
$path
, 'r')) === false) {
core::show_error('模版文件没有读取或执行权限,请检查!');
}
$content
=
fread
(
$r
,
filesize
(
$path
));
fclose(
$r
);
return
$content
;
}
private
function
compile_file(
$filename
,
$content
,
$dir
) {
if
(
empty
(
$filename
)) core::show_error(
"{$filename} Creation failed"
);
$content
=
$this
->body_content(
$content
);
$f
=
$dir
.
$filename
.
$this
->tpl_compile_suffix;
if
((
$fp
= @
fopen
(
$f
, 'wb')) === false) {
core::show_error(
$f
.'<br/>编译文件失败,请检查文件权限.');
}
flock
(
$fp
, LOCK_EX + LOCK_NB);
fwrite(
$fp
,
$content
,
strlen
(
$content
));
flock
(
$fp
, LOCK_UN + LOCK_NB);
fclose(
$fp
);
return
$f
;
}
public
function
check_file_limits(
$path
,
$status
= 'rw') {
clearstatcache();
if
(!
is_writable
(
$path
) &&
$status
== 'w') {
core::show_error(
"{$path}<br/>没有写入权限,请检查."
);
}
elseif
(!
is_readable
(
$path
) &&
$status
== 'r') {
core::show_error(
"{$path}<br/>没有读取权限,请检查."
);
}
elseif
(
$status
== 'rw') {
if
(!
is_writable
(
$path
) || !
is_readable
(
$path
)) {
core::show_error(
"{$path}<br/>没有写入或读取权限,请检查"
);
}
}
}
private
function
get_tpl(
$filename
,
$view_path
) {
empty
(
$filename
) &&
$filename
=
$this
->tpl_name;
foreach
(
$this
->conf['view_path']
as
$path
) {
if
(
$view_path
) {
$tpl_path
=
$path
.
$view_path
;
$view_file_path
=
$tpl_path
.
$filename
.
$this
->_tpl_suffix;
}
else
{
$view_file_path
= (
$tpl_path
=
$this
->get_tpl_path(
$path
)) ?
$tpl_path
.
$filename
.
$this
->_tpl_suffix :
exit
(0);
}
if
(
is_file
(
$view_file_path
)) {
$this
->template_path =
$tpl_path
;
$this
->template_name =
$filename
.
$this
->_tpl_suffix;
return
true;
}
else
{
core::show_error(
$filename
.
$this
->_tpl_suffix.'模板不存在');
}
}
}
private
function
get_tpl_path(
$path
= '') {
core::get_directory_name() &&
$path_arr
[0] = core::get_directory_name();
core::get_controller_name() &&
$path_arr
[1] = core::get_controller_name();
(
is_array
(
$path_arr
)) ?
$newpath
= implode('/',
$path_arr
) : core::show_error('获取模板路径失败!') ;
return
$path
.
$newpath
.'/';
}
private
function
create_dir(
$path
,
$mode
= 0777){
if
(
is_dir
(
$path
))
return
false;
$dir_arr
=
explode
('/',
$path
);
$dir_arr
=
array_filter
(
$dir_arr
);
$allpath
= '';
$newdir
=
$this
->template_c;
foreach
(
$dir_arr
as
$dir
) {
$allpath
=
$newdir
.'/'.
$dir
;
if
(!
is_dir
(
$allpath
)) {
$newdir
=
$allpath
;
if
(!@
mkdir
(
$allpath
,
$mode
)) {
core::show_error(
$allpath
.'<br/>创建目录失败,请检查是否有可都写权限!');
}
chmod
(
$allpath
,
$mode
);
}
else
{
$newdir
=
$allpath
;
}
}
return
true;
}
public
function
__destruct(){
$this
->vars = null;
$this
->view_path_param = null;
}
}