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 / Flexy / Compiler / Flexy.php next >
Encoding:
PHP Script  |  2008-07-02  |  29.5 KB  |  990 lines

  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.com>                            |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Flexy.php,v 1.24 2008/04/29 02:36:05 alan_k Exp $
  20. //
  21. //  Base Compiler Class
  22. //  Standard 'Original Flavour' Flexy compiler
  23.  
  24. // this does the main conversion, (eg. for {vars and methods}) 
  25. // it relays into Compiler/Tag & Compiler/Flexy for tags and namespace handling.
  26.  
  27.  
  28.  
  29.  
  30. require_once 'HTML/Template/Flexy/Tokenizer.php';
  31. require_once 'HTML/Template/Flexy/Token.php';
  32.  
  33. class HTML_Template_Flexy_Compiler_Flexy extends HTML_Template_Flexy_Compiler {
  34.     
  35.     
  36.         
  37.     /**
  38.     * The current template (Full path)
  39.     *
  40.     * @var string
  41.     * @access public
  42.     */
  43.     var $currentTemplate;
  44.     /**
  45.     * The compile method.
  46.     * 
  47.     * @params   object HTML_Template_Flexy
  48.     * @params   string|false string to compile of false to use a file.
  49.     * @return   string   filename of template
  50.     * @access   public
  51.     */
  52.     function compile(&$flexy, $string=false) 
  53.     {
  54.         // read the entire file into one variable
  55.         
  56.         // note this should be moved to new HTML_Template_Flexy_Token
  57.         // and that can then manage all the tokens in one place..
  58.         global $_HTML_TEMPLATE_FLEXY_COMPILER;
  59.         
  60.         $this->currentTemplate  = $flexy->currentTemplate;
  61.         
  62.         
  63.         $gettextStrings = &$_HTML_TEMPLATE_FLEXY_COMPILER['gettextStrings'];
  64.         $gettextStrings = array(); // reset it.
  65.         
  66.         if (@$this->options['debug']) {
  67.             echo "compiling template $flexy->currentTemplate<BR>";
  68.             
  69.         }
  70.          
  71.         // reset the elements.
  72.         $flexy->_elements = array();
  73.         
  74.         // replace this with a singleton??
  75.         
  76.         $GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']  = $this->options;
  77.         $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements']        = array();
  78.         $GLOBALS['_HTML_TEMPLATE_FLEXY']['filename']        = $flexy->currentTemplate;
  79.         $GLOBALS['_HTML_TEMPLATE_FLEXY']['prefixOutput']    = '';
  80.         $GLOBALS['_HTML_TEMPLATE_FLEXY']['compiledTemplate']= $flexy->compiledTemplate;
  81.         
  82.         
  83.         // initialize Translation 2, and 
  84.         $this->initializeTranslator();
  85.         
  86.         
  87.         // load the template!
  88.         $data = $string;
  89.         $res = false;
  90.         if ($string === false) {
  91.             $data = file_get_contents($flexy->currentTemplate);
  92.         }
  93.          
  94.         // PRE PROCESS {_(.....)} translation markers.
  95.         if (strpos($data, '{_(') !== false) {
  96.             $data = $this->preProcessTranslation($data);
  97.         }
  98.         
  99.         // Tree generation!!!
  100.         
  101.         
  102.         
  103.         if (!$this->options['forceCompile'] && isset($_HTML_TEMPLATE_FLEXY_COMPILER['cache'][md5($data)])) {
  104.             $res = $_HTML_TEMPLATE_FLEXY_COMPILER['cache'][md5($data)];
  105.         } else {
  106.         
  107.              
  108.             $tokenizer = new HTML_Template_Flexy_Tokenizer($data);
  109.             $tokenizer->fileName = $flexy->currentTemplate;
  110.             
  111.             
  112.               
  113.             //$tokenizer->debug=1;
  114.             $tokenizer->options['ignore_html'] = $this->options['nonHTML'];
  115.             
  116.           
  117.             require_once 'HTML/Template/Flexy/Token.php';
  118.             $res = HTML_Template_Flexy_Token::buildTokens($tokenizer);
  119.             if (is_a($res, 'PEAR_Error')) {
  120.                 return $res;
  121.             }       
  122.             $_HTML_TEMPLATE_FLEXY_COMPILER['cache'][md5($data)] = $res;
  123.             
  124.         }
  125.         
  126.         
  127.         // technically we shouldnt get here as we dont cache errors..
  128.         if (is_a($res, 'PEAR_Error')) {
  129.             return $res;
  130.         }
  131.         
  132.         // turn tokens into Template..
  133.         
  134.         $data = $res->compile($this);
  135.         
  136.         if (is_a($data, 'PEAR_Error')) {
  137.             return $data;
  138.         }
  139.         
  140.         $data = $GLOBALS['_HTML_TEMPLATE_FLEXY']['prefixOutput'] . $data;
  141.         
  142.         if (   $flexy->options['debug'] > 1) {
  143.             echo "<B>Result: </B><PRE>".htmlspecialchars($data)."</PRE><BR>\n";
  144.         }
  145.  
  146.         if ($this->options['nonHTML']) {
  147.            $data =  str_replace("?>\n", "?>\n\n", $data);
  148.         }
  149.         
  150.          
  151.         
  152.         
  153.         // at this point we are into writing stuff...
  154.         if ($flexy->options['compileToString']) {
  155.             if (   $flexy->options['debug']) {
  156.                 echo "<B>Returning string:<BR>\n";
  157.             }
  158.  
  159.             $flexy->elements =  $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'];
  160.             return $data;
  161.         }
  162.         
  163.         
  164.         
  165.         
  166.         // error checking?
  167.         $file  = $flexy->compiledTemplate;
  168.         if (isset($flexy->options['output.block'])) {
  169.             list($file, $part) = explode('#', $file);
  170.         }
  171.         
  172.         if( ($cfp = fopen($file, 'w')) ) {
  173.             if ($flexy->options['debug']) {
  174.                 echo "<B>Writing: </B>$file<BR>\n";
  175.             }
  176.             fwrite($cfp, $data);
  177.             fclose($cfp);
  178.             
  179.             chmod($file, 0775);
  180.             // make the timestamp of the two items match.
  181.             clearstatcache();
  182.             touch($file, filemtime($flexy->currentTemplate));
  183.             if ($file != $flexy->compiledTemplate) {
  184.                 chmod($flexy->compiledTemplate, 0775);
  185.                 // make the timestamp of the two items match.
  186.                 clearstatcache();
  187.                 touch($flexy->compiledTemplate, filemtime($flexy->currentTemplate));
  188.             }
  189.              
  190.             
  191.         } else {
  192.             return HTML_Template_Flexy::raiseError('HTML_Template_Flexy::failed to write to '.$flexy->compiledTemplate,
  193.                 HTML_TEMPLATE_FLEXY_ERROR_FILE, HTML_TEMPLATE_FLEXY_ERROR_RETURN);
  194.         }
  195.         // gettext strings
  196.          
  197.         if (file_exists($flexy->getTextStringsFile)) {
  198.             unlink($flexy->getTextStringsFile);
  199.         }
  200.         
  201.         if($gettextStrings && ($cfp = fopen( $flexy->getTextStringsFile, 'w') ) ) {
  202.             
  203.             fwrite($cfp, serialize(array_unique($gettextStrings)));
  204.             fclose($cfp);
  205.             chmod($flexy->getTextStringsFile, 0664);
  206.         }
  207.         
  208.         // elements
  209.         if (file_exists($flexy->elementsFile)) {
  210.             unlink($flexy->elementsFile);
  211.         }
  212.         
  213.         if( $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'] &&
  214.             ($cfp = fopen( $flexy->elementsFile, 'w') ) ) {
  215.             fwrite($cfp, serialize( $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements']));
  216.             fclose($cfp);
  217.             chmod($flexy->elementsFile, 0664);
  218.             // now clear it.
  219.         
  220.         }
  221.         
  222.         return true;
  223.     }
  224.     
  225.     
  226.     /**
  227.     * Initilalize the translation methods.
  228.     *
  229.     * Loads Translation2 if required.
  230.     * 
  231.      *
  232.     * @return   none 
  233.     * @access   public 
  234.     */
  235.     function initializeTranslator() {
  236.     
  237.         if (is_array($this->options['Translation2'])) {
  238.             require_once 'Translation2.php';
  239.             $this->options['Translation2'] =  &Translation2::factory(
  240.                 $this->options['Translation2']['driver'],
  241.                 isset($this->options['Translation2']['options']) ? $this->options['Translation2']['options'] : array(),
  242.                 isset($this->options['Translation2']['params']) ? $this->options['Translation2']['params'] : array()
  243.             );
  244.         }
  245.                 
  246.         if (is_a($this->options['Translation2'], 'Translation2')) {
  247.             $this->options['Translation2']->setLang($this->options['locale']);
  248.             // fixme - needs to be more specific to which template to use..
  249.             foreach ($this->options['templateDir'] as $tt) {
  250.                 $n = basename($this->currentTemplate);
  251.                 if (substr($this->currentTemplate, 0, strlen($tt)) == $tt) {
  252.                     $n = substr($this->currentTemplate, strlen($tt)+1);
  253.                 }
  254.                 //echo $n;
  255.             }
  256.             $this->options['Translation2']->setPageID($n);
  257.         } elseif (defined('LC_ALL'))  {
  258.             // not sure what we should really use here... - used to be LC_MESSAGES.. but that did not make sense...
  259.             setlocale(LC_ALL, $this->options['locale']);
  260.         }
  261.         
  262.     }
  263.     
  264.     
  265.     
  266.     /**
  267.     * do the early tranlsation of {_(......)_} text
  268.     *
  269.     * 
  270.     * @param    input string
  271.     * @return   output string
  272.     * @access   public 
  273.     */
  274.     function preProcessTranslation($data) {
  275.         global $_HTML_TEMPLATE_FLEXY_COMPILER;
  276.         $matches = array();
  277.         $lmatches = explode ('{_(', $data);
  278.         array_shift($lmatches);
  279.         // shift the first..
  280.         foreach ($lmatches as $k) {
  281.             if (false === strpos($k, ')_}')) {
  282.                 continue;
  283.             }
  284.             $x = explode(')_}', $k);
  285.             $matches[] = $x[0];
  286.         }
  287.     
  288.     
  289.        //echo '<PRE>';print_r($matches);
  290.         // we may need to do some house cleaning here...
  291.         $_HTML_TEMPLATE_FLEXY_COMPILER['gettextStrings'] = $matches;
  292.         
  293.         
  294.         // replace them now..  
  295.         // ** leaving in the tag (which should be ignored by the parser..
  296.         // we then get rid of the tags during the toString method in this class.
  297.         foreach($matches as $v) {
  298.             $data = str_replace('{_('.$v.')_}', '{_('.$this->translateString($v).')_}', $data);
  299.         }
  300.         return $data;
  301.     }    
  302.  
  303.     
  304.     
  305.     
  306.     
  307.     /**
  308.     * Flag indicating compiler is inside {_( .... )_} block, and should not
  309.     * add to the gettextstrings array.
  310.     *
  311.     * @var boolean 
  312.     * @access public
  313.     */
  314.     var $inGetTextBlock = false;
  315.     
  316.     /**
  317.     * This is the base toString Method, it relays into toString{TokenName}
  318.     *
  319.     * @param    object    HTML_Template_Flexy_Token_*
  320.     * 
  321.     * @return   string     string to build a template
  322.     * @access   public 
  323.     * @see      toString*
  324.     */
  325.   
  326.  
  327.     function toString($element) 
  328.     {
  329.         static $len = 26; // strlen('HTML_Template_Flexy_Token_');
  330.         if ($this->options['debug'] > 1) {
  331.             $x = $element;
  332.             unset($x->children);
  333.             //echo htmlspecialchars(print_r($x,true))."<BR>\n";
  334.         }
  335.         if ($element->token == 'GetTextStart') {
  336.             $this->inGetTextBlock = true;
  337.             return '';
  338.         }
  339.         if ($element->token == 'GetTextEnd') {
  340.             $this->inGetTextBlock = false;
  341.             return '';
  342.         }
  343.         
  344.             
  345.         $class = get_class($element);
  346.         if (strlen($class) >= $len) {
  347.             $type = substr($class, $len);
  348.             return $this->{'toString'.$type}($element);
  349.         }
  350.         
  351.         $ret = $element->value;
  352.         $add = $element->compileChildren($this);
  353.         if (is_a($add, 'PEAR_Error')) {
  354.             return $add;
  355.         }
  356.         $ret .= $add;
  357.         
  358.         if ($element->close) {
  359.             $add = $element->close->compile($this);
  360.             if (is_a($add, 'PEAR_Error')) {
  361.                 return $add;
  362.             }
  363.             $ret .= $add;
  364.         }
  365.         
  366.         return $ret;
  367.     }
  368.  
  369.  
  370.     /**
  371.     *   HTML_Template_Flexy_Token_Else toString 
  372.     *
  373.     * @param    object    HTML_Template_Flexy_Token_Else
  374.     * 
  375.     * @return   string     string to build a template
  376.     * @access   public 
  377.     * @see      toString*
  378.     */
  379.   
  380.  
  381.     function toStringElse($element) 
  382.      {
  383.         // pushpull states to make sure we are in an area.. - should really check to see 
  384.         // if the state it is pulling is a if...
  385.         if ($element->pullState() === false) {
  386.             return $this->appendHTML(
  387.                 "<font color=\"red\">Unmatched {else:} on line: {$element->line}</font>"
  388.                 );
  389.         }
  390.         $element->pushState();
  391.         return $this->appendPhp("} else {");
  392.     }
  393.     
  394.     /**
  395.     *   HTML_Template_Flexy_Token_End toString 
  396.     *
  397.     * @param    object    HTML_Template_Flexy_Token_Else
  398.     * 
  399.     * @return   string     string to build a template
  400.     * @access   public 
  401.     * @see      toString*
  402.     */
  403.   
  404.     function toStringEnd($element) 
  405.     {
  406.         // pushpull states to make sure we are in an area.. - should really check to see 
  407.         // if the state it is pulling is a if...
  408.         if ($element->pullState() === false) {
  409.             return $this->appendHTML(
  410.                 "<font color=\"red\">Unmatched {end:} on line: {$element->line}</font>"
  411.                 );
  412.         }
  413.          
  414.         return $this->appendPhp("}");
  415.     }
  416.  
  417.     /**
  418.     *   HTML_Template_Flexy_Token_EndTag toString 
  419.     *
  420.     * @param    object    HTML_Template_Flexy_Token_EndTag
  421.     * 
  422.     * @return   string     string to build a template
  423.     * @access   public 
  424.     * @see      toString*
  425.     */
  426.   
  427.  
  428.  
  429.     function toStringEndTag($element) 
  430.     {
  431.         return $this->toStringTag($element);
  432.     }
  433.         
  434.     
  435.     
  436.     /**
  437.     *   HTML_Template_Flexy_Token_Foreach toString 
  438.     *
  439.     * @param    object    HTML_Template_Flexy_Token_Foreach 
  440.     * 
  441.     * @return   string     string to build a template
  442.     * @access   public 
  443.     * @see      toString*
  444.     */
  445.   
  446.     
  447.     function toStringForeach($element) 
  448.     {
  449.     
  450.         $loopon = $element->toVar($element->loopOn);
  451.         if (is_a($loopon, 'PEAR_Error')) {
  452.             return $loopon;
  453.         }
  454.         
  455.         $ret = 'if ($this->options[\'strict\'] || ('.
  456.             'is_array('. $loopon. ')  || ' .
  457.             'is_object(' . $loopon  . '))) ' .
  458.             'foreach(' . $loopon  . " ";
  459.             
  460.         $ret .= "as \${$element->key}";
  461.         
  462.         if ($element->value) {
  463.             $ret .=  " => \${$element->value}";
  464.         }
  465.         $ret .= ") {";
  466.         
  467.         $element->pushState();
  468.         $element->pushVar($element->key);
  469.         $element->pushVar($element->value);
  470.         return $this->appendPhp($ret);
  471.     }
  472.     /**
  473.     *   HTML_Template_Flexy_Token_If toString 
  474.     *
  475.     * @param    object    HTML_Template_Flexy_Token_If
  476.     * 
  477.     * @return   string     string to build a template
  478.     * @access   public 
  479.     * @see      toString*
  480.     */
  481.   
  482.     function toStringIf($element) 
  483.     {
  484.         
  485.         $var = $element->toVar($element->condition);
  486.         if (is_a($var, 'PEAR_Error')) {
  487.             return $var;
  488.         }
  489.         
  490.         $ret = "if (".$element->isNegative . $var .")  {";
  491.         $element->pushState();
  492.         return $this->appendPhp($ret);
  493.     }
  494.  
  495.    /**
  496.     *  get Modifier Wrapper 
  497.     *
  498.     * converts :h, :u, :r , .....
  499.     * @param    object    HTML_Template_Flexy_Token_Method|Var
  500.     * 
  501.     * @return   array prefix,suffix
  502.     * @access   public 
  503.     * @see      toString*
  504.     */
  505.  
  506.     function getModifierWrapper($element) 
  507.     {
  508.         $prefix = 'echo ';
  509.         
  510.         $suffix = '';
  511.         $modifier = strlen(trim($element->modifier)) ? $element->modifier : ' ';
  512.         
  513.         switch ($modifier) {
  514.             case 'h':
  515.                 break;
  516.             case 'u':
  517.                 $prefix = 'echo urlencode(';
  518.                 $suffix = ')';
  519.                 break;
  520.             case 'r':
  521.                 $prefix = 'echo \'<pre>\'; echo htmlspecialchars(print_r(';
  522.                 $suffix = ',true)); echo \'</pre>\';';
  523.                 break;                
  524.             case 'n': 
  525.                 // blank or value..
  526.                 $numberformat = @$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['numberFormat'];
  527.                 $prefix = 'echo number_format(';
  528.                 $suffix = $GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['numberFormat'] . ')';
  529.                 break;
  530.             case 'b': // nl2br + htmlspecialchars
  531.                 $prefix = 'echo nl2br(htmlspecialchars(';
  532.                 
  533.                 // add language ?
  534.                 $suffix = '))';
  535.                 break;
  536.             case 'e':
  537.                 $prefix = 'echo htmlentities(';
  538.                 // add language ?
  539.                 $suffix = ')';
  540.                 break;
  541.             case ' ':
  542.                 $prefix = 'echo htmlspecialchars(';
  543.                 // add language ?
  544.                 $suffix = ')';
  545.                 break;
  546.             default:
  547.                $prefix = 'echo $this->plugin("'.trim($element->modifier) .'",';
  548.                $suffix = ')'; 
  549.             
  550.             
  551.         }
  552.         
  553.         return array($prefix, $suffix);
  554.     }
  555.  
  556.  
  557.  
  558.   /**
  559.     *   HTML_Template_Flexy_Token_Var toString 
  560.     *
  561.     * @param    object    HTML_Template_Flexy_Token_Method
  562.     * 
  563.     * @return   string     string to build a template
  564.     * @access   public 
  565.     * @see      toString*
  566.     */
  567.   
  568.     function toStringVar($element) 
  569.     {
  570.         // ignore modifier at present!!
  571.         
  572.         $var = $element->toVar($element->value);
  573.         if (is_a($var, 'PEAR_Error')) {
  574.             return $var;
  575.         }
  576.         list($prefix, $suffix) = $this->getModifierWrapper($element);
  577.         return $this->appendPhp( $prefix . $var . $suffix .';');
  578.     }
  579.    /**
  580.     *   HTML_Template_Flexy_Token_Method toString 
  581.     *
  582.     * @param    object    HTML_Template_Flexy_Token_Method
  583.     * 
  584.     * @return   string     string to build a template
  585.     * @access   public 
  586.     * @see      toString*
  587.     */
  588.   
  589.     function toStringMethod($element) 
  590.     {
  591.  
  592.               
  593.         // set up the modifier at present!!
  594.          
  595.         list($prefix, $suffix) = $this->getModifierWrapper($element);
  596.         
  597.         // add the '!' to if
  598.         
  599.         if ($element->isConditional) {
  600.             $prefix = 'if ('.$element->isNegative;
  601.             $element->pushState();
  602.             $suffix = ')';
  603.         }  
  604.         
  605.         
  606.         // check that method exists..
  607.         // if (method_exists($object,'method');
  608.         $bits = explode('.', $element->method);
  609.         $method = array_pop($bits);
  610.         
  611.         $object = implode('.', $bits);
  612.         
  613.         $var = $element->toVar($object);
  614.         if (is_a($var, 'PEAR_Error')) {
  615.             return $var;
  616.         }
  617.         
  618.         if (($object == 'GLOBALS') && 
  619.             $GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['globalfunctions']) {
  620.             // we should check if they something weird like: GLOBALS.xxxx[sdf](....)
  621.             $var = $method;
  622.         } else {
  623.             $prefix = 'if ($this->options[\'strict\'] || (isset('.$var.
  624.                 ') && method_exists('.$var .", '{$method}'))) " . $prefix;
  625.             $var = $element->toVar($element->method);
  626.         }
  627.         
  628.  
  629.         if (is_a($var, 'PEAR_Error')) {
  630.             return $var;
  631.         }
  632.         
  633.         $ret  =  $prefix;
  634.         $ret .=  $var . "(";
  635.         $s =0;
  636.          
  637.        
  638.          
  639.         foreach($element->args as $a) {
  640.              
  641.             if ($s) {
  642.                 $ret .= ",";
  643.             }
  644.             $s =1;
  645.             if ($a{0} == '#') {
  646.                 if (is_numeric(substr($a, 1, -1))) {
  647.                     $ret .= substr($a, 1, -1);
  648.                 } else {
  649.                     $ret .= '"'. addslashes(substr($a, 1, -1)) . '"';
  650.                 }
  651.                 continue;
  652.             }
  653.             
  654.             $var = $element->toVar($a);
  655.             if (is_a($var, 'PEAR_Error')) {
  656.                 return $var;
  657.             }
  658.             $ret .= $var;
  659.             
  660.         }
  661.         $ret .= ")" . $suffix;
  662.         
  663.         if ($element->isConditional) {
  664.             $ret .= ' { ';
  665.         } else {
  666.             $ret .= ";";
  667.         }
  668.         
  669.         
  670.         
  671.         return $this->appendPhp($ret); 
  672.         
  673.          
  674.  
  675.    }
  676.    /**
  677.     *   HTML_Template_Flexy_Token_Processing toString 
  678.     *
  679.     * @param    object    HTML_Template_Flexy_Token_Processing 
  680.     * 
  681.     * @return   string     string to build a template
  682.     * @access   public 
  683.     * @see      toString*
  684.     */
  685.  
  686.  
  687.     function toStringProcessing($element) 
  688.     {
  689.         // if it's XML then quote it..
  690.         if (strtoupper(substr($element->value, 2, 3)) == 'XML') { 
  691.             return $this->appendPhp("echo '" . str_replace("'", "\\"."'", $element->value) . "';");
  692.         }
  693.         // otherwise it's PHP code - so echo it..
  694.         return $element->value;
  695.     }
  696.     
  697.     /**
  698.     *   HTML_Template_Flexy_Token_Text toString 
  699.     *
  700.     * @param    object    HTML_Template_Flexy_Token_Text
  701.     * 
  702.     * @return   string     string to build a template
  703.     * @access   public 
  704.     * @see      toString*
  705.     */
  706.  
  707.  
  708.  
  709.     function toStringText($element) 
  710.     {
  711.         
  712.         // first get rid of stuff thats not translated etc.
  713.         // empty strings => output.
  714.         // comments -> just output
  715.         // our special tags -> output..
  716.         
  717.         if (!strlen(trim($element->value) )) {
  718.             return $this->appendHtml($element->value);
  719.         }
  720.         // dont add comments to translation lists.
  721.          
  722.         if (substr($element->value, 0, 4) == '<!--') {
  723.             return $this->appendHtml($element->value);
  724.         }
  725.         // ignore anything wrapped with {_( .... )_}
  726.         if ($this->inGetTextBlock) {
  727.             return $this->appendHtml($element->value);
  728.         }
  729.         
  730.         
  731.         if (!$element->isWord()) {
  732.             return $this->appendHtml($element->value);
  733.         }
  734.         
  735.         // grab the white space at start and end (and keep it!
  736.         
  737.         $value = ltrim($element->value);
  738.         $front = substr($element->value, 0, -strlen($value));
  739.         $value = rtrim($element->value);
  740.         $rear  = substr($element->value, strlen($value));
  741.         $value = trim($element->value);
  742.         
  743.         
  744.         // convert to escaped chars.. (limited..)
  745.         //$value = strtr($value,$cleanArray);
  746.         
  747.         $this->addStringToGettext($value);
  748.         $value = $this->translateString($value);
  749.         // its a simple word!
  750.         return $this->appendHtml($front . $value . $rear);
  751.         
  752.     }
  753.     
  754.     
  755.     
  756.       /**
  757.     *   HTML_Template_Flexy_Token_Cdata toString 
  758.     *
  759.     * @param    object    HTML_Template_Flexy_Token_Cdata ?
  760.     * 
  761.     * @return   string     string to build a template
  762.     * @access   public 
  763.     * @see      toString*
  764.     */
  765.  
  766.  
  767.  
  768.     function toStringCdata($element) 
  769.     {
  770.         return $this->appendHtml($element->value);
  771.     }
  772.     
  773.     
  774.     
  775.     
  776.     
  777.     
  778.     
  779.     
  780.     
  781.     
  782.     /**
  783.     * addStringToGettext 
  784.     *
  785.     * Adds a string to the gettext array. 
  786.     * 
  787.     * @param   mixed        preferably.. string to store
  788.     *
  789.     * @return   none
  790.     * @access   public
  791.     */
  792.     
  793.     function addStringToGettext($string) 
  794.     {
  795.     
  796.         
  797.         
  798.         
  799.         if (!is_string($string)) {
  800.             return;
  801.         }
  802.         
  803.         if (!preg_match('/\w+/i', $string)) {
  804.             return;
  805.         }
  806.         $string = trim($string);
  807.         
  808.         if (substr($string, 0, 4) == '<!--') {
  809.             return;
  810.         }
  811.         
  812.         $GLOBALS['_HTML_TEMPLATE_FLEXY_COMPILER']['gettextStrings'][] = $string;
  813.     }
  814.     
  815.     
  816.     /**
  817.     * translateString - a gettextWrapper
  818.     *
  819.     * tries to do gettext or falls back on File_Gettext
  820.     * This has !!!NO!!! error handling - if it fails you just get english.. 
  821.     * no questions asked!!!
  822.     * 
  823.     * @param   string       string to translate
  824.     *
  825.     * @return   string      translated string..
  826.     * @access   public
  827.     */
  828.   
  829.     function translateString($string)
  830.     {
  831.          
  832.         
  833.         
  834.         if (is_a($this->options['Translation2'], 'Translation2')) {
  835.             $result = $this->options['Translation2']->get($string);
  836.             if (!empty($result)) {
  837.                 return $result;
  838.             }
  839.             return $string;
  840.         }
  841.         
  842.         // note this stuff may have been broken by removing the \n replacement code 
  843.         // since i dont have a test for it... it may remain broken..
  844.         // use Translation2 - it has gettext backend support
  845.         // and should sort out the mess that \n etc. entail.
  846.         
  847.         
  848.         $prefix = basename($GLOBALS['_HTML_TEMPLATE_FLEXY']['filename']).':';
  849.         if (@$this->options['debug']) {
  850.             echo __CLASS__.":TRANSLATING $string<BR>\n";
  851.         }
  852.         
  853.         if (function_exists('gettext') && !$this->options['textdomain']) {
  854.             if (@$this->options['debug']) {
  855.                 echo __CLASS__.":USING GETTEXT?<BR>";
  856.             }
  857.             $t = gettext($string);
  858.             
  859.             if ($t != $string) {
  860.                 return $t;
  861.             }
  862.             $tt = gettext($prefix.$string);
  863.             if ($tt != $prefix.$string) {
  864.                 return $tt;
  865.             }
  866.                 // give up it's not translated anywhere...
  867.             return $string;
  868.              
  869.         }
  870.         if (!$this->options['textdomain'] || !$this->options['textdomainDir']) {
  871.             // text domain is not set..
  872.             if (@$this->options['debug']) {
  873.                 echo __CLASS__.":MISSING textdomain settings<BR>";
  874.             }
  875.             return $string;
  876.         }
  877.         $pofile = $this->options['textdomainDir'] . 
  878.                 '/' . $this->options['locale'] . 
  879.                 '/LC_MESSAGES/' . $this->options['textdomain'] . '.po';
  880.         
  881.         
  882.         // did we try to load it already..
  883.         if (@$GLOBALS['_'.__CLASS__]['PO'][$pofile] === false) {
  884.             if (@$this->options['debug']) {
  885.                 echo __CLASS__.":LOAD failed (Cached):<BR>";
  886.             }
  887.             return $string;
  888.         }
  889.         if (!@$GLOBALS['_'.__CLASS__]['PO'][$pofile]) {
  890.             // default - cant load it..
  891.             $GLOBALS['_'.__CLASS__]['PO'][$pofile] = false;
  892.             if (!file_exists($pofile)) {
  893.                  if (@$this->options['debug']) {
  894.                 echo __CLASS__.":LOAD failed: {$pofile}<BR>";
  895.             }
  896.                 return $string;
  897.             }
  898.             
  899.             if (!@include_once 'File/Gettext.php') {
  900.                 if (@$this->options['debug']) {
  901.                     echo __CLASS__.":LOAD no File_gettext:<BR>";
  902.                 }
  903.                 return $string;
  904.             }
  905.             
  906.             $GLOBALS['_'.__CLASS__]['PO'][$pofile] = File_Gettext::factory('PO', $pofile);
  907.             $GLOBALS['_'.__CLASS__]['PO'][$pofile]->load();
  908.             //echo '<PRE>'.htmlspecialchars(print_r($GLOBALS['_'.__CLASS__]['PO'][$pofile]->strings,true));
  909.             
  910.         }
  911.         $po = &$GLOBALS['_'.__CLASS__]['PO'][$pofile];
  912.         // we should have it loaded now...
  913.         // this is odd - data is a bit messed up with CR's
  914.         $string = str_replace('\n', "\n", $string);
  915.         
  916.         if (isset($po->strings[$prefix.$string])) {
  917.             return $po->strings[$prefix.$string];
  918.         }
  919.         
  920.         if (!isset($po->strings[$string])) {
  921.             if (@$this->options['debug']) {
  922.                     echo __CLASS__.":no match:<BR>";
  923.             }
  924.             return $string;
  925.         }
  926.         if (@$this->options['debug']) {
  927.             echo __CLASS__.":MATCHED: {$po->strings[$string]}<BR>";
  928.         }
  929.         
  930.         // finally we have a match!!!
  931.         return $po->strings[$string];
  932.         
  933.     } 
  934.      /**
  935.     *   HTML_Template_Flexy_Token_Tag toString 
  936.     *
  937.     * @param    object    HTML_Template_Flexy_Token_Tag
  938.     * 
  939.     * @return   string     string to build a template
  940.     * @access   public 
  941.     * @see      toString*
  942.     */
  943.   
  944.     function toStringTag($element) {
  945.         
  946.         $original = $element->getAttribute('ALT');
  947.         // techncially only input type=(submit|button|input) alt=.. applies, but we may 
  948.         // as well translate any occurance...
  949.         if ( (($element->tag == 'IMG') || ($element->tag == 'INPUT'))
  950.                 && is_string($original) && strlen($original)) {
  951.             $this->addStringToGettext($original);
  952.             $quote = $element->ucAttributes['ALT']{0};
  953.             $element->ucAttributes['ALT'] = $quote  . $this->translateString($original). $quote;
  954.         }
  955.         $original = $element->getAttribute('TITLE');
  956.         if (is_string($original) && strlen($original)) {
  957.             $this->addStringToGettext($original);
  958.             $quote = $element->ucAttributes['TITLE']{0};
  959.             $element->ucAttributes['TITLE'] = $quote  . $this->translateString($original). $quote;
  960.         }
  961.         
  962.         
  963.         if (strpos($element->tag, ':') === false) {
  964.             $namespace = 'Tag';
  965.         } else {
  966.             $bits =  explode(':', $element->tag);
  967.             $namespace = $bits[0];
  968.         }
  969.         if ($namespace{0} == '/') {
  970.             $namespace = substr($namespace, 1);
  971.         }
  972.         if (empty($this->tagHandlers[$namespace])) {
  973.             
  974.             require_once 'HTML/Template/Flexy/Compiler/Flexy/Tag.php';
  975.             $this->tagHandlers[$namespace] = &HTML_Template_Flexy_Compiler_Flexy_Tag::factory($namespace, $this);
  976.             if (!$this->tagHandlers[$namespace] ) {
  977.                 return HTML_Template_Flexy::raiseError('HTML_Template_Flexy::failed to create Namespace Handler '.$namespace . 
  978.                     ' in file ' . $GLOBALS['_HTML_TEMPLATE_FLEXY']['filename'],
  979.                     HTML_TEMPLATE_FLEXY_ERROR_SYNTAX, HTML_TEMPLATE_FLEXY_ERROR_RETURN);
  980.             }
  981.                 
  982.         }
  983.         return $this->tagHandlers[$namespace]->toString($element);
  984.         
  985.         
  986.     }
  987.     
  988.  
  989. }
  990.