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

/src/lib/HTML/Template/ITX.php

https://github.com/clayhinson/sgl2
PHP | 883 lines | 384 code | 92 blank | 407 comment | 72 complexity | 4c4742f7fb3431ed5c0975d8fd04921b MD5 | raw file
  1. <?php
  2. /**
  3. * Integrated Template - IT
  4. *
  5. * PHP version 4
  6. *
  7. * Copyright (c) 1997-2007 Ulf Wendel, Pierre-Alain Joye,
  8. * David Soria Parra
  9. *
  10. * This source file is subject to the New BSD license, That is bundled
  11. * with this package in the file LICENSE, and is available through
  12. * the world-wide-web at
  13. * http://www.opensource.org/licenses/bsd-license.php
  14. * If you did not receive a copy of the new BSDlicense and are unable
  15. * to obtain it through the world-wide-web, please send a note to
  16. * pajoye@php.net so we can mail you a copy immediately.
  17. *
  18. * Author: Ulf Wendel <ulf.wendel@phpdoc.de>
  19. * Pierre-Alain Joye <pajoye@php.net>
  20. * David Soria Parra <dsp@php.net>
  21. *
  22. * @category HTML
  23. * @package HTML_Template_IT
  24. * @author Ulf Wendel <uw@netuse.de>
  25. * @license BSD http://www.opensource.org/licenses/bsd-license.php
  26. * @version CVS: $Id: ITX.php,v 1.19 2008/11/14 23:57:17 kguest Exp $
  27. * @link http://pear.php.net/packages/HTML_Template_IT
  28. * @access public
  29. */
  30. require_once 'HTML/Template/IT.php';
  31. require_once 'HTML/Template/IT_Error.php';
  32. /**
  33. * Integrated Template Extension - ITX
  34. *
  35. * With this class you get the full power of the phplib template class.
  36. * You may have one file with blocks in it but you have as well one main file
  37. * and multiple files one for each block. This is quite usefull when you have
  38. * user configurable websites. Using blocks not in the main template allows
  39. * you to modify some parts of your layout easily.
  40. *
  41. * Note that you can replace an existing block and add new blocks at runtime.
  42. * Adding new blocks means changing a variable placeholder to a block.
  43. *
  44. * @category HTML
  45. * @package HTML_Template_IT
  46. * @author Ulf Wendel <uw@netuse.de>
  47. * @license BSD http://www.opensource.org/licenses/bsd-license.php
  48. * @link http://pear.php.net/packages/HTML_Template_IT
  49. * @access public
  50. */
  51. class HTML_Template_ITX extends HTML_Template_IT
  52. {
  53. /**
  54. * Array with all warnings.
  55. * @var array
  56. * @access public
  57. * @see $printWarning, $haltOnWarning, warning()
  58. */
  59. var $warn = array();
  60. /**
  61. * Print warnings?
  62. * @var array
  63. * @access public
  64. * @see $haltOnWarning, $warn, warning()
  65. */
  66. var $printWarning = false;
  67. /**
  68. * Call die() on warning?
  69. * @var boolean
  70. * @access public
  71. * @see $warn, $printWarning, warning()
  72. */
  73. var $haltOnWarning = false;
  74. /**
  75. * RegExp used to test for a valid blockname.
  76. * @var string
  77. * @access private
  78. */
  79. var $checkblocknameRegExp = '';
  80. /**
  81. * Functionnameprefix used when searching function calls in the template.
  82. * @var string
  83. * @access public
  84. */
  85. var $functionPrefix = 'func_';
  86. /**
  87. * Functionname RegExp.
  88. * @var string
  89. * @access public
  90. */
  91. var $functionnameRegExp = '[_a-zA-Z]+[A-Za-z_0-9]*';
  92. /**
  93. * RegExp used to grep function calls in the template.
  94. *
  95. * The variable gets set by the constructor.
  96. *
  97. * @access private
  98. * @var string
  99. * @see HTML_Template_IT()
  100. */
  101. var $functionRegExp = '';
  102. /**
  103. * List of functions found in the template.
  104. *
  105. * @access private
  106. * @var array
  107. */
  108. var $functions = array();
  109. /**
  110. * List of callback functions specified by the user.
  111. *
  112. * @access private
  113. * @var array
  114. */
  115. var $callback = array();
  116. /**
  117. * Builds some complex regexps and calls the constructor
  118. * of the parent class.
  119. *
  120. * Make sure that you call this constructor if you derive your own
  121. * template class from this one.
  122. *
  123. * @param string $root Root node?
  124. *
  125. * @access public
  126. * @see HTML_Template_IT()
  127. */
  128. function HTML_Template_ITX($root = '')
  129. {
  130. $this->checkblocknameRegExp = '@' . $this->blocknameRegExp . '@';
  131. $this->functionRegExp = '@' . $this->functionPrefix . '(' .
  132. $this->functionnameRegExp . ')\s*\(@sm';
  133. $this->HTML_Template_IT($root);
  134. } // end func constructor
  135. /**
  136. * Clears all datafields of the object and rebuild the internal blocklist
  137. *
  138. * LoadTemplatefile() and setTemplate() automatically call this function
  139. * when a new template is given. Don't use this function
  140. * unless you know what you're doing.
  141. *
  142. * @access private
  143. * @return null
  144. */
  145. function init()
  146. {
  147. $this->free();
  148. $this->buildFunctionlist();
  149. $this->findBlocks($this->template);
  150. // we don't need it any more
  151. $this->template = '';
  152. $this->buildBlockvariablelist();
  153. } // end func init
  154. /**
  155. * Replaces an existing block with new content.
  156. *
  157. * This function will replace a block of the template and all blocks
  158. * contained in the replaced block and add a new block insted, means
  159. * you can dynamically change your template.
  160. *
  161. * Note that changing the template structure violates one of the IT[X]
  162. * development goals. I've tried to write a simple to use template engine
  163. * supporting blocks. In contrast to other systems IT[X] analyses the way
  164. * you've nested blocks and knows which block belongs into another block.
  165. * The nesting information helps to make the API short and simple. Replacing
  166. * blocks does not only mean that IT[X] has to update the nesting
  167. * information (relatively time consumpting task) but you have to make sure
  168. * that you do not get confused due to the template change itself.
  169. *
  170. * @param string $block Blockname
  171. * @param string $template Blockcontent
  172. * @param boolean $keep_content true if the new block inherits the content
  173. * of the old block
  174. *
  175. * @return boolean
  176. * @throws IT_Error
  177. * @see replaceBlockfile(), addBlock(), addBlockfile()
  178. * @access public
  179. */
  180. function replaceBlock($block, $template, $keep_content = false)
  181. {
  182. if (!isset($this->blocklist[$block])) {
  183. return new IT_Error("The block "."'$block'".
  184. " does not exist in the template and thus it can't be replaced.",
  185. __FILE__, __LINE__);
  186. }
  187. if ($template == '') {
  188. return new IT_Error('No block content given.', __FILE__, __LINE__);
  189. }
  190. if ($keep_content) {
  191. $blockdata = $this->blockdata[$block];
  192. }
  193. // remove all kinds of links to the block / data of the block
  194. $this->removeBlockData($block);
  195. $template = "<!-- BEGIN $block -->" . $template . "<!-- END $block -->";
  196. $parents = $this->blockparents[$block];
  197. $this->findBlocks($template);
  198. $this->blockparents[$block] = $parents;
  199. // KLUDGE: rebuild the list for all block - could be done faster
  200. $this->buildBlockvariablelist();
  201. if ($keep_content) {
  202. $this->blockdata[$block] = $blockdata;
  203. }
  204. // old TODO - I'm not sure if we need this
  205. // update caches
  206. return true;
  207. } // end func replaceBlock
  208. /**
  209. * Replaces an existing block with new content from a file.
  210. *
  211. * @param string $block Blockname
  212. * @param string $filename Name of the file that contains the blockcontent
  213. * @param boolean $keep_content true if the new block inherits the content of
  214. * the old block
  215. *
  216. * @brother replaceBlock()
  217. * @access public
  218. * @return null
  219. */
  220. function replaceBlockfile($block, $filename, $keep_content = false)
  221. {
  222. return $this->replaceBlock($block, $this->getFile($filename), $keep_content);
  223. } // end func replaceBlockfile
  224. /**
  225. * Adds a block to the template changing a variable placeholder
  226. * to a block placeholder.
  227. *
  228. * Add means "replace a variable placeholder by a new block".
  229. * This is different to PHPLibs templates. The function loads a
  230. * block, creates a handle for it and assigns it to a certain
  231. * variable placeholder. To to the same with PHPLibs templates you would
  232. * call set_file() to create the handle and parse() to assign the
  233. * parsed block to a variable. By this PHPLibs templates assume
  234. * that you tend to assign a block to more than one one placeholder.
  235. * To assign a parsed block to more than only the placeholder you specify
  236. * in this function you have to use a combination of getBlock()
  237. * and setVariable().
  238. *
  239. * As no updates to cached data is necessary addBlock() and addBlockfile()
  240. * are rather "cheap" meaning quick operations.
  241. *
  242. * The block content must not start with <!-- BEGIN blockname -->
  243. * and end with <!-- END blockname --> this would cause overhead and
  244. * produce an error.
  245. *
  246. * @param string $placeholder Name of the variable placeholder, the name
  247. * must be unique within the template.
  248. * @param string $blockname Name of the block to be added
  249. * @param string $template Content of the block
  250. *
  251. * @return boolean
  252. * @throws IT_Error
  253. * @see addBlockfile()
  254. * @access public
  255. */
  256. function addBlock($placeholder, $blockname, $template)
  257. {
  258. // Don't trust any user even if it's a programmer or yourself...
  259. if ($placeholder == '') {
  260. return new IT_Error('No variable placeholder given.',
  261. __FILE__, __LINE__);
  262. } elseif ($blockname == '' ||
  263. !preg_match($this->checkblocknameRegExp, $blockname)
  264. ) {
  265. return new IT_Error("No or invalid blockname '$blockname' given.",
  266. __FILE__, __LINE__);
  267. } elseif ($template == '') {
  268. return new IT_Error('No block content given.', __FILE__, __LINE__);
  269. } elseif (isset($this->blocklist[$blockname])) {
  270. return new IT_Error('The block already exists.',
  271. __FILE__, __LINE__);
  272. }
  273. // find out where to insert the new block
  274. $parents = $this->findPlaceholderBlocks($placeholder);
  275. if (count($parents) == 0) {
  276. return new IT_Error("The variable placeholder".
  277. " '$placeholder' was not found in the template.",
  278. __FILE__, __LINE__);
  279. } elseif (count($parents) > 1) {
  280. reset($parents);
  281. while (list($k, $parent) = each($parents)) {
  282. $msg .= "$parent, ";
  283. }
  284. $msg = substr($parent, -2);
  285. return new IT_Error("The variable placeholder "."'$placeholder'".
  286. " must be unique, found in multiple blocks '$msg'.",
  287. __FILE__, __LINE__);
  288. }
  289. $template = "<!-- BEGIN $blockname -->"
  290. . $template
  291. . "<!-- END $blockname -->";
  292. $this->findBlocks($template);
  293. if ($this->flagBlocktrouble) {
  294. return false; // findBlocks() already throws an exception
  295. }
  296. $this->blockinner[$parents[0]][] = $blockname;
  297. $escblockname = '__' . $blockname . '__';
  298. $this->blocklist[$parents[0]] = preg_replace(
  299. '@' . $this->openingDelimiter . $placeholder .
  300. $this->closingDelimiter . '@',
  301. $this->openingDelimiter . $escblockname . $this->closingDelimiter,
  302. $this->blocklist[$parents[0]]);
  303. $this->deleteFromBlockvariablelist($parents[0], $placeholder);
  304. $this->updateBlockvariablelist($blockname);
  305. return true;
  306. } // end func addBlock
  307. /**
  308. * Adds a block taken from a file to the template changing a variable
  309. * placeholder to a block placeholder.
  310. *
  311. * @param string $placeholder Name of the variable placeholder to be converted
  312. * @param string $blockname Name of the block to be added
  313. * @param string $filename File that contains the block
  314. *
  315. * @brother addBlock()
  316. * @access public
  317. * @return null
  318. */
  319. function addBlockfile($placeholder, $blockname, $filename)
  320. {
  321. return $this->addBlock($placeholder, $blockname, $this->getFile($filename));
  322. } // end func addBlockfile
  323. /**
  324. * Returns the name of the (first) block that contains
  325. * the specified placeholder.
  326. *
  327. * @param string $placeholder Name of the placeholder you're searching
  328. * @param string $block Name of the block to scan. If left out (default)
  329. * all blocks are scanned.
  330. *
  331. * @return string Name of the (first) block that contains
  332. * the specified placeholder.
  333. * If the placeholder was not found or an error occured
  334. * an empty string is returned.
  335. * @throws IT_Error
  336. * @access public
  337. */
  338. function placeholderExists($placeholder, $block = '')
  339. {
  340. if ($placeholder == '') {
  341. new IT_Error('No placeholder name given.', __FILE__, __LINE__);
  342. return '';
  343. }
  344. if ($block != '' && !isset($this->blocklist[$block])) {
  345. new IT_Error("Unknown block '$block'.", __FILE__, __LINE__);
  346. return '';
  347. }
  348. // name of the block where the given placeholder was found
  349. $found = '';
  350. if ($block != '') {
  351. if (is_array($variables = $this->blockvariables[$block])) {
  352. // search the value in the list of blockvariables
  353. reset($variables);
  354. while (list($k, $variable) = each($variables)) {
  355. if ($k == $placeholder) {
  356. $found = $block;
  357. break;
  358. }
  359. }
  360. }
  361. } else {
  362. // search all blocks and return the name of the first block that
  363. // contains the placeholder
  364. reset($this->blockvariables);
  365. while (list($blockname, $variables) = each($this->blockvariables)) {
  366. if (is_array($variables) && isset($variables[$placeholder])) {
  367. $found = $blockname;
  368. break;
  369. }
  370. }
  371. }
  372. return $found;
  373. } // end func placeholderExists
  374. /**
  375. * Checks the list of function calls in the template and
  376. * calls their callback function.
  377. *
  378. * @access public
  379. * @return null
  380. */
  381. function performCallback()
  382. {
  383. reset($this->functions);
  384. while (list($func_id, $function) = each($this->functions)) {
  385. if (isset($this->callback[$function['name']])) {
  386. if ($this->callback[$function['name']]['expandParameters']) {
  387. $callFunction = 'call_user_func_array';
  388. } else {
  389. $callFunction = 'call_user_func';
  390. }
  391. if ($this->callback[$function['name']]['object'] != '') {
  392. $call = $callFunction(
  393. array(
  394. &$GLOBALS[$this->callback[$function['name']]['object']],
  395. $this->callback[$function['name']]['function']),
  396. $function['args']);
  397. } else {
  398. $call = $callFunction(
  399. $this->callback[$function['name']]['function'],
  400. $function['args']);
  401. }
  402. $this->variableCache['__function' . $func_id . '__'] = $call;
  403. }
  404. }
  405. } // end func performCallback
  406. /**
  407. * Returns a list of all function calls in the current template.
  408. *
  409. * @return array
  410. * @access public
  411. */
  412. function getFunctioncalls()
  413. {
  414. return $this->functions;
  415. } // end func getFunctioncalls
  416. /**
  417. * Replaces a function call with the given replacement.
  418. *
  419. * @param int $functionID Function ID
  420. * @param string $replacement Replacement
  421. *
  422. * @access public
  423. * @deprecated
  424. * @return null
  425. */
  426. function setFunctioncontent($functionID, $replacement)
  427. {
  428. $this->variableCache['__function' . $functionID . '__'] = $replacement;
  429. } // end func setFunctioncontent
  430. /**
  431. * Sets a callback function.
  432. *
  433. * IT[X] templates (note the X) can contain simple function calls.
  434. * "function call" means that the editor of the template can add
  435. * special placeholder to the template like 'func_h1("embedded in h1")'.
  436. * IT[X] will grab this function calls and allow you to define a callback
  437. * function for them.
  438. *
  439. * This is an absolutely evil feature. If your application makes heavy
  440. * use of such callbacks and you're even implementing if-then etc. on
  441. * the level of a template engine you're reiventing the wheel... - that's
  442. * actually how PHP came into life. Anyway, sometimes it's handy.
  443. *
  444. * Consider also using XML/XSLT or native PHP. And please do not push
  445. * IT[X] any further into this direction of adding logics to the template
  446. * engine.
  447. *
  448. * For those of you ready for the X in IT[X]:
  449. *
  450. * <?php
  451. * ...
  452. * function h_one($args) {
  453. * return sprintf('<h1>%s</h1>', $args[0]);
  454. * }
  455. *
  456. * ...
  457. * $itx = new HTML_Template_ITX(...);
  458. * ...
  459. * $itx->setCallbackFunction('h1', 'h_one');
  460. * $itx->performCallback();
  461. * ?>
  462. *
  463. * template:
  464. * func_h1('H1 Headline');
  465. *
  466. * @param string $tplfunction Function name in the template
  467. * @param string $callbackfunction Name of the callback function
  468. * @param string $callbackobject Name of the callback object
  469. * @param boolean $expandCallbackParameters If the callback is called with
  470. * a list of parameters or with an
  471. * array holding the parameters
  472. *
  473. * @return boolean False on failure.
  474. * @throws IT_Error
  475. * @access public
  476. * @deprecated The $callbackobject parameter is depricated since
  477. * version 1.2 and might be dropped in further versions.
  478. */
  479. function setCallbackFunction($tplfunction, $callbackfunction,
  480. $callbackobject = '',
  481. $expandCallbackParameters = false)
  482. {
  483. if ($tplfunction == '' || $callbackfunction == '') {
  484. return new IT_Error("No template function "."('$tplfunction')".
  485. " and/or no callback function ('$callback') given.",
  486. __FILE__, __LINE__);
  487. }
  488. $this->callback[$tplfunction] = array(
  489. 'function' => $callbackfunction,
  490. 'object' => $callbackobject,
  491. 'expandParameters' => (boolean)
  492. $expandCallbackParameters);
  493. return true;
  494. } // end func setCallbackFunction
  495. /**
  496. * Sets the Callback function lookup table
  497. *
  498. * @param array $functions function table
  499. * array[templatefunction] =
  500. * array(
  501. * "function" => userfunction,
  502. * "object" => userobject
  503. * )
  504. *
  505. * @access public
  506. * @return null
  507. */
  508. function setCallbackFuntiontable($functions)
  509. {
  510. $this->callback = $functions;
  511. } // end func setCallbackFunctiontable
  512. /**
  513. * Recursively removes all data assiciated with a block, including
  514. * all inner blocks
  515. *
  516. * @param string $block block to be removed
  517. *
  518. * @return null
  519. * @access private
  520. */
  521. function removeBlockData($block)
  522. {
  523. if (isset($this->blockinner[$block])) {
  524. foreach ($this->blockinner[$block] as $k => $inner) {
  525. $this->removeBlockData($inner);
  526. }
  527. unset($this->blockinner[$block]);
  528. }
  529. unset($this->blocklist[$block]);
  530. unset($this->blockdata[$block]);
  531. unset($this->blockvariables[$block]);
  532. unset($this->touchedBlocks[$block]);
  533. } // end func removeBlockinner
  534. /**
  535. * Returns a list of blocknames in the template.
  536. *
  537. * @return array [blockname => blockname]
  538. * @access public
  539. * @see blockExists()
  540. */
  541. function getBlocklist()
  542. {
  543. $blocklist = array();
  544. foreach ($this->blocklist as $block => $content) {
  545. $blocklist[$block] = $block;
  546. }
  547. return $blocklist;
  548. } // end func getBlocklist
  549. /**
  550. * Checks wheter a block exists.
  551. *
  552. * @param string $blockname Blockname
  553. *
  554. * @return boolean
  555. * @access public
  556. * @see getBlocklist()
  557. */
  558. function blockExists($blockname)
  559. {
  560. return isset($this->blocklist[$blockname]);
  561. } // end func blockExists
  562. /**
  563. * Returns a list of variables of a block.
  564. *
  565. * @param string $block Blockname
  566. *
  567. * @return array [varname => varname]
  568. * @access public
  569. * @see BlockvariableExists()
  570. */
  571. function getBlockvariables($block)
  572. {
  573. if (!isset($this->blockvariables[$block])) {
  574. return array();
  575. }
  576. $variables = array();
  577. foreach ($this->blockvariables[$block] as $variable => $v) {
  578. $variables[$variable] = $variable;
  579. }
  580. return $variables;
  581. } // end func getBlockvariables
  582. /**
  583. * Checks wheter a block variable exists.
  584. *
  585. * @param string $block Blockname
  586. * @param string $variable Variablename
  587. *
  588. * @return boolean
  589. * @access public
  590. * @see getBlockvariables()
  591. */
  592. function BlockvariableExists($block, $variable)
  593. {
  594. return isset($this->blockvariables[$block][$variable]);
  595. } // end func BlockvariableExists
  596. /**
  597. * Builds a functionlist from the template.
  598. *
  599. * @access private
  600. * @return null
  601. */
  602. function buildFunctionlist()
  603. {
  604. $this->functions = array();
  605. $template = $this->template;
  606. $num = 0;
  607. while (preg_match($this->functionRegExp, $template, $regs)) {
  608. $pos = strpos($template, $regs[0]);
  609. $template = substr($template, $pos + strlen($regs[0]));
  610. $head = $this->getValue($template, ')');
  611. $args = array();
  612. $search = $regs[0] . $head . ')';
  613. $replace = $this->openingDelimiter .
  614. '__function' . $num . '__' .
  615. $this->closingDelimiter;
  616. $this->template = str_replace($search, $replace, $this->template);
  617. $template = str_replace($search, $replace, $template);
  618. while ($head != '' && $args2 = $this->getValue($head, ',')) {
  619. $arg2 = trim($args2);
  620. $args[] = ('"' == $arg2{0} || "'" == $arg2{0}) ?
  621. substr($arg2, 1, -1) : $arg2;
  622. if ($arg2 == $head) {
  623. break;
  624. }
  625. $head = substr($head, strlen($arg2) + 1);
  626. }
  627. $this->functions[$num++] = array('name' => $regs[1],
  628. 'args' => $args);
  629. }
  630. } // end func buildFunctionlist
  631. /**
  632. * Truncates the given code from the first occurence of
  633. * $delimiter but ignores $delimiter enclosed by " or '.
  634. *
  635. * @param string $code The code which should be parsed
  636. * @param string $delimiter The delimiter char
  637. *
  638. * @access private
  639. * @return string
  640. * @see buildFunctionList()
  641. */
  642. function getValue($code, $delimiter)
  643. {
  644. if ($code == '') {
  645. return '';
  646. }
  647. if (!is_array($delimiter)) {
  648. $delimiter = array($delimiter => true);
  649. }
  650. $len = strlen($code);
  651. $enclosed = false;
  652. $enclosed_by = '';
  653. if (isset($delimiter[$code[0]])) {
  654. $i = 1;
  655. } else {
  656. for ($i = 0; $i < $len; ++$i) {
  657. $char = $code[$i];
  658. if (($char == '"' || $char == "'") &&
  659. ($char == $enclosed_by || '' == $enclosed_by) &&
  660. (0 == $i || ($i > 0 && '\\' != $code[$i - 1]))) {
  661. if (!$enclosed) {
  662. $enclosed_by = $char;
  663. } else {
  664. $enclosed_by = "";
  665. }
  666. $enclosed = !$enclosed;
  667. }
  668. if (!$enclosed && isset($delimiter[$char])) {
  669. break;
  670. }
  671. }
  672. }
  673. return substr($code, 0, $i);
  674. } // end func getValue
  675. /**
  676. * Deletes one or many variables from the block variable list.
  677. *
  678. * @param string $block Blockname
  679. * @param mixed $variables Name of one variable or array of variables
  680. * (array (name => true ) ) to be stripped.
  681. *
  682. * @access private
  683. * @return null
  684. */
  685. function deleteFromBlockvariablelist($block, $variables)
  686. {
  687. if (!is_array($variables)) {
  688. $variables = array($variables => true);
  689. }
  690. reset($this->blockvariables[$block]);
  691. while (list($varname, $val) = each($this->blockvariables[$block])) {
  692. if (isset($variables[$varname])) {
  693. unset($this->blockvariables[$block][$varname]);
  694. }
  695. }
  696. } // end deleteFromBlockvariablelist
  697. /**
  698. * Updates the variable list of a block.
  699. *
  700. * @param string $block Blockname
  701. *
  702. * @access private
  703. * @return null
  704. */
  705. function updateBlockvariablelist($block)
  706. {
  707. preg_match_all($this->variablesRegExp,
  708. $this->blocklist[$block], $regs);
  709. if (count($regs[1]) != 0) {
  710. foreach ($regs[1] as $k => $var) {
  711. $this->blockvariables[$block][$var] = true;
  712. }
  713. } else {
  714. $this->blockvariables[$block] = array();
  715. }
  716. // check if any inner blocks were found
  717. if (isset($this->blockinner[$block]) &&
  718. is_array($this->blockinner[$block]) &&
  719. count($this->blockinner[$block]) > 0) {
  720. /*
  721. * loop through inner blocks, registering the variable
  722. * placeholders in each
  723. */
  724. foreach ($this->blockinner[$block] as $childBlock) {
  725. $this->updateBlockvariablelist($childBlock);
  726. }
  727. }
  728. } // end func updateBlockvariablelist
  729. /**
  730. * Returns an array of blocknames where the given variable
  731. * placeholder is used.
  732. *
  733. * @param string $variable Variable placeholder
  734. *
  735. * @return array $parents parents[0..n] = blockname
  736. * @access public
  737. */
  738. function findPlaceholderBlocks($variable)
  739. {
  740. $parents = array();
  741. reset($this->blocklist);
  742. while (list($blockname, $content) = each($this->blocklist)) {
  743. reset($this->blockvariables[$blockname]);
  744. while (list($varname, $val) = each($this->blockvariables[$blockname])) {
  745. if ($variable == $varname) {
  746. $parents[] = $blockname;
  747. }
  748. }
  749. }
  750. return $parents;
  751. } // end func findPlaceholderBlocks
  752. /**
  753. * Handles warnings, saves them to $warn and prints them or
  754. * calls die() depending on the flags
  755. *
  756. * @param string $message Warning
  757. * @param string $file File where the warning occured
  758. * @param int $line Linenumber where the warning occured
  759. *
  760. * @see $warn, $printWarning, $haltOnWarning
  761. * @access private
  762. * @return null
  763. */
  764. function warning($message, $file = '', $line = 0)
  765. {
  766. $message = sprintf('HTML_Template_ITX Warning: %s [File: %s, Line: %d]',
  767. $message,
  768. $file,
  769. $line);
  770. $this->warn[] = $message;
  771. if ($this->printWarning) {
  772. print $message;
  773. }
  774. if ($this->haltOnWarning) {
  775. die($message);
  776. }
  777. } // end func warning
  778. } // end class HTML_Template_ITX
  779. ?>