HTML_Template_Flexy
[ class tree: HTML_Template_Flexy ] [ index: HTML_Template_Flexy ] [ all elements ]

Source for file Token.php

Documentation is available at Token.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors:  Alan Knowles <alan@akbkhome>                               |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Token.php,v 1.36 2004/04/24 02:05:48 alan_k Exp $
  20. //
  21. //  This is the master Token file for The New Token driver Engine.
  22. //  All the Token output, and building routines are in here.
  23. //
  24. //  Note overriden methods are not documented unless they differ majorly from
  25. //  The parent.
  26. //
  27. $GLOBALS['_HTML_TEMPLATE_FLEXY_TOKEN']['base'= 0; 
  28. $GLOBALS['_HTML_TEMPLATE_FLEXY_TOKEN']['state'= 0;
  29. $GLOBALS['_HTML_TEMPLATE_FLEXY_TOKEN']['statevars'= array();
  30. $GLOBALS['_HTML_TEMPLATE_FLEXY_TOKEN']['activeForm''';
  31. $GLOBALS['_HTML_TEMPLATE_FLEXY_TOKEN']['tokens'= array();
  32. $GLOBALS['_HTML_TEMPLATE_FLEXY_TOKEN']['gettextStrings'= array();
  33. $GLOBALS['_HTML_TEMPLATE_FLEXY_TOKEN']['activeFormId'= 0;
  34. $GLOBALS['_HTML_TEMPLATE_FLEXY_TOKEN']['flexyIgnore'= false;
  35. /**
  36. * Base Class for all Tokens.
  37. *
  38. @abstract Provides the static Create Method, and default toString() methods
  39. *
  40. */
  41.  
  42. class HTML_Template_Flexy_Token {
  43.     
  44.     /**
  45.     * the token type (Depreciated when we have classes for all tokens
  46.     *
  47.     * @var string 
  48.     * @access public
  49.     */
  50.     var $token;
  51.     /**
  52.     * the default value (normally a string)
  53.     *
  54.     * @var string 
  55.     * @access public
  56.     */
  57.     var $value;
  58.     /**
  59.     * the line the token is from
  60.     *
  61.     * @var int 
  62.     * @access public
  63.     */
  64.     
  65.     
  66.     var $line;
  67.  
  68.     /**
  69.     * factory a Token
  70.     *
  71.     * Standard factory method.. - with object vars.
  72.     * ?? rename me to factory?
  73.     * @param   string      Token type
  74.     * @param   mixed       Initialization settings for token
  75.     * @param   int   line that the token is defined.
  76.     * 
  77.     *
  78.     * @return   object    Created Object
  79.     * @access   public
  80.     */
  81.   
  82.     function factory($token,$value,$line{
  83.         // try not to reload the same class to often
  84.         static $loaded = array();
  85.         
  86.         
  87.         $c 'HTML_Template_Flexy_Token_'.$token;
  88.         
  89.         if (!class_exists($c&& !isset($loaded[$token])) {
  90.             // make sure parse errors are picked up - now @ here..
  91.             if (file_exists(dirname(__FILE__)."/Token/{$token}.php")) {
  92.                 require_once 'HTML/Template/Flexy/Token/'.$token.'.php';
  93.             }
  94.             $loaded[$token= true;
  95.         
  96.             
  97.         $t = new HTML_Template_Flexy_Token;
  98.         
  99.         if (class_exists($c)) {
  100.             $t = new $c;
  101.         }
  102.         $t->token = $token;
  103.         
  104.         if ($t->setValue($value=== false{
  105.             // kick back error conditions..
  106.             return false;
  107.         }
  108.         $t->line = $line;
  109.         
  110.         return $t;
  111.     }
  112.     
  113.     /**
  114.     * Standard Value iterpretor
  115.     *
  116.     * @param   mixed    value recieved from factory method
  117.  
  118.     * @return   none 
  119.     * @access   public
  120.     */
  121.   
  122.     function setValue($value{
  123.         $this->value = $value;
  124.     }
  125.  
  126.     
  127.     /**
  128.     * compile to String (vistor method) replaces toString
  129.     *
  130.     * @return   string   HTML
  131.     * @access   public
  132.     */
  133.     
  134.     function compile(&$compiler{
  135.         return $compiler->toString($this);
  136.     }
  137.     
  138.      
  139.     /**
  140.     * compile children (visitor approach).
  141.     *
  142.     * @return   string   HTML
  143.     * @access   public
  144.     */
  145.     function compileChildren&$compiler{
  146.          
  147.         if (!$this->children{
  148.             return '';
  149.         }
  150.         if ($this->ignoreChildren{
  151.             return;
  152.         }
  153.         $ret '';
  154.         //echo "output $this->id";
  155.         //new Gtk_VarDump($this);
  156.         foreach ($this->children as $child{
  157.             if (!$child{
  158.                 continue;
  159.             }
  160.             $add $child->compile($compiler);
  161.             if (is_a($add,'PEAR_Error')) {
  162.                 return $add;
  163.             }
  164.             $ret .= $add;
  165.         }
  166.         return $ret;
  167.     }
  168.     
  169.     
  170.  
  171.     
  172.     /* ======================================================= */
  173.     /* Token Managmenet = parse and store all the tokens in 
  174.      * an associative array and tree.
  175.      */
  176.    
  177.     /**
  178.     * Run a Tokenizer and Store its results
  179.     * It should build a DOM Tree of the HTML
  180.     * 
  181.     * @param   object    Tokenizer to run.. - Theoretically other Tokenizers could be done for email,rtf etc.
  182.     *
  183.     * @access   public
  184.     * @return   base token (really a dummy token, which contains the tree)
  185.     * @static
  186.     */
  187.   
  188.     function buildTokens($tokenizer
  189.     {
  190.     
  191.         global $_HTML_TEMPLATE_FLEXY_TOKEN;
  192.         
  193.         // first record is a filler - to stick all the children on !
  194.         // reset my globals..
  195.         $_HTML_TEMPLATE_FLEXY_TOKEN['base'= 0;
  196.         
  197.         $_HTML_TEMPLATE_FLEXY_TOKEN['statevars'= array();
  198.         $_HTML_TEMPLATE_FLEXY_TOKEN['state'= 0;
  199.         
  200.         $_HTML_TEMPLATE_FLEXY_TOKEN['flexyIgnore'= false;
  201.         if (@$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['flexyIgnore']{
  202.             $_HTML_TEMPLATE_FLEXY_TOKEN['flexyIgnore'= true;
  203.         }
  204.         $_HTML_TEMPLATE_FLEXY_TOKEN['activeFormId'= 0;
  205.         $_HTML_TEMPLATE_FLEXY_TOKEN['activeForm''';
  206.         
  207.         $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'= array(new HTML_Template_Flexy_Token);
  208.         $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][0]->id =0;
  209.         $_HTML_TEMPLATE_FLEXY_TOKEN['gettextStrings'= array();
  210.         $i=1;
  211.         
  212.         
  213.         // initialize state - this trys to make sure that
  214.         // you dont do to many elses etc.
  215.        
  216.         //echo "RUNNING TOKENIZER";
  217.         // step one just tokenize it.
  218.         while ($t $tokenizer->yylex()) {  
  219.             
  220.             if ($t == HTML_TEMPLATE_FLEXY_TOKEN_ERROR{
  221.                 //echo "ERROR";
  222.                 
  223.                 //print_r($tokenizer);
  224.                 $err "<PRE>" $tokenizer->error;
  225.                     htmlspecialchars(substr($tokenizer->yy_buffer,0,$tokenizer->yy_buffer_end)) 
  226.                     "<font color='red'>"htmlspecialchars(substr($tokenizer->yy_buffer,$tokenizer->yy_buffer_end,100)) 
  227.                     ".......</font></PRE>";
  228.                     
  229.                 return PEAR::raiseError('HTML_Template_Flexy::Syntax error in ".
  230.                     "Template line:'$tokenizer->yyline .
  231.                     $err
  232.                    HTML_TEMPLATE_FLEXY_ERROR_SYNTAX ,PEAR_ERROR_RETURN);
  233.             }
  234.             if ($t == HTML_TEMPLATE_FLEXY_TOKEN_NONE{
  235.                 continue;
  236.             }
  237.            
  238.             $i++;
  239.             $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i$tokenizer->value;
  240.             $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->id = $i;
  241.             
  242.             // this whole children thing needs rethinking 
  243.             // - I think the body of the page should be wrapped: ..
  244.             //  ?php if (!$this->bodyOnly) { .. <HTML> .... <BODY....>  ?php } ?
  245.             // 
  246.             
  247.             if (isset($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->ucAttributes['FLEXYSTART'])) {
  248.                 $_HTML_TEMPLATE_FLEXY_TOKEN['base'$i;
  249.                 unset($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->ucAttributes['FLEXYSTART']);
  250.             }
  251.             
  252.             if (isset($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->ucAttributes['FLEXYSTARTCHILDREN'])) {
  253.                 $_HTML_TEMPLATE_FLEXY_TOKEN['base'$i;
  254.                 $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->startChildren = true;
  255.                 unset($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->ucAttributes['FLEXYSTARTCHILDREN']);
  256.             }
  257.             
  258.             if (isset($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->ucAttributes['FLEXY:START'])) {
  259.                 $_HTML_TEMPLATE_FLEXY_TOKEN['base'$i;
  260.                 unset($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->ucAttributes['FLEXY:START']);
  261.             }
  262.             
  263.             if (isset($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->ucAttributes['FLEXY:STARTCHILDREN'])) {
  264.                 $_HTML_TEMPLATE_FLEXY_TOKEN['base'$i;
  265.                 $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->startChildren = true;
  266.                 unset($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->ucAttributes['FLEXY:STARTCHILDREN']);
  267.             }
  268.             
  269.             
  270.             //print_r($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]);
  271.              
  272.         }
  273.         //echo "BUILT TOKENS";
  274.         
  275.         $res &$_HTML_TEMPLATE_FLEXY_TOKEN['tokens'];
  276.        
  277.         // DEBUG DUMPTING : foreach($res as $k) {  $k->dump(); }
  278.         
  279.         
  280.         $stack = array();
  281.         $total $i +1;
  282.         
  283.         
  284.         // merge variables into strings. so printf && gettext work.
  285.         
  286.         for($i=1;$i<$total;$i++{
  287.             if (!isset($res[$i])) {
  288.                 continue;
  289.             }
  290.             if (strtolower(get_class($res[$i])) == 'html_template_flexy_token_text'{
  291.                 if (!$res[$i]->isWord()) {
  292.                     continue;
  293.                 }
  294.                 $res[$i]->backSearch();
  295.                 $i $res[$i]->forwardSearch($total);
  296.             }
  297.         }
  298.          
  299.         
  300.         
  301.         // connect open  and close tags.
  302.         
  303.         // this is done by having a stack for each of the tag types..
  304.         // then removing it when it finds the closing one
  305.         // eg.
  306.         //  <a href=""><img src=""></a>
  307.         //  ends up with a stack for <a>'s and a stack for <img>'s
  308.         //
  309.         //
  310.         //
  311.         
  312.        
  313.         for($i=1;$i<$total;$i++{
  314.             //echo "Checking TAG $i\n";
  315.             if (!@$res[$i]->tag{
  316.                 continue;
  317.             }
  318.             if ($res[$i]->tag{0== '/'// it's a close tag..
  319.                 //echo "GOT END TAG: {$res[$i]->tag}\n";
  320.                 $tag strtoupper(substr($res[$i]->tag,1));
  321.                 if (!isset($stack[$tag]['pos'])) {
  322.                     continue; // unmatched
  323.                 }
  324.                 
  325.                 $npos $stack[$tag]['pos'];
  326.                 if (!isset($stack[$tag][$npos])) {
  327.                     // stack is empty!!!
  328.                     continue;
  329.                 }
  330.                 //echo "CLOSING {$stack[$tag][$npos]}:{$_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$stack[$tag][$npos]]->tag} WITH {$i}:{$_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->tag}<BR>";
  331.                 $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$stack[$tag][$npos]]->close = &$_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i];
  332.                 $stack[$tag]['pos']--;
  333.                 // take it off the stack so no one else uses it!!!
  334.                 unset($stack[$tag][$npos]);
  335.                 if ($stack[$tag]['pos'< 0{
  336.                     // too many closes - just ignore it..
  337.                     $stack[$tag]['pos'= 0;
  338.                 }
  339.                 continue;
  340.             }
  341.             // new entry on stack..
  342.             $tag strtoupper($res[$i]->tag);
  343.             
  344.             if (!isset($stack[$tag])) {
  345.                 $npos $stack[$tag]['pos'= 0;
  346.             else {
  347.                 $npos = ++$stack[$tag]['pos'];
  348.             }
  349.             
  350.             $stack[$tag][$npos$i;
  351.         }
  352.                 
  353.         // create a dummy close for the end
  354.         $i $total;
  355.         $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i= new HTML_Template_Flexy_Token;
  356.         $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->id = $total;
  357.         $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][0]->close = &$_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$total];
  358.         
  359.         // now is it possible to connect children...
  360.         // now we need to GLOBALIZE!! - 
  361.         
  362.         
  363.         $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'$res;
  364.         
  365.         HTML_Template_Flexy_Token::buildChildren(0);
  366.         //new Gtk_VarDump($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][0]);
  367.        
  368.         return $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$_HTML_TEMPLATE_FLEXY_TOKEN['base']];
  369.     }
  370.     /**
  371.     * Matching closing tag for a Token
  372.     *
  373.     * @var object|none optional closing tag
  374.     * @access public
  375.     */
  376.     
  377.   
  378.     var $close;
  379.            
  380.     /**
  381.     * array of children to each object.
  382.     *
  383.     * @var array 
  384.     * @access public|private
  385.     */
  386.     
  387.   
  388.     var $children = array();
  389.     
  390.     /**
  391.     * Build the child array for each element.
  392.     * RECURSIVE FUNCTION!!!!
  393.     * @param   int  id of node to add children to.
  394.     *
  395.     * @access   public
  396.     * @static
  397.     */
  398.     function buildChildren($id
  399.     {
  400.         global $_HTML_TEMPLATE_FLEXY_TOKEN;
  401.         
  402.         $base &$_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$id];
  403.         $base->children = array();
  404.         $start $base->id +1;
  405.         $end $base->close->id;
  406.         
  407.         for ($i=$start$i<$end$i++{
  408.             //echo "{$base->id}:{$base->tag} ADDING {$i}{$_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->tag}<BR>";
  409.             //if ($base->id == 1176) {
  410.             //    echo "<PRE>";print_r($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]);
  411.             // }
  412.             $base->children[&$_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i];
  413.             if (isset($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->close)) {
  414.             
  415.                 // if the close id is greater than my id - ignore it! - 
  416.                 if ($_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->close->id > $end{
  417.                     continue;
  418.                 }
  419.                 HTML_Template_Flexy_Token::buildChildren($i);
  420.                 $i $_HTML_TEMPLATE_FLEXY_TOKEN['tokens'][$i]->close->id;
  421.             }
  422.         }
  423.     }
  424.             
  425.             
  426.             
  427.     /**
  428.     * Flag to ignore children - Used to block output for select/text area etc.
  429.     * may not be required as I moved the Tag parsing into the toString ph
  430.     *
  431.     * @var boolean ingore children
  432.     * @access public
  433.     */
  434.     
  435.   
  436.     var $ignoreChildren = false;
  437.     
  438.     
  439.     
  440.      
  441.     /* ======================================================== */
  442.     /* variable STATE management 
  443.     *
  444.     * raw variables are assumed to be $this->, unless defined by foreach..
  445.     * it also monitors syntax - eg. end without an if/foreach etc.
  446.     */
  447.  
  448.     
  449.     /**
  450.     * tell the generator you are entering a block
  451.     *
  452.     * @access   public
  453.     */
  454.     function pushState(
  455.     {
  456.         global $_HTML_TEMPLATE_FLEXY_TOKEN;
  457.         
  458.         $_HTML_TEMPLATE_FLEXY_TOKEN['state']++;
  459.         $s $_HTML_TEMPLATE_FLEXY_TOKEN['state'];
  460.         
  461.         $_HTML_TEMPLATE_FLEXY_TOKEN['statevars'][$s= array()// initialize statevars
  462.     }
  463.     /**
  464.     * tell the generator you are entering a block
  465.     *
  466.     * @return  boolean  parse error - out of bounds
  467.     * @access   public
  468.     */
  469.     function pullState(
  470.     {
  471.         global $_HTML_TEMPLATE_FLEXY_TOKEN;
  472.         
  473.         $s $_HTML_TEMPLATE_FLEXY_TOKEN['state'];
  474.         $_HTML_TEMPLATE_FLEXY_TOKEN['statevars'][$s= array()// initialize statevars
  475.         $_HTML_TEMPLATE_FLEXY_TOKEN['state']--;
  476.         if ($s<0{
  477.             return false;
  478.         }
  479.         return true;
  480.     }
  481.      /**
  482.     * get the real variable name formated x.y.z => $this->x->y->z
  483.     * if  a variable is in the stack it return $x->y->z
  484.     *
  485.     * @return  string PHP variable
  486.     * @access   public
  487.     */
  488.     
  489.     function toVar($s{
  490.         // wrap [] with quotes.
  491.         $s str_replace('[',"['",$s);
  492.         $s str_replace('%5b',"['",$s);
  493.         $s str_replace('%5B',"['",$s);
  494.         $s str_replace(']',"']",$s);
  495.         $s str_replace('%5d',"']",$s);
  496.         $s str_replace('%5D',"']",$s);
  497.         // strip the quotes if it's only numbers..
  498.         $s preg_replace("/'([0-9]+)'/""\\1",$s);
  499.         
  500.         $parts explode(".",$s);
  501.         
  502.         
  503.         $ret =  $this->findVar($parts[0]);
  504.         if (is_a($ret,'PEAR_Error')) {
  505.             return $ret;
  506.         }
  507.         
  508.         array_shift($parts);
  509.         
  510.         if (!count($parts)) {
  511.             return $ret;
  512.         }
  513.         foreach($parts as $p{
  514.             $ret .= "->{$p}";
  515.         }
  516.         return $ret;
  517.     }
  518.     /**
  519.     * do the stack lookup on the variable
  520.     * this relates to flexy
  521.     * t relates to the object being parsed.
  522.     *
  523.     * @return  string PHP variable
  524.     * @access   public
  525.     */
  526.     
  527.     function findVar($string
  528.     {
  529.         global $_HTML_TEMPLATE_FLEXY_TOKEN;
  530.     
  531.         if (!$string || $string == 't'{
  532.             return '$t';
  533.         }
  534.         if ($string == 'this'{
  535.             return '$this';
  536.         }
  537.         // accept global access on some string
  538.         if (@$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['globals'&&
  539.             preg_match('/^(_POST|_GET|_REQUEST|_SESSION|_COOKIE|GLOBALS)\[/',$string)) {
  540.             return '$'.$string;
  541.         
  542.         if (!@$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['privates'&&
  543.                 ($string{0== '_')) {
  544.                 return PEAR::raiseError('HTML_Template_Flexy::Attempt to access private variable:'.
  545.                     " on line {$this->line} of {$GLOBALS['_HTML_TEMPLATE_FLEXY']['filename']}".
  546.                     ", Use options[privates] to allow this."
  547.                    HTML_TEMPLATE_FLEXY_ERROR_SYNTAX ,PEAR_ERROR_RETURN);
  548.         }
  549.         
  550.         $lookup $string;
  551.         if ($p strpos($string,'[')) {
  552.             $lookup substr($string,0,$p);
  553.         }
  554.         
  555.         
  556.         for ($s $_HTML_TEMPLATE_FLEXY_TOKEN['state']$s > 0; $s--{
  557.             if (in_array($lookup $_HTML_TEMPLATE_FLEXY_TOKEN['statevars'][$s])) {
  558.                 return '$'.$string;
  559.             }
  560.         }
  561.         return '$t->'.$string;
  562.     }
  563.     /**
  564.     * add a variable to the stack.
  565.     *
  566.     * @param  string PHP variable
  567.     * @access   public
  568.     */
  569.     
  570.     function pushVar($string
  571.     {
  572.         global $_HTML_TEMPLATE_FLEXY_TOKEN;
  573.         $s $_HTML_TEMPLATE_FLEXY_TOKEN['state'];
  574.         $_HTML_TEMPLATE_FLEXY_TOKEN['statevars'][$s][$string;
  575.     }
  576.     
  577.      /**
  578.     * dump to text ATM
  579.     *
  580.     * 
  581.     * @access   public
  582.     */
  583.     
  584.     function dump({
  585.         echo "{$this->token}/" . (isset($this->tag? "<{$this->tag}>" : ''. ": {$this->value}\n";
  586.     }
  587.     
  588.     
  589.     
  590.     
  591. }

Documentation generated on Mon, 11 Mar 2019 10:15:39 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.