PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/core/web/includes/template.inc.php

https://github.com/vmasilva/mmc
PHP | 989 lines | 592 code | 44 blank | 353 comment | 55 complexity | 12a1e860b99277071c2732e6e1cce518 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * (c) 2004-2007 Linbox / Free&ALter Soft, http://linbox.com
  4. * (c) 2007-2008 Mandriva, http://www.mandriva.com
  5. *
  6. * $Id$
  7. *
  8. * This file is part of Mandriva Management Console (MMC).
  9. *
  10. * MMC is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * MMC is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with MMC; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  23. */
  24. ?>
  25. <?php
  26. /*
  27. * Session Management for PHP3
  28. *
  29. * (C) Copyright 1999-2000 NetUSE GmbH
  30. * Kristian Koehntopp
  31. *
  32. * $Id$
  33. *
  34. */
  35. /*
  36. * Change log since version 7.2c
  37. *
  38. * Bug fixes to version 7.2c compiled by Richard Archer <rha@juggernaut.com.au>:
  39. * (credits given to first person to post a diff to phplib mailing list)
  40. *
  41. * Normalised all comments and whitespace (rha)
  42. * replaced "$handle" with "$varname" and "$h" with "$v" throughout (from phplib-devel)
  43. * added braces around all one-line if statements in: get_undefined, loadfile and halt (rha)
  44. * set_var was missing two sets of braces (rha)
  45. * added a couple of "return true" statements (rha)
  46. * set_unknowns had "keep" as default instead of "remove" (from phplib-devel)
  47. * set_file failed to check for empty strings if passed an array of filenames (phplib-devel)
  48. * remove @ from call to preg_replace in subst -- report errors if there are any (NickM)
  49. * set_block unnecessarily required a newline in the template file (Marc Tardif)
  50. * pparse now calls this->finish to replace undefined vars (Layne Weathers)
  51. * get_var now checks for unset varnames (NickM & rha)
  52. * get_var when passed an array used the array key instead of the value (rha)
  53. * get_vars now uses a call to get_var rather than this->varvals to prevent undefined var warning (rha)
  54. * in finish, the replacement string referenced an unset variable (rha)
  55. * loadfile would try to load a file if the varval had been set to "" (rha)
  56. * in get_undefined, only match non-whitespace in variable tags as in finish (Layne Weathers & rha)
  57. * more elegant fix to the problem of subst stripping '$n', '\n' and '\\' strings (rha)
  58. *
  59. *
  60. * Changes in functionality which go beyond bug fixes:
  61. *
  62. * changed debug handling so set, get and internals can be tracked separately (rha)
  63. * added debug statements throughout to track most function calls (rha)
  64. * debug output contained raw HTML -- is now escaped with htmlentities (rha)
  65. * Alter regex in set_block to remove more whitespace around BEGIN/END tags to improve HTML layout (rha)
  66. * Add "append" option to set_var, works just like append in parse (dale at linuxwebpro.com, rha)
  67. * Altered parse so that append is honored if passed an array (Brian)
  68. * Converted comments and documentation to phpdoc style (rha)
  69. * Added clear_var to set the value of variables to "" (rha)
  70. * Added unset_var to usset variables (rha)
  71. *
  72. */
  73. /**
  74. * The template class allows you to keep your HTML code in some external files
  75. * which are completely free of PHP code, but contain replacement fields.
  76. * The class provides you with functions which can fill in the replacement fields
  77. * with arbitrary strings. These strings can become very large, e.g. entire tables.
  78. *
  79. * Note: If you think that this is like FastTemplates, read carefully. It isn't.
  80. *
  81. */
  82. class Template
  83. {
  84. /**
  85. * Serialization helper, the name of this class.
  86. *
  87. * @var string
  88. * @access public
  89. */
  90. var $classname = "Template";
  91. /**
  92. * Determines how much debugging output Template will produce.
  93. * This is a bitwise mask of available debug levels:
  94. * 0 = no debugging
  95. * 1 = debug variable assignments
  96. * 2 = debug calls to get variable
  97. * 4 = debug internals (outputs all function calls with parameters).
  98. *
  99. * Note: setting $this->debug = true will enable debugging of variable
  100. * assignments only which is the same behaviour as versions up to release 7.2d.
  101. *
  102. * @var int
  103. * @access public
  104. */
  105. var $debug = false;
  106. /**
  107. * The base directory from which template files are loaded.
  108. *
  109. * @var string
  110. * @access private
  111. * @see set_root
  112. */
  113. var $root = ".";
  114. /**
  115. * A hash of strings forming a translation table which translates variable names
  116. * into names of files containing the variable content.
  117. * $file[varname] = "filename";
  118. *
  119. * @var array
  120. * @access private
  121. * @see set_file
  122. */
  123. var $file = array();
  124. /**
  125. * A hash of strings forming a translation table which translates variable names
  126. * into regular expressions for themselves.
  127. * $varkeys[varname] = "/varname/"
  128. *
  129. * @var array
  130. * @access private
  131. * @see set_var
  132. */
  133. var $varkeys = array();
  134. /**
  135. * A hash of strings forming a translation table which translates variable names
  136. * into values for their respective varkeys.
  137. * $varvals[varname] = "value"
  138. *
  139. * @var array
  140. * @access private
  141. * @see set_var
  142. */
  143. var $varvals = array();
  144. /**
  145. * Determines how to output variable tags with no assigned value in templates.
  146. *
  147. * @var string
  148. * @access private
  149. * @see set_unknowns
  150. */
  151. var $unknowns = "remove";
  152. /**
  153. * Determines how Template handles error conditions.
  154. * "yes" = the error is reported, then execution is halted
  155. * "report" = the error is reported, then execution continues by returning "false"
  156. * "no" = errors are silently ignored, and execution resumes reporting "false"
  157. *
  158. * @var string
  159. * @access public
  160. * @see halt
  161. */
  162. var $halt_on_error = "yes";
  163. /**
  164. * The last error message is retained in this variable.
  165. *
  166. * @var string
  167. * @access public
  168. * @see halt
  169. */
  170. var $last_error = "";
  171. /******************************************************************************
  172. * Class constructor. May be called with two optional parameters.
  173. * The first parameter sets the template directory the second parameter
  174. * sets the policy regarding handling of unknown variables.
  175. *
  176. * usage: Template([string $root = "."], [string $unknowns = "remove"])
  177. *
  178. * @param $root path to template directory
  179. * @param $string what to do with undefined variables
  180. * @see set_root
  181. * @see set_unknowns
  182. * @access public
  183. * @return void
  184. */
  185. function Template($root = ".", $unknowns = "remove") {
  186. if ($this->debug & 4) {
  187. echo "<p><b>Template:</b> root = $root, unknowns = $unknowns</p>\n";
  188. }
  189. $this->set_root($root);
  190. $this->set_unknowns($unknowns);
  191. }
  192. /******************************************************************************
  193. * Checks that $root is a valid directory and if so sets this directory as the
  194. * base directory from which templates are loaded by storing the value in
  195. * $this->root. Relative filenames are prepended with the path in $this->root.
  196. *
  197. * Returns true on success, false on error.
  198. *
  199. * usage: set_root(string $root)
  200. *
  201. * @param $root string containing new template directory
  202. * @see root
  203. * @access public
  204. * @return boolean
  205. */
  206. function set_root($root) {
  207. if ($this->debug & 4) {
  208. echo "<p><b>set_root:</b> root = $root</p>\n";
  209. }
  210. if (!is_dir($root)) {
  211. $this->halt("set_root: $root is not a directory.");
  212. return false;
  213. }
  214. $this->root = $root;
  215. return true;
  216. }
  217. /******************************************************************************
  218. * Sets the policy for dealing with unresolved variable names.
  219. *
  220. * unknowns defines what to do with undefined template variables
  221. * "remove" = remove undefined variables
  222. * "comment" = replace undefined variables with comments
  223. * "keep" = keep undefined variables
  224. *
  225. * Note: "comment" can cause unexpected results when the variable tag is embedded
  226. * inside an HTML tag, for example a tag which is expected to be replaced with a URL.
  227. *
  228. * usage: set_unknowns(string $unknowns)
  229. *
  230. * @param $unknowns new value for unknowns
  231. * @see unknowns
  232. * @access public
  233. * @return void
  234. */
  235. function set_unknowns($unknowns = "remove") {
  236. if ($this->debug & 4) {
  237. echo "<p><b>unknowns:</b> unknowns = $unknowns</p>\n";
  238. }
  239. $this->unknowns = $unknowns;
  240. }
  241. /******************************************************************************
  242. * Defines a filename for the initial value of a variable.
  243. *
  244. * It may be passed either a varname and a file name as two strings or
  245. * a hash of strings with the key being the varname and the value
  246. * being the file name.
  247. *
  248. * The new mappings are stored in the array $this->file.
  249. * The files are not loaded yet, but only when needed.
  250. *
  251. * Returns true on success, false on error.
  252. *
  253. * usage: set_file(array $filelist = (string $varname => string $filename))
  254. * or
  255. * usage: set_file(string $varname, string $filename)
  256. *
  257. * @param $varname either a string containing a varname or a hash of varname/file name pairs.
  258. * @param $filename if varname is a string this is the filename otherwise filename is not required
  259. * @access public
  260. * @return boolean
  261. */
  262. function set_file($varname, $filename = "") {
  263. if (!is_array($varname)) {
  264. if ($this->debug & 4) {
  265. echo "<p><b>set_file:</b> (with scalar) varname = $varname, filename = $filename</p>\n";
  266. }
  267. if ($filename == "") {
  268. $this->halt("set_file: For varname $varname filename is empty.");
  269. return false;
  270. }
  271. $this->file[$varname] = $this->filename($filename);
  272. } else {
  273. reset($varname);
  274. while(list($v, $f) = each($varname)) {
  275. if ($this->debug & 4) {
  276. echo "<p><b>set_file:</b> (with array) varname = $v, filename = $f</p>\n";
  277. }
  278. if ($f == "") {
  279. $this->halt("set_file: For varname $v filename is empty.");
  280. return false;
  281. }
  282. $this->file[$v] = $this->filename($f);
  283. }
  284. }
  285. return true;
  286. }
  287. /******************************************************************************
  288. * A variable $parent may contain a variable block defined by:
  289. * &lt;!-- BEGIN $varname --&gt; content &lt;!-- END $varname --&gt;. This function removes
  290. * that block from $parent and replaces it with a variable reference named $name.
  291. * The block is inserted into the varkeys and varvals hashes. If $name is
  292. * omitted, it is assumed to be the same as $varname.
  293. *
  294. * Blocks may be nested but care must be taken to extract the blocks in order
  295. * from the innermost block to the outermost block.
  296. *
  297. * Returns true on success, false on error.
  298. *
  299. * usage: set_block(string $parent, string $varname, [string $name = ""])
  300. *
  301. * @param $parent a string containing the name of the parent variable
  302. * @param $varname a string containing the name of the block to be extracted
  303. * @param $name the name of the variable in which to store the block
  304. * @access public
  305. * @return boolean
  306. */
  307. function set_block($parent, $varname, $name = "") {
  308. if ($this->debug & 4) {
  309. echo "<p><b>set_block:</b> parent = $parent, varname = $varname, name = $name</p>\n";
  310. }
  311. if (!$this->loadfile($parent)) {
  312. $this->halt("set_block: unable to load $parent.");
  313. return false;
  314. }
  315. if ($name == "") {
  316. $name = $varname;
  317. }
  318. $str = $this->get_var($parent);
  319. $reg = "/[ \t]*<!--\s+BEGIN $varname\s+-->\s*?\n?(\s*.*?\n?)\s*<!--\s+END $varname\s+-->\s*?\n?/sm";
  320. preg_match_all($reg, $str, $m);
  321. $str = preg_replace($reg, "{" . "$name}", $str);
  322. $this->set_var($varname, $m[1][0]);
  323. $this->set_var($parent, $str);
  324. return true;
  325. }
  326. /******************************************************************************
  327. * This functions sets the value of a variable.
  328. *
  329. * It may be called with either a varname and a value as two strings or an
  330. * an associative array with the key being the varname and the value being
  331. * the new variable value.
  332. *
  333. * The function inserts the new value of the variable into the $varkeys and
  334. * $varvals hashes. It is not necessary for a variable to exist in these hashes
  335. * before calling this function.
  336. *
  337. * An optional third parameter allows the value for each varname to be appended
  338. * to the existing variable instead of replacing it. The default is to replace.
  339. * This feature was introduced after the 7.2d release.
  340. *
  341. *
  342. * usage: set_var(string $varname, [string $value = ""], [boolean $append = false])
  343. * or
  344. * usage: set_var(array $varname = (string $varname => string $value), [mixed $dummy_var], [boolean $append = false])
  345. *
  346. * @param $varname either a string containing a varname or a hash of varname/value pairs.
  347. * @param $value if $varname is a string this contains the new value for the variable otherwise this parameter is ignored
  348. * @param $append if true, the value is appended to the variable's existing value
  349. * @access public
  350. * @return void
  351. */
  352. function set_var($varname, $value = "", $append = false) {
  353. if (!is_array($varname)) {
  354. if (!empty($varname)) {
  355. if ($this->debug & 1) {
  356. printf("<b>set_var:</b> (with scalar) <b>%s</b> = '%s'<br>\n", $varname, htmlentities($value));
  357. }
  358. $this->varkeys[$varname] = "/".$this->varname($varname)."/";
  359. if ($append && isset($this->varvals[$varname])) {
  360. $this->varvals[$varname] .= $value;
  361. } else {
  362. $this->varvals[$varname] = $value;
  363. }
  364. }
  365. } else {
  366. reset($varname);
  367. while(list($k, $v) = each($varname)) {
  368. if (!empty($k)) {
  369. if ($this->debug & 1) {
  370. printf("<b>set_var:</b> (with array) <b>%s</b> = '%s'<br>\n", $k, htmlentities($v));
  371. }
  372. $this->varkeys[$k] = "/".$this->varname($k)."/";
  373. if ($append && isset($this->varvals[$k])) {
  374. $this->varvals[$k] .= $v;
  375. } else {
  376. $this->varvals[$k] = $v;
  377. }
  378. }
  379. }
  380. }
  381. }
  382. /******************************************************************************
  383. * This functions clears the value of a variable.
  384. *
  385. * It may be called with either a varname as a string or an array with the
  386. * values being the varnames to be cleared.
  387. *
  388. * The function sets the value of the variable in the $varkeys and $varvals
  389. * hashes to "". It is not necessary for a variable to exist in these hashes
  390. * before calling this function.
  391. *
  392. *
  393. * usage: clear_var(string $varname)
  394. * or
  395. * usage: clear_var(array $varname = (string $varname))
  396. *
  397. * @param $varname either a string containing a varname or an array of varnames.
  398. * @access public
  399. * @return void
  400. */
  401. function clear_var($varname) {
  402. if (!is_array($varname)) {
  403. if (!empty($varname)) {
  404. if ($this->debug & 1) {
  405. printf("<b>clear_var:</b> (with scalar) <b>%s</b><br>\n", $varname);
  406. }
  407. $this->set_var($varname, "");
  408. }
  409. } else {
  410. reset($varname);
  411. while(list($k, $v) = each($varname)) {
  412. if (!empty($v)) {
  413. if ($this->debug & 1) {
  414. printf("<b>clear_var:</b> (with array) <b>%s</b><br>\n", $v);
  415. }
  416. $this->set_var($v, "");
  417. }
  418. }
  419. }
  420. }
  421. /******************************************************************************
  422. * This functions unsets a variable completely.
  423. *
  424. * It may be called with either a varname as a string or an array with the
  425. * values being the varnames to be cleared.
  426. *
  427. * The function removes the variable from the $varkeys and $varvals hashes.
  428. * It is not necessary for a variable to exist in these hashes before calling
  429. * this function.
  430. *
  431. *
  432. * usage: unset_var(string $varname)
  433. * or
  434. * usage: unset_var(array $varname = (string $varname))
  435. *
  436. * @param $varname either a string containing a varname or an array of varnames.
  437. * @access public
  438. * @return void
  439. */
  440. function unset_var($varname) {
  441. if (!is_array($varname)) {
  442. if (!empty($varname)) {
  443. if ($this->debug & 1) {
  444. printf("<b>unset_var:</b> (with scalar) <b>%s</b><br>\n", $varname);
  445. }
  446. unset($this->varkeys[$varname]);
  447. unset($this->varvals[$varname]);
  448. }
  449. } else {
  450. reset($varname);
  451. while(list($k, $v) = each($varname)) {
  452. if (!empty($v)) {
  453. if ($this->debug & 1) {
  454. printf("<b>unset_var:</b> (with array) <b>%s</b><br>\n", $v);
  455. }
  456. unset($this->varkeys[$v]);
  457. unset($this->varvals[$v]);
  458. }
  459. }
  460. }
  461. }
  462. /******************************************************************************
  463. * This function fills in all the variables contained within the variable named
  464. * $varname. The resulting value is returned as the function result and the
  465. * original value of the variable varname is not changed. The resulting string
  466. * is not "finished", that is, the unresolved variable name policy has not been
  467. * applied yet.
  468. *
  469. * Returns: the value of the variable $varname with all variables substituted.
  470. *
  471. * usage: subst(string $varname)
  472. *
  473. * @param $varname the name of the variable within which variables are to be substituted
  474. * @access public
  475. * @return string
  476. */
  477. function subst($varname) {
  478. $varvals_quoted = array();
  479. if ($this->debug & 4) {
  480. echo "<p><b>subst:</b> varname = $varname</p>\n";
  481. }
  482. if (!$this->loadfile($varname)) {
  483. $this->halt("subst: unable to load $varname.");
  484. return false;
  485. }
  486. // quote the replacement strings to prevent bogus stripping of special chars
  487. reset($this->varvals);
  488. while(list($k, $v) = each($this->varvals)) {
  489. $varvals_quoted[$k] = preg_replace(array('/\\\\/', '/\$/'), array('\\\\\\\\', '\\\\$'), $v);
  490. }
  491. $str = $this->get_var($varname);
  492. $str = preg_replace($this->varkeys, $varvals_quoted, $str);
  493. return $str;
  494. }
  495. /******************************************************************************
  496. * This is shorthand for print $this->subst($varname). See subst for further
  497. * details.
  498. *
  499. * Returns: always returns false.
  500. *
  501. * usage: psubst(string $varname)
  502. *
  503. * @param $varname the name of the variable within which variables are to be substituted
  504. * @access public
  505. * @return false
  506. * @see subst
  507. */
  508. function psubst($varname) {
  509. if ($this->debug & 4) {
  510. echo "<p><b>psubst:</b> varname = $varname</p>\n";
  511. }
  512. print $this->subst($varname);
  513. return false;
  514. }
  515. /******************************************************************************
  516. * The function substitutes the values of all defined variables in the variable
  517. * named $varname and stores or appends the result in the variable named $target.
  518. *
  519. * It may be called with either a target and a varname as two strings or a
  520. * target as a string and an array of variable names in varname.
  521. *
  522. * The function inserts the new value of the variable into the $varkeys and
  523. * $varvals hashes. It is not necessary for a variable to exist in these hashes
  524. * before calling this function.
  525. *
  526. * An optional third parameter allows the value for each varname to be appended
  527. * to the existing target variable instead of replacing it. The default is to
  528. * replace.
  529. *
  530. * If $target and $varname are both strings, the substituted value of the
  531. * variable $varname is inserted into or appended to $target.
  532. *
  533. * If $handle is an array of variable names the variables named by $handle are
  534. * sequentially substituted and the result of each substitution step is
  535. * inserted into or appended to in $target. The resulting substitution is
  536. * available in the variable named by $target, as is each intermediate step
  537. * for the next $varname in sequence. Note that while it is possible, it
  538. * is only rarely desirable to call this function with an array of varnames
  539. * and with $append = true. This append feature was introduced after the 7.2d
  540. * release.
  541. *
  542. * Returns: the last value assigned to $target.
  543. *
  544. * usage: parse(string $target, string $varname, [boolean $append])
  545. * or
  546. * usage: parse(string $target, array $varname = (string $varname), [boolean $append])
  547. *
  548. * @param $target a string containing the name of the variable into which substituted $varnames are to be stored
  549. * @param $varname if a string, the name the name of the variable to substitute or if an array a list of variables to be substituted
  550. * @param $append if true, the substituted variables are appended to $target otherwise the existing value of $target is replaced
  551. * @access public
  552. * @return string
  553. * @see subst
  554. */
  555. function parse($target, $varname, $append = false) {
  556. if (!is_array($varname)) {
  557. if ($this->debug & 4) {
  558. echo "<p><b>parse:</b> (with scalar) target = $target, varname = $varname, append = $append</p>\n";
  559. }
  560. $str = $this->subst($varname);
  561. if ($append) {
  562. $this->set_var($target, $this->get_var($target) . $str);
  563. } else {
  564. $this->set_var($target, $str);
  565. }
  566. } else {
  567. reset($varname);
  568. while(list($i, $v) = each($varname)) {
  569. if ($this->debug & 4) {
  570. echo "<p><b>parse:</b> (with array) target = $target, i = $i, varname = $v, append = $append</p>\n";
  571. }
  572. $str = $this->subst($v);
  573. if ($append) {
  574. $this->set_var($target, $this->get_var($target) . $str);
  575. } else {
  576. $this->set_var($target, $str);
  577. }
  578. }
  579. }
  580. if ($this->debug & 4) {
  581. echo "<p><b>parse:</b> completed</p>\n";
  582. }
  583. return $str;
  584. }
  585. /******************************************************************************
  586. * This is shorthand for print $this->parse(...) and is functionally identical.
  587. * See parse for further details.
  588. *
  589. * Returns: always returns false.
  590. *
  591. * usage: pparse(string $target, string $varname, [boolean $append])
  592. * or
  593. * usage: pparse(string $target, array $varname = (string $varname), [boolean $append])
  594. *
  595. * @param $target a string containing the name of the variable into which substituted $varnames are to be stored
  596. * @param $varname if a string, the name the name of the variable to substitute or if an array a list of variables to be substituted
  597. * @param $append if true, the substituted variables are appended to $target otherwise the existing value of $target is replaced
  598. * @access public
  599. * @return false
  600. * @see parse
  601. */
  602. function pparse($target, $varname, $append = false) {
  603. if ($this->debug & 4) {
  604. echo "<p><b>pparse:</b> passing parameters to parse...</p>\n";
  605. }
  606. print $this->finish($this->parse($target, $varname, $append));
  607. return false;
  608. }
  609. /******************************************************************************
  610. * This function returns an associative array of all defined variables with the
  611. * name as the key and the value of the variable as the value.
  612. *
  613. * This is mostly useful for debugging. Also note that $this->debug can be used
  614. * to echo all variable assignments as they occur and to trace execution.
  615. *
  616. * Returns: a hash of all defined variable values keyed by their names.
  617. *
  618. * usage: get_vars()
  619. *
  620. * @access public
  621. * @return array
  622. * @see $debug
  623. */
  624. function get_vars() {
  625. if ($this->debug & 4) {
  626. echo "<p><b>get_vars:</b> constructing array of vars...</p>\n";
  627. }
  628. reset($this->varkeys);
  629. while(list($k, $v) = each($this->varkeys)) {
  630. $result[$k] = $this->get_var($k);
  631. }
  632. return $result;
  633. }
  634. /******************************************************************************
  635. * This function returns the value of the variable named by $varname.
  636. * If $varname references a file and that file has not been loaded yet, the
  637. * variable will be reported as empty.
  638. *
  639. * When called with an array of variable names this function will return a a
  640. * hash of variable values keyed by their names.
  641. *
  642. * Returns: a string or an array containing the value of $varname.
  643. *
  644. * usage: get_var(string $varname)
  645. * or
  646. * usage: get_var(array $varname)
  647. *
  648. * @param $varname if a string, the name the name of the variable to get the value of, or if an array a list of variables to return the value of
  649. * @access public
  650. * @return string or array
  651. */
  652. function get_var($varname) {
  653. if (!is_array($varname)) {
  654. if (isset($this->varvals[$varname])) {
  655. $str = $this->varvals[$varname];
  656. } else {
  657. $str = "";
  658. }
  659. if ($this->debug & 2) {
  660. printf ("<b>get_var</b> (with scalar) <b>%s</b> = '%s'<br>\n", $varname, htmlentities($str));
  661. }
  662. return $str;
  663. } else {
  664. reset($varname);
  665. while(list($k, $v) = each($varname)) {
  666. if (isset($this->varvals[$v])) {
  667. $str = $this->varvals[$v];
  668. } else {
  669. $str = "";
  670. }
  671. if ($this->debug & 2) {
  672. printf ("<b>get_var:</b> (with array) <b>%s</b> = '%s'<br>\n", $v, htmlentities($str));
  673. }
  674. $result[$v] = $str;
  675. }
  676. return $result;
  677. }
  678. }
  679. /******************************************************************************
  680. * This function returns a hash of unresolved variable names in $varname, keyed
  681. * by their names (that is, the hash has the form $a[$name] = $name).
  682. *
  683. * Returns: a hash of varname/varname pairs or false on error.
  684. *
  685. * usage: get_undefined(string $varname)
  686. *
  687. * @param $varname a string containing the name the name of the variable to scan for unresolved variables
  688. * @access public
  689. * @return array
  690. */
  691. function get_undefined($varname) {
  692. if ($this->debug & 4) {
  693. echo "<p><b>get_undefined:</b> varname = $varname</p>\n";
  694. }
  695. if (!$this->loadfile($varname)) {
  696. $this->halt("get_undefined: unable to load $varname.");
  697. return false;
  698. }
  699. preg_match_all("/{([^ \t\r\n}]+)}/", $this->get_var($varname), $m);
  700. $m = $m[1];
  701. if (!is_array($m)) {
  702. return false;
  703. }
  704. reset($m);
  705. while(list($k, $v) = each($m)) {
  706. if (!isset($this->varkeys[$v])) {
  707. if ($this->debug & 4) {
  708. echo "<p><b>get_undefined:</b> undefined: $v</p>\n";
  709. }
  710. $result[$v] = $v;
  711. }
  712. }
  713. if (count($result)) {
  714. return $result;
  715. } else {
  716. return false;
  717. }
  718. }
  719. /******************************************************************************
  720. * This function returns the finished version of $str. That is, the policy
  721. * regarding unresolved variable names will be applied to $str.
  722. *
  723. * Returns: a finished string derived from $str and $this->unknowns.
  724. *
  725. * usage: finish(string $str)
  726. *
  727. * @param $str a string to which to apply the unresolved variable policy
  728. * @access public
  729. * @return string
  730. * @see set_unknowns
  731. */
  732. function finish($str) {
  733. switch ($this->unknowns) {
  734. case "keep":
  735. break;
  736. case "remove":
  737. $str = preg_replace('/{[^ \t\r\n}]+}/', "", $str);
  738. break;
  739. case "comment":
  740. $str = preg_replace('/{([^ \t\r\n}]+)}/', "<!-- Template variable \\1 undefined -->", $str);
  741. break;
  742. }
  743. return $str;
  744. }
  745. /******************************************************************************
  746. * This function prints the finished version of the value of the variable named
  747. * by $varname. That is, the policy regarding unresolved variable names will be
  748. * applied to the variable $varname then it will be printed.
  749. *
  750. * usage: p(string $varname)
  751. *
  752. * @param $varname a string containing the name of the variable to finish and print
  753. * @access public
  754. * @return void
  755. * @see set_unknowns
  756. * @see finish
  757. */
  758. function p($varname) {
  759. print $this->finish($this->get_var($varname));
  760. }
  761. /******************************************************************************
  762. * This function returns the finished version of the value of the variable named
  763. * by $varname. That is, the policy regarding unresolved variable names will be
  764. * applied to the variable $varname and the result returned.
  765. *
  766. * Returns: a finished string derived from the variable $varname.
  767. *
  768. * usage: get(string $varname)
  769. *
  770. * @param $varname a string containing the name of the variable to finish
  771. * @access public
  772. * @return void
  773. * @see set_unknowns
  774. * @see finish
  775. */
  776. function get($varname) {
  777. return $this->finish($this->get_var($varname));
  778. }
  779. /******************************************************************************
  780. * When called with a relative pathname, this function will return the pathname
  781. * with $this->root prepended. Absolute pathnames are returned unchanged.
  782. *
  783. * Returns: a string containing an absolute pathname.
  784. *
  785. * usage: filename(string $filename)
  786. *
  787. * @param $filename a string containing a filename
  788. * @access private
  789. * @return string
  790. * @see set_root
  791. */
  792. function filename($filename) {
  793. if ($this->debug & 4) {
  794. echo "<p><b>filename:</b> filename = $filename</p>\n";
  795. }
  796. if (substr($filename, 0, 1) != "/") {
  797. $filename = $this->root."/".$filename;
  798. }
  799. if (!file_exists($filename)) {
  800. $this->halt("filename: file $filename does not exist.");
  801. }
  802. return $filename;
  803. }
  804. /******************************************************************************
  805. * This function will construct a regexp for a given variable name with any
  806. * special chars quoted.
  807. *
  808. * Returns: a string containing an escaped variable name.
  809. *
  810. * usage: varname(string $varname)
  811. *
  812. * @param $varname a string containing a variable name
  813. * @access private
  814. * @return string
  815. */
  816. function varname($varname) {
  817. return preg_quote("{".$varname."}");
  818. }
  819. /******************************************************************************
  820. * If a variable's value is undefined and the variable has a filename stored in
  821. * $this->file[$varname] then the backing file will be loaded and the file's
  822. * contents will be assigned as the variable's value.
  823. *
  824. * Note that the behaviour of this function changed slightly after the 7.2d
  825. * release. Where previously a variable was reloaded from file if the value
  826. * was empty, now this is not done. This allows a variable to be loaded then
  827. * set to "", and also prevents attempts to load empty variables. Files are
  828. * now only loaded if $this->varvals[$varname] is unset.
  829. *
  830. * Returns: true on success, false on error.
  831. *
  832. * usage: loadfile(string $varname)
  833. *
  834. * @param $varname a string containing the name of a variable to load
  835. * @access private
  836. * @return boolean
  837. * @see set_file
  838. */
  839. function loadfile($varname) {
  840. if ($this->debug & 4) {
  841. echo "<p><b>loadfile:</b> varname = $varname</p>\n";
  842. }
  843. if (!isset($this->file[$varname])) {
  844. // $varname does not reference a file so return
  845. if ($this->debug & 4) {
  846. echo "<p><b>loadfile:</b> varname $varname does not reference a file</p>\n";
  847. }
  848. return true;
  849. }
  850. if (isset($this->varvals[$varname])) {
  851. // will only be unset if varname was created with set_file and has never been loaded
  852. // $varname has already been loaded so return
  853. if ($this->debug & 4) {
  854. echo "<p><b>loadfile:</b> varname $varname is already loaded</p>\n";
  855. }
  856. return true;
  857. }
  858. $filename = $this->file[$varname];
  859. /* use @file here to avoid leaking filesystem information if there is an error */
  860. $str = implode("", @file($filename));
  861. if (empty($str)) {
  862. $this->halt("loadfile: While loading $varname, $filename does not exist or is empty.");
  863. return false;
  864. }
  865. if ($this->debug & 4) {
  866. printf("<b>loadfile:</b> loaded $filename into $varname<br>\n");
  867. }
  868. $this->set_var($varname, $str);
  869. return true;
  870. }
  871. /******************************************************************************
  872. * This function is called whenever an error occurs and will handle the error
  873. * according to the policy defined in $this->halt_on_error. Additionally the
  874. * error message will be saved in $this->last_error.
  875. *
  876. * Returns: always returns false.
  877. *
  878. * usage: halt(string $msg)
  879. *
  880. * @param $msg a string containing an error message
  881. * @access private
  882. * @return void
  883. * @see $halt_on_error
  884. */
  885. function halt($msg) {
  886. $this->last_error = $msg;
  887. if ($this->halt_on_error != "no") {
  888. $this->haltmsg($msg);
  889. }
  890. if ($this->halt_on_error == "yes") {
  891. die("<b>Halted.</b>");
  892. }
  893. return false;
  894. }
  895. /******************************************************************************
  896. * This function prints an error message.
  897. * It can be overridden by your subclass of Template. It will be called with an
  898. * error message to display.
  899. *
  900. * usage: haltmsg(string $msg)
  901. *
  902. * @param $msg a string containing the error message to display
  903. * @access public
  904. * @return void
  905. * @see halt
  906. */
  907. function haltmsg($msg) {
  908. printf("<b>Template Error:</b> %s<br>\n", $msg);
  909. }
  910. }
  911. ?>