class.smarttemplate.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. <?php
  2. /**
  3. * SmartTemplate Class
  4. *
  5. * 'Compiles' HTML-Templates to PHP Code
  6. *
  7. *
  8. * Usage Example I:
  9. *
  10. * $page = new SmartTemplate( "template.html" );
  11. * $page->assign( 'TITLE', 'TemplateDemo - Userlist' );
  12. * $page->assign( 'user', DB_read_all( 'select * from ris_user' ) );
  13. * $page->output();
  14. *
  15. * Usage Example II:
  16. *
  17. * $data = array(
  18. * 'TITLE' => 'TemplateDemo - Userlist',
  19. * 'user' => DB_read_all( 'select * from ris_user' )
  20. * );
  21. * $page = new SmartTemplate( "template.html" );
  22. * $page->output( $data );
  23. *
  24. *
  25. * @author Philipp v. Criegern philipp@criegern.com
  26. * @author Manuel 'EndelWar' Dalla Lana endelwar@aregar.it
  27. * @version 1.2.1 03.07.2006
  28. *
  29. * CVS ID: $Id: class.smarttemplate.php 2504 2011-12-28 07:35:29Z liu21st $
  30. */
  31. class SmartTemplate
  32. {
  33. /**
  34. * Whether to store compiled php code or not (for debug purpose)
  35. *
  36. * @access public
  37. */
  38. var $reuse_code = true;
  39. /**
  40. * Directory where all templates are stored
  41. * Can be overwritten by global configuration array $_CONFIG['template_dir']
  42. *
  43. * @access public
  44. */
  45. var $template_dir = 'templates/';
  46. /**
  47. * Where to store compiled templates
  48. * Can be overwritten by global configuration array $_CONFIG['smarttemplate_compiled']
  49. *
  50. * @access public
  51. */
  52. var $temp_dir = 'templates_c/';
  53. /**
  54. * Temporary folder for output cache storage
  55. * Can be overwritten by global configuration array $_CONFIG['smarttemplate_cache']
  56. *
  57. * @access public
  58. */
  59. var $cache_dir = 'templates_c/';
  60. /**
  61. * Default Output Cache Lifetime in Seconds
  62. * Can be overwritten by global configuration array $_CONFIG['cache_lifetime']
  63. *
  64. * @access public
  65. */
  66. var $cache_lifetime = 600;
  67. /**
  68. * Temporary file for output cache storage
  69. *
  70. * @access private
  71. */
  72. var $cache_filename;
  73. /**
  74. * The template filename
  75. *
  76. * @access private
  77. */
  78. var $tpl_file;
  79. /**
  80. * The compiled template filename
  81. *
  82. * @access private
  83. */
  84. var $cpl_file;
  85. /**
  86. * Template content array
  87. *
  88. * @access private
  89. */
  90. var $data = array();
  91. /**
  92. * Parser Class
  93. *
  94. * @access private
  95. */
  96. var $parser;
  97. /**
  98. * Debugger Class
  99. *
  100. * @access private
  101. */
  102. var $debugger;
  103. /**
  104. * SmartTemplate Constructor
  105. *
  106. * @access public
  107. * @param string $template_filename Template Filename
  108. */
  109. function SmartTemplate ( $template_filename = '' )
  110. {
  111. global $_CONFIG;
  112. if (!empty($_CONFIG['smarttemplate_compiled']))
  113. {
  114. $this->temp_dir = $_CONFIG['smarttemplate_compiled'];
  115. }
  116. if (!empty($_CONFIG['smarttemplate_cache']))
  117. {
  118. $this->cache_dir = $_CONFIG['smarttemplate_cache'];
  119. }
  120. if (is_numeric($_CONFIG['cache_lifetime']))
  121. {
  122. $this->cache_lifetime = $_CONFIG['cache_lifetime'];
  123. }
  124. if (!empty($_CONFIG['template_dir']) && is_file($_CONFIG['template_dir'] . '/' . $template_filename))
  125. {
  126. $this->template_dir = $_CONFIG['template_dir'];
  127. }
  128. $this->tpl_file = $template_filename;
  129. }
  130. // DEPRECATED METHODS
  131. // Methods used in older parser versions, soon will be removed
  132. function set_templatefile ($template_filename) { $this->tpl_file = $template_filename; }
  133. function add_value ($name, $value ) { $this->assign($name, $value); }
  134. function add_array ($name, $value ) { $this->append($name, $value); }
  135. /**
  136. * Assign Template Content
  137. *
  138. * Usage Example:
  139. * $page->assign( 'TITLE', 'My Document Title' );
  140. * $page->assign( 'userlist', array(
  141. * array( 'ID' => 123, 'NAME' => 'John Doe' ),
  142. * array( 'ID' => 124, 'NAME' => 'Jack Doe' ),
  143. * );
  144. *
  145. * @access public
  146. * @param string $name Parameter Name
  147. * @param mixed $value Parameter Value
  148. * @desc Assign Template Content
  149. */
  150. function assign ( $name, $value = '' )
  151. {
  152. if (is_array($name))
  153. {
  154. foreach ($name as $k => $v)
  155. {
  156. $this->data[$k] = $v;
  157. }
  158. }
  159. else
  160. {
  161. $this->data[$name] = $value;
  162. }
  163. }
  164. /**
  165. * Assign Template Content
  166. *
  167. * Usage Example:
  168. * $page->append( 'userlist', array( 'ID' => 123, 'NAME' => 'John Doe' ) );
  169. * $page->append( 'userlist', array( 'ID' => 124, 'NAME' => 'Jack Doe' ) );
  170. *
  171. * @access public
  172. * @param string $name Parameter Name
  173. * @param mixed $value Parameter Value
  174. * @desc Assign Template Content
  175. */
  176. function append ( $name, $value )
  177. {
  178. if (is_array($value))
  179. {
  180. $this->data[$name][] = $value;
  181. }
  182. elseif (!is_array($this->data[$name]))
  183. {
  184. $this->data[$name] .= $value;
  185. }
  186. }
  187. /**
  188. * Parser Wrapper
  189. * Returns Template Output as a String
  190. *
  191. * @access public
  192. * @param array $_top Content Array
  193. * @return string Parsed Template
  194. * @desc Output Buffer Parser Wrapper
  195. */
  196. function result ( $_top = '' )
  197. {
  198. ob_start();
  199. $this->output( $_top );
  200. $result = ob_get_contents();
  201. ob_end_clean();
  202. return $result;
  203. }
  204. /**
  205. * Execute parsed Template
  206. * Prints Parsing Results to Standard Output
  207. *
  208. * @access public
  209. * @param array $_top Content Array
  210. * @desc Execute parsed Template
  211. */
  212. function output ( $_top = '' )
  213. {
  214. global $_top;
  215. // Make sure that folder names have a trailing '/'
  216. if (strlen($this->template_dir) && substr($this->template_dir, -1) != '/')
  217. {
  218. $this->template_dir .= '/';
  219. }
  220. if (strlen($this->temp_dir) && substr($this->temp_dir, -1) != '/')
  221. {
  222. $this->temp_dir .= '/';
  223. }
  224. // Prepare Template Content
  225. if (!is_array($_top))
  226. {
  227. if (strlen($_top))
  228. {
  229. $this->tpl_file = $_top;
  230. }
  231. $_top = $this->data;
  232. }
  233. $_obj = &$_top;
  234. $_stack_cnt = 0;
  235. $_stack[$_stack_cnt++] = $_obj;
  236. // Check if template is already compiled
  237. $cpl_file_name = preg_replace('/[:\/.\\\\]/', '_', $this->tpl_file);
  238. if (strlen($cpl_file_name) > 0)
  239. {
  240. $this->cpl_file = $this->temp_dir . $cpl_file_name . '.php';
  241. $compile_template = true;
  242. if ($this->reuse_code)
  243. {
  244. if (is_file($this->cpl_file))
  245. {
  246. if ($this->mtime($this->cpl_file) > $this->mtime($this->template_dir . $this->tpl_file))
  247. {
  248. $compile_template = false;
  249. }
  250. }
  251. }
  252. if ($compile_template)
  253. {
  254. if (@include_once("class.smarttemplateparser.php"))
  255. {
  256. $this->parser = new SmartTemplateParser($this->template_dir . $this->tpl_file);
  257. if (!$this->parser->compile($this->cpl_file))
  258. {
  259. exit( "SmartTemplate Parser Error: " . $this->parser->error );
  260. }
  261. }
  262. else
  263. {
  264. exit( "SmartTemplate Error: Cannot find class.smarttemplateparser.php; check SmartTemplate installation");
  265. }
  266. }
  267. // Execute Compiled Template
  268. include($this->cpl_file);
  269. }
  270. else
  271. {
  272. exit( "SmartTemplate Error: You must set a template file name");
  273. }
  274. // Delete Global Content Array in order to allow multiple use of SmartTemplate class in one script
  275. unset ($_top);
  276. }
  277. /**
  278. * Debug Template
  279. *
  280. * @access public
  281. * @param array $_top Content Array
  282. * @desc Debug Template
  283. */
  284. function debug ( $_top = '' )
  285. {
  286. // Prepare Template Content
  287. if (!$_top)
  288. {
  289. $_top = $this->data;
  290. }
  291. if (@include_once("class.smarttemplatedebugger.php"))
  292. {
  293. $this->debugger = new SmartTemplateDebugger($this->template_dir . $this->tpl_file);
  294. $this->debugger->start($_top);
  295. }
  296. else
  297. {
  298. exit( "SmartTemplate Error: Cannot find class.smarttemplatedebugger.php; check SmartTemplate installation");
  299. }
  300. }
  301. /**
  302. * Start Ouput Content Buffering
  303. *
  304. * Usage Example:
  305. * $page = new SmartTemplate('template.html');
  306. * $page->use_cache();
  307. * ...
  308. *
  309. * @access public
  310. * @desc Output Cache
  311. */
  312. function use_cache ( $key = '' )
  313. {
  314. if (empty($_POST))
  315. {
  316. $this->cache_filename = $this->cache_dir . 'cache_' . md5($_SERVER['REQUEST_URI'] . serialize($key)) . '.ser';
  317. if (($_SERVER['HTTP_CACHE_CONTROL'] != 'no-cache') && ($_SERVER['HTTP_PRAGMA'] != 'no-cache') && @is_file($this->cache_filename))
  318. {
  319. if ((time() - filemtime($this->cache_filename)) < $this->cache_lifetime)
  320. {
  321. readfile($this->cache_filename);
  322. exit;
  323. }
  324. }
  325. ob_start( array( &$this, 'cache_callback' ) );
  326. }
  327. }
  328. /**
  329. * Output Buffer Callback Function
  330. *
  331. * @access private
  332. * @param string $output
  333. * @return string $output
  334. */
  335. function cache_callback ( $output )
  336. {
  337. if ($hd = @fopen($this->cache_filename, 'w'))
  338. {
  339. fputs($hd, $output);
  340. fclose($hd);
  341. }
  342. return $output;
  343. }
  344. /**
  345. * Determine Last Filechange Date (if File exists)
  346. *
  347. * @access private
  348. * @param string $filename
  349. * @return mixed
  350. * @desc Determine Last Filechange Date
  351. */
  352. function mtime ( $filename )
  353. {
  354. if (@is_file($filename))
  355. {
  356. $ret = filemtime($filename);
  357. return $ret;
  358. }
  359. }
  360. }
  361. ?>