📄 pub_dedetag.php
字号:
<?php
/*----------------------------------------------
Copyright 2004-2006 by DedeCms.com itprato
Dede Tag模板解析引挚 V4.1 版
最后修改日期:2006-7-4 PHP版本要求:大于或等于php 4.1
---------------------------------------------*/
/****************************************
class DedeTag 标记的数据结构描述
function c____DedeTag();
**************************************/
class DedeTag
{
var $IsReplace=FALSE; //标记是否已被替代,供解析器使用
var $TagName=""; //标记名称
var $InnerText=""; //标记之间的文本
var $StartPos=0; //标记起始位置
var $EndPos=0; //标记结束位置
var $CAttribute=""; //标记属性描述,即是class DedeAttribute
var $TagValue=""; //标记的值
var $TagID=0;
//获取标记的名称和值
function GetName(){
return strtolower($this->TagName);
}
function GetValue(){
return $this->TagValue;
}
//下面两个成员函数仅是为了兼容旧版
function GetTagName(){
return strtolower($this->TagName);
}
function GetTagValue(){
return $this->TagValue;
}
//获取标记的指定属性
function IsAttribute($str){
return $this->CAttribute->IsAttribute($str);
}
function GetAttribute($str){
return $this->CAttribute->GetAtt($str);
}
function GetAtt($str){
return $this->CAttribute->GetAtt($str);
}
function GetInnerText(){
return $this->InnerText;
}
}
/**********************************************
//DedeTagParse Dede织梦模板类
function c____DedeTagParse();
***********************************************/
class DedeTagParse
{
var $NameSpace = 'dede'; //标记的名字空间
var $TagStartWord = '{'; //标记起始
var $TagEndWord = '}'; //标记结束
var $TagMaxLen = 64; //标记名称的最大值
var $CharToLow = true; // true表示对属性和标记名称不区分大小写
//////////////////////////////////////////////////////
var $IsCache = FALSE; //是否使用缓冲
var $TempMkTime = 0;
var $CacheFile = '';
/////////////////////////////
var $SourceString = '';//模板字符串
var $CTags = ''; //标记集合
var $Count = -1; //$Tags标记个数
function __construct()
{
if(!isset($GLOBALS['cfg_dede_cache'])) $GLOBALS['cfg_dede_cache'] = 'N';
if($GLOBALS['cfg_dede_cache']=='Y') $this->IsCache = true;
else $this->IsCache = FALSE;
$this->NameSpace = 'dede';
$this->TagStartWord = '{';
$this->TagEndWord = '}';
$this->TagMaxLen = 64;
$this->CharToLow = true;
$this->SourceString = '';
$this->CTags = Array();
$this->Count = -1;
$this->TempMkTime = 0;
$this->CacheFile = '';
}
function DedeTagParse(){
$this->__construct();
}
//设置标记的命名空间,默认为dede
function SetNameSpace($str,$s="{",$e="}"){
$this->NameSpace = strtolower($str);
$this->TagStartWord = $s;
$this->TagEndWord = $e;
}
//重置成员变量或Clear
function SetDefault(){
$this->SourceString = '';
$this->CTags = '';
$this->Count=-1;
}
function GetCount(){
return $this->Count+1;
}
function Clear(){
$this->SetDefault();
}
//检测模板缓冲
function LoadCache($filename)
{
if(!$this->IsCache) return false;
$cdir = dirname($filename);
$ckfile = str_replace($cdir,'',$filename).'.cache';
$ckfullfile = $cdir.''.$ckfile;
$ckfullfile_t = $cdir.''.$ckfile.'.t';
$this->CacheFile = $ckfullfile;
$this->TempMkTime = filemtime($filename);
if(!file_exists($ckfullfile)||!file_exists($ckfullfile_t)) return false;
//检测模板最后更新时间
$fp = fopen($ckfullfile_t,'r');
$time_info = trim(fgets($fp,64));
fclose($fp);
if($time_info != $this->TempMkTime){ return false; }
//引入缓冲数组
include($this->CacheFile);
//把缓冲数组内容读入类
if(isset($z) && is_array($z)){
foreach($z as $k=>$v){
$this->Count++;
$ctag = new DedeTAg();
$ctag->CAttribute = new DedeAttribute();
$ctag->IsReplace = FALSE;
$ctag->TagName = $v[0];
$ctag->InnerText = $v[1];
$ctag->StartPos = $v[2];
$ctag->EndPos = $v[3];
$ctag->TagValue = '';
$ctag->TagID = $k;
if(isset($v[4]) && is_array($v[4])){
$i = 0;
foreach($v[4] as $k=>$v){
$ctag->CAttribute->Count++;
$ctag->CAttribute->Items[$k]=$v;
}
}
$this->CTags[$this->Count] = $ctag;
}
}
else{//模板没有缓冲数组
$this->CTags = '';
$this->Count = -1;
}
return true;
}
//写入缓冲
function SaveCache()
{
$fp = fopen($this->CacheFile.'.t',"w");
fwrite($fp,$this->TempMkTime."\n");
fclose($fp);
$fp = fopen($this->CacheFile,"w");
flock($fp,3);
fwrite($fp,'<'.'?php'."\r\n");
if(is_array($this->CTags)){
foreach($this->CTags as $tid=>$ctag){
$arrayValue = 'Array("'.$ctag->TagName.'",';
$arrayValue .= '"'.str_replace('$','\$',str_replace("\r","\\r",str_replace("\n","\\n",str_replace('"','\"',$ctag->InnerText)))).'"';
$arrayValue .= ",{$ctag->StartPos},{$ctag->EndPos});";
fwrite($fp,"\$z[$tid]={$arrayValue}\n");
if(is_array($ctag->CAttribute->Items)){
foreach($ctag->CAttribute->Items as $k=>$v){
$k = trim(str_replace("'","",$k));
if($k=="") continue;
if($k!='tagname') fwrite($fp,"\$z[$tid][4]['$k']=\"".str_replace('$','\$',str_replace("\"","\\\"",$v))."\";\n");
}
}
}
}
fwrite($fp,"\n".'?'.'>');
fclose($fp);
}
//载入模板文件
function LoadTemplate($filename){
$this->SetDefault();
$fp = @fopen($filename,"r") or die("DedeTag Engine Load Template \"$filename\" False!");
while($line = fgets($fp,1024))
$this->SourceString .= $line;
fclose($fp);
if($this->LoadCache($filename)) return;
else $this->ParseTemplet();
}
function LoadTemplet($filename){
$this->LoadTemplate($filename);
}
function LoadFile($filename){
$this->LoadTemplate($filename);
}
//载入模板字符串
function LoadSource($str){
$this->SetDefault();
$this->SourceString = $str;
$this->IsCache = FALSE;
$this->ParseTemplet();
}
function LoadString($str){
$this->LoadSource($str);
}
//获得指定名称的Tag的ID(如果有多个同名的Tag,则取没有被取代为内容的第一个Tag)
function GetTagID($str){
if($this->Count==-1) return -1;
if($this->CharToLow) $str=strtolower($str);
foreach($this->CTags as $ID=>$CTag){
if($CTag->TagName==$str && !$CTag->IsReplace){
return $ID;
break;
}
}
return -1;
}
//获得指定名称的CTag数据类(如果有多个同名的Tag,则取没有被分配内容的第一个Tag)
function GetTag($str){
if($this->Count==-1) return "";
if($this->CharToLow) $str=strtolower($str);
foreach($this->CTags as $ID=>$CTag){
if($CTag->TagName==$str && !$CTag->IsReplace){
return $CTag;
break;
}
}
return "";
}
function GetTagByName($str)
{ return $this->GetTag($str); }
//获得指定ID的CTag数据类
function GetTagByID($ID){
if(isset($this->CTags[$ID])) return $this->CTags[$ID];
else return "";
}
//
//分配指定ID的标记的值
//
function Assign($tagid,$str,$runfunc = true)
{
if(isset($this->CTags[$tagid]))
{
$this->CTags[$tagid]->IsReplace = true;
if( $this->CTags[$tagid]->GetAtt("function")!="" && $runfunc ){
$this->CTags[$tagid]->TagValue = $this->EvalFunc(
$str,
$this->CTags[$tagid]->GetAtt("function")
);
}
else
{ $this->CTags[$tagid]->TagValue = $str; }
}
}
//分配指定名称的标记的值,如果标记包含属性,请不要用此函数
function AssignName($tagname,$str)
{
foreach($this->CTags as $ID=>$CTag){
if($CTag->TagName==$tagname) $this->Assign($ID,$str);
}
}
//处理特殊标记
function AssignSysTag()
{
for($i=0;$i<=$this->Count;$i++)
{
$CTag = $this->CTags[$i];
//获取一个外部变量
if( $CTag->TagName == "global" ){
$this->CTags[$i]->IsReplace = true;
$this->CTags[$i]->TagValue = $this->GetGlobals($CTag->GetAtt("name"));
if( $this->CTags[$i]->GetAtt("function")!="" ){
$this->CTags[$i]->TagValue = $this->EvalFunc(
$this->CTags[$i]->TagValue,$this->CTags[$i]->GetAtt("function")
);
}
}
//引入静态文件
else if( $CTag->TagName == "include" ){
$this->CTags[$i]->IsReplace = true;
$this->CTags[$i]->TagValue = $this->IncludeFile($CTag->GetAtt("file"),$CTag->GetAtt("ismake"));
}
//循环一个普通数组
else if( $CTag->TagName == "foreach" )
{
$rstr = "";
$arr = $this->CTags[$i]->GetAtt("array");
if(isset($GLOBALS[$arr]))
{
foreach($GLOBALS[$arr] as $k=>$v){
$istr = "";
$istr .= preg_replace("/\[field:key([\r\n\t\f ]+)\/\]/is",$k,$this->CTags[$i]->InnerText);
$rstr .= preg_replace("/\[field:value([\r\n\t\f ]+)\/\]/is",$v,$istr);
}
}
$this->CTags[$i]->IsReplace = true;
$this->CTags[$i]->TagValue = $rstr;
}
//运行PHP接口
if( $CTag->GetAtt("runphp") == "yes" )
{
$DedeMeValue = "";
if($CTag->GetAtt("source")=='value')
{ $runphp = $this->CTags[$i]->TagValue; }
else{
$DedeMeValue = $this->CTags[$i]->TagValue;
$runphp = $CTag->GetInnerText();
}
$runphp = eregi_replace("'@me'|\"@me\"|@me",'$DedeMeValue',$runphp);
eval($runphp.";");
$this->CTags[$i]->IsReplace = true;
$this->CTags[$i]->TagValue = $DedeMeValue;
}
}
}
//把分析模板输出到一个字符串中
//不替换没被处理的值
function GetResultNP()
{
$ResultString = "";
if($this->Count==-1){
return $this->SourceString;
}
$this->AssignSysTag();
$nextTagEnd = 0;
$strok = "";
for($i=0;$i<=$this->Count;$i++){
if($this->CTags[$i]->GetValue()!=""){
if($this->CTags[$i]->GetValue()=='#@Delete@#') $this->CTags[$i]->TagValue = "";
$ResultString .= substr($this->SourceString,$nextTagEnd,$this->CTags[$i]->StartPos-$nextTagEnd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -