/[pliva-si]/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.3 - (hide annotations)
Mon Mar 18 11:37:07 2002 UTC (22 years, 1 month ago) by dpavlin
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +1 -0 lines
*** empty log message ***

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

  ViewVC Help
Powered by ViewVC 1.1.26