home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / HTML / Template / ITX.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  26.9 KB  |  833 lines

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