SenTemplate.class.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. <?php
  2. // +--------------------------------------------------------------------------
  3. // | Senthot [ DEVELOPED BY ME ]
  4. // +--------------------------------------------------------------------------
  5. // | Copyright (c) 2005-2013 http://www.senthot.com All rights reserved.
  6. // | License ( http://www.apache.org/licenses/LICENSE-2.0 )
  7. // | Author: ms134n ( [email protected] )
  8. // +--------------------------------------------------------------------------
  9. /**
  10. * Senthot built-in template engine class
  11. * SupportXML tag and generic tag template parsing
  12. * Compiled template engine Support dynamic cache
  13. * @category Sen
  14. * @package Sen
  15. * @subpackage Template
  16. * @author ms134n <[email protected]>
  17. */
  18. class SenTemplate {
  19. // Template page tag library introduced in the list
  20. protected $tagLib = array();
  21. // Current template file
  22. protected $templateFile = '';
  23. // Template Variables
  24. public $tVar = array();
  25. public $config = array();
  26. private $literal = array();
  27. private $block = array();
  28. /**
  29. * Architecture function
  30. * @access public
  31. */
  32. public function __construct(){
  33. $this->config['cache_path'] = C('CACHE_PATH');
  34. $this->config['template_suffix'] = C('TMPL_TEMPLATE_SUFFIX');
  35. $this->config['cache_suffix'] = C('TMPL_CACHFILE_SUFFIX');
  36. $this->config['tmpl_cache'] = C('TMPL_CACHE_ON');
  37. $this->config['cache_time'] = C('TMPL_CACHE_TIME');
  38. $this->config['taglib_begin'] = $this->stripPreg(C('TAGLIB_BEGIN'));
  39. $this->config['taglib_end'] = $this->stripPreg(C('TAGLIB_END'));
  40. $this->config['tmpl_begin'] = $this->stripPreg(C('TMPL_L_DELIM'));
  41. $this->config['tmpl_end'] = $this->stripPreg(C('TMPL_R_DELIM'));
  42. $this->config['default_tmpl'] = C('TEMPLATE_NAME');
  43. $this->config['layout_item'] = C('TMPL_LAYOUT_ITEM');
  44. }
  45. private function stripPreg($str) {
  46. return str_replace(
  47. array('{','}','(',')','|','[',']','-','+','*','.','^','?'),
  48. array('\{','\}','\(','\)','\|','\[','\]','\-','\+','\*','\.','\^','\?'),
  49. $str);
  50. }
  51. // Get and set template variables
  52. public function get($name) {
  53. if(isset($this->tVar[$name]))
  54. return $this->tVar[$name];
  55. else
  56. return false;
  57. }
  58. public function set($name,$value) {
  59. $this->tVar[$name]= $value;
  60. }
  61. /**
  62. * Load Template
  63. * @access public
  64. * @param string $tmplTemplateFile Template File
  65. * @param array $templateVar Template Variables
  66. * @param string $prefix Template identifying prefix
  67. * @return void
  68. */
  69. public function fetch($templateFile,$templateVar,$prefix='') {
  70. $this->tVar = $templateVar;
  71. $templateCacheFile = $this->loadTemplate($templateFile,$prefix);
  72. // Template array variable decomposed into independent variable
  73. extract($templateVar, EXTR_OVERWRITE);
  74. //Load template cache files
  75. include $templateCacheFile;
  76. }
  77. /**
  78. * Loaded and cached master template
  79. * @access public
  80. * @param string $tmplTemplateFile Template File
  81. * @param string $prefix Template identifying prefix
  82. * @return string
  83. * @throws SenExecption
  84. */
  85. public function loadTemplate ($tmplTemplateFile,$prefix='') {
  86. if(is_file($tmplTemplateFile)) {
  87. $this->templateFile = $tmplTemplateFile;
  88. // Read the contents of the template file
  89. $tmplContent = file_get_contents($tmplTemplateFile);
  90. }else{
  91. $tmplContent = $tmplTemplateFile;
  92. }
  93. // According to the template file name to locate the cache file
  94. $tmplCacheFile = $this->config['cache_path'].$prefix.md5($tmplTemplateFile).$this->config['cache_suffix'];
  95. // Determine whether to enable layout
  96. if(C('LAYOUT_ON')) {
  97. if(false !== strpos($tmplContent,'{__NOLAYOUT__}')) { // Do not use the layout can be individually defined
  98. $tmplContent = str_replace('{__NOLAYOUT__}','',$tmplContent);
  99. }else{ // Replace the layout of the main content
  100. $layoutFile = THEME_PATH.C('LAYOUT_NAME').$this->config['template_suffix'];
  101. $tmplContent = str_replace($this->config['layout_item'],$tmplContent,file_get_contents($layoutFile));
  102. }
  103. }
  104. // Compiled template content
  105. $tmplContent = $this->compiler($tmplContent);
  106. // Detection template directory
  107. $dir = dirname($tmplCacheFile);
  108. if(!is_dir($dir))
  109. mkdir($dir,0755,true);
  110. //Rewrite Cache Files
  111. if( false === file_put_contents($tmplCacheFile,trim($tmplContent)))
  112. throw_exception(L('_CACHE_WRITE_ERROR_').':'.$tmplCacheFile);
  113. return $tmplCacheFile;
  114. }
  115. /**
  116. * Compile the template file contents
  117. * @access protected
  118. * @param mixed $tmplContent Template content
  119. * @return string
  120. */
  121. protected function compiler($tmplContent) {
  122. //Template parsing
  123. $tmplContent = $this->parse($tmplContent);
  124. // Restore is replaced Literal tags
  125. $tmplContent = preg_replace('/<!--###literal(\d+)###-->/eis',"\$this->restoreLiteral('\\1')",$tmplContent);
  126. // Add Security Code
  127. $tmplContent = '<?php if (!defined(\'SEN_PATH\')) exit();?>'.$tmplContent;
  128. if(C('TMPL_STRIP_SPACE')) {
  129. /* Strip html whitespace and newline */
  130. $find = array('~>\s+<~','~>(\s+\n|\r)~');
  131. $replace = array('><','>');
  132. $tmplContent = preg_replace($find, $replace, $tmplContent);
  133. }
  134. // Optimize the generated php code
  135. $tmplContent = str_replace('?><?php','',$tmplContent);
  136. return strip_whitespace($tmplContent);
  137. }
  138. /**
  139. * Template parsing entrance
  140. * Support Common tags and TagLib resolution Support custom tag library
  141. * @access public
  142. * @param string $content To parse the template content
  143. * @return string
  144. */
  145. public function parse($content) {
  146. // Content is empty does not resolve
  147. if(empty($content)) return '';
  148. $begin = $this->config['taglib_begin'];
  149. $end = $this->config['taglib_end'];
  150. // Check the include syntax
  151. $content = $this->parseInclude($content);
  152. // Check the PHP syntax
  153. $content = $this->parsePhp($content);
  154. // Replaced first literalTag contents
  155. $content = preg_replace('/'.$begin.'literal'.$end.'(.*?)'.$begin.'\/literal'.$end.'/eis',"\$this->parseLiteral('\\1')",$content);
  156. // Gets the list of tag libraries that need to introduce
  157. // Only need to define a tag library, allow the introduction of more
  158. // General in the top of the file
  159. // Format:<taglib name="html,mytag..." />
  160. // When TAGLIB_LOAD is configured to true only when testing
  161. if(C('TAGLIB_LOAD')) {
  162. $this->getIncludeTagLib($content);
  163. if(!empty($this->tagLib)) {
  164. // Import TagLib parsing
  165. foreach($this->tagLib as $tagLibName) {
  166. $this->parseTagLib($tagLibName,$content);
  167. }
  168. }
  169. }
  170. // Preload the tag library Do not need to use taglib in each template tag loading But you must use the tag library XML prefix
  171. if(C('TAGLIB_PRE_LOAD')) {
  172. $tagLibs = explode(',',C('TAGLIB_PRE_LOAD'));
  173. foreach ($tagLibs as $tag){
  174. $this->parseTagLib($tag,$content);
  175. }
  176. }
  177. // Built-in tag library Import without using taglib tags you can use And you don't need to use the tag library XML prefix
  178. $tagLibs = explode(',',C('TAGLIB_BUILD_IN'));
  179. foreach ($tagLibs as $tag){
  180. $this->parseTagLib($tag,$content,true);
  181. }
  182. //Resolve common template tags {tagName}
  183. $content = preg_replace('/('.$this->config['tmpl_begin'].')([^\d\s'.$this->config['tmpl_begin'].$this->config['tmpl_end'].'].+?)('.$this->config['tmpl_end'].')/eis',"\$this->parseTag('\\2')",$content);
  184. return $content;
  185. }
  186. // Check the PHP syntax
  187. protected function parsePhp($content) {
  188. if(ini_get('short_open_tag')){
  189. // Open short tag to be<? Tags echo output Otherwise normal output XML ID
  190. $content = preg_replace('/(<\?(?!php|=|$))/i', '<?php echo \'\\1\'; ?>'."\n", $content );
  191. }
  192. // PHP syntax check
  193. if(C('TMPL_DENY_PHP') && false !== strpos($content,'<?php')) {
  194. throw_exception(L('_NOT_ALLOW_PHP_'));
  195. }
  196. return $content;
  197. }
  198. // Parsing template layout of tags
  199. protected function parseLayout($content) {
  200. // Reading layout in the template tags
  201. $find = preg_match('/'.$this->config['taglib_begin'].'layout\s(.+?)\s*?\/'.$this->config['taglib_end'].'/is',$content,$matches);
  202. if($find) {
  203. //Replaces the Layout tag
  204. $content = str_replace($matches[0],'',$content);
  205. //Resolution Layout tags
  206. $array = $this->parseXmlAttrs($matches[1]);
  207. if(!C('LAYOUT_ON') || C('LAYOUT_NAME') !=$array['name'] ) {
  208. // Reading layout template
  209. $layoutFile = THEME_PATH.$array['name'].$this->config['template_suffix'];
  210. $replace = isset($array['replace'])?$array['replace']:$this->config['layout_item'];
  211. // Replace the layout of the main content
  212. $content = str_replace($replace,$content,file_get_contents($layoutFile));
  213. }
  214. }else{
  215. $content = str_replace('{__NOLAYOUT__}','',$content);
  216. }
  217. return $content;
  218. }
  219. // Include parsing template tags
  220. protected function parseInclude($content) {
  221. // Resolving inheritance
  222. $content = $this->parseAddons($content);
  223. // Analysis of layout
  224. $content = $this->parseLayout($content);
  225. // Read template include tags
  226. $find = preg_match_all('/'.$this->config['taglib_begin'].'include\s(.+?)\s*?\/'.$this->config['taglib_end'].'/is',$content,$matches);
  227. if($find) {
  228. for($i=0;$i<$find;$i++) {
  229. $include = $matches[1][$i];
  230. $array = $this->parseXmlAttrs($include);
  231. $file = $array['file'];
  232. unset($array['file']);
  233. $content = str_replace($matches[0][$i],$this->parseIncludeItem($file,$array),$content);
  234. }
  235. }
  236. return $content;
  237. }
  238. // Addons parsing template tags
  239. protected function parseAddons($content) {
  240. $begin = $this->config['taglib_begin'];
  241. $end = $this->config['taglib_end'];
  242. // Read inheritance in a template tags
  243. $find = preg_match('/'.$begin.'addons\s(.+?)\s*?\/'.$end.'/is',$content,$matches);
  244. if($find) {
  245. //Replace addons tag
  246. $content = str_replace($matches[0],'',$content);
  247. // Block tag records page
  248. preg_replace('/'.$begin.'block\sname=(.+?)\s*?'.$end.'(.*?)'.$begin.'\/block'.$end.'/eis',"\$this->parseBlock('\\1','\\2')",$content);
  249. // Read inherited template
  250. $array = $this->parseXmlAttrs($matches[1]);
  251. $content = $this->parseTemplateName($array['name']);
  252. // Replace block tags
  253. $content = preg_replace('/'.$begin.'block\sname=(.+?)\s*?'.$end.'(.*?)'.$begin.'\/block'.$end.'/eis',"\$this->replaceBlock('\\1','\\2')",$content);
  254. }else{
  255. $content = preg_replace('/'.$begin.'block\sname=(.+?)\s*?'.$end.'(.*?)'.$begin.'\/block'.$end.'/eis',"stripslashes('\\2')",$content);
  256. }
  257. return $content;
  258. }
  259. /**
  260. * Analysis of XML attributes
  261. * @access private
  262. * @param string $attrs XML attribute string
  263. * @return array
  264. */
  265. private function parseXmlAttrs($attrs) {
  266. $xml = '<tpl><tag '.$attrs.' /></tpl>';
  267. $xml = simplexml_load_string($xml);
  268. if(!$xml)
  269. throw_exception(L('_XML_TAG_ERROR_'));
  270. $xml = (array)($xml->tag->attributes());
  271. $array = array_change_key_case($xml['@attributes']);
  272. return $array;
  273. }
  274. /**
  275. * Replace literal tag page
  276. * @access private
  277. * @param string $content Template content
  278. * @return string|false
  279. */
  280. private function parseLiteral($content) {
  281. if(trim($content)=='') return '';
  282. $content = stripslashes($content);
  283. $i = count($this->literal);
  284. $parseStr = "<!--###literal{$i}###-->";
  285. $this->literal[$i] = $content;
  286. return $parseStr;
  287. }
  288. /**
  289. * Restore has been replacing literal tags
  290. * @access private
  291. * @param string $tag Literal tag serial number
  292. * @return string|false
  293. */
  294. private function restoreLiteral($tag) {
  295. // Restore literal tags
  296. $parseStr = $this->literal[$tag];
  297. // Destruction of literal records
  298. unset($this->literal[$tag]);
  299. return $parseStr;
  300. }
  301. /**
  302. * Block tag records in the current page
  303. * @access private
  304. * @param string $name Block name
  305. * @param string $content Template content
  306. * @return string
  307. */
  308. private function parseBlock($name,$content) {
  309. $this->block[$name] = $content;
  310. return '';
  311. }
  312. /**
  313. * Replacing the inherited template block tag
  314. * @access private
  315. * @param string $name Block name
  316. * @param string $content Template content
  317. * @return string
  318. */
  319. private function replaceBlock($name,$content) {
  320. // Replace block tags Do not redefine the original
  321. $replace = isset($this->block[$name])? $this->block[$name] : $content;
  322. return stripslashes($replace);
  323. }
  324. /**
  325. * Search template page containing the TagLib library
  326. * And return to the list
  327. * @access public
  328. * @param string $content Template content
  329. * @return string|false
  330. */
  331. public function getIncludeTagLib(& $content) {
  332. //Search for TagLib tag
  333. $find = preg_match('/'.$this->config['taglib_begin'].'taglib\s(.+?)(\s*?)\/'.$this->config['taglib_end'].'\W/is',$content,$matches);
  334. if($find) {
  335. //Replace TagLib tag
  336. $content = str_replace($matches[0],'',$content);
  337. //Resolving TagLib tag
  338. $array = $this->parseXmlAttrs($matches[1]);
  339. $this->tagLib = explode(',',$array['name']);
  340. }
  341. return;
  342. }
  343. /**
  344. * TagLib library parsing
  345. * @access public
  346. * @param string $tagLib To parse the tag library
  347. * @param string $content To parse the template content
  348. * @param boolen $hide Whether to hide tag library prefix
  349. * @return string
  350. */
  351. public function parseTagLib($tagLib,&$content,$hide=false) {
  352. $begin = $this->config['taglib_begin'];
  353. $end = $this->config['taglib_end'];
  354. $className = 'TagLib'.ucwords($tagLib);
  355. $tLib = Sen::instance($className);
  356. foreach ($tLib->getTags() as $name=>$val){
  357. $tags = array($name);
  358. if(isset($val['alias'])) {// Alias settings
  359. $tags = explode(',',$val['alias']);
  360. $tags[] = $name;
  361. }
  362. $level = isset($val['level'])?$val['level']:1;
  363. $closeTag = isset($val['close'])?$val['close']:true;
  364. foreach ($tags as $tag){
  365. $parseTag = !$hide? $tagLib.':'.$tag: $tag;// Actual tag name to be resolved
  366. if(!method_exists($tLib,'_'.$tag)) {
  367. // Analytical method may need to define an alias
  368. $tag = $name;
  369. }
  370. $n1 = empty($val['attr'])?'(\s*?)':'\s([^'.$end.']*)';
  371. if (!$closeTag){
  372. $patterns = '/'.$begin.$parseTag.$n1.'\/(\s*?)'.$end.'/eis';
  373. $replacement = "\$this->parseXmlTag('$tagLib','$tag','$1','')";
  374. $content = preg_replace($patterns, $replacement,$content);
  375. }else{
  376. $patterns = '/'.$begin.$parseTag.$n1.$end.'(.*?)'.$begin.'\/'.$parseTag.'(\s*?)'.$end.'/eis';
  377. $replacement = "\$this->parseXmlTag('$tagLib','$tag','$1','$2')";
  378. for($i=0;$i<$level;$i++)
  379. $content=preg_replace($patterns,$replacement,$content);
  380. }
  381. }
  382. }
  383. }
  384. /**
  385. * Resolution tab library
  386. * Need to call the corresponding tag library file parsing class
  387. * @access public
  388. * @param string $tagLib Tag library name
  389. * @param string $tag Tag names
  390. * @param string $attr Tag attributes
  391. * @param string $content Tag contents
  392. * @return string|false
  393. */
  394. public function parseXmlTag($tagLib,$tag,$attr,$content) {
  395. //if (MAGIC_QUOTES_GPC) {
  396. $attr = stripslashes($attr);
  397. $content= stripslashes($content);
  398. //}
  399. if(ini_get('magic_quotes_sybase'))
  400. $attr = str_replace('\"','\'',$attr);
  401. $tLib = Sen::instance('TagLib'.ucwords(strtolower($tagLib)));
  402. $parse = '_'.$tag;
  403. $content = trim($content);
  404. return $tLib->$parse($attr,$content);
  405. }
  406. /**
  407. * Template Tag resolution
  408. * Format: {TagName:args [|content] }
  409. * @access public
  410. * @param string $tagStr Tag contents
  411. * @return string
  412. */
  413. public function parseTag($tagStr){
  414. //if (MAGIC_QUOTES_GPC) {
  415. $tagStr = stripslashes($tagStr);
  416. //}
  417. //Reducing non-template tag
  418. if(preg_match('/^[\s|\d]/is',$tagStr))
  419. //Filtering tags beginning with numbers and spaces
  420. return C('TMPL_L_DELIM') . $tagStr .C('TMPL_R_DELIM');
  421. $flag = substr($tagStr,0,1);
  422. $flag2 = substr($tagStr,1,1);
  423. $name = substr($tagStr,1);
  424. if('$' == $flag && '.' != $flag2 && '(' != $flag2){ //Parsing template variables Format {$varName}
  425. return $this->parseVar($name);
  426. }elseif('-' == $flag || '+'== $flag){ // Output calculation
  427. return '<?php echo '.$flag.$name.';?>';
  428. }elseif(':' == $flag){ // Output the result of a function
  429. return '<?php echo '.$name.';?>';
  430. }elseif('~' == $flag){ // Perform a function
  431. return '<?php '.$name.';?>';
  432. }elseif(substr($tagStr,0,2)=='//' || (substr($tagStr,0,2)=='/*' && substr($tagStr,-2)=='*/')){
  433. //Comment tags
  434. return '';
  435. }
  436. // Identification tags are not returned directly
  437. return C('TMPL_L_DELIM') . $tagStr .C('TMPL_R_DELIM');
  438. }
  439. /**
  440. * Template variable resolution, Support use the function
  441. * Format: {$varname|function1|function2=arg1,arg2}
  442. * @access public
  443. * @param string $varStr Variable data
  444. * @return string
  445. */
  446. public function parseVar($varStr){
  447. $varStr = trim($varStr);
  448. static $_varParseList = array();
  449. //If the variable is a string that has been parsed, the direct return variable value
  450. if(isset($_varParseList[$varStr])) return $_varParseList[$varStr];
  451. $parseStr = '';
  452. $varExists = true;
  453. if(!empty($varStr)){
  454. $varArray = explode('|',$varStr);
  455. //Get the variable name
  456. $var = array_shift($varArray);
  457. if('Sen.' == substr($var,0,4)){
  458. // All to Sen. Variables beginning with a special treat Templates can be exported without assignment
  459. $name = $this->parseSenVar($var);
  460. }elseif( false !== strpos($var,'.')) {
  461. //Support {$var.property}
  462. $vars = explode('.',$var);
  463. $var = array_shift($vars);
  464. switch(strtolower(C('TMPL_VAR_IDENTIFY'))) {
  465. case 'array': // Identified as an array
  466. $name = '$'.$var;
  467. foreach ($vars as $key=>$val)
  468. $name .= '["'.$val.'"]';
  469. break;
  470. case 'obj': // Identifying the object
  471. $name = '$'.$var;
  472. foreach ($vars as $key=>$val)
  473. $name .= '->'.$val;
  474. break;
  475. default: // Automatically determine the array or object Support only two-dimensional
  476. $name = 'is_array($'.$var.')?$'.$var.'["'.$vars[0].'"]:$'.$var.'->'.$vars[0];
  477. }
  478. }elseif(false !== strpos($var,'[')) {
  479. //Support {$var['key']} Mode output array
  480. $name = "$".$var;
  481. preg_match('/(.+?)\[(.+?)\]/is',$var,$match);
  482. $var = $match[1];
  483. }elseif(false !==strpos($var,':') && false ===strpos($var,'::') && false ===strpos($var,'?')){
  484. //Support {$var:property} Output the object's properties
  485. $vars = explode(':',$var);
  486. $var = str_replace(':','->',$var);
  487. $name = "$".$var;
  488. $var = $vars[0];
  489. }else {
  490. $name = "$$var";
  491. }
  492. //The variable using the function
  493. if(count($varArray)>0)
  494. $name = $this->parseVarFunction($name,$varArray);
  495. $parseStr = '<?php echo ('.$name.'); ?>';
  496. }
  497. $_varParseList[$varStr] = $parseStr;
  498. return $parseStr;
  499. }
  500. /**
  501. * Use the template variable function
  502. * Format {$varname|function1|function2=arg1,arg2}
  503. * @access public
  504. * @param string $name Variable name
  505. * @param array $varArray Function List
  506. * @return string
  507. */
  508. public function parseVarFunction($name,$varArray){
  509. //The variable using the function
  510. $length = count($varArray);
  511. //Prohibit the use of a template to obtain a list of functions
  512. $template_deny_funs = explode(',',C('TMPL_DENY_FUNC_LIST'));
  513. for($i=0;$i<$length ;$i++ ){
  514. $args = explode('=',$varArray[$i],2);
  515. //Template function filter
  516. $fun = strtolower(trim($args[0]));
  517. switch($fun) {
  518. case 'default': // Special template function
  519. $name = '('.$name.')?('.$name.'):'.$args[1];
  520. break;
  521. default: // Universal template function
  522. if(!in_array($fun,$template_deny_funs)){
  523. if(isset($args[1])){
  524. if(strstr($args[1],'###')){
  525. $args[1] = str_replace('###',$name,$args[1]);
  526. $name = "$fun($args[1])";
  527. }else{
  528. $name = "$fun($name,$args[1])";
  529. }
  530. }else if(!empty($args[0])){
  531. $name = "$fun($name)";
  532. }
  533. }
  534. }
  535. }
  536. return $name;
  537. }
  538. /**
  539. * Special template variable resolution
  540. * Format $Sen. Heading variable is a special template variables
  541. * @access public
  542. * @param string $varStr Variable string
  543. * @return string
  544. */
  545. public function parseSenVar($varStr){
  546. $vars = explode('.',$varStr);
  547. $vars[1] = strtoupper(trim($vars[1]));
  548. $parseStr = '';
  549. if(count($vars)>=3){
  550. $vars[2] = trim($vars[2]);
  551. switch($vars[1]){
  552. case 'SERVER':
  553. $parseStr = '$_SERVER[\''.strtoupper($vars[2]).'\']';break;
  554. case 'GET':
  555. $parseStr = '$_GET[\''.$vars[2].'\']';break;
  556. case 'POST':
  557. $parseStr = '$_POST[\''.$vars[2].'\']';break;
  558. case 'COOKIE':
  559. if(isset($vars[3])) {
  560. $parseStr = '$_COOKIE[\''.$vars[2].'\'][\''.$vars[3].'\']';
  561. }else{
  562. $parseStr = 'cookie(\''.$vars[2].'\')';
  563. }
  564. break;
  565. case 'SESSION':
  566. if(isset($vars[3])) {
  567. $parseStr = '$_SESSION[\''.$vars[2].'\'][\''.$vars[3].'\']';
  568. }else{
  569. $parseStr = 'session(\''.$vars[2].'\')';
  570. }
  571. break;
  572. case 'ENV':
  573. $parseStr = '$_ENV[\''.strtoupper($vars[2]).'\']';break;
  574. case 'REQUEST':
  575. $parseStr = '$_REQUEST[\''.$vars[2].'\']';break;
  576. case 'CONST':
  577. $parseStr = strtoupper($vars[2]);break;
  578. case 'LANG':
  579. $parseStr = 'L("'.$vars[2].'")';break;
  580. case 'CONFIG':
  581. if(isset($vars[3])) {
  582. $vars[2] .= '.'.$vars[3];
  583. }
  584. $parseStr = 'C("'.$vars[2].'")';break;
  585. default:break;
  586. }
  587. }else if(count($vars)==2){
  588. switch($vars[1]){
  589. case 'NOW':
  590. $parseStr = "date('Y-m-d g:i a',time())";
  591. break;
  592. case 'VERSION':
  593. $parseStr = 'SEN_VERSION';
  594. break;
  595. case 'TEMPLATE':
  596. $parseStr = "'".$this->templateFile."'";//'C("TEMPLATE_NAME")';
  597. break;
  598. case 'LDELIM':
  599. $parseStr = 'C("TMPL_L_DELIM")';
  600. break;
  601. case 'RDELIM':
  602. $parseStr = 'C("TMPL_R_DELIM")';
  603. break;
  604. default:
  605. if(defined($vars[1]))
  606. $parseStr = $vars[1];
  607. }
  608. }
  609. return $parseStr;
  610. }
  611. /**
  612. * Common template loaded and cached and the current template in the same path, or use a relative path
  613. * @access private
  614. * @param string $tmplPublicName Public template file name
  615. * @param array $vars The list of variables to be passed
  616. * @return string
  617. */
  618. private function parseIncludeItem($tmplPublicName,$vars=array()){
  619. // Analyze and read the contents of the template file name
  620. $parseStr = $this->parseTemplateName($tmplPublicName);
  621. // Substitution variables
  622. foreach ($vars as $key=>$val) {
  623. $parseStr = str_replace('['.$key.']',$val,$parseStr);
  624. }
  625. // Template that contains the file again analyzed
  626. return $this->parseInclude($parseStr);
  627. }
  628. /**
  629. * Analysis of the loaded template file and read the contents Support multiple template file read
  630. * @access private
  631. * @param string $tmplPublicName Template file name
  632. * @return string
  633. */
  634. private function parseTemplateName($templateName){
  635. if(substr($templateName,0,1)=='$')
  636. //Support load variable file name
  637. $templateName = $this->get(substr($templateName,1));
  638. $array = explode(',',$templateName);
  639. $parseStr = '';
  640. foreach ($array as $templateName){
  641. if(false === strpos($templateName,$this->config['template_suffix'])) {
  642. // Parsing rules Template Theme:Module:Operating Not Support Cross-project and cross-grouping called
  643. $path = explode(':',$templateName);
  644. $action = array_pop($path);
  645. $module = !empty($path)?array_pop($path):MODULE_NAME;
  646. if(!empty($path) && THEME_NAME) {// Set Template Theme
  647. $path = dirname(THEME_PATH).'/'.array_pop($path).'/';
  648. }else{
  649. $path = THEME_PATH;
  650. }
  651. $templateName = $path.$module.C('TMPL_FILE_DEPR').$action.$this->config['template_suffix'];
  652. }
  653. // Get the template file contents
  654. $parseStr .= file_get_contents($templateName);
  655. }
  656. return $parseStr;
  657. }
  658. }