/[corp_html]/inc/Smarty.class.php
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /inc/Smarty.class.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (hide annotations)
Mon Jul 9 14:22:07 2001 UTC (22 years, 9 months ago) by dpavlin
Branch: MAIN
Changes since 1.4: +1351 -1019 lines
update to Smarty 1.3.0

1 dpavlin 1.5 <?php
2 dpavlin 1.1 /*
3 dpavlin 1.5 * Project: Smarty: the PHP compiling template engine
4     * File: Smarty.class.php
5     * Author: Monte Ohrt <monte@ispi.net>
6 dpavlin 1.1 * Andrei Zmievski <andrei@ispi.net>
7     *
8 dpavlin 1.5 * Version: 1.3.0
9 dpavlin 1.1 * Copyright: 2001 ispi of Lincoln, Inc.
10 dpavlin 1.5 *
11     * This library is free software; you can redistribute it and/or
12     * modify it under the terms of the GNU Lesser General Public
13     * License as published by the Free Software Foundation; either
14     * version 2.1 of the License, or (at your option) any later version.
15 dpavlin 1.1 *
16 dpavlin 1.5 * This library is distributed in the hope that it will be useful,
17 dpavlin 1.1 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 dpavlin 1.5 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19     * Lesser General Public License for more details.
20 dpavlin 1.1 *
21 dpavlin 1.5 * You should have received a copy of the GNU Lesser General Public
22     * License along with this library; if not, write to the Free Software
23     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 dpavlin 1.1 *
25     * You may contact the authors of Smarty by e-mail at:
26     * monte@ispi.net
27     * andrei@ispi.net
28     *
29     * Or, write to:
30     * Monte Ohrt
31     * CTO, ispi
32     * 237 S. 70th suite 220
33     * Lincoln, NE 68510
34     *
35     * The latest version of Smarty can be obtained from:
36     * http://www.phpinsider.com/
37     *
38     */
39    
40 dpavlin 1.5 require('Smarty.addons.php');
41 dpavlin 1.2 require("Smarty.local.php");
42 dpavlin 1.1
43 dpavlin 1.5 define("SMARTY_PHP_PASSTHRU",0);
44     define("SMARTY_PHP_QUOTE",1);
45     define("SMARTY_PHP_REMOVE",2);
46     define("SMARTY_PHP_ALLOW",3);
47    
48 dpavlin 1.1 class Smarty
49     {
50    
51 dpavlin 1.5 // public vars
52     var $template_dir = './templates'; // name of directory for templates
53     var $compile_dir = './templates_c'; // name of directory for compiled templates
54     var $config_dir = './configs'; // directory where config files are located
55    
56     var $global_assign = array('SCRIPT_NAME'); // variables from the GLOBALS array
57     // that are implicitly assigned
58     // to all templates
59     var $compile_check = true; // whether to check for compiling step or not:
60     // This is generally set to false once the
61     // application is entered into production and
62     // initially compiled. Leave set to true
63     // during development. true/false default true.
64    
65     var $force_compile = false; // force templates to compile every time.
66     // if cache file exists, it will
67     // override compile_check and force_compile.
68     // true/false. default false.
69     var $caching = false; // whether to use caching or not. true/false
70     var $cache_dir = './cache'; // name of directory for template cache
71     var $cache_lifetime = 3600; // number of seconds cached content will persist.
72     // 0 = never expires. default is one hour (3600)
73    
74     var $tpl_file_ext = '.tpl'; // template file extention
75    
76     var $php_handling = SMARTY_PHP_PASSTHRU; // how smarty handles php tags
77     // possible values:
78     // SMARTY_PHP_PASSTHRU -> echo tags as is
79     // SMARTY_PHP_QUOTE -> escape tags as entities
80     // SMARTY_PHP_REMOVE -> remove php tags
81     // SMARTY_PHP_ALLOW -> execute php tags
82     // default: SMARTY_PHP_PASSTHRU
83    
84     var $left_delimiter = '{'; // template tag delimiters.
85     var $right_delimiter = '}';
86    
87    
88     var $custom_funcs = array( 'html_options' => 'smarty_func_html_options',
89     'html_select_date' => 'smarty_func_html_select_date',
90     'header' => 'smarty_func_header',
91    
92     //----- local custom_funcs
93 dpavlin 1.4 'img' => 'smarty_func_img',
94     'html_checkboxes' => 'smarty_func_html_checkboxes',
95     'input' => 'smarty_func_input',
96     'rinput' => 'smarty_func_rinput',
97 dpavlin 1.5
98     );
99    
100     var $custom_mods = array( 'lower' => 'strtolower',
101     'upper' => 'strtoupper',
102     'capitalize' => 'ucwords',
103     'escape' => 'smarty_mod_escape',
104     'truncate' => 'smarty_mod_truncate',
105     'spacify' => 'smarty_mod_spacify',
106     'date_format' => 'smarty_mod_date_format',
107     'string_format' => 'smarty_mod_string_format',
108     'replace' => 'smarty_mod_replace',
109     'strip_tags' => 'smarty_mod_strip_tags',
110     'default' => 'smarty_mod_default',
111    
112     //----- local custom_mods
113     'filesize' => 'smarty_mod_filesize',
114    
115     );
116    
117     // internal vars
118     var $_error_msg = false; // error messages. true/false
119     var $_tpl_vars = array();
120     var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part
121     var $_literal_blocks = array(); // keeps literal template blocks
122     var $_current_file = null; // the current template being compiled
123     var $_current_line_no = 1; // line number for error messages
124     var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty'
125    
126    
127     /*======================================================================*\
128     Function: Smarty
129     Purpose: Constructor
130     \*======================================================================*/
131     function Smarty()
132     {
133     foreach ($this->global_assign as $var_name)
134     $this->assign($var_name, $GLOBALS[$var_name]);
135     }
136    
137    
138     /*======================================================================*\
139     Function: assign()
140     Purpose: assigns values to template variables
141     \*======================================================================*/
142    
143     function assign($tpl_var, $value = NULL)
144     {
145     if (is_array($tpl_var)){
146     foreach ($tpl_var as $key => $val) {
147     if (!empty($key))
148     $this->_tpl_vars[$key] = $val;
149     }
150     } else {
151     if (!empty($tpl_var) && isset($value))
152     $this->_tpl_vars[$tpl_var] = $value;
153     }
154     }
155    
156    
157     /*======================================================================*\
158     Function: append
159     Purpose: appens values to template variables
160     \*======================================================================*/
161     function append($tpl_var, $value = NULL)
162     {
163     if (is_array($tpl_var)) {
164     foreach ($tpl_var as $key => $val) {
165     if (!empty($key)) {
166     if (!is_array($this->_tpl_vars[$key]))
167     settype($this->_tpl_vars[$key], 'array');
168     $this->_tpl_vars[$key][] = $val;
169     }
170     }
171     } else {
172     if (!empty($tpl_var) && isset($value)) {
173     if (!is_array($this->_tpl_vars[$tpl_var]))
174     settype($this->_tpl_vars[$tpl_var], 'array');
175     $this->_tpl_vars[$tpl_var][] = $value;
176     }
177     }
178     }
179    
180    
181     /*======================================================================*\
182     Function: clear_assign()
183     Purpose: clear the given assigned template variable.
184     \*======================================================================*/
185    
186     function clear_assign($tpl_var)
187     {
188     if(is_array($tpl_var))
189     foreach($tpl_var as $curr_var)
190     unset($this->_tpl_vars[$curr_var]);
191     else
192     unset($this->_tpl_vars[$tpl_var]);
193     }
194    
195    
196     /*======================================================================*\
197     Function: register_function
198     Purpose: Registers custom function to be used in templates
199     \*======================================================================*/
200     function register_function($function, $function_impl)
201     {
202     $this->custom_funcs[$function] = $function_impl;
203     }
204    
205    
206     /*======================================================================*\
207     Function: register_modifier
208     Purpose: Registers modifier to be used in templates
209     \*======================================================================*/
210     function register_modifier($modifier, $modifier_impl)
211     {
212     $this->custom_mods[$modifier] = $modifier_impl;
213     }
214    
215    
216     /*======================================================================*\
217     Function: clear_cache()
218     Purpose: clear cached content for the given template and cache id
219     \*======================================================================*/
220    
221     function clear_cache($tpl_file, $cache_id = null)
222     {
223     $cache_tpl_md5 = md5(realpath($this->template_dir.'/'.$tpl_file));
224     $cache_dir = $this->cache_dir.'/'.$cache_tpl_md5;
225    
226     if (!is_dir($cache_dir))
227     return false;
228    
229     if (isset($cache_id)) {
230     $cache_id_md5 = md5($cache_id);
231     $cache_id_dir = substr($cache_id_md5, 0, 2);
232     $cache_file = "$cache_dir/$cache_id_dir/{$cache_tpl_md5}_$cache_id_md5.cache";
233     return (bool)(is_file($cache_file) && unlink($cache_file));
234     } else
235     return $this->_clear_tpl_cache_dir($cache_tpl_md5);
236     }
237    
238    
239     /*======================================================================*\
240     Function: clear_all_cache()
241     Purpose: clear the entire contents of cache (all templates)
242     \*======================================================================*/
243    
244     function clear_all_cache()
245     {
246     if (!is_dir($this->cache_dir))
247     return false;
248    
249     $dir_handle = opendir($this->cache_dir);
250     while ($curr_dir = readdir($dir_handle)) {
251     if ($curr_dir == '.' || $curr_dir == '..' ||
252     !is_dir($this->cache_dir.'/'.$curr_dir))
253     continue;
254    
255     $this->_clear_tpl_cache_dir($curr_dir);
256     }
257     closedir($dir_handle);
258    
259     return true;
260     }
261    
262    
263     /*======================================================================*\
264     Function: is_cached()
265     Purpose: test to see if valid cache exists for this template
266     \*======================================================================*/
267    
268     function is_cached($tpl_file, $cache_id = null)
269     {
270     if (!$this->caching)
271     return false;
272    
273     // cache name = template path + cache_id
274     $cache_tpl_md5 = md5(realpath($this->template_dir.'/'.$tpl_file));
275     $cache_id_md5 = md5($cache_id);
276     $cache_id_dir = substr($cache_id_md5, 0, 2);
277     $cache_file = $this->cache_dir."/$cache_tpl_md5/$cache_id_dir/{$cache_tpl_md5}_$cache_id_md5.cache";
278    
279     if (file_exists($cache_file) &&
280     ($this->cache_lifetime == 0 ||
281     (time() - filemtime($cache_file) <= $this->cache_lifetime)))
282     return true;
283     else
284     return false;
285    
286     }
287    
288    
289     /*======================================================================*\
290     Function: clear_all_assign()
291     Purpose: clear all the assigned template variables.
292     \*======================================================================*/
293    
294     function clear_all_assign()
295     {
296     $this->_tpl_vars = array();
297     }
298    
299    
300     /*======================================================================*\
301     Function: get_template_vars
302     Purpose: Returns an array containing template variables
303     \*======================================================================*/
304     function &get_template_vars()
305     {
306     return $this->_tpl_vars;
307     }
308    
309    
310     /*======================================================================*\
311     Function: display()
312     Purpose: executes & displays the template results
313     \*======================================================================*/
314    
315     function display($tpl_file, $cache_id = null)
316     {
317     $this->fetch($tpl_file, $cache_id, true);
318     }
319    
320     /*======================================================================*\
321     Function: fetch()
322     Purpose: executes & returns or displays the template results
323     \*======================================================================*/
324    
325     function fetch($tpl_file, $cache_id = null, $display = false)
326     {
327     global $HTTP_SERVER_VARS;
328    
329     if ($this->caching) {
330     // cache name = template path + cache_id
331     $cache_tpl_md5 = md5(realpath($this->template_dir.'/'.$tpl_file));
332     $cache_id_md5 = md5($cache_id);
333     $cache_id_dir = substr($cache_id_md5, 0, 2);
334     $cache_file = $this->cache_dir."/$cache_tpl_md5/$cache_id_dir/{$cache_tpl_md5}_$cache_id_md5.cache";
335    
336     if (file_exists($cache_file) &&
337     ($this->cache_lifetime == 0 ||
338     (time() - filemtime($cache_file) <= $this->cache_lifetime))) {
339     $results = $this->_read_file($cache_file);
340     $results = $this->_process_cached_inserts($results);
341     if ($display) {
342     echo $results;
343     return;
344     } else
345     return $results;
346     }
347     }
348    
349     // compile files
350     $this->_compile($this->template_dir);
351     //assemble compile directory path to file
352     $_compile_file = $this->compile_dir."/".$tpl_file.".php";
353    
354     extract($this->_tpl_vars);
355    
356     // if we just need to display the results, don't perform output
357     // buffering - for speed
358     if ($display && !$this->caching)
359     include($_compile_file);
360     else {
361     ob_start();
362     include($_compile_file);
363     $results = ob_get_contents();
364     ob_end_clean();
365     }
366    
367     if($this->caching) {
368     $this->_write_file($cache_file, $results, true);
369     $results = $this->_process_cached_inserts($results);
370     }
371    
372     if ($display) {
373     echo $results;
374     return;
375     } else
376     return $results;
377     }
378    
379     /*======================================================================*\
380     Function: compile()
381     Purpose: called to compile the templates
382     \*======================================================================*/
383    
384     function _compile($tpl_dir)
385     {
386     if($this->compile_check || $this->force_compile)
387     {
388     if($this->_traverse_files($tpl_dir, 0))
389     return true;
390     else
391     return false;
392     } else
393     return false;
394     }
395    
396     /*======================================================================*\
397     Function: _traverse_files()
398     Purpose: traverse the template files & process each one
399     \*======================================================================*/
400    
401     function _traverse_files($tpl_dir, $depth)
402     {
403     $retval = true;
404    
405     if (is_dir($tpl_dir)) {
406     $dir_handle = opendir($tpl_dir);
407     while ($curr_file = readdir($dir_handle)) {
408     if ($curr_file == '.' || $curr_file == '..')
409     continue;
410    
411     $filepath = $tpl_dir.'/'.$curr_file;
412     if (is_readable($filepath)) {
413     if (is_file($filepath) && substr($curr_file, -strlen($this->tpl_file_ext)) == $this->tpl_file_ext) {
414     if (!$this->_process_file($filepath)) {
415     $retval = false;
416     break;
417     }
418     } else if (is_dir($filepath)) {
419     if (!$this->_traverse_files($filepath, $depth + 1)) {
420     $retval = false;
421     break;
422     }
423     } else {
424     // invalid file type, skipping
425     $this->_set_error_msg("Invalid filetype for $filepath, skipping");
426     continue;
427     }
428     }
429     }
430    
431     closedir($dir_handle);
432     return $retval;
433     } else {
434     $this->_set_error_msg("Directory \"$tpl_dir\" does not exist or is not a directory.");
435     return false;
436     }
437     }
438    
439     /*======================================================================*\
440     Function: _process_file()
441     Input: test template files for modifications
442     and execute the compilation for each
443     one requiring it.
444     \*======================================================================*/
445    
446     function _process_file($filepath)
447     {
448     if(preg_match("/^(.+)\/([^\/]+)$/", $filepath, $match)) {
449     $tpl_file_dir = $match[1];
450     $tpl_file_name = $match[2] . '.php';
451    
452     $compile_dir = preg_replace('!^' . preg_quote($this->template_dir, '!') . '!',
453     $this->compile_dir, $match[1]);
454    
455     //create directory if none exists
456     $this->_create_dir_structure($compile_dir);
457    
458     // compile the template file if none exists or has been modified or recompile is forced
459     if ($this->force_compile || !file_exists($compile_dir."/".$tpl_file_name) ||
460     ($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) {
461     if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name))
462     return false;
463     } else {
464     // no compilation needed
465     return true;
466     }
467     } else {
468     $this->_set_error_msg("problem matching \"$filepath.\"");
469     return false;
470     }
471    
472     return true;
473     }
474    
475     /*======================================================================*\
476     Function: _create_dir_structure
477     Purpose: create full directory structure
478     \*======================================================================*/
479     function _create_dir_structure($dir)
480     {
481     if (!file_exists($dir)) {
482     $dir_parts = preg_split('!/+!', $dir, -1, PREG_SPLIT_NO_EMPTY);
483     $new_dir = ($dir{0} == '/') ? '/' : '';
484     foreach ($dir_parts as $dir_part) {
485     $new_dir .= $dir_part;
486     if (!file_exists($new_dir) && !mkdir($new_dir, 0755)) {
487     $this->_set_error_msg("problem creating directory \"$dir\"");
488     return false;
489     }
490     $new_dir .= '/';
491     }
492     }
493     }
494    
495     /*======================================================================*\
496     Function: _modified_file()
497     Input: return comparison of modification times of files
498     \*======================================================================*/
499    
500     function _modified_file($filepath, $compilepath)
501     {
502     if (filemtime($filepath) >= filemtime($compilepath))
503     return true;
504     return false;
505     }
506    
507     /*======================================================================*\
508     Function: _compile_file()
509     Input: compile a template file
510     \*======================================================================*/
511    
512     function _compile_file($filepath, $compilepath)
513     {
514     if (!($template_contents = $this->_read_file($filepath)))
515     return false;
516    
517     $this->_current_file = str_replace($this->template_dir . '/', '', $filepath);
518     $this->_current_line_no = 1;
519     $ldq = preg_quote($this->left_delimiter, '!');
520     $rdq = preg_quote($this->right_delimiter, '!');
521    
522     /* Pull out the literal blocks. */
523     preg_match_all("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_contents, $match);
524     $this->_literal_blocks = $match[1];
525     $template_contents = preg_replace("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s",
526     '{literal}', $template_contents);
527    
528     /* Gather all template tags. */
529     preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_contents, $match);
530     $template_tags = $match[1];
531     /* Split content by template tags to obtain non-template content. */
532     $text_blocks = preg_split("!{$ldq}.*?{$rdq}!s", $template_contents);
533    
534     /* TODO: speed up the following with preg_replace and /F once we require that version of PHP */
535    
536     /* loop through text blocks */
537     for ($curr_tb = 0; $curr_tb <= count($text_blocks); $curr_tb++) {
538     /* match anything within <? ?> */
539     if (preg_match_all('!(<\?[^?]*?\?>|<script\s+language\s*=\s*[\"\']?php[\"\']?\s*>)!is', $text_blocks[$curr_tb], $sp_match)) {
540     /* found at least one match, loop through each one */
541     for ($curr_sp = 0; $curr_sp < count($sp_match[0]); $curr_sp++) {
542     if (preg_match('!^(<\?(php\s|\s|=\s)|<script\s*language\s*=\s*[\"\']?php[\"\']?\s*>)!is', $sp_match[0][$curr_sp])) {
543     /* php tag */
544     if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
545     /* echo php contents */
546     $text_blocks[$curr_tb] = str_replace($sp_match[0][$curr_sp], '<?php echo \''.str_replace("'", "\'", $sp_match[0][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
547     } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
548     /* quote php tags */
549     $text_blocks[$curr_tb] = str_replace($sp_match[0][$curr_sp], htmlspecialchars($sp_match[0][$curr_sp]), $text_blocks[$curr_tb]);
550     } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
551     /* remove php tags */
552     if (substr($sp_match[0][$curr_sp], 0, 2) == '<?')
553     $text_blocks[$curr_tb] = str_replace($sp_match[0][$curr_sp], '', $text_blocks[$curr_tb]);
554     else
555     /* attempt to remove everything between <script ...> and </script> */
556     $text_blocks[$curr_tb] = preg_replace('!'.preg_quote($sp_match[0][$curr_sp], '!').'.*?</script\s*>!is', '', $text_blocks[$curr_tb]);
557     }
558     } else
559     /* echo the non-php tags */
560     $text_blocks[$curr_tb] = str_replace($sp_match[0][$curr_sp], '<?php echo \''.str_replace("'", "\'", $sp_match[0][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
561     }
562     }
563     }
564    
565     /* Compile the template tags into PHP code. */
566     $compiled_tags = array();
567     for ($i = 0; $i < count($template_tags); $i++) {
568     $this->_current_line_no += substr_count($text_blocks[$i], "\n");
569     $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
570     $this->_current_line_no += substr_count($template_tags[$i], "\n");
571     }
572    
573     $compiled_contents = '';
574    
575     /* Interleave the compiled contents and text blocks to get the final result. */
576     for ($i = 0; $i < count($compiled_tags); $i++) {
577     $compiled_contents .= $text_blocks[$i].$compiled_tags[$i];
578     }
579     $compiled_contents .= $text_blocks[$i];
580    
581     /* Reformat data between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */
582     if (preg_match_all("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $compiled_contents, $match)) {
583     $strip_tags = $match[0];
584     $strip_tags_modified = preg_replace("!{$ldq}/?strip{$rdq}|[\t ]+$|^[\t ]+!m", '', $strip_tags);
585     $strip_tags_modified = preg_replace('![\r\n]+!m', '', $strip_tags_modified);
586     for ($i = 0; $i < count($strip_tags); $i++)
587     $compiled_contents = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s",
588     $strip_tags_modified[$i], $compiled_contents, 1);
589     }
590    
591     if(!$this->_write_file($compilepath, $compiled_contents))
592     return false;
593    
594     return true;
595     }
596    
597     /*======================================================================*\
598     Function: _process_cached_inserts
599     Purpose: Replace cached inserts with the actual results
600     \*======================================================================*/
601     function _process_cached_inserts($results)
602     {
603     preg_match_all('!'.$this->_smarty_md5.'{insert_cache (.*)}'.$this->_smarty_md5.'!Uis',
604     $results, $match);
605     list($cached_inserts, $insert_args) = $match;
606    
607     for ($i = 0; $i < count($cached_inserts); $i++) {
608     $args = unserialize($insert_args[$i]);
609     $name = $args['name'];
610     unset($args['name']);
611    
612     $function_name = 'insert_' . $name;
613     $replace = $function_name($args);
614    
615     $results = str_replace($cached_inserts[$i], $replace, $results);
616     }
617    
618     return $results;
619     }
620    
621    
622     /*======================================================================*\
623     Function: _compile_tag
624     Purpose: Compile a template tag
625     \*======================================================================*/
626     function _compile_tag($template_tag)
627     {
628     /* Matched comment. */
629     if ($template_tag{0} == '*' && $template_tag{strlen($template_tag)-1} == '*')
630     return '';
631    
632     $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
633    
634     /* Split tag into two parts: command and the arguments. */
635     preg_match('/^(
636     (?: ' . $qstr_regexp . ' | (?>[^"\'\s]+))+
637     )
638     (?:\s+(.*))?
639     /xs', $template_tag, $match);
640     list(, $tag_command, $tag_args) = $match;
641    
642     /* If the tag name matches a variable or section property definition,
643     we simply process it. */
644     if (preg_match('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tag_command) || // if a variable
645     preg_match('!^#(\w+)#(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tag_command) || // or a configuration variable
646     preg_match('!^%\w+\.\w+%(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tag_command)) { // or a section property
647     settype($tag_command, 'array');
648     $this->_parse_vars_props($tag_command);
649     return "<?php echo $tag_command[0]; ?>\n";
650     }
651    
652     switch ($tag_command) {
653     case 'include':
654     return $this->_compile_include_tag($tag_args);
655    
656     case 'if':
657     return $this->_compile_if_tag($tag_args);
658    
659     case 'else':
660     return '<?php else: ?>';
661    
662     case 'elseif':
663     return $this->_compile_if_tag($tag_args, true);
664    
665     case '/if':
666     return '<?php endif; ?>';
667    
668     case 'ldelim':
669     return $this->left_delimiter;
670    
671     case 'rdelim':
672     return $this->right_delimiter;
673    
674     case 'section':
675     array_push($this->_sectionelse_stack, false);
676     return $this->_compile_section_start($tag_args);
677    
678     case 'sectionelse':
679     $this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true;
680     return "<?php endfor; else: ?>";
681    
682     case '/section':
683     if (array_pop($this->_sectionelse_stack))
684     return "<?php endif; ?>";
685     else
686     return "<?php endfor; endif; ?>";
687    
688     case 'config_load':
689     return $this->_compile_config_load_tag($tag_args);
690    
691     case 'strip':
692     case '/strip':
693     return $this->left_delimiter.$tag_command.$this->right_delimiter;
694    
695     case 'literal':
696     list (,$literal_block) = each($this->_literal_blocks);
697     $this->_current_line_no += substr_count($literal_block, "\n");
698     return $literal_block;
699    
700     case 'insert':
701     return $this->_compile_insert_tag($tag_args);
702    
703     default:
704     if (isset($this->custom_funcs[$tag_command])) {
705     return $this->_compile_custom_tag($tag_command, $tag_args);
706     } else {
707     $this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING);
708     return;
709     }
710     }
711     }
712    
713     function _compile_custom_tag($tag_command, $tag_args)
714     {
715     $function = $this->custom_funcs[$tag_command];
716    
717     if (!function_exists($function)) {
718     $this->_syntax_error("custom function '$tag_command' is not implemented", E_USER_WARNING);
719     return;
720     }
721    
722     $attrs = $this->_parse_attrs($tag_args);
723     foreach ($attrs as $arg_name => $arg_value) {
724     if (is_bool($arg_value))
725     $arg_value = $arg_value ? 'true' : 'false';
726     $arg_list[] = "'$arg_name' => $arg_value";
727     }
728    
729     return "<?php $function(array(".implode(',', (array)$arg_list).")); ?>";
730     }
731    
732    
733     /*======================================================================*\
734     Function: _compile_insert_tag
735     Purpose: Compile {insert ...} tag
736     \*======================================================================*/
737     function _compile_insert_tag($tag_args)
738     {
739     $attrs = $this->_parse_attrs($tag_args);
740     $name = substr($attrs['name'], 1, -1);
741    
742     if (empty($name)) {
743     $this->_syntax_error("missing insert name");
744     }
745    
746     foreach ($attrs as $arg_name => $arg_value) {
747     if (is_bool($arg_value))
748     $arg_value = $arg_value ? 'true' : 'false';
749     $arg_list[] = "'$arg_name' => $arg_value";
750     }
751    
752     return "<?php echo _smarty_insert_handler(array(".implode(', ', (array)$arg_list)."), \$this->caching, \$this->_smarty_md5); ?>\n";
753     }
754    
755    
756     /*======================================================================*\
757     Function: _compile_config_load_tag
758     Purpose: Compile {config_load ...} tag
759     \*======================================================================*/
760     function _compile_config_load_tag($tag_args)
761     {
762     $attrs = $this->_parse_attrs($tag_args);
763    
764     if (empty($attrs['file'])) {
765     $this->_syntax_error("missing 'file' attribute in config_load tag");
766     }
767    
768     $output = "<?php if (!class_exists('Config_File'))\n" .
769     " include_once 'Config_File.class.php';\n" .
770     "if (!is_object(\$_conf_obj) || get_class(\$_conf_obj) != 'config_file') {\n" .
771     " \$_conf_obj = new Config_File('".$this->config_dir."');\n" .
772     "}\n" .
773     "\$_config = array_merge((array)\$_config, \$_conf_obj->get(".$attrs['file']."));\n";
774    
775     if (!empty($attrs['section']))
776     $output .= '$_config = array_merge((array)$_config, $_conf_obj->get('.$attrs['file'].', '.$attrs['section'].')); ';
777    
778     $output .= '?>';
779    
780     return $output;
781     }
782    
783    
784     /*======================================================================*\
785     Function: _compile_include_tag
786     Purpose: Compile {include ...} tag
787     \*======================================================================*/
788     function _compile_include_tag($tag_args)
789     {
790     $attrs = $this->_parse_attrs($tag_args);
791    
792     if (empty($attrs['file'])) {
793     $this->_syntax_error("missing 'file' attribute in include tag");
794     } else
795     $attrs['file'] = $this->_dequote($attrs['file']);
796    
797     if (count($attrs) > 1) {
798     $include_func_name = uniqid("_include_");
799     $include_file_name = $this->compile_dir.'/'.$attrs['file'];
800    
801     foreach ($attrs as $arg_name => $arg_value) {
802     if ($arg_name == 'file') continue;
803     if (is_bool($arg_value))
804     $arg_value = $arg_value ? 'true' : 'false';
805     $arg_list[] = "'$arg_name' => $arg_value";
806     }
807    
808     return "<?php " .
809     "if (!function_exists('$include_func_name')) {\n".
810     " function $include_func_name(\$file_name, \$def_vars, \$include_vars)\n" .
811     " {\n" .
812     " extract(\$def_vars);\n" .
813     " extract(\$include_vars);\n" .
814     " include \"\$file_name.php\";\n" .
815     " }\n" .
816     "}\n" .
817     "$include_func_name(\"$include_file_name\", get_defined_vars(), array(".implode(',', (array)$arg_list)."));\n?>";
818     } else
819     return '<?php include "'.$this->compile_dir.'/'.$attrs['file'].'.php"; ?>';
820     }
821    
822    
823     /*======================================================================*\
824     Function: _compile_section_start
825     Purpose: Compile {section ...} tag
826     \*======================================================================*/
827     function _compile_section_start($tag_args)
828     {
829     $attrs = $this->_parse_attrs($tag_args);
830    
831     $output = "<?php ";
832     $section_name = $attrs['name'];
833     if (empty($section_name)) {
834     $this->_syntax_error("missing section name");
835     }
836    
837     $output .= "unset(\$_sections[$section_name]);\n";
838     $section_props = "\$_sections[$section_name]['properties']";
839    
840     foreach ($attrs as $attr_name => $attr_value) {
841     switch ($attr_name) {
842     case 'loop':
843     $output .= "{$section_props}['loop'] = is_array($attr_value) ? count($attr_value) : $attr_value;\n";
844     break;
845    
846     case 'show':
847     if (is_bool($attr_value))
848     $attr_value = $attr_value ? 'true' : 'false';
849     $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
850     break;
851    
852     default:
853     $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
854     break;
855     }
856     }
857    
858     if (isset($attrs['loop'])) {
859     $loop_check_code = "{$section_props}['loop'] > 0 && ";
860     } else {
861     $output .= "{$section_props}['loop'] = 1;\n";
862     }
863    
864     if (isset($attrs['show'])) {
865     $show_check_code = "{$section_props}['show'] && ";
866     } else {
867     $output .= "{$section_props}['show'] = {$section_props}['loop'] > 0;\n";
868     }
869    
870     $output .= "if ($loop_check_code $show_check_code true): ";
871    
872     $output .= "
873     for ({$section_props}['index'] = 0;
874     {$section_props}['index'] < {$section_props}['loop'];
875     {$section_props}['index']++):\n";
876     $output .= "{$section_props}['rownum'] = {$section_props}['index'] + 1;\n";
877    
878     $output .= "?>";
879    
880     return $output;
881     }
882    
883    
884     /*======================================================================*\
885     Function: _compile_if_tag
886     Purpose: Compile {if ...} tag
887     \*======================================================================*/
888     function _compile_if_tag($tag_args, $elseif = false)
889     {
890     /* Tokenize args for 'if' tag. */
891     preg_match_all('/(?:
892     "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | # match all double quoted strings allowed escaped double quotes
893     \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | # match all single quoted strings allowed escaped single quotes
894     [()] | # match parentheses
895     [^"\'\s()]+ # match any other token that is not any of the above
896     )/x', $tag_args, $match);
897     $tokens = $match[0];
898    
899     $this->_parse_vars_props($tokens);
900    
901     $is_arg_stack = array();
902    
903     for ($i = 0; $i < count($tokens); $i++) {
904     $token = &$tokens[$i];
905     switch ($token) {
906     case 'eq':
907     $token = '==';
908     break;
909    
910     case 'ne':
911     case 'neq':
912     $token = '!=';
913     break;
914    
915     case 'lt':
916     $token = '<';
917     break;
918    
919     case 'le':
920     case 'lte':
921     $token = '<=';
922     break;
923    
924     case 'gt':
925     $token = '>';
926     break;
927    
928     case 'ge':
929     case 'gte':
930     $token = '>=';
931     break;
932    
933     case 'and':
934     $token = '&&';
935     break;
936    
937     case 'or':
938     $token = '||';
939     break;
940    
941     case 'not':
942     $token = '!';
943     break;
944    
945     case 'mod':
946     $token = '%';
947     break;
948    
949     case '(':
950     array_push($is_arg_stack, $i);
951     break;
952    
953     case 'is':
954     /* If last token was a ')', we operate on the parenthesized
955     expression. The start of the expression is on the stack.
956     Otherwise, we operate on the last encountered token. */
957     if ($tokens[$i-1] == ')')
958     $is_arg_start = array_pop($is_arg_stack);
959     else
960     $is_arg_start = $i-1;
961     /* Construct the argument for 'is' expression, so it knows
962     what to operate on. */
963     $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
964    
965     /* Pass all tokens from next one until the end to the
966     'is' expression parsing function. The function will
967     return modified tokens, where the first one is the result
968     of the 'is' expression and the rest are the tokens it
969     didn't touch. */
970     $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
971    
972     /* Replace the old tokens with the new ones. */
973     array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
974    
975     /* Adjust argument start so that it won't change from the
976     current position for the next iteration. */
977     $i = $is_arg_start;
978     break;
979     }
980     }
981    
982     if ($elseif)
983     return '<?php elseif ('.implode(' ', $tokens).'): ?>';
984     else
985     return '<?php if ('.implode(' ', $tokens).'): ?>';
986     }
987    
988     function _parse_is_expr($is_arg, $tokens)
989     {
990     $expr_end = 0;
991    
992     if (($first_token = array_shift($tokens)) == 'not') {
993     $negate_expr = true;
994     $expr_type = array_shift($tokens);
995     } else
996     $expr_type = $first_token;
997    
998     switch ($expr_type) {
999     case 'even':
1000     if ($tokens[$expr_end] == 'by') {
1001     $expr_end++;
1002     $expr_arg = $tokens[$expr_end++];
1003     $expr = "!(($is_arg / $expr_arg) % $expr_arg)";
1004     }
1005     else
1006     $expr = "!($is_arg % 2)";
1007     break;
1008    
1009     case 'odd':
1010     if ($tokens[$expr_end] == 'by') {
1011     $expr_end++;
1012     $expr_arg = $tokens[$expr_end++];
1013     $expr = "(($is_arg / $expr_arg) % $expr_arg)";
1014     }
1015     else
1016     $expr = "($is_arg % 2)";
1017     break;
1018    
1019     case 'div':
1020     if ($tokens[$expr_end] == 'by') {
1021     $expr_end++;
1022     $expr_arg = $tokens[$expr_end++];
1023     $expr = "!($is_arg % $expr_arg)";
1024     } else {
1025     $this->_syntax_error("expecting 'by' after 'div'");
1026     }
1027     break;
1028    
1029     default:
1030     $this->_syntax_error("unknown 'is' expression - '$expr_type'");
1031     break;
1032     }
1033    
1034     if ($negate_expr) {
1035     $expr = "!($expr)";
1036     }
1037    
1038     array_splice($tokens, 0, $expr_end, $expr);
1039    
1040     return $tokens;
1041     }
1042    
1043    
1044     /*======================================================================*\
1045     Function: _parse_attrs
1046     Purpose: Parse attribute string
1047     \*======================================================================*/
1048     function _parse_attrs($tag_args, $quote = true)
1049     {
1050     /* Tokenize tag attributes. */
1051     preg_match_all('/(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*" |
1052     \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | (?>[^"\'=\s]+)
1053     )+ |
1054     [=]
1055     /x', $tag_args, $match);
1056     $tokens = $match[0];
1057     $var_delims = array('$', '#', '%');
1058    
1059     $attrs = array();
1060     /* Parse state:
1061     0 - expecting attribute name
1062     1 - expecting '='
1063     2 - expecting attribute value (not '=') */
1064     $state = 0;
1065    
1066     foreach ($tokens as $token) {
1067     switch ($state) {
1068     case 0:
1069     /* If the token is a valid identifier, we set attribute name
1070     and go to state 1. */
1071     if (preg_match('!^\w+$!', $token)) {
1072     $attr_name = $token;
1073     $state = 1;
1074     } else
1075     $this->_syntax_error("invalid attribute name - '$token'");
1076     break;
1077    
1078     case 1:
1079     /* If the token is '=', then we go to state 2. */
1080     if ($token == '=') {
1081     $state = 2;
1082     } else
1083     $this->_syntax_error("expecting '=' after attribute name");
1084     break;
1085    
1086     case 2:
1087     /* If token is not '=', we set the attribute value and go to
1088     state 0. */
1089     if ($token != '=') {
1090     /* We booleanize the token if it's a non-quoted possible
1091     boolean value. */
1092     if (preg_match('!^(on|yes|true)$!', $token))
1093     $token = true;
1094     else if (preg_match('!^(off|no|false)$!', $token))
1095     $token = false;
1096     /* If the token is not variable (doesn't start with
1097     '$', '#', or '%') and not enclosed in single or
1098     double quotes we single-quote it. */
1099     else if ($quote && !in_array($token{0}, $var_delims) &&
1100     !(($token{0} == '"' || $token[0] == "'") &&
1101     $token{strlen($token)-1} == $token{0}))
1102     $token = "'".$token."'";
1103    
1104     $attrs[$attr_name] = $token;
1105     $state = 0;
1106     } else
1107     $this->_syntax_error("'=' cannot be an attribute value");
1108     break;
1109     }
1110     }
1111    
1112     $this->_parse_vars_props($attrs);
1113    
1114     return $attrs;
1115     }
1116    
1117    
1118     /*======================================================================*\
1119     Function: _preg_grep
1120     Purpose: Emulate PHP's preg_grep()
1121     \*======================================================================*/
1122     function _preg_grep($pattern, $array)
1123     {
1124     $result = array();
1125    
1126     foreach ($array as $key => $entry) {
1127     if (preg_match($pattern, $entry))
1128     $result[$key] = $entry;
1129     }
1130    
1131     return $result;
1132     }
1133    
1134     function _parse_vars_props(&$tokens)
1135     {
1136     $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
1137    
1138     /* preg_grep() was fixed to return keys properly in 4.0.4 and later. To
1139     allow people to use older versions of PHP we emulate preg_grep() and
1140     use the version check to see what function to call. */
1141     if (strnatcmp(PHP_VERSION, '4.0.4') >= 0) {
1142     $var_exprs = preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
1143     $conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
1144     $sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
1145     } else {
1146     $var_exprs = $this->_preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
1147     $conf_var_exprs = $this->_preg_grep('!^#(\w+)#(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
1148     $sect_prop_exprs = $this->_preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
1149     }
1150    
1151     if (count($var_exprs)) {
1152     foreach ($var_exprs as $expr_index => $var_expr) {
1153     $tokens[$expr_index] = $this->_parse_var($var_expr);
1154     }
1155     }
1156    
1157     if (count($conf_var_exprs)) {
1158     foreach ($conf_var_exprs as $expr_index => $var_expr) {
1159     $tokens[$expr_index] = $this->_parse_conf_var($var_expr);
1160     }
1161     }
1162    
1163     if (count($sect_prop_exprs)) {
1164     foreach ($sect_prop_exprs as $expr_index => $section_prop_expr) {
1165     $tokens[$expr_index] = $this->_parse_section_prop($section_prop_expr);
1166     }
1167     }
1168     }
1169    
1170     function _parse_var($var_expr)
1171     {
1172     list($var_ref, $modifiers) = explode('|', substr($var_expr, 1), 2);
1173    
1174     $sections = explode('/', $var_ref);
1175     $props = explode('.', array_pop($sections));
1176     $var_name = array_shift($props);
1177    
1178     $output = "\$$var_name";
1179    
1180     foreach ($sections as $section) {
1181     $output .= "[\$_sections['$section']['properties']['index']]";
1182     }
1183     foreach ($props as $prop) {
1184     $output .= "['$prop']";
1185     }
1186    
1187     $this->_parse_modifiers($output, $modifiers);
1188    
1189     return $output;
1190     }
1191    
1192     function _parse_conf_var($conf_var_expr)
1193     {
1194     list($var_ref, $modifiers) = explode('|', $conf_var_expr, 2);
1195    
1196     $var_name = substr($var_ref, 1, -1);
1197    
1198     $output = "\$_config['$var_name']";
1199    
1200     $this->_parse_modifiers($output, $modifiers);
1201    
1202     return $output;
1203     }
1204    
1205     function _parse_section_prop($section_prop_expr)
1206     {
1207     list($var_ref, $modifiers) = explode('|', $section_prop_expr, 2);
1208    
1209     preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
1210     $section_name = $match[1];
1211     $prop_name = $match[2];
1212    
1213     $output = "\$_sections['$section_name']['properties']['$prop_name']";
1214    
1215     $this->_parse_modifiers($output, $modifiers);
1216    
1217     return $output;
1218     }
1219    
1220     function _parse_modifiers(&$output, $modifier_string)
1221     {
1222     $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
1223     preg_match_all('!\|(@?\w+)((?>:(?:'. $qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $match);
1224     list(, $modifiers, $modifier_arg_strings) = $match;
1225    
1226     for ($i = 0; $i < count($modifiers); $i++) {
1227     $modifier_name = $modifiers[$i];
1228     preg_match_all('!:(' . $qstr_regexp . '|[^:]+)!', $modifier_arg_strings[$i], $match);
1229     $modifier_args = $match[1];
1230    
1231     if ($modifier_name{0} == '@') {
1232     $map_array = 'false';
1233     $modifier_name = substr($modifier_name, 1);
1234     } else
1235     $map_array = 'true';
1236    
1237     /*
1238     * First we lookup the modifier function name in the registered
1239     * modifiers table.
1240     */
1241     $mod_func_name = $this->custom_mods[$modifier_name];
1242    
1243     /*
1244     * If we don't find that modifier there, we assume it's just a PHP
1245     * function name.
1246     */
1247     if (!isset($mod_func_name))
1248     $mod_func_name = $modifier_name;
1249    
1250     if (!function_exists($mod_func_name)) {
1251     $this->_syntax_error("modifier '$modifier_name' is not implemented", E_USER_WARNING);
1252     continue;
1253     }
1254    
1255     $this->_parse_vars_props($modifier_args);
1256    
1257     if (count($modifier_args) > 0)
1258     $modifier_args = ', '.implode(', ', $modifier_args);
1259     else
1260     $modifier_args = '';
1261    
1262     $output = "_smarty_mod_handler('$mod_func_name', $map_array, $output$modifier_args)";
1263     }
1264     }
1265    
1266    
1267     /*======================================================================*\
1268     Function: _dequote
1269     Purpose: Remove starting and ending quotes from the string
1270     \*======================================================================*/
1271     function _dequote($string)
1272     {
1273     if (($string{0} == "'" || $string{0} == '"') &&
1274     $string{strlen($string)-1} == $string{0})
1275     return substr($string, 1, -1);
1276     else
1277     return $string;
1278     }
1279    
1280    
1281     /*======================================================================*\
1282     Function: _read_file()
1283     Purpose: read in a file
1284     \*======================================================================*/
1285    
1286     function _read_file($filename)
1287    
1288     {
1289     if (!($fd = fopen($filename, 'r'))) {
1290     $this->_set_error_msg("problem reading '$filename.'");
1291     return false;
1292     }
1293     flock($fd, LOCK_SH);
1294     $contents = fread($fd, filesize($filename));
1295     fclose($fd);
1296     return $contents;
1297     }
1298    
1299     /*======================================================================*\
1300     Function: _write_file()
1301     Purpose: write out a file
1302     \*======================================================================*/
1303    
1304     function _write_file($filename, $contents, $create_dirs = false)
1305     {
1306     if($create_dirs)
1307     $this->_create_dir_structure(dirname($filename));
1308    
1309     if (!($fd = fopen($filename, 'a'))) {
1310     $this->_set_error_msg("problem writing '$filename.'");
1311     return false;
1312     }
1313     flock($fd, LOCK_EX);
1314    
1315     $fd_safe = fopen($filename, 'w');
1316    
1317     fwrite($fd_safe, $contents);
1318     fclose($fd_safe);
1319     fclose($fd);
1320    
1321     return true;
1322     }
1323    
1324    
1325     /*======================================================================*\
1326     Function: _clear_tpl_cache_dir
1327     Purpose: Clear the specified template cache
1328     \*======================================================================*/
1329     function _clear_tpl_cache_dir($cache_tpl_md5)
1330     {
1331     $cache_dir = $this->cache_dir.'/'.$cache_tpl_md5;
1332    
1333     if (!is_dir($cache_dir))
1334     return false;
1335    
1336     $dir_handle = opendir($cache_dir);
1337     while ($curr_dir = readdir($dir_handle)) {
1338     $cache_path_dir = $cache_dir.'/'.$curr_dir;
1339     if ($curr_dir == '.' || $curr_dir == '..' ||
1340     !is_dir($cache_path_dir))
1341     continue;
1342    
1343     $dir_handle2 = opendir($cache_path_dir);
1344     while ($curr_file = readdir($dir_handle2)) {
1345     if ($curr_file == '.' || $curr_file == '..')
1346     continue;
1347    
1348     $cache_file = $cache_path_dir.'/'.$curr_file;
1349     if (is_file($cache_file))
1350     unlink($cache_file);
1351     }
1352     closedir($dir_handle2);
1353     @rmdir($cache_path_dir);
1354     }
1355     closedir($dir_handle);
1356     @rmdir($cache_dir);
1357    
1358     return true;
1359     }
1360    
1361    
1362     /*======================================================================*\
1363     Function: _set_error_msg()
1364     Purpose: set the error message
1365     \*======================================================================*/
1366    
1367     function _set_error_msg($error_msg)
1368     {
1369     $this->_error_msg="smarty error: $error_msg";
1370     return true;
1371     }
1372    
1373     /*======================================================================*\
1374     Function: _syntax_error
1375     Purpose: display Smarty syntax error
1376     \*======================================================================*/
1377     function _syntax_error($error_msg, $error_type = E_USER_ERROR)
1378     {
1379     trigger_error("Smarty: [in " . $this->_current_file . " line " .
1380     $this->_current_line_no . "]: syntax error: $error_msg", $error_type);
1381     }
1382 dpavlin 1.1 }
1383 dpavlin 1.5
1384     /* vim: set expandtab: */
1385 dpavlin 1.1
1386     ?>

  ViewVC Help
Powered by ViewVC 1.1.26