library/smarty/libs/sysplugins/smarty_internal_config_file_compiler.php
changeset 46 f11c31f7fa3e
parent 45 a56e7f9a0463
child 47 03388ec805b4
equal deleted inserted replaced
45:a56e7f9a0463 46:f11c31f7fa3e
     1 <?php
       
     2 /**
       
     3  * Smarty Internal Plugin Config File Compiler
       
     4  * This is the config file compiler class. It calls the lexer and parser to
       
     5  * perform the compiling.
       
     6  *
       
     7  * @package    Smarty
       
     8  * @subpackage Config
       
     9  * @author     Uwe Tews
       
    10  */
       
    11 
       
    12 /**
       
    13  * Main config file compiler class
       
    14  *
       
    15  * @package    Smarty
       
    16  * @subpackage Config
       
    17  */
       
    18 class Smarty_Internal_Config_File_Compiler {
       
    19     /**
       
    20      * Lexer class name
       
    21      *
       
    22      * @var string
       
    23      */
       
    24     public $lexer_class;
       
    25 
       
    26     /**
       
    27      * Parser class name
       
    28      *
       
    29      * @var string
       
    30      */
       
    31     public $parser_class;
       
    32     /**
       
    33      * Lexer object
       
    34      *
       
    35      * @var object
       
    36      */
       
    37     public $lex;
       
    38 
       
    39     /**
       
    40      * Parser object
       
    41      *
       
    42      * @var object
       
    43      */
       
    44     public $parser;
       
    45 
       
    46     /**
       
    47      * Smarty object
       
    48      *
       
    49      * @var Smarty object
       
    50      */
       
    51     public $smarty;
       
    52 
       
    53     /**
       
    54      * Smarty object
       
    55      *
       
    56      * @var Smarty_Internal_Template object
       
    57      */
       
    58     public $template;
       
    59 
       
    60     /**
       
    61      * Compiled config data sections and variables
       
    62      *
       
    63      * @var array
       
    64      */
       
    65     public $config_data = array();
       
    66 
       
    67     /**
       
    68      * compiled config data must always be written
       
    69      *
       
    70      * @var bool
       
    71      */
       
    72     public $write_compiled_code = true;
       
    73 
       
    74     /**
       
    75      * Initialize compiler
       
    76      *
       
    77      * @param string $lexer_class class name
       
    78      * @param string $parser_class class name
       
    79      * @param Smarty $smarty global instance
       
    80      */
       
    81     public function __construct($lexer_class, $parser_class, Smarty $smarty) {
       
    82         $this->smarty = $smarty;
       
    83         // get required plugins
       
    84         $this->lexer_class = $lexer_class;
       
    85         $this->parser_class = $parser_class;
       
    86         $this->smarty = $smarty;
       
    87         $this->config_data['sections'] = array();
       
    88         $this->config_data['vars'] = array();
       
    89     }
       
    90 
       
    91     /**
       
    92      * Method to compile Smarty config source.
       
    93      *
       
    94      * @param Smarty_Internal_Template $template
       
    95      *
       
    96      * @return bool true if compiling succeeded, false if it failed
       
    97      */
       
    98     public function compileTemplate(Smarty_Internal_Template $template) {
       
    99         $this->template = $template;
       
   100         $this->template->properties['file_dependency'][$this->template->source->uid] = array($this->template->source->name, $this->template->source->timestamp, $this->template->source->type);
       
   101         // on empty config just return
       
   102         if ($template->source->content == '') {
       
   103             return true;
       
   104         }
       
   105         if ($this->smarty->debugging) {
       
   106             Smarty_Internal_Debug::start_compile($this->template);
       
   107         }
       
   108         // init the lexer/parser to compile the config file
       
   109         $lex = new $this->lexer_class(str_replace(array("\r\n", "\r"), "\n", $template->source->content) . "\n", $this);
       
   110         $parser = new $this->parser_class($lex, $this);
       
   111 
       
   112         if (function_exists('mb_internal_encoding') && ((int)ini_get('mbstring.func_overload')) & 2) {
       
   113             $mbEncoding = mb_internal_encoding();
       
   114             mb_internal_encoding('ASCII');
       
   115         } else {
       
   116             $mbEncoding = null;
       
   117         }
       
   118 
       
   119         if ($this->smarty->_parserdebug) {
       
   120             $parser->PrintTrace();
       
   121         }
       
   122         // get tokens from lexer and parse them
       
   123         while ($lex->yylex()) {
       
   124             if ($this->smarty->_parserdebug) {
       
   125                 echo "<br>Parsing  {$parser->yyTokenName[$lex->token]} Token {$lex->value} Line {$lex->line} \n";
       
   126             }
       
   127             $parser->doParse($lex->token, $lex->value);
       
   128         }
       
   129         // finish parsing process
       
   130         $parser->doParse(0, 0);
       
   131 
       
   132         if ($mbEncoding) {
       
   133             mb_internal_encoding($mbEncoding);
       
   134         }
       
   135         if ($this->smarty->debugging) {
       
   136             Smarty_Internal_Debug::end_compile($this->template);
       
   137         }
       
   138         // template header code
       
   139         $template_header = "<?php /* Smarty version " . Smarty::SMARTY_VERSION . ", created on " . strftime("%Y-%m-%d %H:%M:%S") . "\n";
       
   140         $template_header .= "         compiled from \"" . $this->template->source->filepath . "\" */ ?>\n";
       
   141 
       
   142         $code = '<?php Smarty_Internal_Extension_Config::loadConfigVars($_smarty_tpl, ' . var_export($this->config_data, true) . '); ?>';
       
   143         return $template_header . Smarty_Internal_Extension_CodeFrame::create($this->template, $code);
       
   144     }
       
   145 
       
   146     /**
       
   147      * display compiler error messages without dying
       
   148      * If parameter $args is empty it is a parser detected syntax error.
       
   149      * In this case the parser is called to obtain information about expected tokens.
       
   150      * If parameter $args contains a string this is used as error message
       
   151      *
       
   152      * @param string $args individual error message or null
       
   153      *
       
   154      * @throws SmartyCompilerException
       
   155      */
       
   156     public function trigger_config_file_error($args = null) {
       
   157         $this->lex = Smarty_Internal_Configfilelexer::instance();
       
   158         $this->parser = Smarty_Internal_Configfileparser::instance();
       
   159         // get config source line which has error
       
   160         $line = $this->lex->line;
       
   161         if (isset($args)) {
       
   162             // $line--;
       
   163         }
       
   164         $match = preg_split("/\n/", $this->lex->data);
       
   165         $error_text = "Syntax error in config file '{$this->template->source->filepath}' on line {$line} '{$match[$line - 1]}' ";
       
   166         if (isset($args)) {
       
   167             // individual error message
       
   168             $error_text .= $args;
       
   169         } else {
       
   170             // expected token from parser
       
   171             foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
       
   172                 $exp_token = $this->parser->yyTokenName[$token];
       
   173                 if (isset($this->lex->smarty_token_names[$exp_token])) {
       
   174                     // token type from lexer
       
   175                     $expect[] = '"' . $this->lex->smarty_token_names[$exp_token] . '"';
       
   176                 } else {
       
   177                     // otherwise internal token name
       
   178                     $expect[] = $this->parser->yyTokenName[$token];
       
   179                 }
       
   180             }
       
   181             // output parser error message
       
   182             $error_text .= ' - Unexpected "' . $this->lex->value . '", expected one of: ' . implode(' , ', $expect);
       
   183         }
       
   184         throw new SmartyCompilerException($error_text);
       
   185     }
       
   186 }