template_cache.class.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <?php
  2. /**
  3. * 模板解析缓存
  4. */
  5. final class template_cache {
  6. /**
  7. * 编译模板
  8. *
  9. * @param $module 模块名称
  10. * @param $template 模板文件名
  11. * @param $istag 是否为标签模板
  12. * @return unknown
  13. */
  14. public function template_compile($module, $template, $style = 'default') {
  15. if(strpos($module, '/')=== false) {
  16. $tplfile = $_tpl = PC_PATH.'templates'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html';
  17. } elseif (strpos($module, 'yp/') !== false) {
  18. $module = str_replace('/', DIRECTORY_SEPARATOR, $module);
  19. $tplfile = $_tpl = PC_PATH.'templates'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html';
  20. } else {
  21. $plugin = str_replace('plugin/', '', $module);
  22. $module = str_replace('/', DIRECTORY_SEPARATOR, $module);
  23. $tplfile = $_tpl = PC_PATH.'plugin'.DIRECTORY_SEPARATOR.$plugin.DIRECTORY_SEPARATOR.'templates'.DIRECTORY_SEPARATOR.$template.'.html';
  24. }
  25. if ($style != 'default' && !file_exists ( $tplfile )) {
  26. $style = 'default';
  27. $tplfile = PC_PATH.'templates'.DIRECTORY_SEPARATOR.'default'.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.'.html';
  28. }
  29. if (! file_exists ( $tplfile )) {
  30. showmessage ( "templates".DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.$template.".html is not exists!" );
  31. }
  32. $content = @file_get_contents ( $tplfile );
  33. $filepath = CACHE_PATH.'caches_template'.DIRECTORY_SEPARATOR.$style.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR;
  34. if(!is_dir($filepath)) {
  35. mkdir($filepath, 0777, true);
  36. }
  37. $compiledtplfile = $filepath.$template.'.php';
  38. $content = $this->template_parse($content);
  39. $strlen = file_put_contents ( $compiledtplfile, $content );
  40. chmod ( $compiledtplfile, 0777 );
  41. return $strlen;
  42. }
  43. /**
  44. * 更新模板缓存
  45. *
  46. * @param $tplfile 模板原文件路径
  47. * @param $compiledtplfile 编译完成后,写入文件名
  48. * @return $strlen 长度
  49. */
  50. public function template_refresh($tplfile, $compiledtplfile) {
  51. $str = @file_get_contents ($tplfile);
  52. $str = $this->template_parse ($str);
  53. $strlen = file_put_contents ($compiledtplfile, $str );
  54. chmod ($compiledtplfile, 0777);
  55. return $strlen;
  56. }
  57. /**
  58. * 解析模板
  59. *
  60. * @param $str 模板内容
  61. * @return ture
  62. */
  63. public function template_parse($str) {
  64. $str = preg_replace ( "/\{template\s+(.+)\}/", "<?php include template(\\1); ?>", $str );
  65. $str = preg_replace ( "/\{include\s+(.+)\}/", "<?php include \\1; ?>", $str );
  66. $str = preg_replace ( "/\{php\s+(.+)\}/", "<?php \\1?>", $str );
  67. $str = preg_replace ( "/\{if\s+(.+?)\}/", "<?php if(\\1) { ?>", $str );
  68. $str = preg_replace ( "/\{else\}/", "<?php } else { ?>", $str );
  69. $str = preg_replace ( "/\{elseif\s+(.+?)\}/", "<?php } elseif (\\1) { ?>", $str );
  70. $str = preg_replace ( "/\{\/if\}/", "<?php } ?>", $str );
  71. //for 循环
  72. $str = preg_replace("/\{for\s+(.+?)\}/","<?php for(\\1) { ?>",$str);
  73. $str = preg_replace("/\{\/for\}/","<?php } ?>",$str);
  74. //++ --
  75. $str = preg_replace("/\{\+\+(.+?)\}/","<?php ++\\1; ?>",$str);
  76. $str = preg_replace("/\{\-\-(.+?)\}/","<?php ++\\1; ?>",$str);
  77. $str = preg_replace("/\{(.+?)\+\+\}/","<?php \\1++; ?>",$str);
  78. $str = preg_replace("/\{(.+?)\-\-\}/","<?php \\1--; ?>",$str);
  79. $str = preg_replace ( "/\{loop\s+(\S+)\s+(\S+)\}/", "<?php \$n=1;if(is_array(\\1)) foreach(\\1 AS \\2) { ?>", $str );
  80. $str = preg_replace ( "/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/", "<?php \$n=1; if(is_array(\\1)) foreach(\\1 AS \\2 => \\3) { ?>", $str );
  81. $str = preg_replace ( "/\{\/loop\}/", "<?php \$n++;}unset(\$n); ?>", $str );
  82. $str = preg_replace ( "/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "<?php echo \\1;?>", $str );
  83. $str = preg_replace ( "/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "<?php echo \\1;?>", $str );
  84. $str = preg_replace ( "/\{(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "<?php echo \\1;?>", $str );
  85. $str = preg_replace_callback("/\{(\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\}/s", array($this, 'addquote'),$str);
  86. $str = preg_replace ( "/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/s", "<?php echo \\1;?>", $str );
  87. $str = preg_replace_callback("/\{pc:(\w+)\s+([^}]+)\}/i", array($this, 'pc_tag_callback'), $str);
  88. $str = preg_replace_callback("/\{\/pc\}/i", array($this, 'end_pc_tag'), $str);
  89. $str = "<?php defined('IN_PHPCMS') or exit('No permission resources.'); ?>" . $str;
  90. return $str;
  91. }
  92. /**
  93. * 转义 // 为 /
  94. *
  95. * @param $var 转义的字符
  96. * @return 转义后的字符
  97. */
  98. public function addquote($matches) {
  99. $var = '<?php echo '.$matches[1].';?>';
  100. return str_replace ( "\\\"", "\"", preg_replace ( "/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var ) );
  101. }
  102. public static function pc_tag_callback($matches) {
  103. return self::pc_tag($matches[1],$matches[2], $matches[0]);;
  104. }
  105. /**
  106. * 解析PC标签
  107. * @param string $op 操作方式
  108. * @param string $data 参数
  109. * @param string $html 匹配到的所有的HTML代码
  110. */
  111. public static function pc_tag($op, $data, $html) {
  112. preg_match_all("/([a-z]+)\=[\"]?([^\"]+)[\"]?/i", stripslashes($data), $matches, PREG_SET_ORDER);
  113. $arr = array('action','num','cache','page', 'pagesize', 'urlrule', 'return', 'start');
  114. $tools = array('json', 'xml', 'block', 'get');
  115. $datas = array();
  116. $tag_id = md5(stripslashes($html));
  117. //可视化条件
  118. $str_datas = 'op='.$op.'&tag_md5='.$tag_id;
  119. foreach ($matches as $v) {
  120. $str_datas .= $str_datas ? "&$v[1]=".($op == 'block' && strpos($v[2], '$') === 0 ? $v[2] : urlencode($v[2])) : "$v[1]=".(strpos($v[2], '$') === 0 ? $v[2] : urlencode($v[2]));
  121. if(in_array($v[1], $arr)) {
  122. ${$v[1]} = $v[2];
  123. continue;
  124. }
  125. $datas[$v[1]] = $v[2];
  126. }
  127. $str = '';
  128. $num = isset($num) && intval($num) ? intval($num) : 20;
  129. $cache = isset($cache) && intval($cache) ? intval($cache) : 0;
  130. $return = isset($return) && trim($return) ? trim($return) : 'data';
  131. if (!isset($urlrule)) $urlrule = '';
  132. if (!empty($cache) && !isset($page)) {
  133. $str .= '$tag_cache_name = md5(implode(\'&\','.self::arr_to_html($datas).').\''.$tag_id.'\');if(!$'.$return.' = tpl_cache($tag_cache_name,'.$cache.')){';
  134. }
  135. if (in_array($op,$tools)) {
  136. switch ($op) {
  137. case 'json':
  138. if (isset($datas['url']) && !empty($datas['url'])) {
  139. $str .= '$json = @file_get_contents(\''.$datas['url'].'\');';
  140. $str .= '$'.$return.' = json_decode($json, true);';
  141. }
  142. break;
  143. case 'xml':
  144. $str .= '$xml = pc_base::load_sys_class(\'xml\');';
  145. $str .= '$xml_data = @file_get_contents(\''.$datas['url'].'\');';
  146. $str .= '$'.$return.' = $xml->xml_unserialize($xml_data);';
  147. break;
  148. case 'get':
  149. $str .= 'pc_base::load_sys_class("get_model", "model", 0);';
  150. if ($datas['dbsource']) {
  151. $dbsource = getcache('dbsource', 'commons');
  152. if (isset($dbsource[$datas['dbsource']])) {
  153. $str .= '$get_db = new get_model('.var_export($dbsource,true).', \''.$datas['dbsource'].'\');';
  154. } else {
  155. return false;
  156. }
  157. } else {
  158. $str .= '$get_db = new get_model();';
  159. }
  160. $num = isset($num) && intval($num) > 0 ? intval($num) : 20;
  161. if (isset($start) && intval($start)) {
  162. $limit = intval($start).','.$num;
  163. } else {
  164. $limit = $num;
  165. }
  166. if (isset($page)) {
  167. $str .= '$pagesize = '.$num.';';
  168. $str .= '$page = intval('.$page.') ? intval('.$page.') : 1;if($page<=0){$page=1;}';
  169. $str .= '$offset = ($page - 1) * $pagesize;';
  170. $limit = '$offset,$pagesize';
  171. $sql = 'SELECT COUNT(*) as count FROM ('.$datas['sql'].') T';
  172. $str .= '$r = $get_db->sql_query("'.$sql.'");$s = $get_db->fetch_next();$pages=pages($s[\'count\'], $page, $pagesize, $urlrule);';
  173. }
  174. $str .= '$r = $get_db->sql_query("'.$datas['sql'].' LIMIT '.$limit.'");while(($s = $get_db->fetch_next()) != false) {$a[] = $s;}$'.$return.' = $a;unset($a);';
  175. break;
  176. case 'block':
  177. $str .= '$block_tag = pc_base::load_app_class(\'block_tag\', \'block\');';
  178. $str .= 'echo $block_tag->pc_tag('.self::arr_to_html($datas).');';
  179. break;
  180. }
  181. } else {
  182. if (!isset($action) || empty($action)) return false;
  183. if (module_exists($op) && file_exists(PC_PATH.DIRECTORY_SEPARATOR.'modules'.DIRECTORY_SEPARATOR.$op.DIRECTORY_SEPARATOR.'classes'.DIRECTORY_SEPARATOR.$op.'_tag.class.php')) {
  184. $str .= '$'.$op.'_tag = pc_base::load_app_class("'.$op.'_tag", "'.$op.'");if (method_exists($'.$op.'_tag, \''.$action.'\')) {';
  185. if (isset($start) && intval($start)) {
  186. $datas['limit'] = intval($start).','.$num;
  187. } else {
  188. $datas['limit'] = $num;
  189. }
  190. if (isset($page)) {
  191. $str .= '$pagesize = '.$num.';';
  192. $str .= '$page = intval('.$page.') ? intval('.$page.') : 1;if($page<=0){$page=1;}';
  193. $str .= '$offset = ($page - 1) * $pagesize;';
  194. $datas['limit'] = '$offset.",".$pagesize';
  195. $datas['action'] = $action;
  196. $str .= '$'.$op.'_total = $'.$op.'_tag->count('.self::arr_to_html($datas).');';
  197. $str .= '$pages = pages($'.$op.'_total, $page, $pagesize, $urlrule);';
  198. $str .= '$pc_pages = pc_pages($'.$op.'_total, $page, $pagesize, $urlrule);';
  199. }
  200. $str .= '$'.$return.' = $'.$op.'_tag->'.$action.'('.self::arr_to_html($datas).');';
  201. $str .= '}';
  202. }
  203. }
  204. if (!empty($cache) && !isset($page)) {
  205. $str .= 'if(!empty($'.$return.')){setcache($tag_cache_name, $'.$return.', \'tpl_data\');}';
  206. $str .= '}';
  207. }
  208. return "<"."?php if(defined('IN_ADMIN') && !defined('HTML')) {echo \"<div class=\\\"admin_piao\\\" pc_action=\\\"".$op."\\\" data=\\\"".$str_datas."\\\"><a href=\\\"javascript:void(0)\\\" class=\\\"admin_piao_edit\\\">".($op=='block' ? L('block_add') : L('edit'))."</a>\";}".$str."?".">";
  209. }
  210. /**
  211. * PC标签结束
  212. */
  213. static private function end_pc_tag() {
  214. return '<?php if(defined(\'IN_ADMIN\') && !defined(\'HTML\')) {echo \'</div>\';}?>';
  215. }
  216. /**
  217. * 转换数据为HTML代码
  218. * @param array $data 数组
  219. */
  220. private static function arr_to_html($data) {
  221. if (is_array($data)) {
  222. $str = 'array(';
  223. foreach ($data as $key=>$val) {
  224. if (is_array($val)) {
  225. $str .= "'$key'=>".self::arr_to_html($val).",";
  226. } else {
  227. if (strpos($val, '$')===0) {
  228. $str .= "'$key'=>$val,";
  229. } else {
  230. $str .= "'$key'=>'".new_addslashes($val)."',";
  231. }
  232. }
  233. }
  234. return $str.')';
  235. }
  236. return false;
  237. }
  238. }
  239. ?>