// +---------------------------------------------------------------------- /** * ThinkPHP标签库TagLib解析基类 * @category Think * @package Think * @subpackage Template * @author liu21st */ class TagLib { /** * 标签库定义XML文件 * @var string * @access protected */ protected $xml = ''; protected $tags = array();// 标签定义 /** * 标签库名称 * @var string * @access protected */ protected $tagLib =''; /** * 标签库标签列表 * @var string * @access protected */ protected $tagList = array(); /** * 标签库分析数组 * @var string * @access protected */ protected $parse = array(); /** * 标签库是否有效 * @var string * @access protected */ protected $valid = false; /** * 当前模板对象 * @var object * @access protected */ protected $tpl; protected $comparison = array(' nheq '=>' !== ',' heq '=>' === ',' neq '=>' != ',' eq '=>' == ',' egt '=>' >= ',' gt '=>' > ',' elt '=>' <= ',' lt '=>' < '); /** * 架构函数 * @access public */ public function __construct() { $this->tagLib = strtolower(substr(get_class($this),6)); $this->tpl = Think::instance('ThinkTemplate'); } /** * TagLib标签属性分析 返回标签属性数组 * @access public * @param string $tagStr 标签内容 * @return array */ public function parseXmlAttr($attr,$tag) { //XML解析安全过滤 $attr = str_replace('&','___', $attr); $xml = ''; $xml = simplexml_load_string($xml); if(!$xml) { throw_exception(L('_XML_TAG_ERROR_').' : '.$attr); } $xml = (array)($xml->tag->attributes()); $array = array_change_key_case($xml['@attributes']); if($array) { $attrs = explode(',',$this->tags[strtolower($tag)]['attr']); if(isset($this->tags[strtolower($tag)]['must'])){ $must = explode(',',$this->tags[strtolower($tag)]['must']); }else{ $must = array(); } foreach($attrs as $name) { if( isset($array[$name])) { $array[$name] = str_replace('___','&',$array[$name]); }elseif(false !== array_search($name,$must)){ throw_exception(L('_PARAM_ERROR_').':'.$name); } } return $array; } } /** * 解析条件表达式 * @access public * @param string $condition 表达式标签内容 * @return array */ public function parseCondition($condition) { $condition = str_ireplace(array_keys($this->comparison),array_values($this->comparison),$condition); $condition = preg_replace('/\$(\w+):(\w+)\s/is','$\\1->\\2 ',$condition); switch(strtolower(C('TMPL_VAR_IDENTIFY'))) { case 'array': // 识别为数组 $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','$\\1["\\2"] ',$condition); break; case 'obj': // 识别为对象 $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','$\\1->\\2 ',$condition); break; default: // 自动判断数组或对象 只支持二维 $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','(is_array($\\1)?$\\1["\\2"]:$\\1->\\2) ',$condition); } if(false !== strpos($condition, '$Think')) $condition = preg_replace('/(\$Think.*?)\s/ies',"\$this->parseThinkVar('\\1');" , $condition); return $condition; } /** * 自动识别构建变量 * @access public * @param string $name 变量描述 * @return string */ public function autoBuildVar($name) { if('Think.' == substr($name,0,6)){ // 特殊变量 return $this->parseThinkVar($name); }elseif(strpos($name,'.')) { $vars = explode('.',$name); $var = array_shift($vars); switch(strtolower(C('TMPL_VAR_IDENTIFY'))) { case 'array': // 识别为数组 $name = '$'.$var; foreach ($vars as $key=>$val){ if(0===strpos($val,'$')) { $name .= '["{'.$val.'}"]'; }else{ $name .= '["'.$val.'"]'; } } break; case 'obj': // 识别为对象 $name = '$'.$var; foreach ($vars as $key=>$val) $name .= '->'.$val; break; default: // 自动判断数组或对象 只支持二维 $name = 'is_array($'.$var.')?$'.$var.'["'.$vars[0].'"]:$'.$var.'->'.$vars[0]; } }elseif(strpos($name,':')){ // 额外的对象方式支持 $name = '$'.str_replace(':','->',$name); }elseif(!defined($name)) { $name = '$'.$name; } return $name; } /** * 用于标签属性里面的特殊模板变量解析 * 格式 以 Think. 打头的变量属于特殊模板变量 * @access public * @param string $varStr 变量字符串 * @return string */ public function parseThinkVar($varStr){ $vars = explode('.',$varStr); $vars[1] = strtoupper(trim($vars[1])); $parseStr = ''; if(count($vars)>=3){ $vars[2] = trim($vars[2]); switch($vars[1]){ case 'SERVER': $parseStr = '$_SERVER[\''.$vars[2].'\']';break; case 'GET': $parseStr = '$_GET[\''.$vars[2].'\']';break; case 'POST': $parseStr = '$_POST[\''.$vars[2].'\']';break; case 'COOKIE': if(isset($vars[3])) { $parseStr = '$_COOKIE[\''.$vars[2].'\'][\''.$vars[3].'\']'; }elseif(C('COOKIE_PREFIX')){ $parseStr = '$_COOKIE[\''.C('COOKIE_PREFIX').$vars[2].'\']'; }else{ $parseStr = '$_COOKIE[\''.$vars[2].'\']'; } break; case 'SESSION': if(isset($vars[3])) { $parseStr = '$_SESSION[\''.$vars[2].'\'][\''.$vars[3].'\']'; }elseif(C('SESSION_PREFIX')){ $parseStr = '$_SESSION[\''.C('SESSION_PREFIX').'\'][\''.$vars[2].'\']'; }else{ $parseStr = '$_SESSION[\''.$vars[2].'\']'; } break; case 'ENV': $parseStr = '$_ENV[\''.$vars[2].'\']';break; case 'REQUEST': $parseStr = '$_REQUEST[\''.$vars[2].'\']';break; case 'CONST': $parseStr = strtoupper($vars[2]);break; case 'LANG': $parseStr = 'L("'.$vars[2].'")';break; case 'CONFIG': $parseStr = 'C("'.$vars[2].'")';break; } }else if(count($vars)==2){ switch($vars[1]){ case 'NOW': $parseStr = "date('Y-m-d g:i a',time())";break; case 'VERSION': $parseStr = 'THINK_VERSION';break; case 'TEMPLATE':$parseStr = 'C("TEMPLATE_NAME")';break; case 'LDELIM': $parseStr = 'C("TMPL_L_DELIM")';break; case 'RDELIM': $parseStr = 'C("TMPL_R_DELIM")';break; default: if(defined($vars[1])) $parseStr = $vars[1]; } } return $parseStr; } // 获取标签定义 public function getTags(){ return $this->tags; } }