PageRenderTime 26ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/Quản lý website các món ăn và ẩm thực php/bbqvietnam.com/images/banners/msd1.24stable/inc/template.php

https://gitlab.com/phamngsinh/baitaplon_sinhvien
PHP | 484 lines | 266 code | 63 blank | 155 comment | 27 complexity | 3ac94f424f063034b5dc9a9394d8c661 MD5 | raw file
  1. <?php
  2. if (!defined('MSD_VERSION')) die('No direct access.');
  3. define('TPL_DEBUG',0); // used if evaluationg of template fails
  4. /***************************************************************************
  5. * template.php
  6. * -------------------
  7. * begin : Saturday, Feb 13, 2001
  8. * copyright : (C) 2001 The phpBB Group
  9. * email : support@phpbb.com
  10. *
  11. * $Id: template.php,v 1.10.2.3 2002/12/21 19:09:57 psotfx Exp $
  12. *
  13. *
  14. ***************************************************************************/
  15. /***************************************************************************
  16. *
  17. * This program is free software; you can redistribute it and/or modify
  18. * it under the terms of the GNU General Public License as published by
  19. * the Free Software Foundation; either version 2 of the License, or
  20. * (at your option) any later version.
  21. *
  22. ***************************************************************************/
  23. /**
  24. * Template class. By Nathan Codding of the phpBB group.
  25. * The interface was originally inspired by PHPLib templates,
  26. * and the template file formats are quite similar.
  27. *
  28. */
  29. class MSDTemplate
  30. {
  31. var $classname="MSDTemplate";
  32. // variable that holds all the data we'll be substituting into
  33. // the compiled templates.
  34. // ...
  35. // This will end up being a multi-dimensional array like this:
  36. // $this->_tpldata[block.][iteration#][child.][iteration#][child2.][iteration#][variablename] == value
  37. // if it's a root-level variable, it'll be like this:
  38. // $this->_tpldata[.][0][varname] == value
  39. var $_tpldata=array();
  40. // Hash of filenames for each template handle.
  41. var $files=array();
  42. // Root template directory.
  43. var $root="";
  44. // this will hash handle names to the compiled code for that handle.
  45. var $compiled_code=array();
  46. // This will hold the uncompiled code for that handle.
  47. var $uncompiled_code=array();
  48. /**
  49. * Constructor. Simply sets the root dir.
  50. *
  51. */
  52. function MSDTemplate($root=".")
  53. {
  54. $this->set_rootdir($root);
  55. }
  56. /**
  57. * Destroys this template object. Should be called when you're done with it, in order
  58. * to clear out the template data so you can load/parse a new template set.
  59. */
  60. function destroy()
  61. {
  62. $this->_tpldata=array();
  63. }
  64. /**
  65. * Sets the template root directory for this Template object.
  66. */
  67. function set_rootdir($dir)
  68. {
  69. if (!is_dir($dir))
  70. {
  71. return false;
  72. }
  73. $this->root=$dir;
  74. return true;
  75. }
  76. /**
  77. * Sets the template filenames for handles. $filename_array
  78. * should be a hash of handle => filename pairs.
  79. */
  80. function set_filenames($filename_array)
  81. {
  82. if (!is_array($filename_array))
  83. {
  84. return false;
  85. }
  86. reset($filename_array);
  87. while (list ($handle, $filename)=each($filename_array))
  88. {
  89. $this->files[$handle]=$this->make_filename($filename);
  90. }
  91. return true;
  92. }
  93. /**
  94. * Load the file for the handle, compile the file,
  95. * and run the compiled code. This will print out
  96. * the results of executing the template.
  97. */
  98. function pparse($handle)
  99. {
  100. // Edit DSB: autimatically assign language vars
  101. global $lang;
  102. $this->assign_vars($lang);
  103. if (!$this->loadfile($handle))
  104. {
  105. die("Template->pparse(): Couldn't load template file for handle $handle");
  106. }
  107. // actually compile the template now.
  108. if (!isset($this->compiled_code[$handle]) || empty($this->compiled_code[$handle]))
  109. {
  110. // Actually compile the code now.
  111. $this->compiled_code[$handle]=$this->compile($this->uncompiled_code[$handle]);
  112. }
  113. // Run the compiled code.
  114. if (defined(TPL_DEBUG) && TPL_DEBUG>0) echo '<pre>'.htmlspecialchars($this->compiled_code[$handle]).'</pre>';
  115. eval($this->compiled_code[$handle]);
  116. return true;
  117. }
  118. /**
  119. * Inserts the uncompiled code for $handle as the
  120. * value of $varname in the root-level. This can be used
  121. * to effectively include a template in the middle of another
  122. * template.
  123. * Note that all desired assignments to the variables in $handle should be done
  124. * BEFORE calling this function.
  125. */
  126. function assign_var_from_handle($varname, $handle)
  127. {
  128. if (!$this->loadfile($handle))
  129. {
  130. die("Template->assign_var_from_handle(): Couldn't load template file for handle $handle");
  131. }
  132. // Compile it, with the "no echo statements" option on.
  133. $_str="";
  134. $code=$this->compile($this->uncompiled_code[$handle],true,'_str');
  135. // evaluate the variable assignment.
  136. eval($code);
  137. // assign the value of the generated variable to the given varname.
  138. $this->assign_var($varname,$_str);
  139. return true;
  140. }
  141. /**
  142. * Block-level variable assignment. Adds a new block iteration with the given
  143. * variable assignments. Note that this should only be called once per block
  144. * iteration.
  145. */
  146. function assign_block_vars($blockname, $vararray)
  147. {
  148. if (strstr($blockname,'.'))
  149. {
  150. // Nested block.
  151. $blocks=explode('.',$blockname);
  152. $blockcount=sizeof($blocks) - 1;
  153. $str='$this->_tpldata';
  154. for ($i=0; $i < $blockcount; $i++)
  155. {
  156. $str.='[\'' . $blocks[$i] . '.\']';
  157. eval('$lastiteration = sizeof(' . $str . ') - 1;');
  158. $str.='[' . $lastiteration . ']';
  159. }
  160. // Now we add the block that we're actually assigning to.
  161. // We're adding a new iteration to this block with the given
  162. // variable assignments.
  163. $str.='[\'' . $blocks[$blockcount] . '.\'][] = $vararray;';
  164. // Now we evaluate this assignment we've built up.
  165. eval($str);
  166. }
  167. else
  168. {
  169. // Top-level block.
  170. // Add a new iteration to this block with the variable assignments
  171. // we were given.
  172. $this->_tpldata[$blockname . '.'][]=$vararray;
  173. }
  174. return true;
  175. }
  176. /**
  177. * Root-level variable assignment. Adds to current assignments, overriding
  178. * any existing variable assignment with the same name.
  179. */
  180. function assign_vars($vararray)
  181. {
  182. global $lang;
  183. while (list ($key, $val)=each($vararray))
  184. {
  185. $this->_tpldata['.'][0][$key]=$val;
  186. }
  187. return true;
  188. }
  189. /**
  190. * Root-level variable assignment. Adds to current assignments, overriding
  191. * any existing variable assignment with the same name.
  192. */
  193. function assign_var($varname, $varval)
  194. {
  195. $this->_tpldata['.'][0][$varname]=$varval;
  196. return true;
  197. }
  198. /**
  199. * Generates a full path+filename for the given filename, which can either
  200. * be an absolute name, or a name relative to the rootdir for this Template
  201. * object.
  202. */
  203. function make_filename($filename)
  204. {
  205. // Check if it's an absolute or relative path.
  206. /*
  207. if (substr($filename, 0, 1) != '/')
  208. {
  209. $filename = $this->root . '/' . $filename;
  210. }
  211. */
  212. if (!file_exists($filename))
  213. {
  214. die("Template->make_filename(): Error - file $filename does not exist");
  215. }
  216. return $filename;
  217. }
  218. /**
  219. * If not already done, load the file for the given handle and populate
  220. * the uncompiled_code[] hash with its code. Do not compile.
  221. */
  222. function loadfile($handle)
  223. {
  224. // If the file for this handle is already loaded and compiled, do nothing.
  225. if (isset($this->uncompiled_code[$handle]) && !empty($this->uncompiled_code[$handle]))
  226. {
  227. return true;
  228. }
  229. // If we don't have a file assigned to this handle, die.
  230. if (!isset($this->files[$handle]))
  231. {
  232. die("Template->loadfile(): No file specified for handle $handle");
  233. }
  234. $filename=$this->files[$handle];
  235. $str=implode("",@file($filename));
  236. if (empty($str))
  237. {
  238. die("Template->loadfile(): File $filename for handle $handle is empty");
  239. }
  240. $this->uncompiled_code[$handle]=$str;
  241. return true;
  242. }
  243. /**
  244. * Compiles the given string of code, and returns
  245. * the result in a string.
  246. * If "do_not_echo" is true, the returned code will not be directly
  247. * executable, but can be used as part of a variable assignment
  248. * for use in assign_code_from_handle().
  249. */
  250. function compile($code, $do_not_echo=false, $retvar='')
  251. {
  252. // replace \ with \\ and then ' with \'.
  253. $code=str_replace('\\','\\\\',$code);
  254. $code=str_replace('\'','\\\'',$code);
  255. // change template varrefs into PHP varrefs
  256. // This one will handle varrefs WITH namespaces
  257. $varrefs=array();
  258. preg_match_all('#\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}#is',$code,$varrefs);
  259. $varcount=sizeof($varrefs[1]);
  260. for ($i=0; $i < $varcount; $i++)
  261. {
  262. $namespace=$varrefs[1][$i];
  263. $varname=$varrefs[3][$i];
  264. $new=$this->generate_block_varref($namespace,$varname);
  265. $code=str_replace($varrefs[0][$i],$new,$code);
  266. }
  267. // This will handle the remaining root-level varrefs
  268. $code=preg_replace('#\{([a-z0-9\-_]*?)\}#is','\' . ( ( isset($this->_tpldata[\'.\'][0][\'\1\']) ) ? $this->_tpldata[\'.\'][0][\'\1\'] : \'\' ) . \'',$code);
  269. // Break it up into lines.
  270. $code_lines=explode("\n",$code);
  271. $block_nesting_level=0;
  272. $block_names=array();
  273. $block_names[0]=".";
  274. // Second: prepend echo ', append ' . "\n"; to each line.
  275. $line_count=sizeof($code_lines);
  276. for ($i=0; $i < $line_count; $i++)
  277. {
  278. $code_lines[$i]=chop($code_lines[$i]);
  279. if (preg_match('#<!-- BEGIN (.*?) -->#',$code_lines[$i],$m))
  280. {
  281. $n[0]=$m[0];
  282. $n[1]=$m[1];
  283. // Added: dougk_ff7-Keeps templates from bombing if begin is on the same line as end.. I think. :)
  284. if (preg_match('#<!-- END (.*?) -->#',$code_lines[$i],$n))
  285. {
  286. $block_nesting_level++;
  287. $block_names[$block_nesting_level]=$m[1];
  288. if ($block_nesting_level < 2)
  289. {
  290. // Block is not nested.
  291. $code_lines[$i]='$_' . $n[1] . '_count = ( isset($this->_tpldata[\'' . $n[1] . '.\']) ) ? sizeof($this->_tpldata[\'' . $n[1] . '.\']) : 0;';
  292. $code_lines[$i].="\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
  293. $code_lines[$i].="\n" . '{';
  294. }
  295. else
  296. {
  297. // This block is nested.
  298. // Generate a namespace string for this block.
  299. $namespace=implode('.',$block_names);
  300. // strip leading period from root level..
  301. $namespace=substr($namespace,2);
  302. // Get a reference to the data array for this block that depends on the
  303. // current indices of all parent blocks.
  304. $varref=$this->generate_block_data_ref($namespace,false);
  305. // Create the for loop code to iterate over this block.
  306. $code_lines[$i]='$_' . $n[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
  307. $code_lines[$i].="\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
  308. $code_lines[$i].="\n" . '{';
  309. }
  310. // We have the end of a block.
  311. unset($block_names[$block_nesting_level]);
  312. $block_nesting_level--;
  313. $code_lines[$i].='} // END ' . $n[1];
  314. $m[0]=$n[0];
  315. $m[1]=$n[1];
  316. }
  317. else
  318. {
  319. // We have the start of a block.
  320. $block_nesting_level++;
  321. $block_names[$block_nesting_level]=$m[1];
  322. if ($block_nesting_level < 2)
  323. {
  324. // Block is not nested.
  325. $code_lines[$i]='$_' . $m[1] . '_count = ( isset($this->_tpldata[\'' . $m[1] . '.\']) ) ? sizeof($this->_tpldata[\'' . $m[1] . '.\']) : 0;';
  326. $code_lines[$i].="\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
  327. $code_lines[$i].="\n" . '{';
  328. }
  329. else
  330. {
  331. // This block is nested.
  332. // Generate a namespace string for this block.
  333. $namespace=implode('.',$block_names);
  334. // strip leading period from root level..
  335. $namespace=substr($namespace,2);
  336. // Get a reference to the data array for this block that depends on the
  337. // current indices of all parent blocks.
  338. $varref=$this->generate_block_data_ref($namespace,false);
  339. // Create the for loop code to iterate over this block.
  340. $code_lines[$i]='$_' . $m[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
  341. $code_lines[$i].="\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
  342. $code_lines[$i].="\n" . '{';
  343. }
  344. }
  345. }
  346. else if (preg_match('#<!-- END (.*?) -->#',$code_lines[$i],$m))
  347. {
  348. // We have the end of a block.
  349. unset($block_names[$block_nesting_level]);
  350. $block_nesting_level--;
  351. $code_lines[$i]='} // END ' . $m[1];
  352. }
  353. else
  354. {
  355. // We have an ordinary line of code.
  356. if (!$do_not_echo)
  357. {
  358. $code_lines[$i]='echo \'' . $code_lines[$i] . '\' . "\\n";';
  359. }
  360. else
  361. {
  362. $code_lines[$i]='$' . $retvar . '.= \'' . $code_lines[$i] . '\' . "\\n";';
  363. }
  364. }
  365. }
  366. // Bring it back into a single string of lines of code.
  367. $code=implode("\n",$code_lines);
  368. return $code;
  369. }
  370. /**
  371. * Generates a reference to the given variable inside the given (possibly nested)
  372. * block namespace. This is a string of the form:
  373. * ' . $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['varname'] . '
  374. * It's ready to be inserted into an "echo" line in one of the templates.
  375. * NOTE: expects a trailing "." on the namespace.
  376. */
  377. function generate_block_varref($namespace, $varname)
  378. {
  379. // Strip the trailing period.
  380. $namespace=substr($namespace,0,strlen($namespace) - 1);
  381. // Get a reference to the data block for this namespace.
  382. $varref=$this->generate_block_data_ref($namespace,true);
  383. // Prepend the necessary code to stick this in an echo line.
  384. // Append the variable reference.
  385. $varref.='[\'' . $varname . '\']';
  386. $varref='\' . ( ( isset(' . $varref . ') ) ? ' . $varref . ' : \'\' ) . \'';
  387. return $varref;
  388. }
  389. /**
  390. * Generates a reference to the array of data values for the given
  391. * (possibly nested) block namespace. This is a string of the form:
  392. * $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['$childN']
  393. *
  394. * If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above.
  395. * NOTE: does not expect a trailing "." on the blockname.
  396. */
  397. function generate_block_data_ref($blockname, $include_last_iterator)
  398. {
  399. // Get an array of the blocks involved.
  400. $blocks=explode(".",$blockname);
  401. $blockcount=sizeof($blocks) - 1;
  402. $varref='$this->_tpldata';
  403. // Build up the string with everything but the last child.
  404. for ($i=0; $i < $blockcount; $i++)
  405. {
  406. $varref.='[\'' . $blocks[$i] . '.\'][$_' . $blocks[$i] . '_i]';
  407. }
  408. // Add the block reference for the last child.
  409. $varref.='[\'' . $blocks[$blockcount] . '.\']';
  410. // Add the iterator for the last child if requried.
  411. if ($include_last_iterator)
  412. {
  413. $varref.='[$_' . $blocks[$blockcount] . '_i]';
  414. }
  415. return $varref;
  416. }
  417. }
  418. ?>