Support Joomla!

Joomla! 1.5 Documentation

Packages

Package: patTemplate

Developer Network License

The Joomla! Developer Network content is © copyright 2006 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution- NonCommercial- ShareAlike 2.5
Source code for file /pattemplate/patTemplate/Compiler.php

Documentation is available at Compiler.php

  1. <?PHP
  2. /**
  3.  * Compiler for patTemplate
  4.  *
  5.  * $Id: Compiler.php 206 2004-05-14 16:49:34Z schst $
  6.  *
  7.  * WARNING: This is still experimental!
  8.  *
  9.  * @package        patTemplate
  10.  * @subpackage    Compiler
  11.  * @author        Stephan Schmidt <[email protected]>
  12.  */
  13.  
  14. // Check to ensure this file is within the rest of the framework
  15. defined('JPATH_BASE'or die();
  16.  
  17. /**
  18.  * Compiler for patTemplate
  19.  *
  20.  * $Id: Compiler.php 206 2004-05-14 16:49:34Z schst $
  21.  *
  22.  * WARNING: This is still experimental!
  23.  *
  24.  * @package        patTemplate
  25.  * @subpackage    Compiler
  26.  * @author        Stephan Schmidt <[email protected]>
  27.  *
  28.  * @todo        implement all template types
  29.  * @todo        implement variable modifiers
  30.  * @todo        implement getParsedTemplate
  31.  * @todo        check for existing compiled template
  32.  */
  33. {
  34.    /**
  35.     * list of all templates that already have been compiled
  36.     *
  37.     * @access    private
  38.     * @var        array() 
  39.     */
  40.     var $_compiledTemplates array();
  41.  
  42.    /**
  43.     * file pointer to the compiled template
  44.     *
  45.     * @access    private
  46.     * @var        resource 
  47.     */
  48.     var $_fp;
  49.  
  50.    /**
  51.     * constructor
  52.     *
  53.     * Creates a new patTemplate Compiler
  54.     *
  55.     * @access    public
  56.     * @param    string        type of the templates, either 'html' or 'tex'
  57.     */
  58.     function patTemplate_Compiler$type 'html' )
  59.     {
  60.         $GLOBALS['patTemplate_Compiler']    =    &$this;
  61.         patTemplate::patTemplate$type );
  62.     }
  63.  
  64.    /**
  65.     * compile the currently loaded templates
  66.     *
  67.     * @access    public
  68.     * @param    string    name of the input (filename, shm segment, etc.)
  69.     */
  70.     function compile$compileName null )
  71.     {
  72.         $this->_varRegexp '/'.$this->_startTag.'([^a-z:]+)'.$this->_endTag.'/U';
  73.         $this->_depRegexp '/'.$this->_startTag.'TMPL:([^a-z:]+)'.$this->_endTag.'/U';
  74.  
  75.         $compileFolder    =    $this->getOption'compileFolder' );
  76.         $compileFile    =    sprintf'%s/%s'$compileFolder$compileName );
  77.  
  78.            $this->_fp    =    fopen$compileFile'w' );
  79.         $this->_addToCode'<?PHP' );
  80.         $this->_addToCode'/**' );
  81.         $this->_addToCode' * compiled patTemplate file' );
  82.         $this->_addToCode' *' );
  83.         $this->_addToCode' * compiled on 'date'Y-m-d H:i:s' ) );
  84.         $this->_addToCode' */' );
  85.         $this->_addToCode'class compiledTemplate {' );
  86.  
  87.         foreach$this->_templates as $template => $spec )
  88.         {
  89.             $this->compileTemplate$template );
  90.         }
  91.  
  92.         $this->_addToCode'}' );
  93.         $this->_addToCode'?>' );
  94.         fclose$this->_fp );
  95.  
  96.         include_once $compileFile;
  97.         return true;
  98.     }
  99.  
  100.    /**
  101.     * compile a template
  102.     *
  103.     * @access    public
  104.     * @param    string    name of the template
  105.     */
  106.     function compileTemplate$template )
  107.     {
  108.         $name    =    strtolower$template );
  109.  
  110.         if!isset$this->_templates[$template) )
  111.         {
  112.             return    patErrorManager::raiseWarning(
  113.                                                     PATTEMPLATE_WARNING_NO_TEMPLATE,
  114.                                                     "Template '$namedoes not exist."
  115.                                                 );
  116.         }
  117.  
  118.  
  119.         /**
  120.          * check, if the template has been loaded
  121.          * and load it if necessary.
  122.          */
  123.         if$this->_templates[$template]['loaded'!== true )
  124.         {
  125.             if$this->_templates[$template]['attributes']['parse'== 'on' )
  126.             {
  127.                 $result $this->readTemplatesFromInput$this->_templates[$template]['attributes']['src']$this->_templates[$template]['attributes']['reader']null$template );
  128.             }
  129.             else
  130.             {
  131.                 $result $this->loadTemplateFromInput$this->_templates[$template]['attributes']['src']$this->_templates[$template]['attributes']['reader']$template );
  132.             }
  133.             ifpatErrorManager::isError$result ) )
  134.             {
  135.                 return $result;
  136.             }
  137.         }
  138.  
  139.         $this->_addToCode'' );
  140.         $this->_addToCode'/**' );
  141.         $this->_addToCode' * Compiled version of '.$template );
  142.         $this->_addToCode' *' );
  143.         $this->_addToCode' * Template type is '.$this->_templates[$template]['attributes']['type');
  144.         $this->_addToCode' */' );
  145.  
  146.  
  147.         /**
  148.          * start the output
  149.          */
  150.         $this->_addToCode'function '.$template.'()' );
  151.         $this->_addToCode'{' );
  152.         $this->_addToCode'$this->_prepareCompiledTemplate( "'.$template.'" );');
  153.         $this->_addToCode'$this->prepareTemplate( "'.$template.'" );');
  154.  
  155.         /**
  156.          * attributes
  157.          */
  158.         $this->_addToCode'$this->_templates["'.$template.'"]["attributes"] = unserialize( \''.serialize($this->_templates[$template]['attributes']).'\' );'1'Read the attributes' );
  159.  
  160.         /**
  161.          * copyVars
  162.          */
  163.         $this->_addToCode'$this->_templates["'.$template.'"]["copyVars"] = unserialize( \''.serialize($this->_templates[$template]['copyVars']).'\' );'1'Read the copyVars' );
  164.  
  165.         /**
  166.          * check visibility
  167.          */
  168.         $this->_addToCode'if( $this->_templates["'.$template.'"]["attributes"]["visibility"] != "hidden" ) {'1'Check, whether template is hidden' );
  169.  
  170.             /**
  171.              * autoloop the template
  172.              */
  173.                $this->_addToCode'$this->_templates["'.$template.'"]["iteration"] = 0;'2'Reset the iteration' );
  174.  
  175.             $this->_addToCode'$loop = count( $this->_vars["'.$template.'"]["rows"] );'2'Get the amount of loops' );
  176.             $this->_addToCode'$loop = max( $loop, 1 );');
  177.             $this->_addToCode'$this->_templates["'.$template.'"]["loop"] = $loop;');
  178.  
  179.             $this->_addToCode'for( $i = 0; $i < $loop; $i++ ) {'2'Traverse all variables.' );
  180.  
  181.                 /**
  182.                  * fetch the variables
  183.                  */
  184.                 $this->_addToCode'unset( $this->_templates["'.$template.'"]["vars"] );');
  185.                 $this->_addToCode'$this->_fetchVariables("'.$template.'");');
  186.  
  187.                 /**
  188.                  * different templates have to be compiled differently
  189.                  */
  190.                 switch$this->_templates[$template]['attributes']['type')
  191.                 {
  192.                     /**
  193.                      * modulo template
  194.                      */
  195.                     case 'modulo':
  196.                         $this->_compileModuloTemplate$template );
  197.                         break;
  198.  
  199.                     /**
  200.                      * simple condition template
  201.                      */
  202.                     case 'simplecondition':
  203.                         $this->_compileSimpleConditionTemplate$template );
  204.                         break;
  205.  
  206.                     /**
  207.                      * condition template
  208.                      */
  209.                     case 'condition':
  210.                         $this->_compileConditionTemplate$template );
  211.                         break;
  212.  
  213.                     /**
  214.                      * standard template
  215.                      */
  216.                     default:
  217.                         $this->_compileStandardTemplate$template );
  218.                         break;
  219.                 }
  220.                 $this->_addToCode'$this->_templates["'.$template.'"]["iteration"]++;');
  221.  
  222.             $this->_addToCode'}');
  223.  
  224.         $this->_addToCode'}');
  225.         $this->_addToCode'}' );
  226.  
  227.         /**
  228.          * remember this template
  229.          */
  230.         array_push$this->_compiledTemplates$template );
  231.     }
  232.  
  233.    /**
  234.     * compile a standard template
  235.     *
  236.     * @access    private
  237.     * @param    string        name of the template
  238.     */
  239.     function _compileStandardTemplate$template )
  240.     {
  241.         $content $this->_templateToPHP$this->_templates[$template]['content']$template );
  242.         $this->_addToCode$content );
  243.         return true;
  244.     }
  245.  
  246.    /**
  247.     * compile a modulo template
  248.     *
  249.     * A modulo template will be compiled into a switch/case
  250.     * statement.
  251.     *
  252.     * @access    private
  253.     * @param    string        name of the template
  254.     * @todo        check special conditions (__first, __last, __default)
  255.     */
  256.     function _compileModuloTemplate$template )
  257.     {
  258.         $this->_compileBuiltinConditions$template );
  259.  
  260.  
  261.         $this->_addToCode'if( !$_displayed ) {'3'Builtin condition has been displayed?' );
  262.  
  263.         /**
  264.          * build switch statement
  265.          */
  266.         $this->_addToCode'switch( ( $this->_templates["'.$template.'"]["iteration"] + 1 ) % '.$this->_templates[$template]['attributes']['modulo'].' ) {');
  267.  
  268.         foreach$this->_templates[$template]['subtemplates'as $condition => $spec )
  269.         {
  270.             $this->_addToCode'case "'.$condition.'":');
  271.             $content $this->_templateToPHP$spec['data']$template );
  272.             $this->_addToCode$content );
  273.             $this->_addToCode'break;');
  274.         }
  275.         $this->_addToCode'}');
  276.         $this->_addToCode'}');
  277.         return true;
  278.     }
  279.  
  280.    /**
  281.     * compile a simpleCondition template
  282.     *
  283.     * A simpleCondition template will be compiled into an 'if'
  284.     * statement.
  285.     *
  286.     * @access    private
  287.     * @param    string        name of the template
  288.     */
  289.     function _compileSimpleConditionTemplate$template )
  290.     {
  291.         $conditions    =    array();
  292.         foreach$this->_templates[$template]['attributes']['requiredvars'as $var )
  293.         {
  294.             array_push$conditions'isset( $this->_templates["'.$template.'"]["vars"]["'.$var.'"] )' );
  295.         }
  296.  
  297.         /**
  298.          * build switch statement
  299.          */
  300.         $this->_addToCode'if( '.implode' && '$conditions ).' ) {'3'Check for required variables' );
  301.  
  302.         $content $this->_templateToPHP$this->_templates[$template]['content']$template );
  303.         $this->_addToCode$content );
  304.         $this->_addToCode'}');
  305.         return true;
  306.     }
  307.  
  308.    /**
  309.     * compile a condition template
  310.     *
  311.     * A condition template will be compiled into an 'switch/case'
  312.     * statement.
  313.     *
  314.     * @access    private
  315.     * @param    string        name of the template
  316.     */
  317.     function _compileConditionTemplate$template )
  318.     {
  319.         /**
  320.          * __first, __last
  321.          */
  322.         $this->_compileBuiltinConditions$template );
  323.  
  324.         $this->_addToCode'if( !$_displayed ) {'3'Builtin condition has been displayed?' );
  325.  
  326.         /**
  327.          * build switch statement
  328.          */
  329.         $this->_addToCode'switch( $this->_templates["'.$template.'"]["vars"]["'.$this->_templates[$template]["attributes"]["conditionvar"].'"] ) {');
  330.  
  331.         foreach$this->_templates[$template]['subtemplates'as $condition => $spec )
  332.         {
  333.             if$condition == '__default' )
  334.             {
  335.                 $this->_addToCode'default:');
  336.             }
  337.             else
  338.             {
  339.                 $this->_addToCode'case "'.$condition.'":');
  340.             }
  341.             $content $this->_templateToPHP$spec['data']$template );
  342.             $this->_addToCode$content );
  343.             $this->_addToCode'break;');
  344.         }
  345.         $this->_addToCode'}');
  346.         $this->_addToCode'}');
  347.         return true;
  348.     }
  349.  
  350.    /**
  351.     * compile built-in conditions
  352.     *
  353.     * This will create the neccessary PHP code for:
  354.     * - __first
  355.     * - __last
  356.     *
  357.     * @access    private
  358.     * @param    string    template name
  359.     */
  360.     function _compileBuiltinConditions$template )
  361.     {
  362.         $this->_addToCode'$_displayed = false;');
  363.  
  364.         ifisset$this->_templates[$template]['subtemplates']['__first') )
  365.         {
  366.             $this->_addToCode'if( $this->_templates["'.$template.'"]["iteration"] == 0 ) {'3'Check for first entry' );
  367.             $content $this->_templateToPHP$this->_templates[$template]['subtemplates']['__first']['data']$template );
  368.             $this->_addToCode$content );
  369.             $this->_addToCode'$_displayed = true;');
  370.             $this->_addToCode'}');
  371.         }
  372.  
  373.         ifisset$this->_templates[$template]['subtemplates']['__last') )
  374.         {
  375.             $this->_addToCode'if( $this->_templates["'.$template.'"]["iteration"] == ($this->_templates["'.$template.'"]["loop"]-1) ) {'3'Check for last entry' );
  376.             $content $this->_templateToPHP$this->_templates[$template]['subtemplates']['__last']['data']$template );
  377.             $this->_addToCode$content );
  378.             $this->_addToCode'$_displayed = true;');
  379.             $this->_addToCode'}');
  380.         }
  381.     }
  382.  
  383.    /**
  384.     * build PHP code from a template
  385.     *
  386.     * This will replace the variables in a template with
  387.     * PHP Code.
  388.     *
  389.     * @access    private
  390.     * @param    string        template content
  391.     * @param    string        name of the template
  392.     * @return    string        PHP code
  393.     */
  394.     function _templateToPHP$content$template )
  395.     {
  396.         $content preg_replace$this->_varRegexp'<?PHP echo $this->_getVar( "'.$template.'", "$1"); ?>'$content  );
  397.         $content preg_replace$this->_depRegexp'<?PHP compiledTemplate::$1(); ?>'$content  );
  398.         $content '?>'.$content.'<?PHP';
  399.         return $content;
  400.     }
  401.  
  402.  
  403.    /**
  404.     * display the compiled template
  405.     *
  406.     * This is a replacement for patTemplate::displayParsedTemplate.
  407.     *
  408.     * @access    public
  409.     * @param    string        name of the template to display
  410.     */
  411.     function displayParsedTemplate$name null )
  412.     {
  413.         ifis_null$name ) )
  414.             $name $this->_root;
  415.  
  416.         $name    =    strtolower$name );
  417.  
  418.         if!is_callable'compiledTemplate'$name ) )
  419.         {
  420.             die'Unknown template' );
  421.         }
  422.  
  423.         compiledTemplate::$name();
  424.     }
  425.  
  426.    /**
  427.     * add a line to the compiled code
  428.     *
  429.     * @access    public
  430.     * @param    string        line to add
  431.     * @param    integer        indentation
  432.     * @return    void 
  433.     */
  434.     function _addToCode$line$indent 0$comment null )
  435.     {
  436.         if!is_null$comment ) )
  437.         {
  438.             fputs$this->_fp"\n" );
  439.             if$indent )
  440.                 fputs$this->_fpstr_repeat"\t"$indent ) );
  441.             fputs$this->_fp"/* $comment */\n);
  442.         }
  443.         if$indent )
  444.             fputs$this->_fpstr_repeat"\t"$indent ) );
  445.         fputs$this->_fp$line."\n" );
  446.     }
  447.  
  448.    /**
  449.     * function, used by the compiler to get a value of a variable
  450.     *
  451.     * Checks, whether the value is locally or globally set
  452.     *
  453.     * @access    private
  454.     * @param    string        template
  455.     * @param    string        variable name
  456.     *
  457.     * @todo        check for 'unusedvars' attribute
  458.     */
  459.     function _getVar$template$varname )
  460.     {
  461.         ifisset$this->_templates[$template]['vars'][$varname) )
  462.             return $this->_templates[$template]['vars'][$varname];
  463.  
  464.         ifisset$this->_globals[$this->_startTag.$varname.$this->_endTag) )
  465.             return $this->_globals[$this->_startTag.$varname.$this->_endTag];
  466.  
  467.         return '';
  468.     }
  469.  
  470.    /**
  471.     * prepare a template for the compiler
  472.     *
  473.     * @access    private
  474.     * @param    string        template name
  475.     */
  476.     function _prepareCompiledTemplate$template )
  477.     {
  478.         $this->_templates[$template]    =    array(
  479.                                                     'attributes' => array(),
  480.                                                     'copyVars'   => array(),
  481.                                                 );
  482.     }
  483. }
  484. ?>

Documentation generated on Mon, 05 Mar 2007 20:54:15 +0000 by phpDocumentor 1.3.1