TagLib.class.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. /**
  12. * ThinkPHP标签库TagLib解析基类
  13. * @category Think
  14. * @package Think
  15. * @subpackage Template
  16. * @author liu21st <liu21st@gmail.com>
  17. */
  18. class TagLib {
  19. /**
  20. * 标签库定义XML文件
  21. * @var string
  22. * @access protected
  23. */
  24. protected $xml = '';
  25. protected $tags = array();// 标签定义
  26. /**
  27. * 标签库名称
  28. * @var string
  29. * @access protected
  30. */
  31. protected $tagLib ='';
  32. /**
  33. * 标签库标签列表
  34. * @var string
  35. * @access protected
  36. */
  37. protected $tagList = array();
  38. /**
  39. * 标签库分析数组
  40. * @var string
  41. * @access protected
  42. */
  43. protected $parse = array();
  44. /**
  45. * 标签库是否有效
  46. * @var string
  47. * @access protected
  48. */
  49. protected $valid = false;
  50. /**
  51. * 当前模板对象
  52. * @var object
  53. * @access protected
  54. */
  55. protected $tpl;
  56. protected $comparison = array(' nheq '=>' !== ',' heq '=>' === ',' neq '=>' != ',' eq '=>' == ',' egt '=>' >= ',' gt '=>' > ',' elt '=>' <= ',' lt '=>' < ');
  57. /**
  58. * 架构函数
  59. * @access public
  60. */
  61. public function __construct() {
  62. $this->tagLib = strtolower(substr(get_class($this),6));
  63. $this->tpl = Think::instance('ThinkTemplate');
  64. }
  65. /**
  66. * TagLib标签属性分析 返回标签属性数组
  67. * @access public
  68. * @param string $tagStr 标签内容
  69. * @return array
  70. */
  71. public function parseXmlAttr($attr,$tag) {
  72. //XML解析安全过滤
  73. $attr = str_replace('&','___', $attr);
  74. $xml = '<tpl><tag '.$attr.' /></tpl>';
  75. $xml = simplexml_load_string($xml);
  76. if(!$xml) {
  77. throw_exception(L('_XML_TAG_ERROR_').' : '.$attr);
  78. }
  79. $xml = (array)($xml->tag->attributes());
  80. $array = array_change_key_case($xml['@attributes']);
  81. if($array) {
  82. $attrs = explode(',',$this->tags[strtolower($tag)]['attr']);
  83. if(isset($this->tags[strtolower($tag)]['must'])){
  84. $must = explode(',',$this->tags[strtolower($tag)]['must']);
  85. }else{
  86. $must = array();
  87. }
  88. foreach($attrs as $name) {
  89. if( isset($array[$name])) {
  90. $array[$name] = str_replace('___','&',$array[$name]);
  91. }elseif(false !== array_search($name,$must)){
  92. throw_exception(L('_PARAM_ERROR_').':'.$name);
  93. }
  94. }
  95. return $array;
  96. }
  97. }
  98. /**
  99. * 解析条件表达式
  100. * @access public
  101. * @param string $condition 表达式标签内容
  102. * @return array
  103. */
  104. public function parseCondition($condition) {
  105. $condition = str_ireplace(array_keys($this->comparison),array_values($this->comparison),$condition);
  106. $condition = preg_replace('/\$(\w+):(\w+)\s/is','$\\1->\\2 ',$condition);
  107. switch(strtolower(C('TMPL_VAR_IDENTIFY'))) {
  108. case 'array': // 识别为数组
  109. $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','$\\1["\\2"] ',$condition);
  110. break;
  111. case 'obj': // 识别为对象
  112. $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','$\\1->\\2 ',$condition);
  113. break;
  114. default: // 自动判断数组或对象 只支持二维
  115. $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','(is_array($\\1)?$\\1["\\2"]:$\\1->\\2) ',$condition);
  116. }
  117. if(false !== strpos($condition, '$Think'))
  118. $condition = preg_replace('/(\$Think.*?)\s/ies',"\$this->parseThinkVar('\\1');" , $condition);
  119. return $condition;
  120. }
  121. /**
  122. * 自动识别构建变量
  123. * @access public
  124. * @param string $name 变量描述
  125. * @return string
  126. */
  127. public function autoBuildVar($name) {
  128. if('Think.' == substr($name,0,6)){
  129. // 特殊变量
  130. return $this->parseThinkVar($name);
  131. }elseif(strpos($name,'.')) {
  132. $vars = explode('.',$name);
  133. $var = array_shift($vars);
  134. switch(strtolower(C('TMPL_VAR_IDENTIFY'))) {
  135. case 'array': // 识别为数组
  136. $name = '$'.$var;
  137. foreach ($vars as $key=>$val){
  138. if(0===strpos($val,'$')) {
  139. $name .= '["{'.$val.'}"]';
  140. }else{
  141. $name .= '["'.$val.'"]';
  142. }
  143. }
  144. break;
  145. case 'obj': // 识别为对象
  146. $name = '$'.$var;
  147. foreach ($vars as $key=>$val)
  148. $name .= '->'.$val;
  149. break;
  150. default: // 自动判断数组或对象 只支持二维
  151. $name = 'is_array($'.$var.')?$'.$var.'["'.$vars[0].'"]:$'.$var.'->'.$vars[0];
  152. }
  153. }elseif(strpos($name,':')){
  154. // 额外的对象方式支持
  155. $name = '$'.str_replace(':','->',$name);
  156. }elseif(!defined($name)) {
  157. $name = '$'.$name;
  158. }
  159. return $name;
  160. }
  161. /**
  162. * 用于标签属性里面的特殊模板变量解析
  163. * 格式 以 Think. 打头的变量属于特殊模板变量
  164. * @access public
  165. * @param string $varStr 变量字符串
  166. * @return string
  167. */
  168. public function parseThinkVar($varStr){
  169. $vars = explode('.',$varStr);
  170. $vars[1] = strtoupper(trim($vars[1]));
  171. $parseStr = '';
  172. if(count($vars)>=3){
  173. $vars[2] = trim($vars[2]);
  174. switch($vars[1]){
  175. case 'SERVER': $parseStr = '$_SERVER[\''.$vars[2].'\']';break;
  176. case 'GET': $parseStr = '$_GET[\''.$vars[2].'\']';break;
  177. case 'POST': $parseStr = '$_POST[\''.$vars[2].'\']';break;
  178. case 'COOKIE':
  179. if(isset($vars[3])) {
  180. $parseStr = '$_COOKIE[\''.$vars[2].'\'][\''.$vars[3].'\']';
  181. }elseif(C('COOKIE_PREFIX')){
  182. $parseStr = '$_COOKIE[\''.C('COOKIE_PREFIX').$vars[2].'\']';
  183. }else{
  184. $parseStr = '$_COOKIE[\''.$vars[2].'\']';
  185. }
  186. break;
  187. case 'SESSION':
  188. if(isset($vars[3])) {
  189. $parseStr = '$_SESSION[\''.$vars[2].'\'][\''.$vars[3].'\']';
  190. }elseif(C('SESSION_PREFIX')){
  191. $parseStr = '$_SESSION[\''.C('SESSION_PREFIX').'\'][\''.$vars[2].'\']';
  192. }else{
  193. $parseStr = '$_SESSION[\''.$vars[2].'\']';
  194. }
  195. break;
  196. case 'ENV': $parseStr = '$_ENV[\''.$vars[2].'\']';break;
  197. case 'REQUEST': $parseStr = '$_REQUEST[\''.$vars[2].'\']';break;
  198. case 'CONST': $parseStr = strtoupper($vars[2]);break;
  199. case 'LANG': $parseStr = 'L("'.$vars[2].'")';break;
  200. case 'CONFIG': $parseStr = 'C("'.$vars[2].'")';break;
  201. }
  202. }else if(count($vars)==2){
  203. switch($vars[1]){
  204. case 'NOW': $parseStr = "date('Y-m-d g:i a',time())";break;
  205. case 'VERSION': $parseStr = 'THINK_VERSION';break;
  206. case 'TEMPLATE':$parseStr = 'C("TEMPLATE_NAME")';break;
  207. case 'LDELIM': $parseStr = 'C("TMPL_L_DELIM")';break;
  208. case 'RDELIM': $parseStr = 'C("TMPL_R_DELIM")';break;
  209. default: if(defined($vars[1])) $parseStr = $vars[1];
  210. }
  211. }
  212. return $parseStr;
  213. }
  214. // 获取标签定义
  215. public function getTags(){
  216. return $this->tags;
  217. }
  218. }